Spring boot `@Configuration` 和`@AutoConfiguration`的顺序研究

时间:2025-03-22 08:26:13

背景

最近在实现一个功能,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相同造成的。关键的方法是:#doProcessConfigurationClass

在这个方法中会扫描注有@SpringBootApplicationDemoApplication。(@SpringBootApplication其实是一个复合注解,里面包括了@Configuration )

#doProcessConfigurationClass的处理顺序是:

  1. 查找component-scan,然后按classpath寻找符合的class时,因为使用的是FULL_CLASSPATH,即classpath:*,所以会匹配到JarConfig
  2. 处理deferred import,这里可以理解为处理@EnableAutoConfigurationImport,这里会把所有的AutoConfigurationClass进行解析。

验证及解决

demomodule的package更换为与monitormodule不同,开始debug,发现正确先执行config()方法。