自定义starter包的知识盲区

@Configuration配置类解析

ConfigurationClassPostProcessor

Spring的SPI机制

SPI全称为Service Provider Interface 服务提供接口。

在SpringBoot的自动装配过程中,最终会加载META-INF/spring.factories文件,而加载的过程是由SpringFactoriesLoader加载的。
从CLASSPATH下的每个Jar包中搜寻所有META-INF/spring.factories配置文件,然后将解析properties文件,找到指定名称的配置后返回。
需要注意的是,其实这里不仅仅是会去Classpath路径下查找,会扫描所有路径下的Jar包,只不过这个文件只会在Classpath下的Jar包中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
// spring.factories文件的格式为:key=value1,value2,value3
// 从所有的jar包中找到META-INF/spring.factories文件
// 然后从文件中解析出key=factoryClass类名称的所有value值
public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) {
String factoryClassName = factoryClass.getName();
// 取得资源文件的URL
Enumeration<URL> urls = (classLoader != null ? classLoader.getResources(FACTORIES_RESOURCE_LOCATION) : ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
List<String> result = new ArrayList<String>();
// 遍历所有的URL
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
// 根据资源文件URL解析properties文件,得到对应的一组@Configuration类
Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));
String factoryClassNames = properties.getProperty(factoryClassName);
// 组装数据,并返回
result.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray(factoryClassNames)));
}
return result;
}

SpringBoot的自动装配机制

如何自定义SpringBoot的starter

什么是SpringBoot自动装配

何谓SpringBoot的自动装配,简要概括就是:引入第三方组件的starter包后能够自动第三方组件的bean加载到IOC容器中供应用程序使用。

自动装配的机制是SpringBoot提供的,因此第三方组件的starter包在编写的时候,就需要根据SpringBoot的自动装配的规则来编写starter包。
规则概括如下:

  1. starter包需要在META-INF目录下提供spring.factories文件;
  2. spring.factories文件中以Key-Values的形式来提供需要Springboot去加载的类的全限定名。
    • Key就是Springboot中各种扩展点的全限定名。
      比如org.springframework.boot.autoconfigure.EnableAutoConfiguration。
    • Values就是starter包中提供的扩展点的所有类的全限定名,以逗号隔开。

/META-INF/spring.factories

spring-boot-autoconfigure-2.3.4.RELEASE.jar的spring.factories

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\
org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener

# Application Listeners
org.springframework.context.ApplicationListener=\
org.springframework.boot.autoconfigure.BackgroundPreinitializer

# Auto Configuration Import Listeners
org.springframework.boot.autoconfigure.AutoConfigurationImportListener=\
org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener

# Auto Configuration Import Filters
org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=\
org.springframework.boot.autoconfigure.condition.OnBeanCondition,\
org.springframework.boot.autoconfigure.condition.OnClassCondition,\
org.springframework.boot.autoconfigure.condition.OnWebApplicationCondition

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
...
...

# Failure analyzers
org.springframework.boot.diagnostics.FailureAnalyzer=\
org.springframework.boot.autoconfigure.data.redis.RedisUrlSyntaxFailureAnalyzer,\
org.springframework.boot.autoconfigure.diagnostics.analyzer.NoSuchBeanDefinitionFailureAnalyzer,\
org.springframework.boot.autoconfigure.flyway.FlywayMigrationScriptMissingFailureAnalyzer,\
org.springframework.boot.autoconfigure.jdbc.DataSourceBeanCreationFailureAnalyzer,\
org.springframework.boot.autoconfigure.jdbc.HikariDriverConfigurationFailureAnalyzer,\
org.springframework.boot.autoconfigure.r2dbc.ConnectionFactoryBeanCreationFailureAnalyzer,\
org.springframework.boot.autoconfigure.session.NonUniqueSessionRepositoryFailureAnalyzer

# Template availability providers
org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider=\
org.springframework.boot.autoconfigure.freemarker.FreeMarkerTemplateAvailabilityProvider,\
org.springframework.boot.autoconfigure.mustache.MustacheTemplateAvailabilityProvider,\
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAvailabilityProvider,\
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafTemplateAvailabilityProvider,\
org.springframework.boot.autoconfigure.web.servlet.JspTemplateAvailabilityProvider

SpringBoot自动配置原理 - 相关注解

  • SpringBoot 是依靠入口注解 @SpringBootApplication 来启动整个自动配置体系的
    其中 @EnableAutoConfiguration 注解启动AutoConfigure功能
  • SpringBoot 是通过读取 META-INF/spring.factories 文件中配置的自动配置类来完成自动配置的
    自动配置类大多以 AutoConfiguration 结尾,AutoConfiguration类主要是通过springboot自定义的条件注解来完成自动配置的

@SpringBootApplication注解

1
2
3
4
5
6
7
@java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE})
@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
@java.lang.annotation.Documented
@java.lang.annotation.Inherited
@org.springframework.boot.SpringBootConfiguration
@org.springframework.boot.autoconfigure.EnableAutoConfiguration
@org.springframework.context.annotation.ComponentScan

@SpringBootApplication是由3个注解组成的复合注解。

  • @SpringBootConfiguration
    该注解表明Springboot启动类是一个配置类。
  • @ComponentScan
    该注解会将指定路径下的被特定注解修饰的类加载为Spring中的bean。
    这些特定注解为@Component、@Controller、@Service、@Repository和@Configuration注解。
  • @EnableAutoConfiguration
    该注解用于开启Springboot的自动装配。

@SpringBootConfiguration注解

@ComponentScan注解

@EnableAutoConfiguration注解

1
2
3
4
5
6
7
8
9
10
11
12
13
@java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE})
@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
@java.lang.annotation.Documented
@java.lang.annotation.Inherited
@org.springframework.boot.autoconfigure.AutoConfigurationPackage
@org.springframework.context.annotation.Import({org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
java.lang.String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

java.lang.Class<?>[] exclude() default {};

java.lang.String[] excludeName() default {};
}

@EnableAutoConfiguration注解也是一个复合注解,主要功能由 @AutoConfigurationPackage注解和 @Import注解实现,那么肯定的,自动装配,就是这两个注解实现的。

@AutoConfigurationPackage

@AutoConfigurationPackage注解作用在Springboot启动类上,会向Spring容器注册一个类型为AutoConfigurationPackages.BasePackages的bean,这个bean中保存了Springboot启动类的包路径,后续Springboot就会扫描这个包路径下由@Component、@Controller、@Service、@Repository和@Configuration注解修饰的类。

@Import(AutoConfigurationImportSelector.class) 重要!!!

  • @Import(AutoConfigurationImportSelector.class)会通过AutoConfigurationImportSelector延迟且分组的向Spring容器导入需要自动装配的组件的配置类,从而在解析这些配置类的时候能够将自动装配的组件的bean注册到容器中
    • 所谓的延迟,是因为AutoConfigurationImportSelector实现了DeferredImportSelector接口,其逻辑会在Springboot启动类被解析完毕后才会执行;
    • 所谓的分组,是因为处理DeferredImportSelector是一组一组的进行的,只要DeferredImportSelector的实现类实现的getImportGroup()方法返回的Class对象一样,那么这样的DeferredImportSelector的实现类就属于同一组;
  • AutoConfigurationImportSelector获取到需要自动装配的组件的配置类的全限定名,是通过SpringFactoriesLoader完成的,而SpringFactoriesLoader就是Spring中的SPI机制的实现。

https://www.bilibili.com/read/cv17225413/

SpringBoot自动配置原理 - 自动装配过程

SpringBootApplication启动对象的注入

SpringApplication#run#prepareContext#load
prepareContext过程中,当前sources列表中只有一个main启动方法所在的Application.class对象,在此处加载springboot启动类。

自动装配过程的方法调用链

  1. SpringApplication#run
  2. SpringApplication#refreshContext
  3. AbstractApplicationContext#refresh()
  4. AbstractApplicationContext#invokeBeanFactoryPostProcessors(beanFactory)
    此处是自动装配的入口!!!
  5. PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors())
  6. ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry(registry)
  7. ConfigurationClassParser#parse(candidates)#processConfigurationClass#doProcessConfigurationClass#processImports
  8. AutoConfigurationImportSelector#selectImports#getAutoConfigurationEntry#getCandidateConfigurations
  9. SpringFactoriesLoader#loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),getBeanClassLoader())#loadSpringFactories

AbstractApplicationContext#postProcessBeanFactory(beanFactory)

beanFactory的后置处理器 postProcessBeanFactory(beanFactory)

当前applicationContext是AnnotationConfigServletWebServerApplicationContext的实例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
// AnnotationConfigServletWebServerApplicationContext#postProcessBeanFactory
public class AnnotationConfigServletWebServerApplicationContext
extends ServletWebServerApplicationContext implements AnnotationConfigRegistry {
//处理beanFactory
@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
//显式调用父类ServletWebServerApplicationContext#postProcessBeanFactory
super.postProcessBeanFactory(beanFactory);
//basePackages默认为null
if (this.basePackages != null && this.basePackages.length > 0) {
//不为空的话,进行扫描
this.scanner.scan(this.basePackages);
}
//annotatedClasses默认为空
if (!this.annotatedClasses.isEmpty()) {
//不为空的话注册类
this.reader.register(ClassUtils.toClassArray(this.annotatedClasses));
}
}
}

// ServletWebServerApplicationContext#postProcessBeanFactory
public class ServletWebServerApplicationContext extends GenericWebApplicationContext
implements ConfigurableWebServerApplicationContext {
@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
//在ServletContext和ServletConfig初始化之前
//进行bean处理
beanFactory.addBeanPostProcessor(
new WebApplicationContextServletContextAwareProcessor(this));
//忽略ServletContextAware自动配置
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
//beanFactory注册web应用scopes
//request和session
registerWebApplicationScopes();
}
}

// WebApplicationContextUtils#registerWebApplicationScopes
public abstract class WebApplicationContextUtils# {
public static void registerWebApplicationScopes(ConfigurableListableBeanFactory beanFactory) {
//传入ServletContext为null
registerWebApplicationScopes(beanFactory, null);
}
public static void registerWebApplicationScopes(ConfigurableListableBeanFactory beanFactory,
@Nullable ServletContext sc) {

//注册Scope
//request
beanFactory.registerScope(WebApplicationContext.SCOPE_REQUEST, new RequestScope());
//session
beanFactory.registerScope(WebApplicationContext.SCOPE_SESSION, new SessionScope());
if (sc != null) {
//传入sc为null
//注册application scope
ServletContextScope appScope = new ServletContextScope(sc);
beanFactory.registerScope(WebApplicationContext.SCOPE_APPLICATION, appScope);
// 设置ServletContext属性
sc.setAttribute(ServletContextScope.class.getName(), appScope);
}

//注册几个Autowired自动装配
//ServletRequest.class
beanFactory.registerResolvableDependency(ServletRequest.class, new RequestObjectFactory());
//ServletResponse.class
beanFactory.registerResolvableDependency(ServletResponse.class, new ResponseObjectFactory());
//HttpSession.class
beanFactory.registerResolvableDependency(HttpSession.class, new SessionObjectFactory());
//WebRequest.class
beanFactory.registerResolvableDependency(WebRequest.class, new WebRequestObjectFactory());
if (jsfPresent) {
//jsfPresent默认为false
FacesDependencyRegistrar.registerFacesDependencies(beanFactory);
}
}
}

AbstractApplicationContext#invokeBeanFactoryPostProcessors(beanFactory)

BeanFactoryPostProcessor是一个接口, 处理beanFactory中所有的bean, 在所有的beanDefinition加载完成之后, BeanFactoryPostProcessor可以对beanDefinition进行属性的修改, 之后再进行bean实例化。

BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子接口, 定义了postProcessBeanDefinitionRegistry方法, 会在postProcessBeanFactory方法执行之前, 获取bean定义, 并注册到spring容器中

1
2
3
4
5
6
7
8
9
10
11
12
13
// AbstractApplicationContext#invokeBeanFactoryPostProcessors(beanFactory)
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
//处理器代理类
//处理this.beanFactoryPostProcessors中维护的bean处理器
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

//TempClassLoader为空
//包含了LoadTimeWeaver(加载到JVM时, 进行切面织入)
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}

PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors

如果beanFactory是BeanDefinitionRegistry的子类, 按优先级,先处理BeanDefinitionRegistryPostProcessor类型的后置处理器, 最后处理传入的其他类型后置处理器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
final class PostProcessorRegistrationDelegate {
/**
* @param beanFactory
* @param beanFactoryPostProcessors有三个:
* CachingMetadataReaderFactoryPostProcessor
* ConfigurationWarningsPostProcessor
* PropertySourceOrderingPostProcessor
*/
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

//processedBeans记录处理过的bean名称
Set<String> processedBeans = new HashSet<>();

if (beanFactory instanceof BeanDefinitionRegistry) {
//优先处理传入的BeanDefinitionRegistryPostProcessor
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
//非BeanDefinitionRegistryPostProcessor类型, 常规BeanFactory后置处理器
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
//BeanDefinitionRegistryPostProcessor类型的bean定义注册器后置处理器
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
//regularPostProcessors有1个:PropertySourceOrderingPostProcessor
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
//bean定义注册器后置处理器,有如下两个:
//CachingMetadataReaderFactoryPostProcessor
//ConfigurationWarningsPostProcessor
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
//执行其postProcessBeanDefinitionRegistry方法
registryProcessor.postProcessBeanDefinitionRegistry(registry);
//然后加入到registryProcessors中
registryProcessors.add(registryProcessor);
}
else {
//如果不是BeanDefinitionRegistryPostProcessor
//那么放入regularPostProcessors(常规后置处理器)中
regularPostProcessors.add(postProcessor);
}
}

//处理beanFactory中注册的BeanDefinitionRegistryPostProcessor

//当前正在处理的PostProcessor, 处理完成之后会清空
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

//将其名称放入postProcessorNames数组中
//当前只能获取到一个bean:
//名称为org.springframework.context.annotation.internalConfigurationAnnotationProcessor
//类型为ConfigurationClassPostProcessor
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
//优先处理PriorityOrdered接口的BeanDefinitionRegistryPostProcessor
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
//处理完成之后, 放到processedBeans列表
processedBeans列表中.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
//添加到registryProcessors
registryProcessors.addAll(currentRegistryProcessors);
//遍历currentRegistryProcessors,调用其postProcessBeanDefinitionRegistry方法
//执行ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry, 扫描并注册模块中@Configuration注解的bean
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
//清空currentRegistryProcessors
currentRegistryProcessors.clear();

// 实现Order注解的bean
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();

// 最后,调用其他的BeanDefinitionRegistryPostProcessor的方法
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
//调用其他BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}

//调用BeanDefinitionRegistryPostProcessor的postProcessBeanFactory
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
//方法传入普通BeanFactoryPostProcessor, 实现其postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}

else {
//如果beanFactory不是BeanDefinitionRegistry
//方法传入普通BeanFactoryPostProcessor, 实现其postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}

//处理beanFactory中注册的普通BeanFactoryPostProcessor
//非BeanDefinitionRegistryPostProcessor类型后置处理器
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
//说明已经处理过了
}
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
//优先处理实现了PriorityOrdered接口的子类
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
//再处理实现了Ordered接口的子类
orderedPostProcessorNames.add(ppName);
}
else {
//最后处理其他BeanFactoryPostProcessor
nonOrderedPostProcessorNames.add(ppName);
}
}

//实现了PriorityOrdered接口的BeanFactoryPostProcessor, 优先处理
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

// 实现了Ordered接口的BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

// 最后再实现不排序BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

// 清除缓存
beanFactory.clearMetadataCache();
}
}

ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry(registry)

ConfigurationClassPostProcessor扫描和注册BeanDefinition

  1. 首先处理手动注册的BeanDefinition
  2. 实例化ConfigurationClassParser, 递归扫描@Configuration, @ComponentScan, @Import等注解
  3. 实例化ConfigurationClassBeanDefinitionReader,递归读取并注册BeanDefinition
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,
PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware {

//bean定义扫描和注册
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
int registryId = System.identityHashCode(registry);
if (this.registriesPostProcessed.contains(registryId)) {
//this.registriesPostProcessed包含了registryId
//说明postProcessBeanDefinitionRegistry方法已经执行
throw new IllegalStateException(
"postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
}
if (this.factoriesPostProcessed.contains(registryId)) {
//this.factoriesPostProcessed已经包含了registryId
//说明postProcessBeanFactory方法已经执行
throw new IllegalStateException(
"postProcessBeanFactory already called on this post-processor against " + registry);
}
//添加到this.registriesPostProcessed中
//标记已经被执行
this.registriesPostProcessed.add(registryId);

//处理bean定义
processConfigBeanDefinitions(registry);
}

//处理bean定义
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();

//首先处理手动注册的BeanDefinition
//获取手工注册的bean定义名称列表
String[] candidateNames = registry.getBeanDefinitionNames();

for (String beanName : candidateNames) {
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
ConfigurationClassUtils.isLiteConfigurationClass(bean)) {

//beanDefinition是lite或者是full
//full指的是使用了Configuration注解
//lite指的是使用了Component, ComponentScan, Import, ImportResource注解
//或者方法包含了Bean注解
if (logger.isDebugEnabled()) {
logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
}
}
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
//当前beanDefinition是一个配置类
//添加到configCandidates中
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}

if (configCandidates.isEmpty()) {
//如果配置类为空,那么立即返回
return;
}

//@Order注解排序
configCandidates.sort((bd1, bd2) -> {
int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return Integer.compare(i1, i2);
});

//设置bean名称生成策略
SingletonBeanRegistry sbr = null;
if (registry instanceof SingletonBeanRegistry) {
sbr = (SingletonBeanRegistry) registry;
if (!this.localBeanNameGeneratorSet) {
BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);
if (generator != null) {
this.componentScanBeanNameGenerator = generator;
this.importBeanNameGenerator = generator;
}
}
}

if (this.environment == null) {
this.environment = new StandardEnvironment();
}

//ConfigurationClassParser只负责解析被注解的类
//并不进行BeanDefinition的注册
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);

//Configuration类名
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
//已经解析过的ConfigurationClass
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
do {
//解析, 维护到parser.configurationClasses中
parser.parse(candidates);
//验证
//类不可以为final类型, 必须可重写, static方法不处理
parser.validate();

//configClasses维护待处理的ConfigurationClasse
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);

// this.reader初始化为ConfigurationClassBeanDefinitionReader
//进行BeanDefinition的加载
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
//加载BeanDefinition
this.reader.loadBeanDefinitions(configClasses);
//alreadyParsed维护已经解析完的class
alreadyParsed.addAll(configClasses);

candidates.clear();

if (registry.getBeanDefinitionCount() > candidateNames.length) {
//说明在加载Configuration注解类的过程中,
//扫描到了Import注解, 引入了新的BeanDefinition
String[] newCandidateNames = registry.getBeanDefinitionNames();
Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
Set<String> alreadyParsedClasses = new HashSet<>();
for (ConfigurationClass configurationClass : alreadyParsed) {
alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
}
for (String candidateName : newCandidateNames) {
if (!oldCandidateNames.contains(candidateName)) {
//上次没有处理过的类
BeanDefinition bd = registry.getBeanDefinition(candidateName);
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
!alreadyParsedClasses.contains(bd.getBeanClassName())) {
//@Configuration注解的类
//没有被处理过
candidates.add(new BeanDefinitionHolder(bd, candidateName));
}
}
}
candidateNames = newCandidateNames;
}
}
//candidates不为空, 说明处理@Configuration注解的类
//扫描到了@Import注解, 引入了新的@Configuration注解类
while (!candidates.isEmpty());

//将@Import引入的类列表注册为单例Bean
//这样可以支持Configuration注解的ImportAware的实现类
//在实例化Bean的时候, 可以将Import导入的类, 传递给Bean实例
if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
}

if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
//清空缓存
((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
}
}
}

ConfigurationClassParser#parse

ConfigurationClassParser#parse方法, 共执行了下面8步:

  1. 处理内部类ConfigurationClassParser#processMemberClasses
  2. 处理@PropertySource注解
  3. ComponentScanAnnotationParser处理@ComponentScan注解
  4. 处理@Import注解
  5. 处理@ImportResource注解
  6. 处理方法上的@Bean注解
  7. 处理接口的中的default方法
  8. 处理@Import导入的DeferredImportSelector类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
class ConfigurationClassParser {
//解析
//最终都会执行processConfigurationClass方法
public void parse(Set<BeanDefinitionHolder> configCandidates) {
for (BeanDefinitionHolder holder : configCandidates) {
BeanDefinition bd = holder.getBeanDefinition();
try {
if (bd instanceof AnnotatedBeanDefinition) {
//AnnotatedBeanDefinition类型
//解析metadata
parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
}
else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
//AbstractBeanDefinition类型
//解析beanClass
parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
}
else {
//MetadataReader类型
//解析beanClassName
parse(bd.getBeanClassName(), holder.getBeanName());
}
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);
}
}

//处理@Import导入的DeferredImportSelectorHolder类
this.deferredImportSelectorHandler.process();
}

//处理@Configuration注解的class
protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
return;
}

//判断是否已经被处理过
ConfigurationClass existingClass = this.configurationClasses.get(configClass);
if (existingClass != null) {
//已经被处理过了
if (configClass.isImported()) {
//configClass是被Import导入的
if (existingClass.isImported()) {
//将configClass的importedBy合并到existingClass的existingClass中
existingClass.mergeImportedBy(configClass);
}
return;
}
else {
//如果configClass不是被Import导入
//那么说明是一个显式的bean定义, 我们旧的移除掉
this.configurationClasses.remove(configClass);
this.knownSuperclasses.values().removeIf(configClass::equals);
}
}


SourceClass sourceClass = asSourceClass(configClass);
do {
//递归扫描并处理父类, 以及其注解
sourceClass = doProcessConfigurationClass(configClass, sourceClass);
}
while (sourceClass != null);

//维护已经处理的类
this.configurationClasses.put(configClass, configClass);
}

//实际解析配置类的方法
@Nullable
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
throws IOException {

//configClass使用了@Component注解
if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
//递归处理内部类
processMemberClasses(configClass, sourceClass);
}

//处理@PropertySources注解
for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), @PropertySources.class,
org.springframework.context.annotation.PropertySource.class)) {
if (this.environment instanceof ConfigurableEnvironment) {
//this.environment是ConfigurableEnvironment实例, 才进行@PropertySources属性替换
processPropertySource(propertySource);
}
else {
logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
"]. Reason: Environment must implement ConfigurableEnvironment");
}
}

// 处理configClass类的@ComponentScans,ComponentScan注解
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
if (!componentScans.isEmpty() &&
!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
for (AnnotationAttributes componentScan : componentScans) {
// 交付给ComponentScanAnnotationParser进行扫描
Set<BeanDefinitionHolder> scannedBeanDefinitions =
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());

for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
//获取来源Beanthis.reader.loadBeanDefinitions(configClasses)Definition
//OriginatingBeanDefinition由代理设置
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {
bdCand = holder.getBeanDefinition();
}

if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
//BeanDefinition中的类由@Configuration注解
//调用parse方法, 递归处理@Configuration注解的类
parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
}

//处理configClass类的@Import注解
processImports(configClass, sourceClass, getImports(sourceClass), true);

//处理configClass类的@ImportResource注解
AnnotationAttributes importResource =
AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
if (importResource != null) {
//获取ImportResource的属性
String[] resources = importResource.getStringArray("locations");
Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
for (String resource : resources) {
//处理导入的resource
String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
configClass.addImportedResource(resolvedResource, readerClass);
}
}

// 处理sourceClass中@Bean注解的方法
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {
//添加到configClass中
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}

//处理接口中的default方法
processInterfaces(configClass, sourceClass);

// 如果有父类的话, 处理父类
if (sourceClass.getMetadata().hasSuperClass()) {
String superclass = sourceClass.getMetadata().getSuperClassName();
if (superclass != null && !superclass.startsWith("java") &&
!this.knownSuperclasses.containsKey(superclass)) {
this.knownSuperclasses.put(superclass, configClass);

//返回父类
//递归处理父类
return sourceClass.getSuperClass();
}
}

//没有父类, 处理结束
return null;
}
}

AutoConfigurationImportSelector#selectImports

SpringFactoriesLoader#loadFactoryNames#loadSpringFactories