Spring源码1——容器创建流程

本文详细介绍了Spring容器启动的过程,从无参构造、注册BeanDefinition到容器,再到容器的刷新步骤,包括BeanFactory的预处理、后置处理器的执行、BeanPostProcessor的注册和初始化。文章通过示例代码展示了Bean的初始化和销毁方法,以及测试过程中容器的构建步骤。
摘要由CSDN通过智能技术生成

Spring源码学习1——容器启动流程

总结:
第一步、调用无参构造

  • 调用父类午餐构造,初始化BeanFactrory
  • 实例化BeanDefinitionReader读取器
  • 实例化一个ClassPathBeanDefinitionScanner扫包器

第二步、注册BeanDefinition到容器

  • 根据Conditional注解决定是否跳过此步
  • 对通用注解做一些处理
  • 封装一个BeanDefinitionHolder
  • 处理scopeProxyMode,根据@Scope注解决定代理为单例【默认】还是原型【TARGET_CLASS】
  • 注册BeanDefinitionHolder到registry

第三步、刷新容器:

  • 3.1刷新预处理方法:,暂时空的,可以自行继承实现。用于处理属性和校验属性、添加事件等。【prepareRefresh()】
  • 3.2获取Bean工厂【obtainBeanFactory】
    • 刷新工厂,给他生成一个序列化id【refreshBeanFactory】
    • 返回工厂【getBeanFactory】
  • 3.3.BeanFactory的预处理工作。【prepareBeanFactory】
    • 设置类加载器、表达解析器等,设置ApplicationContextAwarePostProcessor
    • 设置需要忽略装配、需要全局可装配的
    • 添加ApplicationLitensnerDetector, 添加AspectJ支持, 给工厂设置enviroment
  • 3.4.初始化BeanFactory,调用后置处理postProcessBeanFactory【暂时空的】
  • 3.5.执行BeanFactory初始化后置处理器。【invokeBeanFactoryPostProcessors
    • 注意两个接口:BeanFactoryPostProcessor、BeanDefinitionRegisterPostProcessor。一个执行依次针对整容器的Bean,一个针对每个Bean执行多次
    • 先执行BeanDefinitionRegisterPostProcessor,后执行BeanFactoryPostProcessor,他们的执行步骤为:
      • 先排序并执行实现了PriorityOrdered的后置处理器
      • 排序并执行实现@Ordered接口的后置处理器
      • 执行没有实现二者的后置处理器
  • 3.6.注册Bean的后置处理器【registerBeanPostProcessors】,注意多种,MergedBeanDefinitionPostProcessor 特殊处理。
    • 先排序并执行实现了PriorityOrdered接口的BeanPostProcessor
    • 在排序并执行实现了Ordered接口的BeanPostProcessor
    • 最后执行没有实现优先级和顺序接口的BeanPostProcessor
    • 注册internalPostProcessors中的BeanPostProcessor,即MergedBeanDefinitionPostProcessor 。
    • 添加探查后置处理器,用于检查是不是监听器,是的话添加到容器
  • 3.7初始化MessageSource组件【initMessageSource】
  • 3.8初始化事件派发器【initApplicationEventMulticaster】
  • 3.9.刷新容器,留给子容器。【onRefresh】
  • 3.10.注册所有配置的监听器【registerListeners】
  • 3.11.初始化剩余的非抽象、单实例、非懒加载Bean
    • 先尝试从map获取,获取不到,开始创建bean流程【重点,后面单独分析】
  • 3.12.扫尾工作,如清除缓存、发布容器刷新事件等【finishRefresh】

零、编写测试代码

  • bean
@Data
@AllArgsConstructor
public class Book {
    private String name;
    private double price;

    public void init(){
        System.out.println("bean初始化");
    }
    public void destroy(){
        System.out.println("bean销毁");
    }
}
  • 配置类注册
@Configuration
@ComponentScan({"org.example"})
public class SpringConfig {
    @Bean(initMethod = "init",destroyMethod = "destroy")
    public Book book(){
        return new Book("挪威的森林",100.0);
    }
}
  • BeanPostProcessor回调
@Component
public class myProcessor implements BeanPostProcessor {
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("BeanPostProcessor初始化前置执行");
        return bean;
    }

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("BeanPostProcessor初始化后置执行");
        return bean;
    }
}
  • 测试
public class App {
    public static void main( String[] args ){
        AnnotationConfigApplicationContext context = 
            new AnnotationConfigApplicationContext(SpringConfig.class);
        Book book = context.getBean(Book.class);
        System.out.println(book.toString());
        context.close();
    }
}

在new容器哪里打上断点:
在这里插入图片描述

一、进入new容器

在这里插入图片描述

  • 第一步调用无参构造
  • 注册到容器中
  • 刷新容器

1.无参构造:实例化BeanFac、实例化BeanDefinitionReader读取器、实例化ClassPathBeanDefinitionScanner扫包器

  • 先执行父类初始化方法:实例化一个BeanFactory
  • 实例化BeanDefinitionReader读取器【this.reader = new AnnotatedBeanDefinitionReader(this);】
    • 添加两个BeanFactory后置处理器:【ConfigurationClassPostProcessor】、【EventListenerMethodProcessor】
    • 添加两个Bean后置处理器:【AutowiredAnnotationBeanPostProcessor】、【CommonAnnotationBeanPostProcessor】
    • 向容器添加普通组件:【DefaultEventListenerFactory】
  • 实例化一个ClassPathBeanDefinitionScanner扫包器【this.scanner = new ClassPathBeanDefinitionScanner(this);】

在这里插入图片描述

1.1调用父类无参构造初始化BeanFactory:

在这里插入图片描述

1.2.初始化BeanDefinitionReader读取器:new AnnotatedBeanDefinitionReader

在这里插入图片描述

1.3实例化ClassPathBeanDefinitionScanner扫包器:new ClassPathBeanDefinitionScanner

在这里插入图片描述

2.注册的BeanDefinition到容器

扫描并解析配置类生成BeanDefinition,注册到容器。

  • 根据@Conditional决定是否跳过
  • 处理类上的注解
  • 封装一个BeanDefinitionHolder
  • 处理scopeProxyMode,根据@Scope注解创建单例代理【默认】/原型代理【TARGET_CLASS】。
  • 将BeanDefinitionHolder注册到regisy
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

Befinition大致长这样:
后面还有不想截了。

3.刷新容器(重点)

在这里插入图片描述

3.1.刷新预处理方法:prepareRefresh();——暂时空的,可以子类重写对之做个性化处理

查看刷新预处理方法:

在这里插入图片描述

3.1.1.属性设置:initPropertySources();

set和日志处理不用管,查看第一个方法,作用大概是初始化一些属性设置:
在这里插入图片描述
居然是空的,这里实际是留给子类做一些事情的,如自己可以写一个子类,重写此方法,做一些个性化属性处理。

3.1.2.属性校验:getEnvironment().validateRequiredProperties();

因为这里没有自定义属性,自然也不会去校验,所以这里就不看了

3.1.3.事件创建:earlyApplicationEvents = new LinkedHashSet();

保存一些事件。

3.2.获取Bean工厂:this.obtainFreshBeanFactory();

在这里插入图片描述
在这里插入图片描述
发现1刷新工厂,2获取工厂

3.2.1.刷新工厂refreshBeanFactory

进入刷新工厂方法refreshBeanFactory,设置一个序列化id。
在这里插入图片描述
综述,此步骤作用:创建工程对象,给工厂设置一个序列化id。

3.2.2.获取bean工厂:getBeanFactory

进入进入GenericApplicationContext类
在这里插入图片描述

3.3.beanFactory的预准备工作:prepareBeanFactory
  • 设置类加载器、表达式解析器等等
  • 设置AppContextAwareBeanPostProcessor
  • 设置忽略自动装配的接口
  • 设置可以在任一组件注入的接口,如:容器、资源加载器、事件发布器
  • 添加ApplicationLitensnerDetector
  • 添加AspectJ支持
  • 给工厂设置enviroment
    在这里插入图片描述
3.4.BeanFactory后置处理:this.postProcessBeanFactory(beanFactory);——暂时空的,执行到这里bf标准初始化已完成

在这里插入图片描述
进入发现:
在这里插入图片描述
空的,可以写IOC容器的子类重写该方法,对工厂做一个后置处理。
BeanFactory标准初始化已完成

3.5.执行beanFactory的后置处理器:invokeBeanFactoryPostProcessors

在这里插入图片描述
**注意两个接口:**BeanFactoryPostProcessor,BeanDefinitionRegistryPostProcessor。二者用于在容器加载Bean后,实例化之前对Bean的进行修改或(修改元数据或添加逻辑),但是前者是对整个BeanFactory,仅执行一次;后者对每个Bean,每个Bean一次。

在这里插入图片描述
点进去第一个invoke:

  • 先找到所有的BeanDefinitionRegisterPostProcessor
    • 先排序并执行实现了PriorityOrdered接口的BeanDefinitionRegisterPostProcessor
    • 在排序并执行实现了Ordered接口的BeanDefinitionRegisterPostProcessor
    • 最后执行没有实现优先级和顺序接口的BeanDefinitionRegisterPostProcessor
  • 找到所有BeanFactoryPostProcessor
    • 先排序并执行实现了PriorityOrdered接口的BeanFactoryPostProcessor
    • 在排序并执行实现了Ordered接口的BeanFactoryPostProcessor
    • 最后执行没有实现优先级和顺序接口的BeanFactoryPostProcessor
      在这里插入图片描述
3.6.执行Bean的后置处理器:registerBeanPostProcessors

在这里插入图片描述
注意有多种BeanPostProcessor,:
BeanPostProcessor:初始化前后对bean进行处理
DestructionAwareBeanPostProcessor:销毁前后对bean进行处理
InstantiationAwareBeanPostProcessor:实例化前后进行处理
SmartInstantiationAwareBeanPostProcessor:对实例化过程进行干预,预测Bean实际类型,提前暴露实例以解决循环依赖。
MergedBeanDefinitionPostProcessor :BeanDefinition合并后,bean实例化前,对合并的BeanDefinition处理。注意这个会存放到internalPostProcessors。
不同类型的执行时机是不一样的:

  • 先找到所有的BeanPostProcessor
    • 先排序并执行实现了PriorityOrdered接口的BeanPostProcessor
    • 在排序并执行实现了Ordered接口的BeanPostProcessor
    • 最后执行没有实现优先级和顺序接口的BeanPostProcessor
    • 注册internalPostProcessors中的BeanPostProcessor,即MergedBeanDefinitionPostProcessor 。
    • 添加探查后置处理器,用于检查是不是监听器,是的话添加到容器
      在这里插入图片描述
      点进去看新注册的后置处理器,观察其作用。
      在这里插入图片描述
3.7.初始化MessageSource组件:this.initMessageSource();

获取BeanFactory,查看有无MesageSource组件,有则赋值,无则new一个默认的DelegatingMessageSource并注册到容器。
负责国际化,消息绑定,消息解析。
在这里插入图片描述

3.8.初始化事件派发器:this.initApplicationEventMulticaster();
  • 获取BeanFactory工厂
  • 获取自己配置的事件派发器:applicationEventMulticaster
  • 如果没有配置,new一个默认的SimpleApplicationEventMulticaster,并单例地注册到BeanFactory
    在这里插入图片描述
3.9.容器刷新方法,留给子容器:this.onRefresh();

空的,子类重写该方法,在容器刷新地时候可以自定义逻辑。
在这里插入图片描述

3.10.注册所有配置地监听器:this.registerListeners();

1.获取所有直接注册的事件监听器:之前步骤通过getApplicationListeners加入的,并放入事件派发器
2.获取所有以Bean方式注册的事件监听器
3.迭代,放入时间派发器
4.派发早期事件:
在这里插入图片描述

3.11.初始化剩余单实例:this.finishBeanFactoryInitialization(beanFactory);
  • 获取所有的BD信息,依次实例化
  • 如果不是FactoryBean且非抽象单实例非懒加载
    • 调用getBean初始化,会去调用doGetBean方法。
    • 调用doGetBean,尝试从缓存中获取已经创建的。
    • 获取不到
      • 标记Bean为已创建
      • 先获取依赖的Bean,先创建依赖的Bean
      • 若当前Bean是单例的,启动单例创建流程:【createBean(beanName, mbd, args)】
        • 让InstationAwareBeanPostProcessor拦截返回代理对象【resolveBeforeInstantiation】
        • 如果没有返回代理对象,开始创建Bean:【doCreateBean
          • 利用工厂方法/构造器等通过反射机制创建实例【createBeanInstance】
          • 调用MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition
          • 为属性赋值,【populateBean(beanName, mbd, instanceWrapper);】
            • 先达到InstantiationAwareBeanPostProcessor执行postProcessAfterInstantiation
            • 再拿到InstantiationAwareBeanPostProcessors执行postProcessProperties
            • 注入属性,通过setter等方法通过反射赋值
          • 初始化Bean,【initializeBean】
            • 执行各种Aware方法,包括BeanNameAware、BeanFactoryAware、BeanClassLoaderAware【invokeAwareMethods】
            • 初始化Bean,【invokeInitMethods】
              • 执行BeanPostProcessor的初始化前置方法【applyBeanPostProcessorsBeforeInitialization】
              • 初始化Bean,会调用初始化回调【this.invokeInitMethods】
              • 执行BeanPostProcessor的初始化后置方法【applyBeanPostProcessorsAfterInitialization】
          • 注册销毁Bean的销毁回调方法【registerDisposableBeanIfNecessary】

点入refresh的11步骤:
在这里插入图片描述
点入:
在这里插入图片描述
查看getBean:

在这里插入图片描述

3.12:发布BeanFactory容器刷新完成事件:finishRefresh()

会在这里进行一些扫尾工作,如清理缓存,初始化生命周期处理器,发布容器刷新事件等。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值