关于Spring框架的 @Configuration 与@Service 加载顺序哪个先后(某些环境加载是随机的)

很多资料都说@Configuration 优先加载,@Service后加载,如下图:

 

本来也是以为 @Configuration 优先加载于  @Service ,那参数处理放在@Configuration注入完后,@service构建时就可以拿来用的,在我在IDEA的调试时下断点验证过。但在正式环境跑项目时并不是这样的。

先看原代码:

  带@Configuration注解的配置参数代码如下:

@Configuration
public class SysParamApi {


    /**
     * 是否调试模式
     */
    public static boolean is_debug=true;

    @Value("${sys-param.sys.is_debug}")
    public  void setIs_debug(String is_debug) {
        SysParamApi.is_debug = "Y".equals(is_debug);

        System.out.println("是否调试模式:"+SysParamApi.is_debug);
    }



}

带@Service业务类,有两个地方在使用这个参数。上面的@Configuration参数,代码如下:

@Service
public class PushStatusServiceImpl {

    private static final Logger logger = LogManager.getLogger(PushStatusServiceImpl.class);


    //调试时设置false
    boolean isRun=true;
   

    @PostConstruct
    public void init() {
        int cpuCount = Runtime.getRuntime().availableProcessors();
        System.out.println("start RedisStatusProcess > cpus=" + cpuCount);

        if(!SysParamApi.is_debug) {
            //业务处理
            logger.info("=========================== start rev pole status -> "+isRun);
            processOrderImport();
        }else{
            logger.info("xxxxxxxxxxxxxxxxxx start rev status -> Fail");
        }
    }
}



@Service
public class PushOrderServiceImpl {

    private static final Logger logger = LogManager.getLogger(PushOrderServiceImpl.class);



    @PostConstruct
    public void init() {
        int cpuCount = Runtime.getRuntime().availableProcessors();
        System.out.println("start RedisOrderProcess > cpus=" + cpuCount);
        //调试时设置false
        if(!SysParamApi.is_debug){
            logger.info("=========================== start rev order -> "+isRun);
            processOrderImport(cpuCount);

        }else{
            logger.info("xxxxxxxxxxxxxxxxxx start rev order -> Fail");
        }
    }

    boolean isRun=true;
}

上面的代码在IDEA调试器执行时,确实是加载 @Configuration 执行打印是否调试模式这行 后加载@Service并执行init()方法,此时拿到SysParamApi.is_debug值 是注入后的值 。这也是大家认可。

在正式服务器发布后就翻车了,在不改上面任何代码及配置的情况下,执行的效果是:

第一次执行时:

发现先加载执行 @Service  ->  @Service ->   @Configuration

第二次执行时:

发现先加载执行@Service  -> @Configuration  -> @Service 

由于是正式服务器不能尝试多次,上面两次验证加载是随机的。

解决加载参数需要用到@PostConstruct注解,再修改代码如下:

@Service
public class PushOrderServiceImpl {

    private static final Logger logger = LogManager.getLogger(PushOrderServiceImpl.class);


    @Value("${sys-param.sys.is_debug}")
    public  void setIs_debug(String is_debug) {
        SysParamApi.is_debug = "Y".equals(is_debug);

        System.out.println("是否调试模式:"+SysParamApi.is_debug);
    }


    @PostConstruct
    public void init() {
        int cpuCount = Runtime.getRuntime().availableProcessors();
        System.out.println("start RedisOrderProcess > cpus=" + cpuCount);
        //调试时设置false
        if(!SysParamApi.is_debug){
            logger.info("=========================== start rev order -> "+isRun);
            processOrderImport(cpuCount);

        }else{
            logger.info("xxxxxxxxxxxxxxxxxx start rev order -> Fail");
        }
    }

    boolean isRun=true;
}

说明:@PostConstruct注解的作用是本类加载完所有的参数(包含了流入参数),再执行。

生产环境测试验证:

上面测试生产环境参数:

操作系统:CentOS Linux release 8.1.1911 

jdk环境:

openjdk version "1.8.0_275"
OpenJDK Runtime Environment (build 1.8.0_275-b01)
OpenJDK 64-Bit Server VM (build 25.275-b01, mixed mode)


 

  • 21
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

qyhua

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

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

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

打赏作者

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

抵扣说明:

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

余额充值