一、前言:
最近项目有一需求,我需要指定一个配置类必须在另一个配置类执行之后才能执行。SpringBoot 提供了两个注解 :@AutoConfigureAfter或@AutoConfigureBefore注解为配置类指定特定的顺序。在实现的过程中遇到一些问题,注解不生效,没有按照特定顺序执行,这里做下分析及解决办法。
二、原关键问题代码:
目的:我想先加载 WebMvcConfig 配置,让 yml 文件里面值注入到静态成员变量中,然后再加载 DirConfig 配置类获取 WebMvcConfig 里面已经注入好的静态成员的value并创建对应文件夹。
WebMvcConfig.java
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Autowired
private AccessLimitInterceptor accessLimitInterceptor;
// 文件夹路径
public static String headIconUrl;
public static String lostFoundUrl;
public static String productUrl;
@Value("${uploadFile.headIconUrl}")
public void setHeadIconUrl(String headIconUrl) {
System.out.println("============== WebMvcConfig 执行了 ==============");
WebMvcConfig.headIconUrl = headIconUrl;
}
@Value("${uploadFile.lostFoundUrl}")
public void setLostFoundUrl(String lostFoundUrl) {
WebMvcConfig.lostFoundUrl = lostFoundUrl;
}
@Value("${uploadFile.productUrl}")
public void setProduct_image(String productUrl) {
WebMvcConfig.productUrl = productUrl;
}
// 以下代码忽略
....
}
DirConfig.java
// @AutoConfigureAfter 在加载 WebMvcConfig 配置类之后再加载当前类
@AutoConfigureAfter(WebMvcConfig.class)
@Configuration
public class DirConfig {
// 创建存放图片的文件夹
static {
System.out.println("============== DirConfig 执行了 ==============");
String rootPath = System.getProperty("user.dir");
// 文件夹路径
File path0 = new File(rootPath + WebMvcConfig.headIconUrl);
File path1 = new File(rootPath + WebMvcConfig.lostFoundUrl);
File path2 = new File(rootPath + WebMvcConfig.productUrl);
// 文件夹不存在创建
if (!path0.exists()) { path0.mkdirs(); }
if (!path1.exists()) { path1.mkdirs(); }
if (!path2.exists()) { path2.mkdirs(); }
}
}
运行结果:
三、问题分析:
解决问题的好方法之一:仔细阅读官网文档。
意思就是 @AutoConfigureAfter 和 @AutoConfigureBefore 在自动配置类上才会生效,自定义的配置类是不会生效的。
什么是自动配置类?自动配置类就是我们平时引入的 Pom 依赖包时,这些依赖包的配置会自动注入到spring容器中。例如如下的 spring-boot-2.3.7 依赖包,spring容器启动时会获取 spring.factories文件中的类并自动注入到容器中。
什么是自定义配置类呢? 就是使用 @Configuration 注解的类
spring.factories的原理是什么?:springboot核心基础之spring.factories机制
四、解决办法:
对问题进行分析之后我们知道要想 @AutoConfigureAfter 生效,那我们就必须把自定义配置类变成自动配置类。我们就要模仿上图中 spring-boot-2.3.7 依赖包 的写法,META-INF下的spring.factories文件中写入自动配置类:
# Auto Config
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.xxx.xxx.config.DirConfig,\
com.xxx.xxx.config.WebMvcConfig
注意:使用自动装配方式后,类上不能再写 @Configuration 注解!否则 @AutoConfigureAfter 依旧无法生效。
正确写法:
WebMvcConfig.java
public class WebMvcConfig implements WebMvcConfigurer {
// 代码同上,省略...
}
DirConfig.java
// @AutoConfigureAfter 在加载 WebMvcConfig 配置类之后再加载当前类
@AutoConfigureAfter(WebMvcConfig.class)
public class DirConfig {
// 代码同上,省略...
}
运行结果: