SpringIOC 容器加载过程
第一步:实例化化容器:AnnotationConfigApplicationContext
@Configuration
@ComponentScan("cn.zhe")
public class MainStartTest {
public static void main(String[] args) {
// SpringIOC 出发点 加载Spring上下文
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainStartTest.class);
HelloSpring bean = applicationContext.getBean(HelloSpring.class);
bean.sayHello();
}
}
构造函数
// 根据参数可知,可以传入多个Class,但这种情况及其少见
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
/**
* 调用无参构造函数
* 主要分三步:
* a.调用父类构造函数
* b.本类构造函数 初始化注解模式下的 bean定义读取器 AnnotatedBeanDefinitionReader
* c.本类构造函数 初始化 classPath类型的 bean定义扫描器 AnnotatedBeanDefinitionScaner
*/
this();
/**
* 注册配置类
* 把传入的类进行注册,分为两种情况
* a. @Configuration的配置类
* b. 传入普通 Bean (基本不会这么做)
* Spring把配置类分为两种
* a. 带@Configuration注解的配置类称之为FULL配置类
* b. 不带@Configuration注解,是带有@Component,@Import,@ImportResouce,
* @Service, @ComponentScan等注解的配置类称之为Lite配置类
*/
register(componentClasses);
// 刷新IOC容器
refresh();
}
this()方法分析开始
第二步:实例化工厂:DefaultListableBeanFactory
DefaultListableBeanFactory 就是我们所说的容器,里面放着beanDefinitionMap, beanDefinitionNames等
// 调用无参构造,会先调用父类GenericApplicationContext的构造函数
// 第一步调用父类构造函数,创建一个Bean工厂
public GenericApplicationContext() {
/**
* 调用父类的构造函数,为 ApplicationContext spring 上下文对象初始 beanFactory
* 因为 DefaultListableBeanFactory 是最底层的实现,功能是最全的
*/
this.beanFactory = new DefaultListableBeanFactory();
}
// 第二三步
public class AnnotationConfigApplicationContext extends GenericApplicationContext
implements AnnotationConfigRegistry {
// 注解bean定义读取器,主要作用是用来读取被注解的Bean
private final AnnotatedBeanDefinitionReader reader;
// 外部调用scan手动扫描的scanner对象,用处不大
private final ClassPathBeanDefinitionScanner scanner;
public AnnotationConfigApplicationContext() {
/**
* 初始化注解模式下的bean定义扫描器
* 调用AnnotatedBeanDefinitionReader构造方法,传入的
* 是this(AnnotationConfigApplicationContext)对象
*/
this.reader = new AnnotatedBeanDefinitionReader(this);
/**
* 初始化classPath类型的bean定义扫描器
* 使用场景极少,仅外部手动调用扫描使用,常规方式是不会用到scanner对象的
* 此处扫描器仅用于自定义的扫描 applicationContext.scan();
*/
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
}
第三步:实例化 BeanDefinition 读取器 (AnnotatedBeanDefinitionReader)
主要就做了两件事情:
- 注册内置 BeanPostProcessor
- 注册内置相关核心的 BeanDefinition
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
Assert.notNull(environment, "Environment must not be null");
// 把ApplicationContext对象赋值给AnnotatedBeanDefinitionReader
this.registry = registry;
// 用户处理条件表达式计算 @Condition
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
// 注册一些配置的后置处理器,并注册Spring内置的多个Bean
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
关于registerAnnotationConfigProcessors(this.registry);
方法内容较多,但大多相同的判断,注册 Spring 内置的多个 Bean,以ConfigurationClassPostProcesso
为例:
/**
* 为容器中注册解析配置类的后置处理器 ConfigurationClassPostProcessor
* org.springframework.context.annotation.internalConfigurationAnnotationProcessor
*/
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
/**
* 这方法为BeanDefinition设置了一个Role,ROLE_INFRASTRUCTURE代表这是spring内部的,并非用户定义的
* registry.registerBeanDefinition(beanName, definition);是一个接口方法,
* 实现类是 DefaultListableBeanFactory
* 核心工作就是
* a.this.beanDefinitionMap.put(beanName, beanDefinition);
* 把beanName作为key,beanDefinition作为value,放到map里面
* b.beanDefinitionNames就是一个List<String>,这里就是把beanName放到List中去
* DefaultListableBeanFactory就是我们所说的容器,里面放着beanDefinitionMap, beanDefinitionNames,
* beanDefinitionMap是一个hashMap,beanName作为Key,beanDefinition作为Value,
* beanDefinitionNames是一个集合,里面存放了beanName
*/
private static BeanDefinitionHolder registerPostProcessor(
BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
// 核心已在上方注释
registry.registerBeanDefinition(beanName, definition);
return new BeanDefinitionHolder(definition, beanName);
}
逻辑就是:
- 判断容器中是否已经存在了
ConfigurationClassPostProcessor
Bean - 如果不存在,就通过 RootBeanDefinition 的构造方法获得
ConfigurationClassPostProcessor
的BeanDefinition - 执行
registerPostProcessor()
方法,其内部就是注册Bean(与其他 Bean 注册流程一致)
internalConfigurationAnnotationProcessor
ConfigurationClassPostProcessor 是 Spring 中极其重要的一个类,它实现 BeanDefinitionRegistryPostProcessor 接口,BeanDefinitionRegistryPostProcessor 接口又扩展了 BeanFactoryPostProcessor 接口,BeanFactoryPostProcessor 是 Spring 的扩展点之一。
至此加载完以下扩展点(beanDefinition -> beanDefinitionMap)
第四步:创建 BeanDefinition 扫描器 (ClassPathBeanDefinitionScanner)
初始化 classPath 类型的 BeanDefinition 扫描器,使用场景极少,仅外部手动调用扫描使用,常规方式是不会用到 scanner 对象的此处扫描器仅用于自定义的扫描applicationContext.scan()
。
至此this()方法结束
register(annotatedClasses);分析开始
第五步:注册配置类为BeanDefinition (register(annotatedClasses);)
/**
* 注册配置类
* 把传入的类进行注册,分为两种情况
* a. @Configuration的配置类
* b. 传入普通 Bean (基本不会这么做)
* Spring把配置类分为两种
* a. 带@Configuration注解的配置类称之为FULL配置类
* b. 不带@Configuration注解,是带有@Component,@Import,@ImportResouce,
* @Service, @ComponentScan等注解的配置类称之为Lite配置类
*/
register(componentClasses);
public void register(Class<?>... componentClasses) {
this.reader.register(componentClasses);
}
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
@Nullable BeanDefinitionCustomizer[] customizers) {
// AnnotatedGenericBeanDefinition可以理解为一种数据结构,是用来描述Bean的,这里的作用就是把传入
// 的标记了注解的类转为AnnotatedGenericBeanDefinition数据结构,里面有一个getMetadata方法,可以拿到类上的注解
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
// 判断是否需要跳过注解,spring中有一个@Condition注解,当不满足条件,这个bean就不会被解析
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
abd.setInstanceSupplier(supplier);
// 解析bean的作用域,如果没有设置的话,默认为单例
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
// 获得beanName
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
// 解析通用注解,填充到AnnotatedGenericBeanDefinition,
// 解析的注解 Lazy,Primary,DependsOn,Role,Description
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);
}
}
// 这个方法用处不大,就是把AnnotatedGenericBeanDefinition数据结构和beanName封装到一个对象中
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
// 注册,最终会调用DefaultListableBeanFactory中的registerBeanDefinition方法去注册
// DefaultListableBeanFactory维护着一系列信息,比如beanDefinitionNames,beanDefinitionMap
// beanDefinitionMap是一个Map,用来保存beanName和beanDefinition
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
- 通过AnnotatedGenericBeanDefinition的构造方法,获得配置类的BeanDefinition
- 判断需不需要跳过注册,Spring中有一个@Condition注解,如果不满足条件,就会跳过这个类的注册
- 然后是解析作用域,如果没有设置的话,默认为单例
- 获得BeanName
- 解析通用注解,填充到 AnnotatedGenericBeanDefinition,解析的注解为Lazy,Primary,DependsOn,Role,Description
- 限定符处理,不是特指@Qualifier注解,也有可能是Primary,或者是Lazy,或者是其他(理论上是任何注解,这里没有判断注解的有效性)
- 把AnnotatedGenericBeanDefinition数据结构和beanName封装到一个对象中(不重要,方便传参)
- 注册,最终会调用 DefaultListableBeanFactory 中的 registerBeanDefinition() 方法
至此,注册配置类加载结束,配置类(MainStartTest,标记了@Configuration的类) 被放入 BeanDefinitionMap 中未实例化。(实例化都在reflesh()
方法中进行)
至此register()方法结束,将我们传入的配置类加载完毕即:mainStartTest
refresh() 方法分析开始
第六步:refresh();
到这一步 Spring 还没有进行扫描,只是实例化了一个工厂,注册了一些内置的 Bean 和 配置类,这一行是至关重要的一个方法,也是内容最多的,里面做了大量的处理。
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 1:准备刷新上下文环境
// 刷新预处理,和主流程关系不大,就是保存了容器的启动时间,启动标志等
prepareRefresh();
//2:告诉子类初始化Bean工厂(MVC),获取Bean工厂
// 和主流程关系也不大,最终获得了DefaultListableBeanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 3:对Bean工厂进行填充属性
/**
* ①添加了两个后置处理器:
* a.ApplicationContextAwareProcessor
* b.ApplicationListenerDetector
* ②设置忽略自动装配和允许自动装配的接口,如果不存在某个bean的时候,
* spring就自动注册singleton bean
* ③ 设置了bean表达式解析器
*/
prepareBeanFactory(beanFactory);
try {
// 4:空方法 留给子类去实现该接口 允许在上下文子类中对Bean工厂进行后置处理。
postProcessBeanFactory(beanFactory);
// 5:调用Bean工厂的后置处理器.
// 执行自定义的BeanFactoryPostProcessor和内置的BeanFactoryPostProcessor
invokeBeanFactoryPostProcessors(beanFactory);
// 6:注册BeanPostProcessors
registerBeanPostProcessors(beanFactory);
// 7:初始化国际化资源处理器.
initMessageSource();
// 8:创建事件多播器
initApplicationEventMulticaster();
// 9:这个方法同样也是留个子类实现的springboot也是从这个方法进行启动tomcat的.
// 模板方法,在容器刷新的时候可以自定义逻辑,不同的Spring容器做不同的事情
onRefresh();
// 10:将事件监听器注册到多播器上
registerListeners();
// 11:实例化懒加载单例Bean的,也就是Bean绝大部分都是在这里被创建出来的
finishBeanFactoryInitialization(beanFactory);
// 12:最后容器刷新 发布刷新事件(Spring cloud也是从这里启动的)
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);
throw ex;
}
finally {
// 清除元数据缓冲,实例化后就不需要了
resetCommonCaches();
}
}
}
下面来逐一解析里面比较重要的几个方法,有些不重要的就仅在上面注释了
6.1 prepareBeanFactory(beanFactory)
顾名思义,BeanFactory的一些准备工作
- 设置了一个类加载器
- 设置了bean表达式解析器
- 添加了属性编辑器的支持
- 添加了一个后置处理器:ApplicationContextAwareProcessor,此后置处理器实现了BeanPostProcessor接口
- 设置了一些忽略自动装配的接口
- 设置了一些允许自动装配的接口,并且进行了赋值操作
- 在容器中还没有XX的 bean 的时候,帮我们注册 beanName 为 XX 的 singleton bean
6.2 invokeBeanFactoryPostProcessors(beanFactory)
首先看一下我们到这一步时 BeanDefinitionMap 里面 bean 定义的情况:
/**
* 调用Bean工厂的后置处理器.
* 执行自定义的 BeanFactoryPostProcessor 和内置的 BeanFactoryPostProcessor
*/
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// getBeanFactoryPostProcessors(),获得外部可以手动添加一个后置处理器,如果不添加获得的集合永远为空
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
// (例如通过ConfigurationClassPostProcessor注册的@Bean方法)
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// 第一步:首先调用BeanDefinitionRegistryPostProcessor的后置处理器
// 装beanName 后续会根据这个集合来判断处理器是否已经被执行过了
Set<String> processedBeans = new HashSet<>();
if (beanFactory instanceof BeanDefinitionRegistry) {
// 强行把bean工厂转为BeanDefinitionRegistry
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
// 保存BeanFactoryPostProcessor类型的后置
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
// 循环传递进来的 beanFactoryPostProcessors,正常情况为数据,只有手动添加了后置处理器才会有数据
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
// 判断后置处理器是不是 BeanDefinitionRegistryPostProcessor
// 因为BeanDefinitionRegistryPostProcessor扩展了BeanFactoryPostProcessor
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
// 进行强制转换
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
// 调用作为BeanDefinitionRegistryPostProcessor的处理器的后置方法
registryProcessor.postProcessBeanDefinitionRegistry(registry);
// 添加到用于保存的BeanDefinitionRegistryPostProcessor的集合中
registryProcessors.add(registryProcessor);
}
// 若没有实现BeanDefinitionRegistryPostProcessor 接口,那么它就是BeanFactoryPostProcessor
// 把当前的后置处理器加入到regularPostProcessors中
else {
regularPostProcessors.add(postProcessor);
}
}
// 定义一个集合用户保存当前准备创建的BeanDefinitionRegistryPostProcessor
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// 第一步:去容器中获取BeanDefinitionRegistryPostProcessor的bean的处理器名称
// internalConfigurationAnnotationProcessor即ConfigurationAnnotationProcessor
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
// 循环上一步获取的BeanDefinitionRegistryPostProcessor的类型名称
for (String ppName : postProcessorNames) {
// 判断是否实现了PriorityOrdered接口的
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// 显示的调用getBean()的方式获取出该对象然后加入到currentRegistryProcessors集合中去
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
// 同时也加入到processedBeans集合中去
// 后续会根据这个集合来判断处理器是否已经被执行过了
processedBeans.add(ppName);
}
}
// 对currentRegistryProcessors集合中BeanDefinitionRegistryPostProcessor进行排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
// 把他加入到用于保存到registryProcessors中
// 为什么要合并,因为registryProcessors是装载BeanDefinitionRegistryPostProcessor的
// 一开始的时候,spring只会执行BeanDefinitionRegistryPostProcessor独有的方法
// 而不会执行BeanDefinitionRegistryPostProcessor父类的方法,即BeanFactoryProcessor的方法
// 所以这里需要把处理器放入一个集合中,后续统一执行父类的方法
registryProcessors.addAll(currentRegistryProcessors);
/**
* 在这里典型的BeanDefinitionRegistryPostProcessor就是
* ConfigurationClassPostProcessor
* 用于进行bean定义的加载 比如我们的包扫描,@import 等等
*/
// Spring热插播的体现,像ConfigurationClassPostProcessor就相当于一个组件
// Spring很多事情就是交给组件去管理,如果不想用这个组件,直接去掉注册组件就行
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
// 调用完之后,马上clear掉,临时变量需要清除
// list.clear()只清除对象的引用使其变为垃圾,与list = null 集合也会置空
currentRegistryProcessors.clear();
// 接下来,去容器中获取BeanDefinitionRegistryPostProcessor的bean的处理器名称
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
// 循环上一步获取的BeanDefinitionRegistryPostProcessor的类型名称
for (String ppName : postProcessorNames) {
// 没有被处理过,且实现了Ordered接口的
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
// 显示的调用getBean()的方式获取出该对象然后加入到currentRegistryProcessors集合中去
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
// 同时也加入到processedBeans集合中去
processedBeans.add(ppName);
}
}
// 对currentRegistryProcessors集合中BeanDefinitionRegistryPostProcessor进行排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
// 把他加入到用于保存到registryProcessors中
registryProcessors.addAll(currentRegistryProcessors);
// 调用他的后置处理方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
// 调用完之后,马上clear掉
currentRegistryProcessors.clear();
// 调用没有实现任何优先级接口的BeanDefinitionRegistryPostProcessor
// 定义一个重复处理的开关变量 默认值为true
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
boolean reiterate = true;
// 第一次就可以进来
while (reiterate) {
// 进入循环马上把开关变量给改为fasle
reiterate = false;
// 去容器中获取BeanDefinitionRegistryPostProcessor的bean的处理器名称
// 根据类型查 beanName 一般情况下只会获取到一个
org.springframework.context.annotation.internalConfigurationAnnotationProcessor,
也就是 ConfigurationAnnotationProcessor
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
// 循环上一步获取的BeanDefinitionRegistryPostProcessor的类型名称
for (String ppName : postProcessorNames) {
// 没有被处理过的
if (!processedBeans.contains(ppName)) {
// 显示的调用getBean()的方式获取出该对象然后加入到currentRegistryProcessors集合中去
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
// 同时也加入到processedBeans集合中去
processedBeans.add(ppName);
// 再次设置为true
reiterate = true;
}
}
// 对currentRegistryProcessors集合中BeanDefinitionRegistryPostProcessor进行排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
// 把他加入到用于保存到registryProcessors中
registryProcessors.addAll(currentRegistryProcessors);
// 调用他的后置处理方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
// 调用完之后,马上clear掉
currentRegistryProcessors.clear();
}
// 调用实现了BeanDefinitionRegistryPostProcessor的接口 他是他也同时实现了BeanFactoryPostProcessor的方法
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
// 调用BeanFactoryPostProcessor成品的不是通过getBean的
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
// 若当前的beanFactory没有实现了BeanDefinitionRegistry 直接调用
// 直接调用 beanFactoryPostProcessor 接口的方法进行后置处理
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// 获取容器中所有的 BeanFactoryPostProcessor
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// 保存BeanFactoryPostProcessor类型实现了priorityOrdered
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
// 保存BeanFactoryPostProcessor类型实现了Ordered接口的
List<String> orderedPostProcessorNames = new ArrayList<>();
// 保存BeanFactoryPostProcessor没有实现任何优先级接口的
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
// processedBeans包含的话,表示在上面处理BeanDefinitionRegistryPostProcessor的时候处理过了
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
// 判断是否实现了PriorityOrdered
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
// 判断是否实现了Ordered
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
// 没有实现任何的优先级接口的
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// 首先,先调用BeanFactoryPostProcessor实现了 PriorityOrdered接口的
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 再调用BeanFactoryPostProcessor实现了 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);
// 最后调用没有实现任何方法接口的
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
beanFactory.clearMetadataCache();
}
总结:
首先,之前已经了解过 BeanDefinition 的两个扩展点 postProcessBeanFactory 和 postProcessBeanDefinitionRegistry。前者是可以修改 BeanDefinition,重写方法,后者可以多添加 BeanDefinition
1、定义了一个 Set,
processedBeans
装载BeanName,后面会根据此 Set 来判断后置处理器是否被执行过2、判断当前的 beanFactory 有没有实现 BeanDefinitionRegistry,当然是肯定的, 定义了两个 List 一个是 regularPostProcessors,用来装载 BeanFactoryPostProcessor。它只有一个实现 方法
postProcessBeanFactory()
。一个是 registryProcessors, 用来装载 BeanDefinitionRegistryPostProcessor。因为 它继承了 BeanFactoryPostProcessor 它不仅有postProcessBeanFactory()
还有postProcessBeanDefinitionRegistry()
。3、循环传进来的
beanFactoryPostProcessors
,一般情况下都是空的,除非自己 add 了 beanFactory 的后置处理器。假设有数据,先判断是否是BeanDefinitionRegistryPostProcessor
如果是调用postProcessBeanDefinitionRegistry()
方法,并添加到集合 registryProcessors 中,否的话直接加入到集合 regularPostProcessors。(postProcessBeanFactory()
会在后面执行,先存起来)4、 定义一个集合(List 临时变量)
currentRegistryProcessors
用户保存当前准备创建的 BeanDefinitionRegistryPostProcessor5、去容器中获取BeanDefinitionRegistryPostProcessor的bean的处理器名称
internalConfigurationAnnotationProcessor
即ConfigurationAnnotationProcessor
一般情况都只会获取到一个。此时Spring还未扫描完成,扫描是在ConfigurationClassPostProcessor类完成的,就是下面的第一个invokeBeanDefinitionRegistryPostProcessors()
方法6、循环 postProcessorNames
internalConfigurationAnnotationProcessor
判断是否实现了 PriorityOrdered,实现了添加到currentRegistryProcessors和processedBeans表示它们被处理过了(下一步才处理)7、对 currentRegistryProcessors 集合中BeanDefinitionRegistryPostProcessor 进行排序
8、将
currentRegistryProcessors
集合加到registryProcessors
集合中,因为registryProcessors
是装载BeanDefinitionRegistryPostProcessor
,一开始的时候,spring只会执行BeanDefinitionRegistryPostProcessor
独有的方法postProcessBeanDefinitionRegistry()
。而不会执行 BeanDefinitionRegistryPostProcessor 父类的方法,即 BeanFactoryProcessor 的方法postProcessBeanFactory()
。所有在此统一放到一起等待后续执行9、
internalConfigurationAnnotationProcessor(currentRegistryProcessors, registry)
,执行currentRegistryProcessors
中的ConfigurationClassPostProcessor
中的postProcessBeanDefinitionRegistry()
方法,这里体现了 Spring 中热插拔,插件化开发的思想,如果不想用这个,不添加就行了。从下图可以看到,执行完该方法后 bean定义 被加载到了BeanDefinitionMap中
10、清空
currentRegistryProcessors
,用完了就需要清空,给后面的其他的重复使用11、最后会重复上面的逻辑,调用顺序如下:
- 实现了PriorityOrdered接口的
- 实现了Ordered接口的
- 没有实现任何的优先级接口的
如果实现了多个的话,将在最先实现的地方调用,第二次将会判断是否已经处理过
再来看一下postProcessBeanFactory()
方法,它调用了一个会解析我们BeanDefinition的方法processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
int factoryId = System.identityHashCode(beanFactory);
if (this.factoriesPostProcessed.contains(factoryId)) {
throw new IllegalStateException(
"postProcessBeanFactory already called on this post-processor against " + beanFactory);
}
this.factoriesPostProcessed.add(factoryId);
if (!this.registriesPostProcessed.contains(factoryId)) {
// BeanDefinitionRegistryPostProcessor hook apparently not supported...
// Simply call processConfigurationClasses lazily at this point then.
processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
}
// 为属性为full的Bean定义做CGLIB增强
enhanceConfigurationClasses(beanFactory);
beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
}
这个方法中会引申出一个知识点
注册配置类 把传入的类进行注册,分为两种情况
- a. @Configuration 的配置类
- b. 传入普通 Bean (基本不会这么做)
Spring 把配置类分为两种
- a. 带 @Configuration 注解的配置类称之为 FULL 配置类
- b. 不带 @Configuration 注解,而是带有 @Component,@Import,@ImportResouce, @Service, @ComponentScan 等注解的配置类称之为 Lite 配置类
如果我们注册了Full 配置类,我们 getBean 这个配置类,会发现它已经不是原本那个配置类了,而是已经被 CGLIB 代理的类
例如:写一个A类,其中有一个构造方法,打印出“HelloSpring”,再写一个配置类,里面有两个 带 @Bean 的方法。假设其中一个方法
getA()
它new A()
,并且返回A的对象。第二个方法又调用了getA()
。如果配置类是 Lite 配置类,会发现打印了两次“HelloSpring”,即 A 类被 new 了两次。如果配置类是 FULL 配置类,会发现只打印一次,因为这个类被CGLIB
代理了。
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
// 获取IOC 容器中目前所有bean定义的名称
String[] candidateNames = registry.getBeanDefinitionNames();
// 循环上一步获取的所有的Bean定义信息
for (String beanName : candidateNames) {
// 通过Bean的名称来获取我们的bean定义对象
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
// 判断是否有没有解析过
if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
if (logger.isDebugEnabled()) {
logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
}
}
// 进行正在的解析判断是不是完全的配置类 还是一个非正式的配置类
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
// 满足添加就加入到候选的配置类集合中
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
// Return immediately if no @Configuration classes were found
// 若没有找到配置类直接返回
if (configCandidates.isEmpty()) {
return;
}
// Sort by previously determined @Order value, if applicable
// 对配置类进行Order排序
configCandidates.sort((bd1, bd2) -> {
int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return Integer.compare(i1, i2);
});
// Detect any custom bean name generation strategy supplied through the enclosing application context
// 创建我们通过@CompentScan导入进来的bean name的生成器
// 创建我们通过@Import导入进来的bean的名称
SingletonBeanRegistry sbr = null;
if (registry instanceof SingletonBeanRegistry) {
sbr = (SingletonBeanRegistry) registry;
if (!this.localBeanNameGeneratorSet) {
BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(
AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR);
if (generator != null) {
// 设置@CompentScan导入进来的bean的名称生成器
this.componentScanBeanNameGenerator = generator;
// 设置@Import导入进来的bean的名称生成器
this.importBeanNameGenerator = generator;
}
}
}
if (this.environment == null) {
this.environment = new StandardEnvironment();
}
// 创建一个配置类解析器对象
// Parse each @Configuration class
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
// 创建一个集合用于保存我们的配置类BeanDefinitionHolder集合默认长度是配置类集合的长度
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
// 创建一个集合用于保存我们的已经解析的配置类,长度默认为解析出来默认的配置类的集合长度
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
//do while 会进行第一次解析
do {
// 解析配置类
// 经过这一步,会将@ComponentScans、@ComponentScan、@Bean、@Import等注解要注册的类扫描出来
parser.parse(candidates);
parser.validate();
// 解析出来的配置类
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
// Read the model and create bean definitions based on its content
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
// 把解析出来的配置类注册到容器中
// 经过这一步会将@Bean、@import 注册的类变成BeanDefinition
this.reader.loadBeanDefinitions(configClasses);
// 加入到已经解析的集合中
alreadyParsed.addAll(configClasses);
candidates.clear();
//判断我们IOC容器中的是不是>候选原始的bean定义的个数
if (registry.getBeanDefinitionCount() > candidateNames.length) {
// 获取所有的bean定义
String[] newCandidateNames = registry.getBeanDefinitionNames();
// 原始的老的候选的bean定义
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);
// 判断有没有被解析过
// checkConfigurationClassCandidate 此时为Bean定义标识为full或lite,在后面根据属性潘森是否需要用CGLIB增强
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();
}
}
至此自定义的配置类都加载到了beanDefinitonMap 中,但仍未初始化
此处会实例化以下几个内置 Bean
6.3 registerBeanPostProcessors(beanFactory);
实例化和注册 beanFactory 中扩展了 BeanPostProcessor 的bean。
例如:
AutowiredAnnotationBeanPostProcessor(处理被@Autowired注解修饰的bean并注入)
RequiredAnnotationBeanPostProcessor(处理被@Required注解修饰的方法)
CommonAnnotationBeanPostProcessor(处理@PreDestroy、@PostConstruct、@Resource等多个注解的作用)等。
此处会实例化以下几个内置 Bean
6.4 initApplicationEventMulticaster(); 和 registerListeners();
创建事件多播器
注册监听器,广播early application events
后续监听机制再来看这两个
6.5 finishBeanFactoryInitialization(beanFactory);
实例化 非懒加载单例 Bean ,也就是我们的 Bean 都是在这里被创建出来的。包括(实例化、填充属性、初始化)
里面会有一个方法preInstantiateSingletons()
是一个接口方法,这个方法只有一个实现类DefaultListableBeanFactory
,里面最重要的就是getBean();
。这中间还会去判断是否是一个特殊的Bean(即:FactoryBean)一旦一个类实现了 FactoryBean 并从写了getObject() 方法那么,IOC容器拿到的实例就是调用getObject方法得到的特殊的实例,没有实现这个接口时注册到IOC容器中的就是一个普通的Bean,当实现后,IOC容器会调用getObject方法返回的实例(工厂模式)
// 初始化所有的非懒加载单例Bean
beanFactory.preInstantiateSingletons();
// 执行 getBean流程
getBean(beanName);
复制代码
里面调用的是 AbstractBeanFactory.java 里面的getBean();
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
doGetBean 方法太多了,这里挑出主要创建 单例bean 的逻辑
// 创建单例bean
if (mbd.isSingleton()) {
// 把beanName 和一个 singletonFactory 并且传入一个回调对象用于回调
sharedInstance = getSingleton(beanName, () -> {
try {
// 进入创建bean的逻辑
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// 创建bean的过程中发生异常,需要销毁关于当前bean的所有信息
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
这里的creatBean()
又是一个接口方法,但也仅仅只有一个类对其做了实现AbstractAutowireCapableBeanFactory
。该方法前面也会进行一大堆的判断,我们再次挑出关键步骤
// 真正的开始创建Bean实例对象
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
点进方法doCreateBean(beanName, mbdToUse, args);
发现也在该类下面,里面又做了一大堆的事情,我们主要调出机构关键点
创建实例
// 使用合适的实例化策略来创建新的实例:工厂方法、构造函数自动注入、简单初始化
instanceWrapper = createBeanInstance(beanName, mbd, args);
填充属性及初始化
// 给我们的属性进行赋值(调用set方法进行赋值)
populateBean(beanName, mbd, instanceWrapper);
// 进行对象初始化操作(在这里可能生成代理对象)
exposedObject = initializeBean(beanName, exposedObject, mbd);
在initializeBean(beanName, exposedObject, mbd);
中,又调用了invokeInitMethods(beanName, wrappedBean, mbd);
和invokeAwareMethods(beanName, bean);
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
// 若我们的bean实现了XXXAware接口进行方法的回调
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 调用我们的bean的后置处理器的postProcessorsBeforeInitialization方法 @PostCust注解的方法
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 调用初始化方法
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
// 调用我们bean的后置处理器的PostProcessorsAfterInitialization方法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
// 此bean实现了BeanNameAware
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
// 实现了BeanClassLoaderAware接口
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
// 实现了BeanFactoryAware
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
至此剩余的Bean也全部初始化完成至 IOC 容器中
验证Spring Bean 的生命周期
定义一个SpringBean
@ComponentScan
public class SpringBean
implements InitializingBean, DisposableBean, BeanNameAware, BeanFactoryAware, BeanClassLoaderAware {
// 就是一个普通的被@Component标注的类
@Autowired
AutoBean autoBean;
public SpringBean() {
System.out.println("SpringBean Constructor Method:" + autoBean);
System.out.println("SpringBean()");
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
System.out.println("ClassLoader");
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("setBeanFactory");
}
@Override
public void setBeanName(String name) {
System.out.println("setBeanName:" + autoBean);
System.out.println("setBeanName");
}
@Override
public void destroy() throws Exception {
System.out.println("destroy");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("afterPropertiesSet");
}
public void initMethod() {
System.out.println("initMethod");
}
public void destroyMethod() {
System.out.println("destroyMethod");
}
}
再定义一个BeanPostProcessor,在重写的两个方法中进行了判断,如果传进来的 beanName 是 springBean 才进行打印
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if(beanName.equals("springBean")) {
System.out.println("postProcessBeforeInitialization");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if(beanName.equals("springBean")) {
System.out.println("postProcessAfterInitialization");
}
return bean;
}
}
定义一个配置类,完成自动扫描,但是SpringBean是手动注册的,并且声明了initMethod和destroyMethod:
@Configuration
@ComponentScan
public class MainConfig {
@Bean(initMethod = "initMethod",destroyMethod = "destroyMethod")
public SpringBean springBean() {
return new SpringBean();
}
}
然后是启动类:
public class Main {
public static void main(String[] args) throws Exception {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);
// Spring 的 destroy() 方法已过时会报错,推荐使用 registerShutdownHook() 优雅的关闭 IOC
// context.registerShutdownHook() 是一个钩子方法,当jvm关闭退出的时候会调用这个钩子方法
// 当然 context.close() 也可以销毁容器
context.registerShutdownHook();
}
}
运行结果:
由此我们可以推导出Spring的生命周期
- ① 实例化Bean对象,这个时候 Bean 的对象是非常低级的,基本不能够被我们使用,因为连最基本的属性都没有设置,可以理解为 连Autowired注解都是没有解析的
- ② 填充属性,当做完这一步,Bean对象基本是完整的了,可以理解为Autowired注解已经解析完毕,依赖注入完成了
- ③ 如果Bean实现了BeanNameAware接口,则调用setBeanName方法
- ④ 如果Bean实现了BeanClassLoaderAware接口,则调用setBeanClassLoader方法
- ⑤ 如果Bean实现了BeanFactoryAware接口,则调用setBeanFactory方法
- ⑥ 调用BeanPostProcessor的postProcessBeforeInitialization方法
- ⑦ 如果Bean实现了InitializingBean接口,调用afterPropertiesSet方法
- ⑧ 如果Bean定义了init-method方法,则调用Bean的init-method方法
- ⑨ 调用BeanPostProcessor的postProcessAfterInitialization方法。当进行到这一步,Bean已经被准备就绪了,一直停留在应用的上下文中,直到被销毁
- ⑩ 如果应用的上下文被销毁了,如果Bean实现了DisposableBean接口,则调用destroy方法,如果Bean定义了destory-method声明了销毁方法也会被调用
思考
配置类 @Configuration 加与不加的区别,加上会创建 CGLIB 动态代理,保证配置类中的 Bean 是受 IOC容器控制的,是单例的,如果配置类中重复的用某一个类,不加的话就是是重复调用方法,多次创建,不受 IOC 容器控制。
重复 beanName 覆盖原则,如果是通过 Scanner 扫描到的同一包下两个相同的 beanName 会抛异常,如果一个是 @Compontent 扫描的 bean,一个是通过 @Bean 配置的 bean,那么 @Bean 配置的 bean 会覆盖前面的 bean,因为它是后创建的。
网友评论