SpringBoot源码思考
createApplicationContext
- 方法:createApplicationContext
- 作用:创建应用上下文ApplicationContext,注册5个后置处理器
其中ConfigurationClassPostProcessor扫描器,用来加载@Configuration注解。 - 实现:
- 委派给AnnotationConfigServletWebServerApplicationContext类
- 实例化AnnotationConfigServletWebServerApplicationContext类
- 委派给AnnotatedBeanDefinitionReader类去实现
- 委派给AnnotationConfigUtils类注册注解后置管理器registerAnnotationConfigProcessors
prepareContext
- 方法:prepareContext
- 作用:将enviroment设置到context中,使用load方法加载启动类(其他的如设置懒加载和单例加载)
- 实现:
- 调用getAllSources方法加载启动类
- 创建BeanDefinitionHolder加载器
- load方法直接调用工具类BeanUtils.instantiateClass实例化启动类
invokeBeanFactoryPostProcessors
- 方法:invokeBeanFactoryPostProcessors
- 作用:将BeanFactoryPostProcessor注册到BeanFactory上面。加载注解@SpringBootApplication、还递归加载其父类@EnableAutoConfiguration、@Import
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
String[] candidateNames = registry.getBeanDefinitionNames();
// for循环代码干了一件事就是
// 将@Configuration注解beanFactory后置处理器(ConfigurationClassPostProcessor)放入configCandidates
for (String beanName : candidateNames) {
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
if (logger.isDebugEnabled()) {
logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
}
}
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
// Return immediately if no @Configuration classes were found
if (configCandidates.isEmpty()) {
return;
}
// Sort by previously determined @Order value, if applicable
// 将beanFactory后置处理器根据实现order接口排序
configCandidates.sort((bd1, bd2) -> {
int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return Integer.compare(i1, i2);
});
。。。
// 解析每一个@Configuration类
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
do {
StartupStep processConfig = this.applicationStartup.start("spring.context.config-classes.parse");
// 递归处理超类,如META-INF下@EnableAutoConfiguration、@Import
parser.parse(candidates);
parser.validate();
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
// Read the model and create bean definitions based on its content
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
// 加载配置类
this.reader.loadBeanDefinitions(configClasses);
alreadyParsed.addAll(configClasses);
processConfig.tag("classCount", () -> String.valueOf(configClasses.size())).end();
candidates.clear();
if (registry.getBeanDefinitionCount() > candidateNames.length) {
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())) {
candidates.add(new BeanDefinitionHolder(bd, candidateName));
}
}
}
candidateNames = newCandidateNames;
}
}
while (!candidates.isEmpty());
// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
}
if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
// Clear cache in externally provided MetadataReaderFactory; this is a no-op
// for a shared cache since it'll be cleared by the ApplicationContext.
((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
}
}
finishBeanFactoryInitialization
- 方法:finishBeanFactoryInitialization
- 作用:实例化所有非懒加载的类
- 实现:
- 委派给preInstantiateSingletons方法
- preInstantiateSingletons方法逻辑:遍历beanNames集合,调用getBean方法实例化(反射调用构造方法 -> 反射调用set方法)
SpringBoot中Bean什么时候实例化?
finishBeanFactoryInitialization方法调用getBean方法中createBeanInstance方法反射实例化bean。
SpringBoot中什么时候属性注入?
createBeanInstance方法反射实例化bean之后,populateBean方法注入属性。
SpringBoot中bean的后置处理器什么时候注册?
refresh方法调用registerBeanPostProcessors方法的时候,注册后置处理器。
SpringBoot中init-method什么时候执行?
在实例化bean和属性填充之后,调用初始化initializeBean方法时,反射执行bean配置的init-method方法。
SpringBoot中bean的前置处理器和后置处理器什么时候执行?
在实例化bean和属性填充之后,调用初始化initializeBean方法时,init-method方法前执行前置处理器,init-method方法后执行后置处理器。
SpringBoot中注解的后置处理器什么时候加载?
run方法中的createApplicationContext方法注册注解到BeanFactory。
SpringBoot中注解什么时候加载?
refresh方法中的invokeBeanFactoryPostProcessors方法。在加载@SpringBootApplication注解中的@ComponentScan注解,会扫描路径下的@Component注解的类。
因此注解的加载invokeBeanFactoryPostProcessors方法在实例化操作finishBeanFactoryInitialization方法之前,将@Component的bean类注册到BeanFactory。