背景
最近在实现一个功能,AutoConfiguration如果发现应用project定义了就不再生成。
工程目录结构如下: monitor是要deploy的工具包,demo是测试的module.
Root
-- demo
-- monitor
在demo Module中代码如下:
package com.xxx.yyy.config;
public class ProjectConfig {
@Bean
public XXX config() {
return new XXX();
}
}
package com.xxx.yyy;
@SpringBootApplication
public class DemoApplication {
}
然后在monitormodule中代码如下:
package com.xxx.yyy.monitor;
public class JarConfigAutoConfiguration {
@Bean
@ConditionalOnMissingBean()
public XXX configX() {
return new XXX();
}
}
在测试的过程中发现总是monitor中的configX方法先执行,而我一直记得是Spring会先执行project中的,之后才是三方jar中的。
原因
经过将近一个小时的Debug,发现这是由于package相同造成的。关键的方法是:org.springframework.context.annotation.ConfigurationClassParser#doProcessConfigurationClass。
在这个方法中会扫描注有@SpringBootApplication的DemoApplication。(@SpringBootApplication其实是一个复合注解,里面包括了@Configuration )
org.springframework.context.annotation.ConfigurationClassParser#doProcessConfigurationClass的处理顺序是:
- 查找component-scan,然后按classpath寻找符合的class时,因为使用的是FULL_CLASSPATH,即
classpath:*,所以会匹配到JarConfig - 处理deferred import,这里可以理解为处理
@EnableAutoConfigurationImport,这里会把所有的AutoConfigurationClass进行解析。 - …
验证及解决
把demomodule的package更换为与monitormodule不同,开始debug,发现正确先执行config()方法。
版权声明:本文为kang389110772原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。