springboot如何在static代码块中引用application.yml配置文件参数

背景

springboot项目启动需要根据所处项目组需求加载dll动态库,并启用相应的功能,于是在配置文件application.yml添加字段区分是否需要加载以及功能启用。

thermal-sdk:
  enable: true

问题

springboot提供@Value注解可以向变量注入配置值,于是有以下代码

@Configuration
public class ThermalDisposeServerJNI {

	@Value("${thermal-sdk.enable:false}")
	private static boolean thermalSdkEnable;
	
	static {
		if (thermalSdkEnable){
			// load dll
		}
	}
}

很遗憾,thermalSdkEnable并不能拿到true值,因为@Value并不能给静态变量注入属性值。

解决方案

  1. 创建Config类来管理静态变量,在Config类中通过@Value注入属性值
@Component
@Data
public class Config {

    @Value("${thermal-sdk.enable:false}")
    private boolean enableThermalSdk;

    public static Config getInstance(){
        return ConfigContextUtil.getBean("config", Config.class);
    }
}
  1. 创建ConfigContext类,实现ApplicationContextAware接口
@Component
public class ConfigContextUtil implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(@NotNull ApplicationContext applicationContext) throws BeansException {
        ConfigContextUtil.applicationContext = applicationContext;
    }

    public static <T> T getBean(String beanName, Class<? extends T> beanType) {
        return applicationContext.getBean(beanName, beanType);
    }
}
  1. 在static代码块中调用Config类中enableThermalSdk变量的get方法
public class ThermalDisposeServerJNI {

    public static final boolean ENABLE_THERMAL_SDK;

    static {
        ENABLE_THERMAL_SDK = Config.getInstance().isEnableThermalSdk();
        if(ENABLE_THERMAL_SDK) {
        	// load dll
        }
    }
}

总结

  1. @Value不能直接给static变量注入属性值,@Value注入属性值基于spring的实例,参与spring的生命周期,而static变量是静态变量,且不参与spring的生命周期。
  2. 关于调用链路:
    1. Config构造器
    2. ConfigContextUtil构造器
    3. ConfigContextUtil注入applicationContext属性
    4. static块方法执行
    5. Config类getInstance方法被调用
    6. ConfigContextUtil类getBean方法被调用
    7. Config类enableThermalSdk属性的get方法被调用
  3. 大致猜想一下:jvm加载ThermalDisposeServerJNI类时,分析static代码块,需要调用Config的实例方法get方法,调用ConfigContextUtil变量applicationContext的getBean方法,所以预先实例化了,等这两个类的实例化完成,spring的生命周期也完成了,也就能成功注入属性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值