Skip to content
欢迎扫码关注公众号

Spring 如何将配置文件中的值保存到静态字段

需求是 在实例化一个对象时,将某个字段的值默认初始化为配置文件中的配置项
使用到了 @Component@Resource@PostConstruct 三个注解。

首先按照需求增加配置项。

application.yml

yaml
# Service
service:
  settings:
    name: SampleService

再增加对应的配置类,在类上使用 @Component 注解,在字段的 set 方法上使用 @Value 注解注入配置文件中对应的配置项值。

ServiceSettings.java

java
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 * 服务配置类
 */
@Component
public class ServiceSettings {
    /**
     * 服务名
     */
    private String name;

    /**
     * 服务名
     */
    public String getName() {
        return name;
    }

    @Value("${service.settings.name}")
    public void setName(String name) {
        this.name = name;
    }
}

在模型类上使用 @Component 注解,在私有字段上使用 @Resource 注解注入配置类的实例,另外使用 @PostConstruct 注解为静态的配置类字段赋值。

从 Java EE5 规范开始,Servlet 增加了两个影响 Servlet 生命周期的注解(Annotation):@PostConstruct@PreDestroy。这两个注解被用来修饰一个非静态的 void 方法.而且这个方法不能有抛出异常声明。

@PostConstruct 说明
@PostConstruct 修饰的方法会在服务器加载 Servlet 的时候运行,并且只会被服务器调用一次,类似于 Servlet 的 init() 方法。被 @PostConstruct 修饰的方法会在构造函数之后,Servlet 的 init() 方法之前运行。

摘自:java 开发之@PostConstruct 和@PreDestroy 注解

SampleEntity.java

java
import com.octopus.middle.common.settings.ServiceSettings;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

@Component
public class SampleEntity {
    @Resource
    private ServiceSettings initServiceSettings;

    private static ServiceSettings serviceSettings;

    @PostConstruct
    public void init() {
        serviceSettings = initServiceSettings;
    }

    /**
     * 服务名
     */
    private String serviceName = serviceSettings != null ? serviceSettings.getName() : null;

    /**
     * 服务名
     */
    public String getServiceName() {
        return serviceName;
    }

    public void setServiceName(String serviceName) {
        this.serviceName = serviceName;
    }
}

在执行 @PostConstruct 方法前会先实例化 SampleEntity 类,此时 initServiceSettingsserviceSettings 均为 null

实例化之后再调用实例方法 init(),此时 initServiceSettings 有值,serviceSettings 为 null。

在此方法中将使用 @Resource 注解注入的字段(initServiceSettings)值赋给静态变量(serviceSettings),这样就可以在之后的处理中直接使用了。

之后在代码中通过 new 关键字创建实例 (new SampleEntity()) 时,serviceName 字段就可以直接获取到配置文件中的值了。

如果模型组件不在同一个模块中,需要使用 @ComponentScan 注解扫描组件。示例如下:

java
@ComponentScan(basePackages = { "com.xxxx.xxx.common" })
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

参考

  1. Springboot 静态资源类里静态属性注入
  2. java 开发之@PostConstruct 和@PreDestroy 注解

Page Layout Max Width

Adjust the exact value of the page width of VitePress layout to adapt to different reading needs and screens.

Adjust the maximum width of the page layout
A ranged slider for user to choose and customize their desired width of the maximum width of the page layout can go.

Content Layout Max Width

Adjust the exact value of the document content width of VitePress layout to adapt to different reading needs and screens.

Adjust the maximum width of the content layout
A ranged slider for user to choose and customize their desired width of the maximum width of the content layout can go.