Spring静态变量无法注入的简单实用解决方法

一、前言

最近有一个Java后台项目,使用了远程的配置中心(SpringCloudConfig),也就是说配置信息都在远程(一个git上存着),这个Java项目启动时会从远程读取yml等配置信息,然后完成启动。

现在同事想在Util类中写一个静态方法,用到一个静态变量(static类型),让静态变量读取远程yml上配置的值,给类加了@Component注解,给变量加了@Value注解,但是发现那个静态变量还是没有值

根据spring的实现原理,加了@Component注解后,spring会创建一个类对象放入spring容器;但是@Value注解只能让非静态变量读取到yml中配置的值,静态变量加上@Value也是没有效果的

因此,本人想到了一种简便的实现方式,可以让静态变量也读取到远程yml中配置的值,现总结如下。

二、具体方法(亲测可用)

1.假设application.yml中配置了这样一个值:

settingStr: abc

2.假设写一个Java类,目标是让静态变量获取到yml中配置的值。

//加注解,交给spring管理,spring会new【1个】MyUtil,装入spring容器,使用【myUtil】可以从容器中取出来
@Component
public class MyUtil {
    //【目标,让settingStr使用yml中配置的值。】
    //这里,静态变量加Value也是没有用的,获取不到yml中配置的值
    @Value("settingStr")
    public static String settingStr;

    //这样写是可以获取到的
    @Value("settingStr")
    public String ss;

    //实际要用这个方法处理某些逻辑
    public static String execute(){
       //要用到静态变量,值应该是yml中配置的才行
       System.out.println(settingStr);
       //省略具体步骤
       return settingStr;
    }
}

●这里,写了一个MyUtil类,想让静态变量settingStr使用yml中配置的settingStr的值。
●注意,ss可以正确使用yml中配置的值,但是静态变量settingStr是获取不到的。

3.写一个监听器类,当spring容器初始化完成后执行,使用这个监听器类给settingStr赋值即可。

@Component
public class AfterSpringListener implements ApplicationListener<ContextRefreshedEvent>
{
    @Override
    public void onApplicationEvent(ContextRefreshedEvent event)
    {
        //从spring容器中拿出spring创建的MyUtil对象
        MyUtil myUtil = (MyUtil) event.getApplicationContext().getBean("myUtil");
        //sprign容器已经给ss赋值了,现在用ss给static变量赋值
        MyUtil.settingStr = myUtil.ss;
    }
}

●这里,因为spring容器已经初始化完成了,MyUtil对象已经存在于spring容器了,ss的值也由spring初始化完成了(从yml中读取的);所以现在把ss的值设置给settingStr,就相当于静态变量settingStr使用yml中的值初始化完成了。

4.写一个Controller类自测一下,就可以发现静态变量settingStr使用的确实是yml中配置的值了。

@RestController
public class TestController {
    @ResponseBody
    @RequestMapping(value = "/abc")
    public JSONObject findAbc(){
        JSONObject jsonObject = new JSONObject();
        //直接获取测试
        jsonObject.put("key", MyUtil.settingStr);
        //通过静态方法测试
        String str = MyUtil.execute();
        System.out.println(str);
        return jsonObject;
    }
}

三、注意事项

1.静态变量settingStr的值,是在spring容器初始化完成后、自己写的监听器方法执行后、才被赋予的;
因此,只有这个时间点后的操作才能获取到settingStr的值(Controller),这个时间点前获取的话仍然为null。
如果实在想在spring容器初始化前让静态变量获取到yml中的值,那只能自己写个读取yml的方法、提前调用赋值给静态变量了。
<不过本项目的yml在远程,是不能这样实现的。(你这是在为难我spring-_-)>

2.关于SpringCloudConfig动态刷新的问题,如果远程yml被修改了(yml在git上),那么其它Java后台是可以使用新的yml的,无需其它操作(不用重启项目)。
通过百度发现,当远程配置文件yml被修改后,其它Java后台会重新加载spring容器(重新new一个);

因此,假如修改了远程yml中的静态变量的值,就会使spring容器被重新加载,继而重新调用spring容器初始化后的监听方法,也就让静态变量的值刷新为最新的了。

3.据说使用Spring的Bean后置处理器也可以实现,但是感觉用的少、较复杂,在此就不研究怎么用了。


相关文章:
Spring Cloud Config 动态刷新实现机制
https://blog.csdn.net/woshilijiuyi/article/details/88293782

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

追逐梦想永不停

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值