当前位置: 首页 > 面试题库 >

如何将application.properties中的值分配给静态变量?

濮阳君浩
2023-03-14
问题内容

我正在使用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");

它给出了相同的错误。


问题答案:

你不必application.properties在静态字段中保留任何属性。

  • 你不知道何时修改此静态字段
  • 你不知道哪个线程html" target="_blank">修改了它的价值
  • 任何时候任何线程都可以更改此静态字段的值,并且你被拧紧了
  • 初始化私有静态字段对我来说没有意义

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

建议
做这样的事情会更好:

@Service
public class UserService {
    private final String svnUrl;

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

由于以下几个原因,此方法更好:

  • 构造函数注入直接描述了初始化对象所需的值
  • final 字段表示此值在构造函数调用中初始化后将不会更改(你是线程安全的)

使用 @ConfigurationProperties

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

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

    private String svnUrl;

    private int somePort;

    // ... getters and setters
}

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

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

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



 类似资料:
  • 问题内容: 在上面,这是硬代码。我想将 变量 分配 给值。即,均值=注册; 让我知道! 问题答案: 您的问题不是很清楚。我假设变量是在Servlet中声明的,因为在JSP中使用Java是一种不好的做法。为了能够在转发到JSP的Servlet之间共享变量,您需要将此变量设置为request属性: 然后在JSP中,您可以使用JSP EL获得“ registration”属性的值: 您应该阅读Java

  • 问题内容: 我正在使用以下代码: 该值不警报。怎么了 问题答案: 实质上:

  • 问题内容: 我想为容器分配一个端口,以便在每次重新启动容器后都获得相同的端口。 示例:我有一个容器,其中有一个Apache。Apache在容器内的端口80上运行。现在,在启动容器后,docker将一个主机端口分配给该容器端口,例如:49154->80。但是该主机端口在重新启动后会更改,具体取决于正在运行的容器的数量。我试图在容器的config.json文件中指定端口,但该端口被覆盖。 是否可以手动

  • 我正在我的项目中使用AWS,我只想使在属性文件中可配置。 因此接受类似于的枚举值。 我尝试在中分配它: 这就是不行。它给了我这个: java.lang.IllegalStateException:无法将类型[java.lang.String]的值转换为所需类型[com.amazonaws.regions.regions]:找不到匹配的编辑器或转换策略

  • 我现在尝试在启动Docker容器时分配静态IP172.17.0.1。 我使用端口2122作为该容器的ssh端口,以便让该容器侦听端口2122。 这个命令将运行一个带有随机IP的Docker容器,如172.17.0.5,但我需要为容器分配一个特定的IP。 下面的shell脚本是我在高级网络设置中引用Docker文档的部分。 此shell脚本将分配一个静态IP 172.17.0.1并链接到world

  • 问题内容: 嗨,我正在使用Java Optional。我看到Optional有一个ifPresent方法。 而不是做类似的事情: 我想知道如何使用Optional.ifPresent()将值分配给变量。 我正在尝试类似的东西: 我需要lambda函数来获取分配给该变量的值是什么? 问题答案: 您可以使用#orElse或orElseThrow来提高代码的可读性。