目录
3.5 初始化非延迟加载的的单例Bean (延迟加载的单例将在第一次调用的时候初始化)
使用示例:
AnnotationConfigApplicationContext annotationConfigApplicationContext =new AnnotationConfigApplicationContext(AppConfig.class);
UserService userService = (UserService) annotationConfigApplicationContext.getBean("userService");
userService.query();
分析:
- 构建AnnotationConfigApplicationContext实例
- 调用getBean方法获取Bean
- 执行目标bean的方法
AnnotationConfigApplicationContext#AnnotationConfigApplicationContext实现:
/**
* 这个构造方法需要传入一个被javaconfig注解了的配置类
* 然后会把这个被注解了javaconfig的类通过注解读取器读取后继而解析
*/
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
/**
* 1. 初始化上下文环境 --> 完成了Spring内部定义的BeanFactory后处理器的注册
* 2. 初始化注解bean定义解析器和类路径bean定义扫描器
*/
this();
/**
* 程序执行到这步之前, Spring内部的BeanDefinition(BeanFactory后处理器)已经注册到beanFactory中;
* 该步骤只是将手动提供的annotatedClasses(配置类)也注册到beanFactory中;
* 其他的注解bean还没有被注册, 整个注册过程刚刚开始
* 其他的注解bean是在激活后处理器中的方法时, 对配置类进行解析, 解析到@ComponentScan注解中的包路径后才进行解析注册
*/
register(annotatedClasses);
//环境刷新
refresh();
}
分析:
- 初始化上下文环境; 完成了Spring内部定义的BeanFactory后处理器的注册, 初始化注解bean定义解析器和类路径bean定义扫描器
- 程序执行到这步之前, Spring内部的BeanDefinition(BeanFactory后处理器)已经注册到beanFactory中; 该步骤只是将手动提供的annotatedClasses(配置类)也注册到beanFactory中; 其他的注解bean还没有被注册, 整个注册过程刚刚开始其他的注解bean是在激活后处理器中的方法时, 对配置类进行解析, 解析到@ComponentScan注解中的包路径后才进行解析注册
- 应用环境刷新
1. 注册内部处理器类
_1. AnnotationConfigApplicationContext#AnnotationConfigApplicationContext实现:
/**
* 初始化一个bean的读取和扫描器
* 何谓读取器和扫描器参考上面的属性注释
* 默认构造函数,如果直接调用这个默认构造方法,需要在稍后通过调用其register()
* 去注册配置类(javaconfig),并调用refresh()方法刷新容器,
* 触发容器对注解Bean的载入、解析和注册过程
* 这种使用过程我在ioc应用的第二节课讲@profile的时候讲过
*
* 注意在初始化AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner时需要传递的是bean定义注册器用来存储解析好的bean定义信息
* AnnotationConfigApplicationContext实现了GenericApplicationContext,而GenericApplicationContext实现了BeanDefinitionRegistry接口
*/
public AnnotationConfigApplicationContext() {
/**
* 实例化注解bean的解析器, 并会对beanFactory进行一些初始化配置
*/
this.reader = new AnnotatedBeanDefinitionReader(this);
/**
* ClassPathBeanDefinitionScanner: 可以用来扫描包或者类,继而转换成bd
* 1.当初始化AnnotationConfigApplicationContext时传入的是配置类的Class信息时
* 在后面根据注解信息获取到包信息并扫描时使用的并不是这个scanner对象, 而是spring内部实例化的一个ClassPathBeanDefinitionScanner
* {@link ComponentScanAnnotationParser#parse(org.springframework.core.annotation.AnnotationAttributes, java.lang.String)}
* 2.当初始化AnnotationConfigApplicationContext时传入的是配置类的包路径信息时
* 在{@link this#scan(String...)}方法中对包路径进行扫描时使用的是该scanner对象
*
* 总之: 两种方式对包的扫描工作都是在{@link ClassPathBeanDefinitionScanner#doScan(String...)}中进行的
*/
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
分析:
- 实例化注解bean的解析器, 并会对beanFactory进行一些初始化配置, 其中就包括处理器类的注册
- 实例化类路径扫描器,可以用来扫描包信息,对该包路径下的Bean进行解析
注意:
- 当初始化AnnotationConfigApplicationContext时传入的是配置类的Class信息时在后面根据注解信息获取到包信息并扫描时使用的并不是这个scanner对象, 而是spring内部实例化的一个ClassPathBeanDefinitionScanner
- 当初始化AnnotationConfigApplicationContext时传入的包路径信息时, 在{@link this#scan(String...)}方法中对包路径进行扫描时使用的是该scanner对象
_1. AnnotatedBeanDefinitionReader#AnnotatedBeanDefinitionReader实现:
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
. . .
this.registry = registry;
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
/**
* 设置beanFactory中的DependencyComparator和AutowireCandidateResolver属性
* 注册一些beanFactory内部的注解配置处理器类
*/
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
分析: 将注册中心维护在AnnotatedBeanDefinitionReader中以及注册一些BeanFactory内部的注解配置处理器类
AnnotationConfigUtils#registerAnnotationConfigProcessors实现:
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
/**
* 1. 对beanFactory的属性进行设置
*/
//获取注册器中维护的DefaultListableBeanFactory工厂
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
//如果beanFactory不为空, 则设置beanFactory的DependencyComparator和AutowireCandidateResolver属性
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
//AnnotationAwareOrderComparator主要能解析@Order注解和@Priority
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
//ContextAnnotationAutowireCandidateResolver提供处理延迟加载的功能
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
/**
* 2. 注册Spring内部的处理器类(实现BeanDefinitionRegistryPostProcessor接口和BeanFactoryPostProcessor接口)
* Spring在内部类维护这些类, 为BeanFactory提供特定的功能
* 以下7个类是最先注册到beanFactory中的BeanDefinitionMap集合中去
* (1).org.springframework.context.annotation.internalConfigurationAnnotationProcessor -->只有这一个实现了BeanDefinitionRegistryPostProcessor接口
* (2).org.springframework.context.annotation.internalAutowiredAnnotationProcessor
* (3).org.springframework.context.annotation.internalRequiredAnnotationProcessor
* (4).org.springframework.context.annotation.internalCommonAnnotationProcessor
* (5).org.springframework.context.annotation.internalPersistenceAnnotationProcessor -->这个没有被注册
* (6).org.springframework.context.event.internalEventListenerProcessor
* (7).org.springframework.context.event.internalEventListenerFactory
*/
//暂存BeanDefinitionHolder的Set集合
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
//判断注册器中是否含有指定的BeanDefinition,并注册到到注册器中, 然后将beanName和BeanDefinition封装到BeanDefinitionHolder
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
//需要注意的是ConfigurationClassPostProcessor的类型是BeanDefinitionRegistryPostProcessor
//而 BeanDefinitionRegistryPostProcessor 最终实现BeanFactoryPostProcessor这个接口
//根据spring内部提供的class实例化ConfigurationClassPostProcessor
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
//AutowiredAnnotationBeanPostProcessor 实现了 MergedBeanDefinitionPostProcessor
//MergedBeanDefinitionPostProcessor 最终实现了 BeanPostProcessor
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
/**
* 注册后处理器类
*/
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// 检查JPA支持,如果存在,添加PersistenceAnnotationBeanPostProcessor
if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition();
try {
def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
AnnotationConfigUtils.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
}
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
}
/**
* 3. 将注册Spring内部的类封装到Set集合中返回
*/
return beanDefs;
}
分析:
1. 对beanFactory的属性进行设置
2. 注册Spring内部的处理器类(实现BeanDefinitionRegistryPostProcessor接口和BeanFactoryPostProcessor接口), Spring在内部类维护这些类, 为BeanFactory提供特定的功能
以下7个类是最先注册到beanFactory中的BeanDefinitionMap集合中去
(1). org.springframework.context.annotation.internalConfigurationAnnotationProcessor (重点)
(2). org.springframework.context.annotation.internalAutowiredAnnotationProcessor
(3). org.springframework.context.annotation.internalRequiredAnnotationProcessor
(4). org.springframework.context.annotation.internalCommonAnnotationProcessor
(5). org.springframework.context.annotation.internalPersistenceAnnotationProcessor
(6). org.springframework.context.event.internalEventListenerProcessor
(7). org.springframework.context.event.internalEventListenerFactory
3. 将注册Spring内部的类封装到Set集合中返回
_2. AnnotationConfigUtils#registerPostProcessor实现:
private static BeanDefinitionHolder registerPostProcessor(BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(beanName, definition);
return new BeanDefinitionHolder(definition, beanName);
}
GenericApplicationContext#registerBeanDefinition ==> DefaultListableBeanFactory#registerBeanDefinition实现:
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {
. . .
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
/**
* 注册前的最后一次校验,这里的校验不同于之前的XML文件校验
* 主要是对于AbstracBeanDefinition属性中的methodOverrides校验,
* 校验methodOverrides是否与工厂方法并存或者methodOverrides对应的方法不存在
*/
((AbstractBeanDefinition) beanDefinition).validate();
}
. . .
}
//判断该beanName是否已经注册 ,根据不同的设置记性处理; (不愧是Spring, 在我模拟的SpringIOC中我管它那么多, 直接覆盖 ,简单粗暴)
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
if (existingDefinition != null) {
//如果对应的BeanName已经注册且在配置中配置了bean不允许被覆盖,则抛出异常
. . .
//注册beanDefinition(将beanDefinition放入map缓存中)
this.beanDefinitionMap.put(beanName, beanDefinition);
}
//处理注册未被注册的beanName的情况
else {
/**
* 检查这个工厂的bean创建阶段是否已经开始,即 是否有任何bean被标记为同时创建。
* 如果bean工厂的bean创建已经开始, 那么就不能在beanDefinitionNames集合中添加beanName; 因为创建bean时, 会迭代beanDefinitionNames集合,获取beanName,获取BeanDefinition创建bean实例
* 一旦开始迭代, 则不允许在向该map集合中插入元素
*/
if (hasBeanCreationStarted()) {
//处于bean创建阶段
//因为beanDefinitionMap是全局变量,这里肯定会存在并发访问的情况
synchronized (this.beanDefinitionMap) {
//注册beanDefinitionv
this.beanDefinitionMap.put(beanName, beanDefinition);
//创建新的集合来更新存储已注册beanName的beanDefinitionNames集合
List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
//更新manualSingletonNames(存储单例bean)集合
if (this.manualSingletonNames.contains(beanName)) {
Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);
updatedSingletons.remove(beanName);
this.manualSingletonNames = updatedSingletons;
}
}
}
//仍处于注册阶段
else {
//将beanName和bean的定义信息加入beanDefinitionMap集合
this.beanDefinitionMap.put(beanName, beanDefinition);
//bean定义名称列表,按注册顺序排列
this.beanDefinitionNames.add(beanName);
//手动注册的单例程序的名称列表,按注册顺序排列
this.manualSingletonNames.remove(beanName);
}
this.frozenBeanDefinitionNames = null;
}
//如果该bean定义已经注册,并且为单例,则进行重置
if (existingDefinition != null || containsSingleton(beanName)) {
resetBeanDefinition(beanName);
}
}
分析:
- 注册前的最后一次校验,这里的校验不同于之前的XML文件校验, 主要是对于AbstracBeanDefinition属性中的methodOverrides校验, 校验methodOverrides是否与工厂方法并存或者methodOverrides对应的方法不存在
- 判断该beanName是否已经注册; 如果beanName已经注册过: 根据不同的设置进行处理(是否允许覆盖, 如果不允许,则抛出异常; 允许的话, 则进行注册)
- 如果beanName没有被注册过; 则开始检查这个工厂的bean创建阶段是否已经开始,即是否有任何bean被标记为同时创建。如果bean工厂的bean创建已经开始, 那么就不能在beanDefinitionNames集合中添加beanName; 因为创建bean时, 会迭代beanDefinitionNames集合, 获取beanName, 获取BeanDefinition创建bean实例; 一旦开始迭代, 则不允许在向该list集合中插入元素, 但是beanDefinitionMap集合可以, 因为beanDefinitionMap集合并没有被迭代, 而是通过beanName获取BeanDefinition信息;
- 如果该bean定义已经注册, 并且为单例, 则进行重置
2. 注册Java配置类
AnnotationConfigApplicationContext#register实现:
public void register(Class<?>... annotatedClasses) {
...
this.reader.register(annotatedClasses);
}
分析: 通过读取器AnnotatedBeanDefinitionReader的register()方法, 去读取配置类的信息, 并进行注册;
AnnotatedBeanDefinitionReader#register
==> AnnotatedBeanDefinitionReader#registerBean
==> AnnotatedBeanDefinitionReader#doRegisterBean实现:
<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
//封装注解bean的定义信息
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
//设置InstanceSupplier属性
abd.setInstanceSupplier(instanceSupplier);
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
//设置bean的模式, 默认为单例模式
abd.setScope(scopeMetadata.getScopeName());
//获取beanName
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
//处理普通的bean定义注解 对@Lazy,@Primary,@DependsOn @Description @Role等标签的解析
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
if (qualifiers != null) {
for (Class<? extends Annotation> qualifier : qualifiers) {
if (Primary.class == qualifier) {
abd.setPrimary(true);
}
else if (Lazy.class == qualifier) {
abd.setLazyInit(true);
}
else {
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
}
}
}
for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
customizer.customize(abd);
}
//将AnnotatedGenericBeanDefinition(bean定义信息)和beanName封装到BeanDefinitionHolder中
// //目的: 封装更多的bean定义信息(bean定义信息, 别名信息, beanName等), 将bean定义信息与beanName进行封装传递
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
//没看懂. . .
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
/**
* Purpose: 向BeanDefinitionRegistry注册bean的定义信息
* registry 是AnnotatedBeanDefinitionReader初始化时传入的(this.reader = new AnnotatedBeanDefinitionReader(this),this是AnnotationConfigApplicationContext实例化对象)
* {@link AnnotationConfigApplicationContext#AnnotationConfigApplicationContext()}
*/
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
分析:
- 创建AnnotatedGenericBeanDefinition实例, 用于封装注解Bean的定义信息
- 对注解Bean的普通注解信息进行解析(对@Lazy,@Primary,@DependsOn @Description @Role等标签的解析)
- 将AnnotatedGenericBeanDefinition(bean定义信息)和beanName封装到BeanDefinitionHolder中; 这样可以封装更多的bean定义信息(bean定义信息, 别名信息, beanName等), 将bean定义信息与beanName进行封装传递
- 注册BeanDefinition
BeanDefinitionReaderUtils#registerBeanDefinition实现:
public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {
// 根据主名称注册bean定义信息
String beanName = definitionHolder.getBeanName();
/**
* GenericApplicationContext类实现了BeanDefinitionRegistry接口,
* 并且在 GenericApplicationContext类中维护了一个DefaultListableBeanFactory beanFactory (卧槽, 终于见到bean工厂了)
*
* 该步骤实际调用的是GenericApplicationContext类中的registerBeanDefinition()方法
*{@link org.springframework.context.support.GenericApplicationContext#registerBeanDefinition(String,BeanDefinition)}
*/
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// 如果该bean有别名的话, 为bean名称注册别名
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
registry.registerAlias(beanName, alias);
}
}
}
分析:
- 根据主名称获取Bean名称
- 通过注册中心注册BeanDefinitionHolder
- 如果该bean有别名的话, 为bean名称注册别名
GenericApplicationContext#registerBeanDefinition
==> DefaultListableBeanFactory#registerBeanDefinition
前面注册内部处理器时已经分析过DefaultListableBeanFactory#registerBeanDefinition()方法, 这里不再赘述了;
3. 注册普通BeanDefinition
AbstractApplicationContext#refresh方法实现:
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 准备好刷新上下文(设置一些变量)
prepareRefresh();
/**
* obtainFreshBeanFactory()方法中根据实现类的不同调用不同的refreshBeanFactory()方法
* <----- 注解模式 ----->
* 1. 如果是使用AnnotationConfigApplicationContext来初始化环境
* 调用的是GenericApplicationContext#refreshBeanFactory()方法
* {@link GenericApplicationContext#refreshBeanFactory()}
* 在该方法中只是对beanFactory的一些变量进行设置
* <----- XML配置模式 ----->
* 2. 如果是使用ClassPathXmlApplicationContext来初始化环境
* 调用的是{@link AbstractRefreshableApplicationContext#refreshBeanFactory()}
* 由于还没有对beanFactory进行初始化,所以在该方法中,完成了对beanFactory的初始化操作
* 并对设置的资源位置进行扫描, 解析
* 注意:此方法是使用ClassPathXmlApplicationContext来初始化上下文是解析注册bean的重要入口 <-------------------重要
*/
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//对beanFactory进行属性设置
prepareBeanFactory(beanFactory);
try {
//允许在子类中对bean工厂进行后处理。
postProcessBeanFactory(beanFactory);
/**
* <----- 注解模式 ----->
* 1. 如果是使用AnnotationConfigApplicationContext来初始化环境(该方法是解析注册bean的重要入口) <--------------------重要
* 在该方法中执行了
* {@link org.springframework.context.annotation.ConfigurationClassPostProcessor#processConfigBeanDefinitions} 方法
* 对配置类进行解析(如果该注解bean是配置类则在这个方法里完成了包扫描操作) <--------------- 重要
* 注意:
* 1. 一般情况下, 此时beanFactory中只注册了这一个BeanFactoryPostProcessor类-->ConfigurationClassPostProcessor
* 在{@link AnnotationConfigUtils#registerAnnotationConfigProcessors(org.springframework.beans.factory.support.BeanDefinitionRegistry)}中注册的
* 2. 注解模式下,此时BeanDefinitionMap中含有6个Spring内部处理器类, 其中通过ConfigurationClassPostProcessor类来解析配置类,完成包扫描,bean注册等操作
* 然而, 在xml配置模式下, 此时BeanDefinitionMap只有自定义配置的BeanDefinition信息
*
* <----- XML配置模式 ----->
* 2. 如果是使用ClassPathXmlApplicationContext来初始化环境
* 默认情况下, 此时BeanDefinitionMap只有自定义配置的BeanDefinition信息, 并没有任何Spring内部所定义的BeanFactory后处理器
* 除非用户自定义了BeanFactory后处理器, 需要对BeanFactory进行修改, 那么才会执行对应后处理器里面的方法;
*
*/
invokeBeanFactoryPostProcessors(beanFactory);
//注册拦截bean创建的bean后处理处理器。
registerBeanPostProcessors(beanFactory);
//为上下文初始化Message源,即不同的语言体,国际化处理
initMessageSource();
// 初始化应用消息广播,并放入"appliactionEventMulitcaster"bean中
initApplicationEventMulticaster();
// 留给子类来初始化其他的Bean
onRefresh();
//在所有注册的bean中查找listener bean,注册到消息广播器中
registerListeners();
// 初始化剩下的单例(非延迟加载的,延迟加载的单例在第一次调用的时候初始化)
finishBeanFactoryInitialization(beanFactory);
//最后一步:完成刷新过程,通知生命周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知别人
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// 销毁已创建的单例以避免资源悬空。
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
resetCommonCaches();
}
}
}
分析:
- prepareRefresh(): 准备刷新上下文, 设置相关监听器, 以及状态开关的设置
- obtainFreshBeanFactory(): (1) 如果是使用AnnotationConfigApplicationContext来初始化环境: 调用的是GenericApplicationContext#refreshBeanFactory()方法,在该方法中只是对beanFactory的一些变量进行设置;
(2) 如果是使用ClassPathXmlApplicationContext来初始化环境: 调用的是AbstractRefreshableApplicationContext#refreshBeanFactory(), 由于还没有对beanFactory进行初始化, 所以在该方法中, 完成了对beanFactory的初始化操作, 并对设置的资源位置进行扫描, 解析; 注意: 此方法是使用ClassPathXmlApplicationContext来初始化上下文是解析注册bean的重要入口
prepareBeanFactory(beanFactory): 对beanFactory相关配置进行设置; 设置bean工厂的类加载器, 表达式语言处理器, 工厂后处理器, 以及需要忽略的自动装配的接口
postProcessBeanFactory(beanFactory): 留给子类实现, 允许在子类中对bean工厂进行后处理
invokeBeanFactoryPostProcessors(beanFactory): 激活bean工厂的后处理器 (1) 如果是使用AnnotationConfigApplicationContext来初始化环境(该方法是解析注册bean的重要入口)在该方法中执行了ConfigurationClassPostProcessor#processConfigBeanDefinitions} 方法对配置类进行解析(如果该注解bean是配置类则在这个方法里完成了包扫描操作) (2) 如果是使用ClassPathXmlApplicationContext来初始化环境, 默认情况下, 此时BeanDefinitionMap只有自定义配置的BeanDefinition信息, 并没有任何Spring内部所定义的BeanFactory后处理器; 除非用户自定义了BeanFactory后处理器, 需要对BeanFactory进行修改, 那么才会执行对应后处理器里面的方法;
注意: 注解模式下,此时BeanDefinitionMap中含有6个Spring内部处理器类(但是只有一个BeanFactoryPostProcessor类的实例-->ConfigurationClassPostProcessor), 其中通过ConfigurationClassPostProcessor类来解析配置类,完成包扫描,bean注册等操作; 然而, 在xml配置模式下, 此时BeanDefinitionMap只有自定义配置的BeanDefinition信息registerBeanPostProcessors(beanFactory): 注册bean后处理处理器
initMessageSource(): 为上下文初始化Message源,即不同的语言体,国际化处理
initApplicationEventMulticaster(): 初始化应用消息广播,并放入"appliactionEventMulitcaster"bean中
onRefresh(): 留给子类来初始化其他的Bean
registerListeners(): 在所有注册的bean中查找listener bean,注册到消息广播器中
finishBeanFactoryInitialization(beanFactory): 初始化剩下的单例(非延迟加载的,延迟加载的单例在第一次调用的时候初始化)
finishRefresh(): 最后一步:完成刷新过程,通知生命周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知别人
destroyBeans(): 销毁已创建的单例bean, 避免资源悬空
cancelRefresh(ex): 重置状态开关
3.1 刷新, 获取Bean工厂
_2. AbstractApplicationContext#obtainFreshBeanFactory实现:
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
/**
* 此处根据实现类的不同调用不同的refreshBeanFactory()方法
*
* <----- 注解配置模式 ----->
* 1. 如果是使用AnnotationConfigApplicationContext来初始化环境
* 调用的是GenericApplicationContext#refreshBeanFactory()方法
* {@link GenericApplicationContext#refreshBeanFactory()}
* 在该方法中只是对beanFactory的一些变量进行设置
*
* <----- XML配置模式 ----->
* 2. 如果是使用ClassPathXmlApplicationContext来初始化环境
* 调用的是{@link AbstractRefreshableApplicationContext#refreshBeanFactory()}
* 由于还没有对beanFactory进行初始化,所以在该方法中,完成了对beanFactory的初始化操作
*
* 注意:两种方式都使用的是间接继承AbstractApplicationContext这个抽象类,并重写refreshBeanFactory()方法
*/
refreshBeanFactory();
/**
* <----- 注解配置模式 ----->
* 1. GenericApplicationContext 继承了 AbstractApplicationContext 并重写了getBeanFactory()方法;
* 2. 所以此处调用的是GenericApplicationContext#getBeanFactory()方法,将GenericApplicationContext中
* DefaultListableBeanFactory类型的beanFactory以ConfigurableListableBeanFactory类型返回;
* 3. DefaultListableBeanFactory实现了ConfigurableListableBeanFactory接口
* {@link GenericApplicationContext#getBeanFactory()}
*
* <----- XML配置模式 ----->
* 返回已经刷新完成bean工厂
* {@link AbstractRefreshableApplicationContext#getBeanFactory()}
*
*/
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
分析:
- refreshBeanFactory(): 根据子类的不同实现, 执行不同的逻辑; 这里着重分析使用AnnotationConfigApplicationContext来初始化环境时, 调用GenericApplicationContext#refreshBeanFactory()方法, 对Bean工厂进行相关参数设置
- 返回刷新完成的bean工厂 (由GenericApplicationContext#getBeanFactory()方法实现)
GenericApplicationContext#refreshBeanFactory方法实现:
@Override
protected final void refreshBeanFactory() throws IllegalStateException {
if (!this.refreshed.compareAndSet(false, true)) { //使用CAS将refreshed标签设置为true; 设置失败就报错
throw new IllegalStateException(
"GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
}
this.beanFactory.setSerializationId(getId());
}
3.2 Bean工厂配置的设置
_3. AbstractApplicationContext#prepareBeanFactory实现:
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 告诉内部bean工厂使用上下文的类加载器等等。
beanFactory.setBeanClassLoader(getClassLoader());
//设置beanFactory的表达式语言处理器,Spring3增加了表达式语言的支持
//默认可以使用#{bean.xxx}的形式来调用相关属性值
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
//为beanfactory增加了一个默认的属性编辑器,这个主要是对bean的属性等设置管理的一个工具
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// 给beanFactory添加后置处理器
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.\
//设置了几个自动装配的特殊规则
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.
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
//增加对AspectJ的支持
// 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()));
}
//添加默认系统环境bean
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());
}
}
3.3. 激活Bean工厂后处理器(重点)
_5. AbstractApplicationContext#invokeBeanFactoryPostProcessors实现:
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
/**
* getBeanFactoryPostProcessors()方法:
* 获取通过{@link AbstractApplicationContext#addBeanFactoryPostProcessor(BeanFactoryPostProcessor)}
* 方法添加的实现BeanDefinitionRegistryPostProcessor接口和BeanFactoryPostProcessor接口的beanFactory处理器类
*
* 注意: 如果是自定义的添加@Component注解的,此处是获取不到的, 后面Spring会自动去扫描
* 如果此处存在自定义的类,则会在ConfigurationClassPostProcessor#processConfigBeanDefinitions()方法之前执行
*/
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
//检测LoadTimeWeaver并准备编织(如果在此期间发现)
// (e.g. 通过ConfigurationClassPostProcessor注册的@Bean方法)
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
分析:
- getBeanFactoryPostProcessors()方法: 获取通过AbstractApplicationContext#addBeanFactoryPostProcessor方法添加的实现BeanDefinitionRegistryPostProcessor接口和BeanFactoryPostProcessor接口的beanFactory处理器类
- 激活Bean工厂后处理器; 通常情况下这里主要激活的是Spring内部的工厂后处理器
注意: 如果是自定义的添加@Component注解的,此处是获取不到的, 后面Spring会自动去扫描; 如果此处存在自定义的类,则会在ConfigurationClassPostProcessor#processConfigBeanDefinitions()方法之前执行
PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors实现:
/**
* 1. 执行自定义的实现BeanDefinitionRegistryPostProcessor接口时重写的postProcessBeanDefinitionRegistry()方法
*
* 2. 执行Spring内部的实现BeanDefinitionRegistryPostProcessor接口时重写的postProcessBeanDefinitionRegistry()方法
* {@link PostProcessorRegistrationDelegate#invokeBeanDefinitionRegistryPostProcessors(Collection, BeanDefinitionRegistry)}
*
* 3. 执行自定义的实现BeanDefinitionRegistryPostProcessor接口和BeanFactoryPostProcessor接口时重写的postProcessBeanFactory()方法
* 和Spring内部的实现BeanDefinitionRegistryPostProcessor接口时重写的postProcessBeanFactory()方法
*
* 4. 执行Spring内部实现BeanFactoryPostProcessor接口的处理器中的postProcessBeanFactory()方法
* {@link PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors(Collection, ConfigurableListableBeanFactory)}
*
*
*/
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<>();
if (beanFactory instanceof BeanDefinitionRegistry) {
//注意: 前提条件是改注册器是实现了BeanDefinitionRegistry接口的
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
/**
* 1. 将自定义的实现BeanDefinitionRegistryPostProcessor接口和BeanFactoryPostProcessor接口的类区分保存在不同的集合中
* 在区分过程中执行自定义实现BeanDefinitionRegistryPostProcessor接口时重写的postProcessBeanDefinitionRegistry()方法
*/
/**
* 注意: BeanDefinitionRegistryPostProcessor接口 继承了 BeanFactoryPostProcessor接口
* 之所以要将所有的后处理器区分开, 是因为实现BeanDefinitionRegistryPostProcessor接口的要执行两个方法
* {@link BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry(BeanDefinitionRegistry)}
* 和{@link BeanFactoryPostProcessor#postProcessBeanFactory(ConfigurableListableBeanFactory)}这两个方法
* 而实现BeanFactoryPostProcessor接口的只需要执行{@link BeanFactoryPostProcessor#postProcessBeanFactory(ConfigurableListableBeanFactory)}
* 这个方法即可
*/
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
/**
* 遍历bean工厂后处理器集合,将不同的处理器添加分别添加到regularPostProcessors和registryProcessors集合中
* beanFactoryPostProcessors集合中存储的是用户自定义的后处理器类
* 有两种方式自定义:
* (1). 实现BeanDefinitionRegistryPostProcessor接口重写postProcessBeanDefinitionRegistry()方法和postProcessBeanFactory()方法, 还需要加@Component注解
* (2). 实现BeanFactoryPostProcessor接口重写postProcessBeanFactory()方法, 还需要加@Component注解
*/
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor;
//执行自定义实现BeanDefinitionRegistryPostProcessor接口的类中的postProcessBeanDefinitionRegistry()方法
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}
/**
* 2. 将Spring内部的实现BeanDefinitionRegistryPostProcessor接口的根据优先级顺序执行 处理器类中重写该接口的postProcessBeanDefinitionRegistry()方法
* (实现PriorityOrdered接口的先执行,实现ordered接口的后执行,两者都没有实现的,最后执行)
*/
/**
* 将实现PriorityOrdered,Ordered等接口的BeanDefinitionRegistryPostProcessors分开按优先级执行
* 这个currentRegistryProcessors 存储的是spring内部自己实现了BeanDefinitionRegistryPostProcessor接口的对象
*/
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
/**
* 2.1 首先,调用实现PriorityOrdered的BeanDefinitionRegistryPostProcessor
* 根据BeanDefinitionRegistryPostProcessor.class获取所有实现BeanDefinitionRegistryPostProcessor接口的beanName;
* getBeanNamesForType()
* {@link DefaultListableBeanFactory#getBeanNamesForType(java.lang.Class, boolean, boolean)}
*/
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
/**
* 这个地方可以得到一个BeanFactoryPostProcessor(org.springframework.context.annotation.internalConfigurationAnnotationProcessor ->内部配置注解处理器),
* 因为是spring默认在最开始自己注册的,在下面的方法中注册的
* {@link AnnotationConfigUtils#registerAnnotationConfigProcessors()}
*
* 为什么要在最开始注册这个呢?
* 因为spring的工厂需要许解析去扫描等等功能,这些功能都是需要在spring工厂初始化完成之前执行
* 要么在工厂最开始的时候、要么在工厂初始化之中,反正不能再之后; 因为如果在之后就没有意义,因为那个时候已经需要使用工厂了
* 所以这里spring在一开始就注册了一个BeanFactoryPostProcessor,用来插手springfactory的实例化过程
* 在这个地方断点可以知道这个类叫做ConfigurationClassPostProcessor
* (ConfigurationClassPostProcessor类的beanName为"org.springframework.context.annotation.internalConfigurationAnnotationProcessor")
*
* ConfigurationClassPostProcessor那么这个类能干嘛呢? ----> 很重要
* Spring使用ConfigurationClassPostProcessor完成对注解的扫描
* (1) ConfigurationClassPostProcessor调用postProcessBeanDefinitionRegistry()方法
* {@link PostProcessorRegistrationDelegate#invokeBeanDefinitionRegistryPostProcessors(Collection, BeanDefinitionRegistry)}
* (2) 在步骤四中ConfigurationClassPostProcessor调用postProcessBeanFactory()方法
* {@link PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors(Collection, BeanDefinitionRegistry)}
*
*/
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
//即将执行的BeanDefinitionRegistryPostProcessor类
processedBeans.add(ppName);
}
}
//根据PriorityOrdered接口设置的不同优先级进行排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
//将Spring内部实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor类实添加到registryProcessors结合中,便于后面一块执行postProcessBeanFactory()方法
// 在下面的执行中只执行Spring内部的,自定义的在上面区分两种类时已经执行过了
registryProcessors.addAll(currentRegistryProcessors);
/**
* 循环遍历currentRegistryProcessors,.执行BeanDefinitionRegistryPostProcessor中的postProcessBeanDefinitionRegistry方法
* {@link BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry(BeanDefinitionRegistry)}
* 该方法时BeanDefinitionRegistryPostProcessor接口继承BeanFactoryPostProcessor接口后增加的方法
*/
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
//currentRegistryProcessors集合中的类遍历执行完postProcessBeanDefinitionRegistry()方法后,清空该集合,以便后面进行重复使用
currentRegistryProcessors.clear();
/**
* 2.2 接下来,调用实现Ordered的BeanDefinitionRegistryPostProcessor
*/
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
// !processedBeans.contains(ppName) 如果processedBeans集合中已存在该beanName,那么说明已经执行过了,不需要再次执行
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
//把符合条件的BeanDefinition从从工厂中获取出来, 存储到currentRegistryProcessors集合中
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
//即将执行的BeanDefinitionRegistryPostProcessor类
processedBeans.add(ppName);
}
}
//根据Ordered接口设置的不同优先级进行排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
//将Spring内部实现Ordered接口的BeanDefinitionRegistryPostProcessor类实添加到registryProcessors结合中,便于后面一块执行postProcessBeanFactory()方法
//在下面的执行中只执行Spring内部的,自定义的在上面区分两种类时已经执行过了
registryProcessors.addAll(currentRegistryProcessors);
//同上, 优先执行实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor, 然后再执行实现Ordered接口的
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
/**
* 2.3 最后,执行其他没有实现PriorityOrdered接口和ordered接口的注册器后处理器类
*/
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
//把符合条件的BeanDefinition从从工厂中获取出来, 存储到currentRegistryProcessors集合中
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
//将Spring内部实现Ordered接口的BeanDefinitionRegistryPostProcessor类实添加到registryProcessors结合中,便于后面一块执行postProcessBeanFactory()方法
registryProcessors.addAll(currentRegistryProcessors);
//同上, 该步骤执行没有实现PriorityOrdered接口和Ordered接口的处理器类的BeanDefinitionRegistryPostProcessor()方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
/**
* 3. 执行所有处理器类(实现BeanDefinitionRegistryPostProcessor接口和BeanFactoryPostProcessor接口的)的BeanFactoryPostProcessor方法
* 因为BeanDefinitionRegistryPostProcessor继承BeanFactoryPostProcessor接口,所以实现BeanDefinitionRegistryPostProcessor接口的处理器类也需要
* 重写BeanFactoryPostProcessor接口中的BeanFactoryPostProcessor方法
*
* 注意: registryProcessors中存储的是Spring内部和自定义实现BeanDefinitionRegistryPostProcessor接口的处理器类
* regularPostProcessors中存储的是自定义实现BeanFactoryPostProcessor接口的处理器类
*/
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
// 如果该注册器是没有实现BeanDefinitionRegistry接口
else {
// 调用用上下文实例注册的工厂处理器
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
/**
* 4. 执行Spring内部实现BeanFactoryPostProcessor接口的处理器中的postProcessBeanFactory()方法
* 根据BeanFactoryPostProcessor类型获取到所有Spring内部实现BeanFactoryPostProcessor接口的处理器类的beanName
* {@link DefaultListableBeanFactory#getBeanNamesForType(java.lang.Class, boolean, boolean)}
*/
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
//初始化存储实现PriorityOrdered接口的处理器的集合
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
//初始化存储实现Ordered接口的BeanName的集合,后面还需要再次遍历该集合, 获取BeanDefinition存储到orderedPostProcessors集合中
List<String> orderedPostProcessorNames = new ArrayList<>();
//初始化存储没有实现PriorityOrdered接口和Ordered接口的BeanName的集合,后面还需要再次遍历该集合, 获取BeanDefinition存储到nonOrderedPostProcessors集合中
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
//遍历postProcessorNames集合中所有的postProcessorName,从bean工厂中获取到相关的bean定义,存储在不同的集合中
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)) {
//注意此处存储的是beanName;
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
/**
* 4.1 执行实现PriorityOrdered接口的BeanFactoryPostProcessors处理器类
*/
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
/**
* 4.2 遍历orderedPostProcessorNames集合, 获取BeanDefinition存储到orderedPostProcessors集合中
* 然后执行实现Ordered接口的BeanFactoryPostProcessors处理器类
*/
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
/**
* 4.3 遍历nonOrderedPostProcessorNames集合, 获取BeanDefinition存储到nonOrderedPostProcessors集合中
*/
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
//清除缓存的合并bean定义,因为后处理器可能有修改原始元数据,例如替换值中的占位符…
beanFactory.clearMetadataCache();
}
分析:
- 执行自定义实现BeanDefinitionRegistryPostProcessor接口时重写的postProcessBeanDefinitionRegistry()方法
- 执行Spring内部实现BeanDefinitionRegistryPostProcessor接口时重写的postProcessBeanDefinitionRegistry()方法PostProcessorRegistrationDelegate# invokeBeanDefinitionRegistryPostProcessors
- 执行自定义实现BeanDefinitionRegistryPostProcessor接口和BeanFactoryPostProcessor接口时重写的postProcessBeanFactory()方法和Spring内部的实现BeanDefinitionRegistryPostProcessor接口时重写的postProcessBeanFactory()方法
- 执行Spring内部实现BeanFactoryPostProcessor接口的处理器中的postProcessBeanFactory()方法PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors
注意: 该方法比较复杂, 但是也很重要, 上面只是简单分析下, 详细解析内容已在代码上标注; 该方法主要是根据一定逻辑去激活所有的Bean工厂后处理器, 并从容器角度看, 此时只注册了处理器类和配置类, 对于普通的BeanDefinition此时还没有进行注册; 并且注册BeanDefinition是属于工厂级别的操作, 那么是需要一个工厂处理器来进行普通BeanDefinition的注册操作的; 因此, 在该方法中会激活一个Bean工厂后处理器ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry方法; 由此方法开启普通BeanDefinition的注册过程;
PostProcessorRegistrationDelegate#invokeBeanDefinitionRegistryPostProcessors实现:
private static void invokeBeanDefinitionRegistryPostProcessors(Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
/**
* <----- 注解模式下 ----->
* 当postProcessor为ConfigurationClassPostProcessor时, 执行
* {@link org.springframework.context.annotation.ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry}
* 上面的方法中完成了注解类中的扫描和注册
*/
postProcessor.postProcessBeanDefinitionRegistry(registry);
}
}
分析: 此时PostProcessor为ConfigurationClassPostProcessor实例, 该实例重写了BeanDefinitionRegistryPostProcessor接口中的postProcessBeanDefinitionRegistry()方法;
ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry实现:
@Override
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);
}
ConfigurationClassPostProcessor#processConfigBeanDefinitions实现:
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
//获取到所有已经注册的beanName(7个)
/**
* 0 = org.springframework.context.annotation.internalConfigurationAnnotationProcessor
* 1 = org.springframework.context.event.internalEventListenerFactory
* 2 = org.springframework.context.event.internalEventListenerProcessor
* 3 = org.springframework.context.annotation.internalAutowiredAnnotationProcessor
* 4 = org.springframework.context.annotation.internalCommonAnnotationProcessor
* 5 = appConfig
* 6 = org.springframework.context.annotation.internalRequiredAnnotationProcessor
*/
String[] candidateNames = registry.getBeanDefinitionNames();
/**
* 1. 遍历所有的BeanDefinition, 将加了@Configuration, @Component, @ComponentScan, @Import, @ImportResource注解的配置类
* 添加到configCandidates集合中
*/
for (String beanName : candidateNames) {
//根据beanName获取到BeanDefinition
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
//如果BeanDefinition中的configurationClass属性为full或者lite,则意味着已经处理过了,直接跳过(Spring内部的BeanDefinition会直接跳过)
if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) || ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
if (logger.isDebugEnabled()) {
logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
}
}
/**
* 对beanDef的注解信息进行检查, 并根据不同的注解信息对beanDef的CONFIGURATION_CLASS_ATTRIBUTE属性进行设置 FULL或LITE
* 如果是注解类, 则将注解类加入到configCandidates集合中,后面将对该注解类进行处理
*/
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
/**
* 如果没有自定义注解类,直接退出
* 下面只对添加@Configuration,@Component, @ComponentScan, @Import, @ImportResource注解的类进行处理
*/
if (configCandidates.isEmpty()) {
return;
}
/**
* 2. 对所有的配置类进行排序
*/
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;
// 如果BeanDefinitionRegistry是SingletonBeanRegistry子类的话,
// 由于我们当前传入的是DefaultListableBeanFactory,是SingletonBeanRegistry 的子类, 因此会将registry强转为SingletonBeanRegistry
if (registry instanceof SingletonBeanRegistry) {
sbr = (SingletonBeanRegistry) registry;
if (!this.localBeanNameGeneratorSet) { //是否有自定义的
BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);
//SingletonBeanRegistry中有id为 org.springframework.context.annotation.internalConfigurationBeanNameGenerator
//如果有则利用他的,否则则是spring默认的
if (generator != null) {
this.componentScanBeanNameGenerator = generator;
this.importBeanNameGenerator = generator;
}
}
}
if (this.environment == null) {
this.environment = new StandardEnvironment();
}
/**
*
* 3. 循环解析每个配置类
*
*/
//初始化ConfigurationClassParser解析器, 解析每个注解类
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
//将configCandidates(List)集合中的BeanDefinitionHolder放入candidates(Set)集合中进行去重,因为可能有多个配置类重复了
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
//alreadyParsed用于存储已处理过的
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
//循环遍历解析
do {
/**
* candidates: 需要解析的配置类集合
* 对添加注解(@Configuration, @Component, @ComponentScan, @Import, @ImportResource等)的类进行解析
* 该步骤完成了对所有加注解的bean的解析工作
*/
parser.parse(candidates);
//验证
parser.validate();
//获取所有的配置类
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
//移除所有已经解析过的配置类
configClasses.removeAll(alreadyParsed);
// 读取模型并根据其内容创建bean定义
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
/**
* 这里值得注意的是扫描出来的bean当中可能包含了特殊类
* 比如ImportBeanDefinitionRegistrar那么也在这个方法里面处理
* 但是并不是包含在configClasses当中
* configClasses当中主要包含的是importSelector
* 因为ImportBeanDefinitionRegistrar在扫描出来的时候已经被添加到一个list当中去了
*/
//bd 到 map 除却普通
this.reader.loadBeanDefinitions(configClasses);
alreadyParsed.addAll(configClasses);
//清空上面已经解析过的bean
candidates.clear();
//由于我们这里进行了扫描,把扫描出来的BeanDefinition注册给了factory
if (registry.getBeanDefinitionCount() > candidateNames.length) {
//获取所有的beanName
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();
}
}
分析:
- 遍历所有的BeanDefinition, 将加了@Configuration, @Component, @ComponentScan, @Import, @ImportResource注解的配置类添加到configCandidates集合中
- 对所有的配置类进行排序
- 循环解析每个配置类
ConfigurationClassParser#parse(java.util.Set<BeanDefinitionHolder>)实现:
public void parse(Set<BeanDefinitionHolder> configCandidates) {
this.deferredImportSelectors = new LinkedList<>();
//遍历集合中所有的BeanDefinitionHolder, 根据不同的注解类型采取不同的解析方案
for (BeanDefinitionHolder holder : configCandidates) {
BeanDefinition bd = holder.getBeanDefinition();
try {
if (bd instanceof AnnotatedBeanDefinition) {
/**
* 解析注解对象,并且把解析出来的bd放到map,但是这里的bd指的是普通的
* 何谓不普通的呢?比如@Bean 和各种beanFactoryPostProcessor得到的bean不在这里put
* 但是是这里解析,只是不put而已
*/
parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
}
else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
/**
* 如果是AbstractBeanDefinition类型的则获取BeanClass信息
*/
parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
}
else {
/**
* 如果两种类型都不是的
*/
parse(bd.getBeanClassName(), holder.getBeanName());
}
}
...
}
//处理延迟加载的importSelect?为什么要延迟加载,估计就是为了延迟吧
processDeferredImportSelectors();
}
分析: 遍历集合中所有的BeanDefinitionHolder, 根据不同的注解类型采取不同的解析方案;
ConfigurationClassParser#parse(AnnotationMetadata, String)实现:
protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {
/**
* 将元数据信息和beanName封装为ConfigurationClass类型进行传递
*/
processConfigurationClass(new ConfigurationClass(metadata, beanName));
}
ConfigurationClassParser#processConfigurationClass实现:
protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
return;
}
//处理Imported情况
ConfigurationClass existingClass = this.configurationClasses.get(configClass);
if (existingClass != null) {
if (configClass.isImported()) {
if (existingClass.isImported()) {
existingClass.mergeImportedBy(configClass);
}
return;
}
else {
this.configurationClasses.remove(configClass);
this.knownSuperclasses.values().removeIf(configClass::equals);
}
}
//将configClass类型封装为SourceClass类型
SourceClass sourceClass = asSourceClass(configClass);
// 递归地处理配置类及其超类层次结构
do {
/**
* 处理配置类
*/
sourceClass = doProcessConfigurationClass(configClass, sourceClass);
}
while (sourceClass != null);
this.configurationClasses.put(configClass, configClass);
}
分析:
- 处理Imported情况
- 将configClass类型封装为SourceClass类型
- 递归地处理配置类及其超类层次结构
ConfigurationClassParser#doProcessConfigurationClass实现(重点):
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
throws IOException {
// Recursively process any member (nested) classes first
//处理内部类
processMemberClasses(configClass, sourceClass);
/**
* 处理所有@PropertySource注解
*/
for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), PropertySources.class,
org.springframework.context.annotation.PropertySource.class)) {
if (this.environment instanceof ConfigurableEnvironment) {
processPropertySource(propertySource);
}
else {
logger.warn("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
"]. Reason: Environment must implement ConfigurableEnvironment");
}
}
/**
* 处理所有@ComponentScan注解
*/
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
if (!componentScans.isEmpty() &&!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
//如果这个配置类是加了@ComponentScan注解的, 则立刻执行扫描工作
for (AnnotationAttributes componentScan : componentScans) {
/**
* scannedBeanDefinitions存储扫描出来的BeanDefinition信息
* 对@ComponentScan中配置的包路径信息进行扫描, 并注册扫描出来的BeanDefinition, 最后将所有扫描出来的BeanDefinition信息返回
*/
Set<BeanDefinitionHolder> scannedBeanDefinitions = this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
/**
* 检查扫描出来的BeanDefinition集合中是否有其他配置类,并在需要时递归解析 <------ Spring考虑的很严谨
* 检查是否在普通注解类上添加了一些配置相关的注解 (@Configuration, @ComponenSacn ...)
*/
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {
bdCand = holder.getBeanDefinition();
}
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
}
/**
* 上面的代码就是扫描普通类----@Component
* 并且放到了map当中
*/
// Process any @Import annotations
//处理@Import imports 3种情况
//ImportSelector
//普通类
//ImportBeanDefinitionRegistrar
//这里和内部地柜调用时候的情况不同
/**
* 这里处理的import是需要判断我们的类当中时候有@Import注解
* 如果有这把@Import当中的值拿出来,是一个类
* 比如@Import(xxxxx.class),那么这里便把xxxxx传进去进行解析
* 在解析的过程中如果发觉是一个importSelector那么就回调selector的方法
* 返回一个字符串(类名),通过这个字符串得到一个类
* 继而在递归调用本方法来处理这个类
*
* 判断一组类是不是imports(3种import)
*
*/
/**
* 处理所有@Import注解
*/
processImports(configClass, sourceClass, getImports(sourceClass), true);
/**
* 处理所有@ImportResource注解
*/
AnnotationAttributes importResource =
AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
if (importResource != null) {
String[] resources = importResource.getStringArray("locations");
Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
for (String resource : resources) {
String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
configClass.addImportedResource(resolvedResource, readerClass);
}
}
/**
* 处理所有@Bean methods
*/
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
// Process default methods on interfaces
processInterfaces(configClass, sourceClass);
// Process superclass, if any
if (sourceClass.getMetadata().hasSuperClass()) {
String superclass = sourceClass.getMetadata().getSuperClassName();
if (superclass != null && !superclass.startsWith("java") &&
!this.knownSuperclasses.containsKey(superclass)) {
this.knownSuperclasses.put(superclass, configClass);
// Superclass found, return its annotation metadata and recurse
return sourceClass.getSuperClass();
}
}
// No superclass -> processing is complete
return null;
}
分析:
- 处理所有@PropertySource注解
- 处理所有@ComponentScan注解, 可以获取到在配置类中配置包路径信息, 那么就可以扫描到所有需要注册的Bean信息, 进行注册;
- 处理所有@Import注解
- 处理所有@ImportResource注解
- 处理所有@Bean methods
ComponentScanAnnotationParser#parse实现:
public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
/**
* 1. 实例化一个扫描对象,完成对包的扫描解析工作
* 注意:此处的在之前也实例化了一个ClassPathBeanDefinitionScanner类型的scanner对象,
* {@link AnnotationConfigApplicationContext#AnnotationConfigApplicationContext()}
*/
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);
//BeanNameGenerator,beanNames生成器
Class<? extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator");
boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass);
/**
* 2. 对scanner扫描对象进行相关初始化配置
*/
scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator :
BeanUtils.instantiateClass(generatorClass));
//web相关
ScopedProxyMode scopedProxyMode = componentScan.getEnum("scopedProxy");
if (scopedProxyMode != ScopedProxyMode.DEFAULT) {
scanner.setScopedProxyMode(scopedProxyMode);
}
else {
Class<? extends ScopeMetadataResolver> resolverClass = componentScan.getClass("scopeResolver");
scanner.setScopeMetadataResolver(BeanUtils.instantiateClass(resolverClass));
}
scanner.setResourcePattern(componentScan.getString("resourcePattern"));
//遍历当中的过滤条件
for (AnnotationAttributes filter : componentScan.getAnnotationArray("includeFilters")) {
for (TypeFilter typeFilter : typeFiltersFor(filter)) {
scanner.addIncludeFilter(typeFilter);
}
}
for (AnnotationAttributes filter : componentScan.getAnnotationArray("excludeFilters")) {
for (TypeFilter typeFilter : typeFiltersFor(filter)) {
scanner.addExcludeFilter(typeFilter);
}
}
//修改默认的配置信息
boolean lazyInit = componentScan.getBoolean("lazyInit");
if (lazyInit) {
scanner.getBeanDefinitionDefaults().setLazyInit(true);
}
/**
* 3.解析配置的包路径信息
*/
Set<String> basePackages = new LinkedHashSet<>();
String[] basePackagesArray = componentScan.getStringArray("basePackages");
for (String pkg : basePackagesArray) {
String[] tokenized = StringUtils.tokenizeToStringArray(this.environment.resolvePlaceholders(pkg),
ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
Collections.addAll(basePackages, tokenized);
}
for (Class<?> clazz : componentScan.getClassArray("basePackageClasses")) {
basePackages.add(ClassUtils.getPackageName(clazz));
}
if (basePackages.isEmpty()) {
basePackages.add(ClassUtils.getPackageName(declaringClass));
}
scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) {
@Override
protected boolean matchClassName(String className) {
return declaringClass.equals(className);
}
});
/**
* 4. 根据包路径信息执行解析操作
*/
return scanner.doScan(StringUtils.toStringArray(basePackages));
}
分析:
- 实例化一个扫描对象,完成对包的扫描解析工作;注意:此处的在之前也实例化了一个ClassPathBeanDefinitionScanner类型的scanner对象,那个scanner对象是用于AnnotationConfigApplicationContext[包路径配置方式]初始化容器时, 用于扫描包信息
- 对scanner扫描对象进行相关初始化配置
- 解析配置的包路径信息
- 根据包路径信息执行解析操作
ClassPathBeanDefinitionScanner#doScan实现:
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
//存储扫描到的BeanDefinition信息
Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
//循环遍历包路径信息,进行解析,注册
for (String basePackage : basePackages) {
//扫描出该包路径下左右的候选Bean
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
//对所有的候选bean进行解析
for (BeanDefinition candidate : candidates) {
//获取Scope属性
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
candidate.setScope(scopeMetadata.getScopeName());
//根据Bean信息生成BeanName
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
//对于配置类型BeanDefinition类型和注解类型BeanDefinition类型进行区分设置
if (candidate instanceof AbstractBeanDefinition) {
/**
* 如果这个类是AbstractBeanDefinition的子类
* 则为他设置默认值,比如lazy,init destory
*/
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
}
if (candidate instanceof AnnotatedBeanDefinition) {
/**
* 检查并且处理常用的注解
* 这里的处理主要是指把常用注解的值设置到AnnotatedBeanDefinition当中
* 当前前提是这个类必须是AnnotatedBeanDefinition类型的,说白了就是加了注解的类
*/
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}
//判断注册器中是否已经存在该BeanName
if (checkCandidate(beanName, candidate)) {
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
beanDefinitions.add(definitionHolder);
/**
* 注册BeanDefinition
*/
registerBeanDefinition(definitionHolder, this.registry);
}
}
}
return beanDefinitions;
}
分析: 循环遍历包路径信息,进行解析,注册
ClassPathBeanDefinitionScanner#registerBeanDefinition
==> BeanDefinitionReaderUtils#registerBeanDefinition实现
public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {
// 根据主名称注册bean定义信息
String beanName = definitionHolder.getBeanName();
/**
* GenericApplicationContext类实现了BeanDefinitionRegistry接口,
* 并且在 GenericApplicationContext类中维护了一个DefaultListableBeanFactory beanFactory (卧槽, 终于见到bean工厂了)
*
* 该步骤实际调用的是GenericApplicationContext类中的registerBeanDefinition()方法
*{@link org.springframework.context.support.GenericApplicationContext#registerBeanDefinition(String,BeanDefinition)}
*/
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// 如果该bean有别名的话, 为bean名称注册别名
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
registry.registerAlias(beanName, alias);
}
}
}
GenericApplicationContext#registerBeanDefinition ==> DefaultListableBeanFactory#registerBeanDefinition
注: 前面已经解析过DefaultListableBeanFactory#registerBeanDefinition相关逻辑, 这里不再进行解析了
3.4 注册bean后处理处理器
_6. AbstractApplicationContext#registerBeanPostProcessors
==> PostProcessorRegistrationDelegate#registerBeanPostProcessors实现:
public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
/**
* BeanPostProcessorChecker是一个普通的信息打印,但是会出现一些请况:
* 当Spring的配置中的后处理器还没有被注册就已经开始了bean的初始化时,便会打印出BeanPostProcessorChecker中设定的信息
*/
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
//使用priorityOrdered保证顺序
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
//使用Ordered保证顺序
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
//将bean处理器分类存储
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
//第一步,注册所有实现了PriorityOrdered接口的BeanPostProcessors
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
/**
* {@link org.springframework.beans.factory.support.AbstractBeanFactory#addBeanPostProcessor(BeanPostProcessor)}
*/
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
//第二步,注册所有实现Ordered的BeanPostProcessors
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
//第三步,注册所有无序的BeanPostProcessor
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
//第四步,注册所有MergedBeanDefinitionPostProcessors类型的BeanPostProcessor,并非重复注册
//在beanFactory.addBeanPostProcessor中会先移除已经存在的BeanPostProcessor
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
//添加ApplicationListener探测器
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
分析: 先按照BeanPostProcessor.class从bean工厂中获取所有的Bean后处理器名称, 按照优先级对Bean后处理器进行注册
3.5 初始化非延迟加载的的单例Bean (延迟加载的单例将在第一次调用的时候初始化)
_11. AbstractApplicationContext#finishBeanFactoryInitialization实现:
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
beanFactory.freezeConfiguration();
/**
* 实例化所有的单例对象
* {@link org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons()}
*/
beanFactory.preInstantiateSingletons();
}
DefaultListableBeanFactory#preInstantiateSingletons实现:
@Override
public void preInstantiateSingletons() throws BeansException {
if (logger.isDebugEnabled()) {
logger.debug("Pre-instantiating singletons in " + this);
}
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
/**
* 获取所有注册的BeanName, 后面将遍历这个集合进行实例化;注意: 这里是对beanDefinitionNames集合进行拷贝
*/
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
/**
* 触发所有非惰性单例bean的初始化...
*/
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
/**
* 如果是工厂bean
*/
if (isFactoryBean(beanName)) {
//在beanName前加"&"前缀, 获取到FactoryBean (如果直接通过BeanName获取的则是getObject()方法返回的bean)
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
//判断该bean对象是否是FactoryBean
if (bean instanceof FactoryBean) {
//如果是的话则进行强转
final FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
//只有isEagerInit值为true,才会在此时对FactoryBean进行初始化
if (isEagerInit) {
getBean(beanName);
}
}
}
/**
* 如果是普通bean
*/
else {
getBean(beanName);
}
}
}
/**
* 触发所有适用bean的初始化后回调...
* 如果目标Bean实现了SmartInitializingSingleton接口并重写了afterSingletonsInstantiated()方法,
* 这里将会执行该方法
*/
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
/**
* 执行afterSingletonsInstantiated()方法
*/
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
分析:
- 获取所有注册的BeanName, 后面将遍历这个集合进行实例化;注意: 这里是对beanDefinitionNames集合进行拷贝
- 触发所有非惰性单例bean的初始化, 对工厂bean和普通bean区分处理
- 触发所有适用bean的初始化后的回调方法afterSingletonsInstantiated()
AbstractBeanFactory#getBean ==> AbstractBeanFactory#doGetBean
注: 关于Bean的初始化在后面播客会专门讲解, 这里不再分析了
3.6 应用上下文刷新结束, 进行事件广播
_12. AbstractApplicationContext#finishRefresh实现:
protected void finishRefresh() {
//清除上下文级别的资源缓存(例如来自扫描的ASM元数据)
clearResourceCaches();
//为此上下文初始化生命周期处理器
initLifecycleProcessor();
//首先将刷新传播到生命周期处理器
getLifecycleProcessor().onRefresh();
/**
* 发布结束事件(事件对象:ContextRefreshedEvent)
*/
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
LiveBeansView.registerApplicationContext(this);
}
分析: 刷新结束后一些资源的清理以及生命周期的设置, 以及发布结束事件, 通知监听者Spring容器以及初始化完成, 观察者可以进行相关操作;
至此, 使用AnnotationConfigApplicationContext[Java配置类方式]方式初始化容器解析完成;
相关文章:
Spring源码解析二 (IOC容器初始化方式一:XmlBeanFactory)
Spring源码解析三 (IOC容器初始化方式二:ClassPathXmlApplicationContext)
Spring源码解析四 (IOC容器初始化方式三: AnnotationConfigApplicationContext[包路径配置方式])
Spring源码解析五 (IOC容器初始化方式四: AnnotationConfigApplicationContext[Java配置类方式])