spring源码4 -- 内置的后置处理器PostProcess加载源码 上
可以学习到什么?
1. BeanFactoryPostProcessor调用过程源码剖析
2. 配置类的解析过程源码
3. 配置类@Configuration加与不加的区别
4. 重复beanName的覆盖规则
5. @ComponentScan的解析原理
一、研究目标: 解析spring如何加载配置类
我们经常会在一个类上打上@Configuration, @Component, @Bean等. 带有这些注解的类, 就是我们所说的配置类. 那么, spring启动的时候,是如何加载这些配置类的呢?
下面就以此为目的, 分析spring源码. 本节的内容是对上一节内容的实战分析, 同时更加详细的解读spring源码
我们知道, spring启动的时候做了3件事, 就是上面的三件事.
第一件事: 调用this()自身的无参构造函数. 初始化了BeanDefinitionReader和BeanDefinitionScanner, 同时初始化了很多spring的原始后置处理器, 这些处理器是用来加载bean的
第二件事: 调用register(..) 注册配置类
第三件事: refresh(..) 这里包含了整个ioc创建bean的全生命周期, 今天重点看invokeBeanFactoryPostProcessors(beanFactory)加载配置类
二、准备工作: 自定义配置类MainConfig
我们先定义好要分析加载的配置类
package com.agony.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
* 这是一个配置类,
* 在配置类里面定义了扫描的包路径agony
* 这是会将这个包下配置了注解的类扫描到ioc容器里面,成为一个成熟的bean
*/
@Configuration
@ComponentScan(basePackages = {"com.agony"})
public class MainConfig {
}
这个配置类很简单, 使用@ComponentScan注解指定了扫描的包. @Configuration指定当前是一个配置类.
接下来定义一个main方法, 加载配置类.
package com.agony.demo;
import com.agony.domain.Car;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MainStarter {
public static void main(String[] args) {
// 第一步: 通过AnnotationConfigApplicationContext读取一个配置类
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainStarter.class);
// context.addBeanFactoryPostProcessor();
Car car = (Car) context.getBean("car");
System.out.println(car.getName());
context.close();
}
}
在main里, 通过AnnotationConfigurationApplicationContext读取配置类MainConfig.class.
配置类被传进来以后, 到底是怎么被解析的呢? 这就是我们分析的线索
始终不要忘记我们的整体架构图. 对照这个图来分析. 思路更清晰.
下面, 从入口进入. 我们的入口就是这里
new AnnotationConfigApplicationContext(MainConfig.class);
下面进入AnnotationConfigApplicationContext
的构造方法
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
// 进入构造函数, 首先调用自身的构造方法this();
// 调用自身的构造方法之前, 要先调用父类的构造方法
this();
// register配置注册类
register(componentClasses);
// ioc容器刷新接口--非常重要
refresh();
}
三、读取配置类后置处理器ConfigurationClassPostProcessor
3.1 调用this()无参构造函数
public AnnotationConfigApplicationContext() {
StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
/**todo:
* 创建了一个Bean定义的读取器.
* 完成了spring内部BeanDefinition的注册(主要是后置处理器)
* 读取了很多spring自定义的配置(主要是后置处理器). 这些类都是spring的原始类.
*/
this.reader = new AnnotatedBeanDefinitionReader(this);
createAnnotatedBeanDefReader.end();
/**todo:
* 创建BeanDefinition扫描器
* 可以用来扫描包或者类, 进而转换为bd
*
* todo:
* Spring默认的扫描包不是这个this.scanner对象
* 而是自己new的一个ClassPathBeanDefinitionScanner
* Spring在执行工程后置处理器ConfigurationClassPostProcessor时, 去扫描包时会new一个ClassPathBeanDefinitionScanner
*
* todo:
* 这里的scanner仅仅是为了程序员可以手动调用AnnotationConfigApplicationContext对象的scan方法
* 通过调用context.scan("包名");扫描处理配置类
* 扫描
*/
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
在初始化AnnotatedBeanDefinitionReader(this);
的时候, 注册了很多后置处理器
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
/*todo: 获取到beanFactory : DefaultListableBeanFactory和GenericApplicationContext都是BeanDefinitionRegistry接口的实现类*/
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
/*todo: 判断beanFactory中是否有AnnotationAwareOrderComparator和ContextAnnotationAutowireCandidateResolver,没有则添加*/
/**
* (1) AnnotationAwareOrderComparator
* 是OrderComparator的扩展,支持Spring的Ordered接口以及@Order和@Priority注解.Ordered实例提供的order值覆盖静态定义的注解值(如果有)
* (2) ContextAnnotationAutowireCandidateResolver:
* 完成AutowireCandidateResolver策略接口的实现,支持限定符注释以及context.annotation包中的lazy注释驱动的惰性解析
*/
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
/* todo: BeanDefinitionHolder: 为BeanDefinition设置名字和别名 */
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
/* todo: 1. 如果registry中没有ConfigurationClassPostProcessor配置类后置处理器, 就添加一个 */
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
/** 构建BeanDefinitionHolder, 并添加到beanDefs */
/**
* registry: BeanDefinitionRegistry注册器, 用于注册BeanDefinition
* def: 刚刚构建的RootBeanDefinition
* CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME: 构建BeanDefinition使用的beanName是org.springframework.context.annotation.internalConfigurationAnnotationProcessor
*/
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
/* todo: 2. 如果registry中, 没有AutowiredAnnotationBeanPostProcessor Autowired注解bean的后置处理器, 则添加一个 */
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
/** 构建BeanDefinitionHolder, 并添加到beanDefs */
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
/* todo: 3. 检查对JSR-250的支持, 如果registry中没有CommonAnnotationBeanPostProcessor通用注解后置处理器, 则添加一个 */
// 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);
/** 构建BeanDefinitionHolder, 并添加到beanDefs */
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
/* todo: 4. 检查对jpa的支持, 如果不包含internalPersistenceAnnotationProcessor, 持久化注解处理器, 就添加一个 */
// Check for JPA support, and if present add the 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);
/** 构建BeanDefinitionHolder, 并添加到beanDefs */
beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
}
/* todo: 5. 检查对事件监听的支持, 如果不包含事件监听处理器internalEventListenerProcessor, 就添加一个 */
if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
def.setSource(source);
/** 构建BeanDefinitionHolder, 并添加到beanDefs */
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
}
/* todo: 6. 如果不包含事件监听工厂处理器internalEventListenerFactory , 就添加一个 */
if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
def.setSource(source);
/** 构建BeanDefinitionHolder, 并添加到beanDefs */
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
}
return beanDefs;
}
我们看到, 注册了6个原始RootBeanDefinition, 这些bean是spring自己提前定义好的, 他们的加载是整个spring的基础. 用于解析spring中其他的类
而这一次我们要研究配置类是如何被读取的, 所以重点关注的是下面这个后置处理器
ConfigurationClassPostProcessor.class
3.2 ConfigurationClassPostProcessor的继承结构
可以看到ConfigurationClassPostProcessor是同时实现了BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor. 这一点我们需要记住, 后面会使用到
3.3 ConfigurationClassPostProcessor是如何被注册的
// 如果registry中没有ConfigurationClassPostProcessor配置类后置处理器, 就添加一个
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
// 构建BeanDefinitionHolder, 并添加到beanDefs
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
首先,构建了一个RootBeanDefinition. 然后调用了registerPostProcessor
方法, 三个入参分别是
registry
: BeanDefinitionRegistry注册器, 用于注册BeanDefinition
def
: 刚刚构建的RootBeanDefinition
CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME
: 构建BeanDefinition使用的beanName
/**
* 到这里已经初始化了 Bean 容器,<bean/>的配置也相应的转换为了一个个BeanDefinition,然后注册了所有的BeanDefinition到beanDefinitionMap
*/
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
Assert.hasText(beanName, "Bean name must not be empty");
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
((AbstractBeanDefinition) beanDefinition).validate();
} catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Validation of bean definition failed", ex);
}
}
// 所有的 Bean 注册后都会被放入到这个beanDefinitionMap 中,查看是否已存在这个bean
/*todo:
* 从BeanDefinition的一级缓存BeanDefinitionMap中读取BeanDefinition对象
* 判断是否已经存在BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
*/
// 将ConfigurationClassPostProcessor放入到了beanDefinitionMap里面
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
// 处理重复名称的 Bean 定义的情况
/**这里,如果已经存在,说明被重复加载了, 那么后面加载的会覆盖前面加载的bean*/
if (existingDefinition != null) {
// 判断是否允许BeanDefinition重写
// 如果不允许覆盖的话,抛异常
if (!isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
}
// 用框架定义的 Bean 覆盖用户自定义的 Bean
else if (existingDefinition.getRole() < beanDefinition.getRole()) {
// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
if (logger.isInfoEnabled()) {
logger.info("Overriding user-defined bean definition for bean '" beanName
"' with a framework-generated bean definition: replacing ["
existingDefinition "] with [" beanDefinition "]");
}
}
// 用新的 Bean 覆盖旧的 Bean
else if (!beanDefinition.equals(existingDefinition)) {
if (logger.isDebugEnabled()) {
logger.debug("Overriding bean definition for bean '" beanName
"' with a different definition: replacing [" existingDefinition
"] with [" beanDefinition "]");
}
} else {
// log...用同等的 Bean 覆盖旧的 Bean
if (logger.isTraceEnabled()) {
logger.trace("Overriding bean definition for bean '" beanName
"' with an equivalent definition: replacing [" existingDefinition
"] with [" beanDefinition "]");
}
}
// 覆盖一级缓存的bean定义
this.beanDefinitionMap.put(beanName, beanDefinition);
} else {
// 处理循环引用的问题
// 判断是否已经有其他的 Bean 开始初始化了.注意,"注册Bean" 这个动作结束,Bean 依然还没有初始化 在 Spring 容器启动的最后,会预初始化所有的 singleton beans
if (hasBeanCreationStarted()) {
// Cannot modify startup-time collection elements anymore (for stable iteration)
synchronized (this.beanDefinitionMap) {
this.beanDefinitionMap.put(beanName, beanDefinition);
List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
removeManualSingletonName(beanName);
}
} else {
// Still in startup registration phase
// 将 BeanDefinition 放到这个 map 中,这个 map 保存了所有的 BeanDefinition
this.beanDefinitionMap.put(beanName, beanDefinition);
// 这是个 ArrayList,所以会按照 bean 配置的顺序保存每一个注册的 Bean 的名字
this.beanDefinitionNames.add(beanName);
// 这是个 LinkedHashSet,代表的是手动注册的 singleton bean
removeManualSingletonName(beanName);
}
this.frozenBeanDefinitionNames = null;
}
if (existingDefinition != null || containsSingleton(beanName)) {
resetBeanDefinition(beanName);
} else if (isConfigurationFrozen()) {
clearByTypeCache();
}
}
这里面的关键代码是, 将ConfigurationClassPostProcessor放入到了beanDefinitionMap
里面
下面的else是处理循环引用的问题, 暂时先不要看
3.4 对照整体框架, 我们知道ConfigurationClassPostProcessor被解析成beanDefinition放入到BeanDefinitionMap中了
3.5 初始化ClassPathBeanDefinitionScanner
在this()构造方法里, 还初始化了ClassPathBeanDefinitionScanner, 这里只说一句.
this.scanner = new ClassPathBeanDefinitionScanner(this);
我们在扫描配置类的时候, 确实使用的是ClassPathBeanDefinitionScanner, 但是, 不是this.scanner对象. 而是自己new的一个ClassPathBeanDefinitionScanner.
这里的scanner仅仅是为了程序员可以手动调用AnnotationConfigApplicationContext对象的scan方法
通过调用context.scan("package name");扫描处理配置类
使用方式如下:
public static void main(String[] args) {
// 第一步: 通过AnnotationConfigApplicationContext读取一个配置类
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);
context.scan("package");
Car car = (Car) context.getBean("car");
System.out.println(car.getName());
context.close();
}
到目前为止完成了后置处理器注册为BeanDefinition
备注:
ConfigurationClassPostProcessor是一个工具类, 这个类的作用是解析配置类.
工具类有了, 那么还得有主角呀, 那就是我们上面的配置类. 下面看看配置类的加载
四、读取自定义配置类MainConfig
注册配置类,入口自然是这里了
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
/* todo: 调用自身的构造方法之前, 要先调用父类的构造方法 ---> this.beanFactory = new DefaultListableBeanFactory(); */
/* todo: 然后调用自身的构造方法this() ---> 一共做了两件事情*/
this();
// 调用注册器, 这里会加载两个BeanDefinitionReader和BeanDefinitionScanner. 这两位的角色是什么呢? 可以回忆一下之前的框架图
register(componentClasses);
/*todo:ioc容器刷新接口--非常重要*/
refresh();
}
跟踪进去找到doRegisterBean(...)方法
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
@Nullable BeanDefinitionCustomizer[] customizers) {
/*todo:将入参beanClass构建成AnnotatedGenericBeanDefinition对象*/
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
abd.setInstanceSupplier(supplier);
// 读取配置类的元数据
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
/*todo:处理通用定义注解*/
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));
}
}
}
if (customizers != null) {
for (BeanDefinitionCustomizer customizer : customizers) {
customizer.customize(abd);
}
}
// 将MainConfig.java配置类进行解析.放到BeanDefinitionHolder
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
重点就是这句话, 其他可以略过, 因为我们的配置类很简单, 直接看 BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder,this.registry);
我们找到 registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());方法, 进入到DefaultListableBeanFactory查看方法, 这个方法之前我们已经调用过一次
就是在注册ConfigurationClassPostProcessor的时候, 我们需要将其解析为BeanDefinition然后放到BeanDefinitionMap中, 这里也是一样的, 将我们的配置类MainConfig解析成BeanDefinition放入到BeanDefinitionMap中.
这里的代码在整个框架中处于什么位置呢? 将MainConfig解析为BeanDefinition放入到BeanDefinitionMap中
以上两步, 一个是将ConfigurationClassPostProcessor配置类后置处理器, 也就是解析配置的工具类, 解析成BeanDefinition放入到BeanDefinitionMap中
另一个是将我们的目标配置类MainConfig加载到内存, 组装成BeanDefinition放入到BeanDefinitionMap中.
到这里,我们完成了两步.
第一步: 准备工具类ConfigurationClassPostProcessor
第二步: 准备配置类MainConfig.
接下来, 就是要使用工具类来解析配置类MainConfig了
五、调用bean工厂的后置处理器invokeBeanFactoryPostProcessors(beanFactory);
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
// 进入构造函数, 首先调用自身的构造方法this();
// 调用自身的构造方法之前, 要先调用父类的构造方法
this();
// register配置注册类
register(componentClasses);
// ioc容器刷新接口--非常重要
refresh();
}
在refresh()中有很多步骤, 我们重点来看invokeBeanFactoryPostProcessors(beanFactory);
@Override
public void refresh() throws BeansException, IllegalStateException {
// 为了避免refresh()还没结束,再次发起启动或者销毁容器引起的冲突
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// Prepare this context for refreshing.做一些准备工作,记录容器的启动时间、标记“已启动”状态、检查环境变量等
/*todo: 1.准备刷新上下文环境*/
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
// 乍一看这个方法也没几行代码,但是这个方法负责了BeanFactory的初始化、Bean的加载和注册等事件
/*todo: 2.获取告诉子类初始化bean工厂, 不同工厂不同实现*/
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
// 这个方法主要会设置BeanFactory的类加载器、添加几个 BeanPostProcessor、手动注册几个特殊的bean
/*todo: 3.对bean工厂进行填充属性*/
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
/**
* 这个比较简单,又是Spring的一个扩展点
* 如果有Bean实现了BeanFactoryPostProcessor接口,
* 那么在容器初始化以后,Spring 会负责调用里面的 postProcessBeanFactory 方法。
* 具体的子类可以在这步的时候添加一些特殊的 BeanFactoryPostProcessor 的实现类或做点什么事
*/
/*todo: 4.Spring开放接口 留给子类去实现该接口*/
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// Invoke factory processors registered as beans in the context.
// 调用BeanFactoryPostProcessor各个实现类的postProcessBeanFactory(factory) 方法
/*todo: 5.调用我们的bean工厂的后置处理器: (1) 会再次class扫描成BeanDefinition*/
/**
* 调用bean工厂的后置处理器
* 我们之前在Reader的时候读取了很多创世纪的PostProcessor后置处理器.
* 这里要调用bean工厂的后置处理器. 这么多创世纪的PostProcessor, 只有一个PostProcessor实现了
* BeanFactoryPostProcessor. 那个类就是 ConfigurationClassPostProcessor
* 前面已经将ConfigurationClassPostProcessor放入到BeanDefinitionMap中了,
* 对应的BeanDefinitionName 是 internalConfigurationAnnotationProcessor
*/
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
/**
* 又是一个扩展点
* 注册 BeanPostProcessor 的实现类,注意不是BeanFactoryPostProcessor
* 此接口有两个方法: postProcessBeforeInitialization 和 postProcessAfterInitialization分别会在Bean初始化之前和初始化之后得到执行
*/
/*todo: 6.注册我们bean后置处理器*/
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// Initialize message source for this context.
// 初始化当前 ApplicationContext 的 MessageSource,有想了解国际化的相关知识可以深入研究一下
/*todo: 7.初始化国际化资源处理器*/
initMessageSource();
// Initialize event multicaster for this context.
// 这个方法主要为初始化当前 ApplicationContext 的事件广播器
/*todo: 8.初始化事件多播放器*/
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
// 又是一个扩展点,子类可以在这里来搞事情
/*todo: 9.这个方法同样也是留个子类实现,其中springboot也是从这个方法进行tomcat的启动*/
onRefresh();
// Check for listener beans and register them.
// 注册事件监听器
/*todo: 10.把我们的事件监听器注册到多播器上*/
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons. 实例化剩余的单实例bean
// 刚才我们提到了bean还没有初始化。这个方法就是负责初始化所有的没有设置懒加载的singleton bean
/*todo: 11.实例化所有的非懒加载的单实例bean*/
/**
* 这个方法就是循环遍历BeanDefinitionMap, 调用getBean, 去生产bean
*/
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
// 最后一步: 发布相应的事件
/*todo: 12.最后刷新容器 发布刷新事件(Spring cloud eureka也是从这里启动的)*/
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...
// 最后一步还是清除缓存
resetCommonCaches();
contextRefresh.end();
}
}
}
invokeBeanFactoryPostProcessors(beanFactory);看名字, 调用的是Bean工厂的后置处理器, 上面分析了, 初始化的时候初始化了很多spring原生的后置处理器, 这么多后置处理器, 其实, 只有一个后置处理器实现了BeanFactoryPostProcessor, 它就是ConfigurationClassPostProcessor, 还记得上面的结构图么, 拿下来, 再看一遍.
这里调用的时候, 原生处理器只会调用ConfigurationClassPostProcessor
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
/**
* 获取两处存储BeanFactoryPostProcessor的对象, 传入供接下来调用
* 1. 当前bean工厂
* 2. 和我们自己调用addBeanFactoryPostProcessor自定义BeanFactoryPostProcessor
*
* 参数: getBeanFactoryPostProcessors() 传了一个工厂的后置处理器的List, 这个时候list是空的
* getBeanFactoryPostProcessors()里面的值是怎么来的呢?
* 通过在自定义main方法中调用context.addBeanFactoryPostProcessor(...);来添加
*
* public static void main(String[] args) {
* // 第一步: 通过AnnotationConfigApplicationContext读取一个配置类
* AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);
* context.addBeanFactoryPostProcessor(...);
* Car car = (Car) context.getBean("car");
* System.out.println(car.getName());
* context.close();
* }
*/
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
if (!IN_NATIVE_IMAGE && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
这里要调用bean工厂的后置处理器了. 看上面的注释, 注释写的很清晰.
在调用PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors())
;的时候调用了getBeanFactoryPostProcessors()方法.
public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
return this.beanFactoryPostProcessors;
}
getBeanFactoryPostProcessors() 返回的是一个工厂的后置处理器的List, 这个时候list是空的
getBeanFactoryPostProcessors()里面的值是怎么来的呢?
通过在自定义main方法中调用context.addBeanFactoryPostProcessor(...);来添加. 也就是通过main方法手动添加的beanFactoryPostProcessor. 如下所示
public static void main(String[] args) {
// 第一步: 通过AnnotationConfigApplicationContext读取一个配置类
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);
context.addBeanFactoryPostProcessor(...);
Car car = (Car) context.getBean("car");
System.out.println(car.getName());
context.close();
}
接下来重点来了. PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors**(beanFactory, getBeanFactoryPostProcessors());
方法实现一共分为两大步:
第一步: 调用所有实现了 BeanDefinitionRegistryPostProcessor 接口的bean定义.
(BeanDefinitionRegistryPostProcessor带注册功能的后置处理器)
第二步: 调用BeanFactoryPostProcessor Bean工厂的后置处理器
第一步: 调用所有实现了 BeanDefinitionRegistryPostProcessor 接口的bean定义.
来看看源码是如何定义的. 重点看代码的注释, 每一部分的功能都有明确标出, 注释写的很详细
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
/**
* 首先,调用BeanDefinitionRegistryPostProcessors的后置处理器
* 定义已处理的后置处理器
*/
Set<String> processedBeans = new HashSet<>();
/**
* 这里一共分为两大步:
* 第一步: 调用所有实现了 BeanDefinitionRegistryPostProcessor 接口的bean定义. (BeanDefinitionRegistryPostProcessor带注册功能的后置处理器)
* 第二步: 调用BeanFactoryPostProcessor Bean工厂的后置处理器
*/
/**********************第一步: 调用所有实现了BeanDefinitionRegistryPostProcessor接口的bean定义 begin****************************/
// 判断beanFactory是否实现了BeanDefinitionRegistry, 实现了该结构就有注册和获取Bean定义的能力
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
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.
/**
* 这是一个集合, 存马上即将要被调用的BeanDefinitionRegistryPostProcessor
*/
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
// 第一步, 调用实现了PriorityOrdered的BeanDefinitionRegistryPostProcessors
// 在所有创世纪的后置处理器中, 只有 internalConfigurationAnnotationProcessor 实现了 BeanDefinitionRegistryPostProcessors 和 PriorityOrdered
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
// 判断beanFactory是否实现了PriorityOrdered接口. 如果实现了,是最优先调用.
// 在整个加载过程中,会调用四次BeanDefinitionRegistryPostProcessor, 而实现了PriorityOrdered的接口最先调用
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
/**
* 第一次调用BeanDefinitionRegistryPostProcessors
* 在这里典型的BeanDefinitionRegistryPostProcessors就是ConfigurationClassPostProcessor
* 用于进行bean定义的加载 比如我们的包扫描 @import 等
*/
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
// 处理完了,清空currentRegistryProcessors
currentRegistryProcessors.clear();
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
/** 第二步: 调用实现 Ordered 的 BeanDefinitionRegistryPostProcessors。*/
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
/**这时实现了PriorityOrdered.class的postProcessor就不会再被加载进来了, 因为processedBeans.contains(ppName) == true*/
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
// 将其放入到currentRegistryProcessors, 马上就要被调用
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
// 对所有的处理器进行排序. 调用了Ordered的方法, 会返回排序(一个数字), 然后根据数字排序即可
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
/**
* 第二次调用BeanDefinitionRegistryPostProcessors
* 在这里典型的BeanDefinitionRegistryPostProcessors就是ConfigurationClassPostProcessor
* 用于进行bean定义的加载 比如我们的包扫描 @import 等
*/
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
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) {
// 已处理过的postProcessor不再处理
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
/**
* 第三次调用BeanDefinitionRegistryPostProcessors
* 在这里典型的BeanDefinitionRegistryPostProcessors就是ConfigurationClassPostProcessor
* 用于进行bean定义的加载 比如我们的包扫描 @import 等
*/
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
}
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
/**
* 第四步:调用bean工厂的后置处理器
* registryProcessors: 带有注册功能的bean工厂的后置处理器
* regularPostProcessors: 不带注册功能的bean工厂的后置处理器
*/
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
// Invoke factory processors registered with the context instance.
/**
* 如果当前的beanFactory没有实现BeanDefinitionRegistry 说明没有注册Bean定义的能力
* 那么就直接调用 BeanDefinitionRegistryPostProcessor.postProcessBeanFactory方法
*/
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
/**********************第一步: 调用所有实现了BeanDefinitionRegistryPostProcessor接口的bean定义 end****************************/
/**********************第二步: 调用BeanFactoryPostProcessor Bean工厂的后置处理器 begin****************************/
// 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.
/** 第二, 调用实现了Ordered排序的后置处理器 */
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors.
/** 最后, 调用没有实现任何排序接口的beanFactory后置处理器 */
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
/**********************第二步: 调用BeanFactoryPostProcessor Bean工厂的后置处理器 end****************************/
// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
beanFactory.clearMetadataCache();
}
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgbaeee
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01