很多资料都说@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)