我正在使用 Spring MVC。我有一个 UserService
用 @Service
注释的类,它有很多静态变量。我想用 application.properties 文件中的值来实例化它们。
例如在 application.properties 我有: SVN_URL = http://some.url/repositories
然后在课堂上有: @Value("${SVN_URL}") private static String SVN_URL
我得到了 Instantiation of bean failed; nested exception is java.lang.ExceptionInInitializerError
我也试过 @Autowired private static Environment env;
然后: private static String SVN_URL=env.getProperty("SVN_URL");
它给出了同样的错误。
原文由 dannemp 发布,翻译遵循 CC BY-SA 4.0 许可协议
想一想你的问题。您不必在静态字段中保留
application.properties
的任何属性。帕特里克建议的“解决方法”非常肮脏:请记住,当您的 bean 由
@Service
注释控制时,您将其创建委托给 Spring 容器。 Spring 通过只创建一个在整个应用程序中共享的 bean 来控制这个 bean 生命周期(当然你可以改变这种行为,但我在这里指的是默认的)。在这种情况下,任何静态字段都没有意义 - Spring 确保只有一个UserService
实例。你会得到你所描述的错误,因为静态字段初始化在 Spring 容器启动之前发生了许多处理器周期。在这里您可以找到更多关于 何时初始化静态字段的信息。建议
做这样的事情会更好:
这种方法更好有几个原因:
final
字段表示该值在构造函数调用中初始化后不会更改(您是线程安全的)使用
@ConfigurationProperties
还有另一种将多个属性加载到单个类的方法。它需要对要加载到配置类的所有值使用前缀。考虑以下示例:
Spring 将处理
TestProperties
类初始化(它将创建一个testProperties
bean),您可以将此对象注入由 Spring 容器初始化的任何其他 bean。这是示例application.properties
文件的样子:Baeldung 在他的博客上写了一篇关于这个主题的精彩文章,我建议阅读它以获取更多信息。
替代解决方案
如果您需要以某种方式在静态上下文中使用值,最好定义一些带有
public static final
字段的公共类 - 这些值将在类加载器加载此类时实例化,并且在应用程序生命周期内不会被修改。唯一的问题是您将无法从 Spring 的application.properties
文件中加载这些值,您必须直接在代码中维护它们(或者您可以实现一些从属性文件,但这对于您要解决的问题来说听起来很冗长)。