如何将application.properties中的值赋给静态变量? [英] How to assign a value from application.properties to a static variable?

查看:1307
本文介绍了如何将application.properties中的值赋给静态变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Spring MVC。我有一个带有 @Service 注释的 UserService 类,它有很多静态变量。我想用application.properties文件中的值来实例化它们。

I am using Spring MVC. I have a UserService class annotated with @Service that has a lot of static variables. I would like to instantiate them with values from the application.properties file.

例如在application.properties中我有: SVN_URL = http:/ /some.url/repositories

For example in application.properties I have: SVN_URL = http://some.url/repositories

然后在课堂上有: @Value($ {SVN_URL} )private static String SVN_URL

我得到 bean的实例化失败;嵌套异常是java.lang.ExceptionInInitializerError

我还试过 @Autowired private static Environment env;

然后:私有静态字符串SVN_URL = env.getProperty(SVN_URL);

它给出了同样的错误。

推荐答案

考虑你的问题一秒。您不必在静态字段中保留 application.properties 中的任何属性。 Patrick建议的解决方法非常脏:

Think about your problem for a second. You don't have to keep any properties from application.properties in static fields. The "workaround" suggested by Patrick is very dirty:


  • 你不知道何时修改了这个静态字段

  • 你不知道哪个线程修改它的值

  • 任何时候任何线程都可以改变这个静态字段的值并且你被搞砸了

  • 初始化私有静态字段对我来说没有意义

  • you have no idea when this static field is modified
  • you don't know which thread modifies it's value
  • any thread at any time can change value of this static field and you are screwed
  • initializing private static field that way has no sense to me

请记住,当你的bean由<$ c $控制时c> @Service 将您的创建委托给Spring容器的注释。 Spring通过仅创建一个在整个应用程序中共享的bean来控制此bean生命周期(当然,您可以更改此行为,但我在此处引用默认行为)。在这种情况下,任何静态字段都没有意义 - Spring确保只有一个 UserService 的实例。并且您得到了您所描述的错误,因为静态字段初始化在Spring容器启动之前发生了许多处理器周期。在这里,您可以找到有关初始化静态字段的更多信息。

Keep in mind that when you have bean controlled by @Service annotation you delegate its creation to Spring container. Spring controls this bean lifecycle by creating only one bean that is shared across the whole application (of course you can change this behavior, but I refer to a default one here). In this case any static field has no sense - Spring makes sure that there is only one instance of UserService. And you get the error you have described, because static fields initialization happens many processor-cycles before Spring containers starts up. Here you can find more about when static fields are initialized.

做这样的事情要好得多:

It would be much better to do something like this:

@Service
public class UserService {
    private final String svnUrl;

    @Autowired
    public UserService(@Value("${SVN_URL}") String svnUrl) {
        this.svnUrl = svnUrl;
    }
}

出于以下几个原因,这种方法更好:

This approach is better for a few reasons:


  • 构造函数注入直接描述初始化对象所需的值

  • final 字段表示在构造函数调用中初始化之后不会更改此值(您是线程安全的)

  • constructor injection describes directly what values are needed to initialize the object
  • final field means that this value wont be changed after it gets initialized in a constructor call (you are thread safe)

还有另一种方法可以将多个属性加载到单个类中。它需要为要加载到配置类的所有值使用前缀。请考虑以下示例:

There is also another way to load multiple properties to a single class. It requires using prefix for all values you want to load to your configuration class. Consider following example:

@ConfigurationProperties(prefix = "test")
public class TestProperties {

    private String svnUrl;

    private int somePort;

    // ... getters and setters
}

Spring将处理 TestProperties 类初始化(它将创建一个 testProperties bean)并且可以将此对象注入任何其他bean由Spring容器初始化。这是示例 application.properties 文件的样子:

Spring will handle TestProperties class initialization (it will create a testProperties bean) and you can inject this object to any other bean initialized by Spring container. And here is what exemplary application.properties file look like:

test.svnUrl=https://svn.localhost.com/repo/
test.somePort=8080

Baeldung在他的博客上创建了一个关于此主题的精彩帖子,我建议阅读它以获取更多信息。

Baeldung created a great post on this subject on his blog, I recommend reading it for more information.

如果您需要以某种方式在静态上下文中使用值最好使用 public static final 字段定义一些公共类 - 这些值将在类加载器加载此类时实例化,并且在应用程序生命周期内不会被修改。唯一的问题是你无法从Spring的 application.properties 文件加载这些值,你必须直接在代码中维护它们(或者你可以实现一些类从属性文件加载这些常量的值,但这听起来对你要解决的问题非常冗长。)

If you need somehow to use values in static context it's better to define some public class with public static final fields inside - those values will be instantiated when classloader loads this class and they wont be modified during application lifetime. The only problem is that you won't be able to load these values from Spring's application.properties file, you will have to maintain them directly in the code (or you could implement some class that loads values for these constants from properties file, but this sounds so verbose to the problem you are trying to solve).

这篇关于如何将application.properties中的值赋给静态变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆