刷新容器-BeanFactory的预处理
// 4.9 初始化IOC容器
prepareContext(context, environment, listeners, applicationArguments, printedBanner);
// 4.10 刷新容器
refreshContext(context);
// 刷新容器后的后置处理
afterRefresh(context, applicationArguments);
4.10 refreshContext:刷新容器
private void refreshContext(ConfigurableApplicationContext context) {
if (this.registerShutdownHook) {
shutdownHook.registerApplicationContext(context);
}
this.refresh(context);
}
直接调了refresh方法(注意此时还是 SpringApplication,没有进到真正的IOC容器),后面又注册了一个关闭的钩子。
向JVM运行时注册一个shutdown的钩子,除非JVM当时已经关闭,否则在JVM关闭时关闭上下文。
protected void refresh(ConfigurableApplicationContext applicationContext) {
applicationContext.refresh();
}
SpringBoot 默认环境下会调用 ServletWebServerApplicationContext 的 refresh 方法
@Override
public final void refresh() throws BeansException, IllegalStateException {
try {
super.refresh();
}
catch (RuntimeException ex) {
WebServer webServer = this.webServer;
if (webServer != null) {
webServer.stop();
}
throw ex;
}
}
然后会调用父类 AbstractApplicationContext 的 refresh 方法
//最终调到AbstractApplicationContext的refresh方法
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
// 1. 初始化前的预处理
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
// 2. 获取BeanFactory,加载所有bean的定义信息(未实例化)
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
// 3. BeanFactory的预处理配置
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
// 4. 准备BeanFactory完成后进行的后置处理
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
// 5. 执行BeanFactory创建后的后置处理器
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
// 6. 注册Bean的后置处理器
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
// 7. 初始化MessageSource
initMessageSource();
// Initialize event multicaster for this context.
// 8. 初始化事件派发器
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
// 9. 子类的多态onRefresh
onRefresh();
// Check for listener beans and register them.
// 10. 注册监听器
registerListeners();
//到此为止,BeanFactory已创建完成
// Instantiate all remaining (non-lazy-init) singletons.
// 11. 初始化所有剩下的单例Bean
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
// 12. 完成容器的创建工作
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
// 13. 清除缓存
resetCommonCaches();
}
}
}
1 prepareRefresh:初始化前的预处理
protected void prepareRefresh() {
this.startupDate = System.currentTimeMillis(); // 记录启动时间
this.closed.set(false); // 标记IOC容器的关闭状态为false
this.active.set(true); // 标记IOC容器已激活
if (logger.isInfoEnabled()) {
logger.info("Refreshing " + this);
}
// Initialize any placeholder property sources in the context environment
// 1.1 初始化属性配置
initPropertySources();
// Validate that all properties marked as required are resolvable
// see ConfigurablePropertyResolver#setRequiredProperties
// 1.2 属性校验,主要检验一些必需的属性是否为空,如果有null的属性会抛出异常。
getEnvironment().validateRequiredProperties();
// Allow for the collection of early ApplicationEvents,
// to be published once the multicaster is available...
// 这个集合的作用,是保存容器中的一些事件,以便在合适的时候利用事件广播器来广播这些事件
// 【配合registerListeners方法中的第三部分使用】
this.earlyApplicationEvents = new LinkedHashSet<>();
}
2 obtainFreshBeanFactory:获取BeanFactory,加载所有bean的定义信息
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
// 2.1 刷新BeanFactory,只是设置了 BeanFactory 的序列化ID而已。
refreshBeanFactory();
return getBeanFactory();
}
3. prepareBeanFactory:BeanFactory的预处理配置
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
// 设置BeanFactory的类加载器、表达式解析器等
beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
// 3.1 配置一个可回调注入ApplicationContext的BeanPostProcessor
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
// BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
// 3.2 自动注入的支持
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// Register early post-processor for detecting inner beans as ApplicationListeners.
// 3.3 配置一个可加载所有监听器的组件
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// Register default environment beans.
// 注册了默认的运行时环境、系统配置属性、系统环境的信息
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}
发现了一个组件概念:BeanPostProcessor。它通常被称为 “Bean的后置处理器”,它可以在对象实例化但初始化之前,以及初始化之后进行一些后置处理。
BeanPostProcessor 相对于 bean 其它初始化方法的执行顺序
- 始化执行顺序:
- 构造方法
- @PostConstruct / init-method
- InitializingBean 的 afterPropertiesSet 方法
- BeanPostProcessor的执行时机
- before:构造方法之后,@PostConstruct 之前
- after:afterPropertiesSet 之后
小结
- IOC容器在开始刷新之前有加载 BeanDefinition 的过程。
- BeanFactory 的初始化中会注册后置处理器,和自动注入的支持。
- BeanPostProcessor 的执行时机是在Bean初始化前后执行。
4. postProcessBeanFactory:BeanFactory的后置处理
在 AbstractApplicationContext 中,这个方法又被设置成模板方法了:
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
}
借助IDEA,发现 AnnotationConfigServletWebServerApplicationContext 重写了这个方法。
// AnnotationConfigServletWebServerApplicationContext
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 4.1 向 IOC 中注册web 支持的几种作用域:request 、session 、application
super.postProcessBeanFactory(beanFactory);
// 4.2 包扫描
if (this.basePackages != null && this.basePackages.length > 0) {
this.scanner.scan(this.basePackages);
}
if (!this.annotatedClasses.isEmpty()) {
this.reader.register(ClassUtils.toClassArray(this.annotatedClasses));
}
}
4.2 包扫描
扫描加载 ComponentScan 注解所在目录及其子目录中的所有 *.class
文件,扫描完后解析 Component ,使用 excludeFilters 和 includeFilters 两组过滤器判断class是否被 @Component / @ManagedBean 标注,判定为 Component 后,会将这个class封装为 BeanDefinition,最后返回。
对封装返回的 BeanDefinition 遍历进行一些后置处理
- 生成 bean 名称
- 执行 BeanPostProcessor 的后置处理器 —— 设置 BeanDefinition 的一些默认值。
- 检查给定候选者的Bean名称,以确定是否需要注册相应的Bean定义或与现有定义冲突。
- 最后就可以注册 BeanDefinition
5 invokeBeanFactoryPostProcessors:执行BeanFactory创建后的后置处理器
BeanFactoryPostProcessor(BeanFactory后置处理器)是一个接口,它只定义了一个方法:
/**
* 在应用程序上下文的标准初始化之后修改其内部bean工厂。
* 所有bean定义都已经加载,但是还没有实例化bean。这允许覆盖或添加属性,甚至可以初始化bean。
*/
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
实现了这个接口,BeanFactory 标准初始化完毕后,可以对这个 BeanFactory
进行后置处理。
这个时机下,所有的 BeanDefinition 已经被加载,但没有Bean被实例化。
另外,BeanFactoryPostProcessor 还有一个子接口:BeanDefinitionRegistryPostProcessor(Bean定义注册的后置处理器)它额外定义了一个方法
/**
* 在标准初始化之后修改应用程序上下文的内部bean定义注册表。
* 所有常规bean定义都已加载,但还没有实例化bean。
* 这允许在下一个后期处理阶段开始之前添加进一步的bean定义。
*/
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
它的执行时机是所有Bean的定义信息即将被加载但未实例化时,也就是先于 BeanFactoryPostProcessor。
【规律】BeanPostProcessor 是对Bean的后置处理,BeanFactoryPostProcessor 是对 BeanFactory 的后置处理
5.1 PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors:回调后置处理器
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
// 首先调用BeanDefinitionRegistryPostProcessor
Set<String> processedBeans = new HashSet<>();
// 这里要判断BeanFactory的类型,默认SpringBoot创建的BeanFactory是DefaultListableBeanFactory
// 这个类实现了BeanDefinitionRegistry接口,则此if结构必进
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
// 保存 BeanDefinition 的后置处理器
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
// 保存 BeanDefinition 注册后置处理器
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
// 该部分会将 BeanFactoryPostProcessor 与 BeanDefinitionRegistryPostProcessor 分离开
// foreach中为了区分不同的后置处理器,并划分到不同的集合中
// 注意如果是BeanDefinitionRegistryPostProcessor,根据原理描述,还会回调它的后置处理功能
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// Separate between BeanDefinitionRegistryPostProcessors that implement
// PriorityOrdered, Ordered, and the rest.
// 不要在这里初始化BeanFactory:我们需要保留所有未初始化的常规bean,以便让bean工厂后处理器应用到它们!
// 独立于实现PriorityOrdered、Ordered和其他的BeanDefinitionRegistryPostProcessor之间。
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// 这部分实际上想表达的意思是,在创建Bean之前,要先执行这些 BeanDefinitionRegistryPostProcessor的后置处理方法,
// 并且实现了 PriorityOrdered排序接口或实现了Ordered接口的Bean需要优先被加载。
// 下面一段是从BeanFactory中取出所有BeanDefinitionRegistryPostProcessor类型的全限定名(String[]),
// 放到下面遍历,还要判断这些类里是否有实现PriorityOrdered接口的,
// 如果有,存到集合里,之后进行排序、统一回调这些后置处理器
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
// 首先,调用实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessors。
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
// 接下来,调用实现Ordered接口的BeanDefinitionRegistryPostProcessors。
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();
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
// 最后,调用所有其他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);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
// 回调所有BeanFactoryPostProcessor的postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
// 先回调BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法
// 再调用BeanFactoryPostProcessor的postProcessBeanFactory方法
}
// 如果BeanFactory没有实现BeanDefinitionRegistry接口,则进入下面的代码流程
else {
// Invoke factory processors registered with the context instance.
// 调用在上下文实例中注册的工厂处理器。
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// 下面的部分是回调BeanFactoryPostProcessor,思路与上面的几乎一样
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors.
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
// 清理缓存
beanFactory.clearMetadataCache();
}
BeanDefinitionRegistryPostProcessors 注册顺序
这其中会注册一个 ConfigurationClassPostProcessor 的后置处理器,这个后置处理器用于 @Configuration 类的扫描加载处理
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
int registryId = System.identityHashCode(registry);
if (this.registriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(
"postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
}
if (this.factoriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(
"postProcessBeanFactory already called on this post-processor against " + registry);
}
this.registriesPostProcessed.add(registryId);
processConfigBeanDefinitions(registry);
}
它取出 BeanFactory 的id,并在下面的if结构中判断是否已经被调用过了。确定没有,在被调用过的集合中加上当前 BeanFactory 的id,之后调用 processConfigBeanDefinitions 方法:
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
String[] candidateNames = registry.getBeanDefinitionNames();
// 5.2.1 确定配置类和组件
for (String beanName : candidateNames) {
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
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
// 对配置类进行排序
configCandidates.sort((bd1, bd2) -> {
int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return Integer.compare(i1, i2);
});
// Detect any custom bean name generation strategy supplied through the enclosing application context
// 5.2.2 加载获取BeanNameGenerator
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();
}
// Parse each @Configuration class
// 加载所有配置类
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 {
// 5.2.3 解析配置类
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());
}
// 5.2.4 解析配置类中的内容
this.reader.loadBeanDefinitions(configClasses);
alreadyParsed.addAll(configClasses);
candidates.clear();
// 5.2.5 加载配置类中的被@Bean标注的组件
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
// 将ImportRegistry注册为Bean,以支持ImportAware @Configuration类
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();
}
}
5.2.1 确定配置类和组件,这里面需要关注的几个 ConfigurationClassUtils 方法:
- isFullConfigurationClass:判断一个配置类是否为full类型
- isLiteConfigurationClass:判断一个配置类是否为lite类型
- checkConfigurationClassCandidate:检查一个类是否为配置类
full与lite
- full:@Configuration 标注的类
- lite:有 @Component 、@ComponentScan 、@Import 、@ImportResource 标注的类,以及 @Configuration 中标注 @Bean 的类。
5.2.2 加载获取BeanNameGenerator
5.2.3 解析配置类 与 包扫描的触发时机:它会解析 @PropertySource 、@ComponentScan 、@Import 、@ImportResource 、@Bean 等注解,并整理成一个 ConfigClass
在解析 @ComponentScan 时会触发:doScan 方法!然后执行 ConfigurationClassPostProcessor 的 postProcessBeanDefinitionRegistry 方法,
5.2.4 loadBeanDefinitions:解析配置类中的内容:在之前已经解析过这个 configClass 了,所以在这里可以很容易的解析出这里面的 @Import 、标注了 @Bean 的方法、@ImportResource 等,并进行相应处理。
5.2.5 加载配置类中的未加载完成的被@Bean标注的组件:在上面的配置类都加载完成后,它要比对 BeanDefinition 的个数,以及被处理过的数量。只要数量不对应,就会展开那些配置类继续加载
小结
- BeanFactoryPostProcessor 的执行时机是所有的 BeanDefinition 已经加载,但还没有实例化
- 包扫描会加载所有 BeanDefinition,底层采用递归扫描
- IOC 容器使用 ConfigurationClassPostProcessor 进行注解组件解析