说明
SpringBoot 版本 2.7.1
SpringApplication.run(),refresh()调用之前解析
-
SpringApplication在构造方法时,就会读取META-INF/spring.factories的类,缓存到SpringFactoriesLoader中(这是Spring的SPI),注意这里的缓存不仅仅只有org.springframework.boot.autoconfigure.EnableAutoConfiguration,包括文件中所有key-value
缓存是一个静态变量
-
SpringApplication第298行,通过SPI从META-INF/spring.factories获取org.springframework.boot.SpringApplicationRunListener的实现类并加载
通过构造器创建自定义RunListener实例
进入到自定义RunListener的构造方法
-
第299行,通过spring.factories获取的所有SpringApplicationRunListener的实现类,并调用start方法
-
SpringApplication第302行,创建spring环境配置类,默认环境变量实现类为ApplicationServletEnvironme
ApplicationServletEnvironment的抽象父类为AbstractEnvironment,他的成员变量MutablePropertySources propertySources是环境变量核心。包含了List<PropertySource<?>> propertySourceList
PropertySource类结构
继续回到ApplicationServletEnvironment的构造方法创建,在默认调用抽象父类的构造中,执行了customizePropertySources(MutablePropertySources propertySources)方法
这个方法由ApplicationServletEnvironment的直接父类StandardServletEnvironment来实现,添加了两个默认的propertySource,再去调用StandardServletEnvironment的直接父类StandardEnvironment的customizePropertySources(MutablePropertySources propertySources)方法。再添加两个默认的propertySource,这里就包含了系统配置System.getProperties()和系统运行环境System.getenv()
以上只是prepareEnvironment方法的第341行逻辑,341行之后,还会添加一些propertySource、调用省略SpringApplicationRunListener的environmentPrepared方法等
完成spring环境配置类创建 -
创建IOC核心ApplicationContext,第305行
context核心变量的核心包括:
a. List beanFactoryPostProcessors
b. ConfigurableEnvironment environment
c. DefaultListableBeanFactory beanFactory
默认ApplicationContext的实现类是AnnotationConfigServletWebServerApplicationContext
它的间接父类是GenericApplicationContext,构造方法中初始化了beanFactory,这里与spring的ClassPathXmlApplicationContext有区别,ClassPathXmlApplicationContext是在refresh执行时才创建beanFactory,而GenericApplicationContext是在refresh之前
以上为创建ApplicationContext逻辑。 -
进行ApplicationContext赋值处理,SpringApplication第307行prepareContext方法
进入prepareContext方法,这里赋值了environment、添加默认类到IOC容器(beanFactory的间接父类DefaultSingletonBeanRegistry中的singletonObjects,作为一级缓存)、设置循环依赖状态、添加默认BeanFactoryPostProcessor
调用SpringApplicationRunListener的contextPrepared、contextLoaded方法
-
SpringApplication第308行,核心方法refreshContext(context);
调用context.refresh(),由AnnotationConfigServletWebServerApplicationContext的间接抽象父类AbstractApplicationContext来实现。
Context.refresh()调用方法解析
- AbstractApplicationContext第553行obtainFreshBeanFactory()
这里的实现很简单,只是返回了beanFactory对象(如果context是用spring的ClassPathXmlApplicationContext,会在这里进行beanDefinition的构建,这里不做深入区别讨论)
- AbstractApplicationContext第556行,prepareBeanFactory
Prepare the bean factory for use in this context.
会默认添加一些beanPostProcess实现(比如ApplicationContextAwareProcessor,用来判断bean是否实现了各种Aware接口,如果实现了,ApplicationContextAwareProcessor会在postProcessBeforeInitialization执行回调)。
会默认注册一些单例bean到ioc容器(比如 environment、systemProperties、systemEnvironment等)。DefaultListableBeanFactory的父类DefaultSingletonBeanRegistry,里面的成员变量 Map<String, Object> singletonObjects,作为IOC容器用来存放单例对象,注册的单例bean会放在这里。
- AbstractApplicationContext第560行,postProcessBeanFactory
Allows post-processing of the bean factory in context subclasses.
由AnnotationConfigServletWebServerApplicationContext实现
super.postProcessBeanFactory(beanFactory)。会添加WebApplicationContextServletContextAwareProcessor到BeanPostProcessor
invokeBeanFactoryPostProcessors
AbstractApplicationContext第564行,invokeBeanFactoryPostProcessors。
这个方法会执行springboot的自动装配核心逻辑
Invoke factory processors registered as beans in the context.
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors 方法
第112行invokeBeanDefinitionRegistryPostProcessors
在这里执行BeanDefinitionRegistryPostProcessor的实现方法postProcessBeanDefinitionRegistry。
当前postProcessor是ConfigurationClassPostProcessor
进入ConfigurationClassPostProcessor.processConfigBeanDefinitions方法
从beanFactory的beanDefinitionMap中,目前beanDefinitionMap的数据只有初始化时候加入的,如下
接着第287行 ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory),会依次遍历判断是否有@Configuration注解,启动类因为有@SpringBootApplication,它引用了@SpringBootConfiguration,而@SpringBootConfiguration又引用了@Configuration。把符合要求的BeanDefinition封装成BeanDefinitionHolder(第288行),然后加入到 List configCandidates 集合中
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
通过过滤放这里configCandidates集合只有启动类
第327行
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
332行
构建了一个
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
processConfigBeanDefinitions方法第329-367行,递归遍历candidates集合,解析每一个BeanDefinitionHolder
第331行 parser.parse(candidates)
ConfigurationClassParser的parse方法,第175行
ConfigurationClassParser第206行,parse的重载方法
进入ConfigurationClassParser第225行,processConfigurationClass
第250行,开始处理@Configuration注解的类逻辑
进入doProcessConfigurationClass,可以看到这里针对类上的注解做了很多判断,是否有@Component、@PropertySource、@ComponentScan、@Import注解等
先看ConfigurationClassParser-doProcessConfigurationClass-272行,当类上有@Component注解时,判断是否有内部类,再递归判断内部类是否有@Component
ConfigurationClassParser-第276行,判断是否有@PropertySources注解
ConfigurationClassParser-第442行开始,processPropertySource 方法
先判断@PropertySource的value是否为空(这是必要配置),然后加载value的值为Resource对象
ConfigurationClassParser-第463行,factory.createPropertySource(name, new EncodedResource(resource, encoding)),这里的factory默认是DefaultPropertySourceFactory
ConfigurationClassParser-第479行,进入DefaultPropertySourceFactory.createPropertySource方法
会创建并返回ResourcePropertySource对象
ResourcePropertySource的构造方法如下,通过getNameForResource(resource.getResource()) 和 *PropertiesLoaderUtils.loadProperties(resource)方法构造成 String name 和 Properties source,继续调用父类构造方法
最终ResourcePropertySource的顶层抽象类为PropertySource。构造完成后返回
回到ConfigurationClassParser-463行,将构造返回的propertySource,再调用addPropertySource(propertySource)*方法
ConfigurationClassParser-479行,addPropertySource方法
判断environment的propertySources是否已经包含了此propertySource,如果没有包含,添加到propertySources中
第505-510行,是用来判断插入propertySources的位置
回到ConfigurationClassParser-280行,处理完了@PropertySources的逻辑,继续往下
ConfigurationClassParser-289行,开始处理@ComponentScan逻辑,进入296行componentScanParser.parse
ComponentScanAnnotationParser-68行parse方法,初始化ClassPathBeanDefinitionScanner类,处理了basePackages的包扫描路径等
直接看到ComponentScanAnnotationParser-128行,ClassPathBeanDefinitionScanner scanner.doScan(StringUtils.toStringArray(basePackages));
进入ClassPathBeanDefinitionScanner-272行的doScan方法,入参为scanBasePackages的值
从275行开始,遍历所有basePackages,276行,从basePackage的值开始扫描符合要求的bean,并封装成BeanDefinition
由父类ClassPathScanningCandidateComponentProvider实现findCandidateComponents 方法,第311行
再进入316行 scanCandidateComponents(basePackage);
ClassPathScanningCandidateComponentProvider第416行开始
获取classpath下符合basePackage的 .class路径。如这里的: classpath:org/hopehomi/**/*.class
获取到该路径下所有的 *.class路径
tips:
基于class扫描,我们可以自定义ResourceLoaderAware,或者直接继承ClassPathScanningCandidateComponentProvider。
使用ClassPathScanningCandidateComponentProvider的class加载能力
package org.hopehomi.core.tool.aware;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternUtils;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
* @author Ledison
* @date 2023/3/17
*/
public class HopeResourceLoaderAware extends ClassPathScanningCandidateComponentProvider implements ResourceLoaderAware{
private ResourceLoader resourceLoader;
private final String DEFAULT_RESOURCE_PATTERN = "/**/*.class";
private ClassPathScanningCandidateComponentProvider provider;
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
provider = new ClassPathScanningCandidateComponentProvider(true);
provider.setResourceLoader(resourceLoader);
this.resourceLoader = resourceLoader;
}
public Resource[] getPackagePathResources(String packagePath) throws IOException {
ResourcePatternResolver resourcePatternResolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader);
packagePath = packagePathParse(packagePath);
// classpath*:org/hopehomi/**/*.class
return resourcePatternResolver.getResources(packagePath);
}
private String packagePathParse(String packagePath) {
packagePath = packagePath.replace(".","/");
if (!packagePath.startsWith(ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX)) {
// 不是以classpath开头
packagePath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + packagePath;
}
if (!packagePath.endsWith(DEFAULT_RESOURCE_PATTERN)) {
packagePath += DEFAULT_RESOURCE_PATTERN;
}
return packagePath;
}
public List<String> getPackagePathClassNames(String packagePath) throws IOException {
List<String> classNames = new ArrayList<>();
Resource[] packagePathResources = this.getPackagePathResources(packagePath);
CachingMetadataReaderFactory cachingMetadataReaderFactory = new CachingMetadataReaderFactory(resourceLoader);
for (Resource resource : packagePathResources) {
MetadataReader metadataReader = cachingMetadataReaderFactory.getMetadataReader(resource);
classNames.add(metadataReader.getClassMetadata().getClassName());
}
return classNames;
}
public Set<BeanDefinition> getPackagePathBeanDefinitions(String packagePath) {
packagePath = packagePath.replace(".","/");
return provider.findCandidateComponents(packagePath);
}
}
解析每一个resource,429行,通过CachingMetadataReaderFactory将resource构建成MetadataReader
430行isCandidateComponent来判断MetadataReader是否包含@Component注解
这里进行判断是否有@Component
如果包含,将metadataReader构建成beanDefinition,加入candidates。
注意这里只要有@Component注解就会加入到集合,并没有处理bean上面的Condition相关注解
上面的ignoreModel是加了@ConditionalOnBean(Test.class)。Test只是一个普通类
package org.hopehomi.boot.config;
import org.hopehomi.boot.controller.Test;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.stereotype.Component;
/**
* @author Ledison
* @date 2023/3/16
*/
@ConditionalOnBean(Test.class)
@Component
public class IgoreModel {
}
package org.hopehomi.boot.controller;
import lombok.Data;
/**
* @author Ledison
* @date 2023/3/16
*/
@Data
public class Test {
private String name = "zhangsan";
}
findCandidateComponents方法执行完后,回到ClassPathBeanDefinitionScanner第277行
将返回的Set candidates(@Component的Bean)构造成BeanDefinitionHolder
并在292行,将每个BeanDefinition加入到beanFactory的beanDefinitionMap中
添加到beanDefinitionMap的过程略,最终beanFactory的beanDefinitionMap结果如下
注意这里只是把beanDefinition放入了beanDefinitionMap,没有对bean进行任何初始化操作
以上是ConfigurationClassParser-doProcessConfigurationClass-295行的逻辑。通过启动类上ComponentScan注解,加载了包下面符合要求的@Component并构建成BeanDefinitionHolder。
小提一点:springboot是通过扫描来加载beanDefinition,而springXml是通过解析XML文件来加载beanDefinition
从298行开始,会开始递归这些BeanDefinitionHolder,让每一个BeanDefinitionHolder都走一遍刚才的加载流程
接下来ConfigurationClassParser-doProcessConfigurationClass-311行。
processImports(configClass, sourceClass, getImports(sourceClass), filter, true);
先看getImports方法
进入collectImports(sourceClass, imports, visited);
这里会递归,直到找到@Import注解。比如@SpringBootApplication 上的 @EnableAutoConfiguration上的@Import(AutoConfigurationImportSelector.class)
这里找到了@HopeSpringBootApplication上有@Import注解。引入了一个我定义的环境配置Selector
package org.hopehomi.core.launch.props;
import org.hopehomi.core.launch.selector.EnvironmentConfigurationSelector;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Import;
import org.springframework.core.annotation.AliasFor;
import java.lang.annotation.*;
/**
* @author Ledison
* @date 2023/3/16
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@SpringBootApplication
@Import(EnvironmentConfigurationSelector.class)
public @interface HopeSpringBootApplication {
@AliasFor(
annotation = SpringBootApplication.class,
attribute = "scanBasePackages"
)
String[] scanBasePackages() default {};
}
package org.hopehomi.core.launch.selector;
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;
/**
* 环境基础配置
*
* @author Ledison
* @date 2023/3/16
*/
public class EnvironmentConfigurationSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{
"org.hopehomi.core.database.config.DruidConfiguration"
};
}
}
进入ConfigurationClassParser-collectImports-549行,sourceClass.getAnnotationAttributes(Import.class.getName(), “value”)
进入getAnnotationAttributes,第1068行,这里会获取到@Import的Value值,也就是@Import需要引入的类名
第1071行,执行getRelated方法,将引入的类名构造成SourceClass,并加入到集合返回
回到collectImports方法,第549行。添加到所有imports引用类的集合中
collectImports方法结束并返回,回到ConfigurationClassParser-getImports-522行。
以上代码总结为:获取从启动类开始,一直递归找到@Import的引入类,并放在集合返回,所有结果如下
imports表示满足@Import条件的,visited表示递归过的注解类
这里找到了 org.springframework.boot.autoconfigure.AutoConfigurationImportSelector(自动装配核心Selector),以及我们自定义的org.hopehomi.core.launch.selector.EnvironmentConfigurationSelector环境配置Selector
getImports方法结束,回到ConfigurationClassParser第311行,执行processImports方法
Process any @Import annotations
processImports方法,遍历所有importCandidates(SourceClass集合),判断每个SourceClass是否实现ImportSelector
如果实现了,会通过构造器生成实例,并判断Selector类是否实现了aware方法,将environment、beanFactory等变量设置到实例中
如果Selector实现了DeferredImportSelector(延时引入Selector),AutoConfigurationImportSelector实现了。进入578 行逻辑,将Selector放入延时引入的集合中
而如果Selector未实现DeferredImportSelector,比如我们自定义的Selector,进入581行逻辑
第582行,会通过默认的三个Condition(OnClass、OnWeb、OnBean,更详细的在后面还会说明)来判断是否需要过滤掉这个引入的Class,如果不需要过滤,继续将这些class会通过递归,也执行刚才的processImports逻辑
如果没有实现ImportSelector或者ImportBeanDefinitionRegistrar,会执行第600行逻辑,再执行processConfigurationClass,也是通过递归最终把@Component类,放入ConfigurationClassParser的configurationClasses变量
以上是通过@Import来加载配置类的逻辑
第ConfigurationClassParser-314行,通过@ImportResource来加载配置类
第326行,通过方法上的@Bean来加载配置类
doProcessConfigurationClass方法结束
结束方法后,来到ConfigurationClassParser-parse-193行。
这里开始处理延时引入的Selector(AutoConfigurationImportSelector)
进入process方法,创建DeferredImportSelectorGroupingHandler来处理每一个DeferredImportSelectorHolder
第780行开始执行DeferredImportSelectorHolder的
遍历DeferredImportSelectorGrouping,调用grouping.getImports()方法
getImports方法的第879行,进入this.group.process(这里的group是的AutoConfigurationImportSelector内部静态类AutoConfigurationGroup)
AutoConfigurationGroup-process-434行,准备开始通过Spring Spi读取自动装载类。
440行,进入getAutoConfigurationEntry方法
getAutoConfigurationEntry方法第125行,getCandidateConfigurations
进入getCandidateConfigurations方法,开始装载配置类
AutoConfigurationImportSelector的第182行,通过SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader())) 来装载配置类
getSpringFactoriesLoaderFactoryClass()方法返回的默认@EnableAutoConfiguration
getBeanClassLoader()方法返回类加载器(这里是appClassLoader)
进入SpringFactoriesLoader.loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader)
这里factoryType是EnableAutoConfiguration.class,classLoader是appClassLoader
表示加载spring.factories下,key为factoryType类型的value值
这里在applicationContext初始化的时候已经加载过一次SPI,所以SpringFactoriesLoader的cache变量是有值的。再根据factoryType进行过滤,返回EnableAutoConfiguration对应的value
AutoConfigurationImportSelector-getCandidateConfigurations-184行
ImportCandidates.load方法,用来加载META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件下的类
这个和java的SPI很类似,可以从下图看到初始化定义了很多类,这些类基本都是配置在org.springframework.boot:spring-boot-autoconfigure项目下
org.springframework.boot:spring-boot-autoconfigure下的org.springframework.boot.autoconfigure.AutoConfiguration.imports配置文件
ImportCandidates.load方法结束,然后把刚才加载的类和上面通过spring.factories加载的EnableAutoConfiguration实现类,合并成集合后返回。getCandidateConfigurations方法结束
继续回到AutoConfigurationImportSelector第130行,过滤加上Condition相关的注解类,这里的Condition默认有三个(OnBeanCondition、OnClassCondition、OnWebApplicationCondition),依然是配置在spring.factories里面
getConfigurationClassFilter().filter(configurations);
getConfigurationClassFilter()返回ConfigurationClassFilter对象,他是AutoConfigurationImportSelector的内部类
进入filter方法,依次执行三个默认Condition类的match方法,match是三个Condition的抽象父类FilteringSpringBootCondition的方法
通过模板模式,调用Condition的实现类getOutcomes方法
我这里就以OnBeanCondition举例,因为我的自定义配置类有这个注解,且@ConditionalOnBean(Test.class) 这个Test并不会被加载成bean。
但是这里依然没有把我自定义的类过滤掉???这个地方后面再回头思考,留一个疑问
结束*grouping.getImports()*方法,返回Iterable<Group.Entry>
遍历所有Entry(获取到的spring.factories加载的EnableAutoConfiguration实现类自动装配类、org.springframework.boot.autoconfigure.AutoConfiguration.imports定义的类),统称为 配置文件扫描自动配置类
到812行,再次执行processImports方法,这里第三个参数Collection importCandidates。数据来自Collections.singleton(asSourceClass(entry.getImportClassName(), exclusionFilter))。
继续将每一个配置文件扫描自动配置类通过processImports来判断是否实现ImportSelector和ImportBeanDefinitionRegistrar类
回忆一下processImports的逻辑,如果实现了ImportSelector切继承DeferredImportSelector类,加入延时Selector;如果没有实现DeferredImportSelector,立即触发selectImports方法
注意区分这里调用processImports和之前递归调用。之前是通过@ComponentScan,扫描包下面的类,依次调用processImports方法。
这里是通过扫描 配置文件扫描自动配置类,来处理processImports逻辑。
回看process方法,其实方法已经结束,而且parse()方法也已经结束,在finally里把延时Selector集合清空。
总结一下parse()方法,分为两部分,两部分的执行目的就是获取配置类,放在ConfigurationClassParser的configurationClasses中。
第一部分:通过从启动类的@ComponentScan开始,找到符合@Component注解的类,并且在@ComponentScan之前,处理了内部类@Component、@PropertySources自定义配置加载的逻辑。递归判断@Component对象上是否包含了@Import注解,如果包含了判断引用的类是否实现ImportSelector:如果实现ImportSelector且继承自DeferredImportSelector,那么放入延时Selector继承,在后面第二部分进行处理;如果实现ImportSelector但是没有继承DeferredImportSelector,会立即执行引用Selector的selectImports方法。当类没有继承自ImportSelector或者ImportBeanDefinitionRegistrar,会作为普通配置类加入到configurationClasses集合中。这段逻辑在@ComponentScan是递归处理的
第二部分:process()方法处理第一部分获取的延时Selector集合的逻辑,主要是处理核心AutoConfigurationImportSelector,在这里会获取从spring.factories加载的EnableAutoConfiguration实现类自动装配类、org.springframework.boot.autoconfigure.AutoConfiguration.imports定义的类。然后遍历这些类,执行第一部分关于是否实现ImportSelector的逻辑。最终将这些配置放到configurationClasses集合中。
parse()方法,核心字段configurationClasses
可以看到configurationClasses已经缓存了很多配置类
parse()方法结束,回到ConfigurationClassPostProcessor343行,this.reader.loadBeanDefinitions(configClasses);
在这里开始过滤@Condition相关逻辑,并不是在之前进行判断,解决了疑问
从beanFactory的beanDefinitionMap去掉该类,loadBeanDefinitionsForConfigurationClass方法第143行
loadBeanDefinitionsForConfigurationClass第157行,在这里会调用实现了ImportBeanDefinitionRegistrar的registerBeanDefinitions方法
结束loadBeanDefinitions方法,该方法主要处理Condition相关的注解
至此,invokeBeanDefinitionRegistryPostProcessors方法也基本结束,但它只是refresh方法中invokeBeanFactoryPostProcessors(beanFactory后置处理)的一部分。
通过invokeBeanFactoryPostProcessors方法执行(ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry方法)。让beanFactory的beanDefinitionMap、beanDefinitionNames正确赋值
回到PostProcessorRegistrationDelegate-116行,从bdMap中获取实现了BeanDefinitionRegistryPostProcessor的类,在142行,会调用postProcessBeanDefinitionRegistry方法。这里的依然通过调用invokeBeanDefinitionRegistryPostProcessors来执行,和前面执行自动装配逻辑调用方法一样,只是前面通过beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false)获取的实现类只有ConfigurationClassPostProcessor。通过自动装配处理后,在后面再次调用beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false)时,可以获取到我们自定义的实现类。
142行进入invokeBeanDefinitionRegistryPostProcessors。调用自定义类的postProcessBeanDefinitionRegistry
在147行,执行BeanFactoryPostProcessor接口的postProcessBeanFactory的回调
因为BeanDefinitionRegistryPostProcessor实现了BeanFactoryPostProcessor。所以这里的自定义类也会进行postProcessBeanDefinitionRegistry回调
invokeBeanFactoryPostProcessors方法总结
执行BeanDefinitionRegistryPostProcessor回调
- 执行默认传入的三个BeanDefinitionRegistryPostProcessor的回调postProcessBeanDefinitionRegistry
Invoke BeanDefinitionRegistryPostProcessors first, if any.
- 执行beanFactory中前面设置的bdMap中类型为BeanDefinitionRegistryPostProcessor的回调,且bean实现了PriorityOrdered接口
这一步是自动装配核心,由ConfigurationClassPostProcessor执行
First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
在beanFactory.getBean(beanName, xxx.class)。会通过beanFactory查询singletonObjects中是否能获取到对象实例,如果获取不到,且在mergedBeanDefinitions存在该key,会创建对象实例,放到singletonObjects中,这一块逻辑在以后章节再分析
- 通过第二步自动装载后,再次执行bdMap中类型为BeanDefinitionRegistryPostProcessor的回调,且bean实现了Ordered接口
Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
- 执行剩余未执行的BeanDefinitionRegistryPostProcessor的回调
Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
- 执行实现了BeanDefinitionRegistryPostProcessor的父类BeanFactoryPostProcessor回调方法postProcessBeanFactory。如果bean只实现了BeanFactoryPostProcessor,不会在这里执行回调
Now, invoke the postProcessBeanFactory callback of all processors handled so far.
这里ConfigurationClassPostProcessor也是实现了BeanDefinitionRegistryPostProcessor,他是动态代理处理类,这个在(下)文章中说明
执行BeanFactoryPostProcessors回调
- 执行BeanFactoryPostProcessors的回调,且实现了PriorityOrdered
First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
- 执行BeanFactoryPostProcessors的回调,且实现了Ordered
Next, invoke the BeanFactoryPostProcessors that implement Ordered.
- 执行剩余的BeanFactoryPostProcessors的回调
Finally, invoke all other BeanFactoryPostProcessors.