【Spring注解】Spring容器创建 refresh()源码解析

当我们执行这一句就是容器创建的过程

AnnotationConfigApplicationContext applicationContext= new AnnotationConfigApplicationContext(ExtConfig.class);

AnnotationConfigApplicationContext
在这里插入图片描述
我们通过refresh() 方法来看

BeanFactory预准备

refresh()的前几个方法我们可以看成是BeanFactory预准备阶段:

  • prepareRefresh()
  • obtainFreshBeanFactory()
  • prepareBeanFactory(beanFactory)
  • postProcessBeanFactory(beanFactory)

prepareRefresh()

prepareRefresh():prepare this context for refreshing 刷新前的预处理
在这里插入图片描述

  • initPropertySources() 初始化一些属性设置
    默认是空的,留给子类自定义个性化的设置
    在这里插入图片描述

  • validateRequiredProperties() 属性校验
    在这里插入图片描述

  • earlyApplicationListeners
    在这里插入图片描述

obtainFreshBeanFactory()

obtainFreshBeanFactory() :

//Tell the subclass to refresh the internal bean Factory 
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();

这一步是用来获取设置了序列化标识后的BeanFactory
在这里插入图片描述

  • this.refreshBeanFactory()
    调用GenericApplicationContext的refreshBeanFactory() 方法
    在这里插入图片描述
  • this.getBeanFactory()
    返回设置了序列标识后的beanFactory
    在这里插入图片描述

prepareBeanFactory(beanFactory)

对beanFactory做一些设置

//Prepare the bean factory for use in this context
this.prepareBeanFactory(beanFactory);
  • 告诉internal bean factory 去用容器的class Loader 等
    在这里插入图片描述

  • Configure the bean factory with context call backs

    • 添加部分BeanPostProcessor【ApplicationContextAwareProcessor】
      beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
      
    • 设置忽略的自动装配的接口
      这样这些接口的实现类不能通过接口类型来自动注入
      在这里插入图片描述
    • 注册可以解析的自动装配
      这样我们就能直接在任何组件中自动注入
      BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext在这里插入图片描述
    • 添加部分BeanPostProcessor【ApplicationListenerDetector】
      beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
      
    • 添加编译时AspectJ
      在这里插入图片描述
    • 给beanFactory中注册默认的环境beans
      在这里插入图片描述

postProcessBeanFactory(beanFactory)

BeanFactory准备工作完成后进行的后置处理工作

//Allows post-processing of the bean factory in context subclasses
this.postProcessBeanFactory(beanFactory);

postProcessBeanFactory:
默认是空的,子类通过重写这个方法来在BeanFactory创建并预准备完成以后做进一步的设置
在这里插入图片描述

invokeBeanFactoryPostProcessors

前面也总结过
执行BeanFactoryPostProcessors

// invoke factory processors registered as beans in the context
this.invokeBeanFactoryPostProcessors(beanFactory);

BeanFactoryPostProcessor: 是BeanFactory的后置处理器,他是在BeanFactory标准初始化之后执行的 也就是我们上面的准备工作

这里invokeBeanFactoryPostProcessors主要就是执行了
BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry 方法和postProcessBeanFactory方法

以及BeanFactoryPostProcessors的postProcessBeanFactory方法

BeanDefinitionRegistryPostProcessor

  • 判断beanFactory是不是BeanDefinitionRegistry,是执行下面的

    // 1. 如果beanFactory实现了BeanDefinitionRegistry接口,则表示可以通过BeanDefinitionRegistryPostProcessor接口来注册BeanDefinition
    // 2. 因为现在是Spring启动过程中的比较早的阶段(还没有开始扫描@Component),所以只能获取Spring默认添加到BeanFactory中的bean工厂后置处理器,以及程序员手动添加的bean工厂后置处理器
    // 3. 执行的顺序是,先执行BeanDefinitionRegistryPostProcessor中的postProcessBeanDefinitionRegistry方法,因为这个方法可以注册BeanDefinition
    //这里说的有问题
    // 4. 先执行手动添加进行来的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法,这个过程中可能会向BeanFactory中注册其他的BeanDefinitionRegistryPostProcessor
    // 5. 从BeanFactory中获取PriorityOrdered接口的BeanDefinitionRegistryPostProcessor,并执行postProcessBeanDefinitionRegistry方法
    // 6. 从BeanFactory中获取Ordered接口的BeanDefinitionRegistryPostProcessor,并执行postProcessBeanDefinitionRegistry方法
    // 7. 在5,6步中都有可能注册新的BeanDefinitionRegistryPostProcessor的
    // 8. 从BeanFactory中获取普通的BeanDefinitionRegistryPostProcessor,并执行postProcessBeanDefinitionRegistry方法
    // 9. 在8步中也有可能注册新的BeanDefinitionRegistryPostProcessor,所以第8步会递归,直到没有新的BeanDefinitionRegistryPostProcessor注册进来了
    // 10. 在前面的步骤中都是执行BeanDefinitionRegistryPostProcessor中的postProcessBeanDefinitionRegistry方法,进行BeanDefinition的注册
    // 11. BeanDefinition注册完了之后,因为BeanDefinitionRegistryPostProcessor本身也是一个BeanFactoryProcessor,所以最后再执行postProcessBeanFactory方法
    
    • 根据优先级,分别执行BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry 方法
      可以发现这里每次都执行了beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);,这是因为 我们每次执行可能会加载进来BeanDefinition,所以每次都要重新获取
      • 执行实现了PriorityOrdered的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry 方法
        在这里插入图片描述

        • 获取所有BeanDefinitionRegistryPostProcessor类型的
           postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
          
          默认拿到的是ConfigurationClassPostProcessor
          第一次获取其实只能获取到ConfigurationClassPostProcessor,因为我们手工加的只是BeanDefinition,等internalConfigurationAnnotationProcessor把对应的Definition加载后 下面才能获取到我们手工加载的
          ConfigurationClassPostProcessor 做的工作
          • 解析AppConfig类,生成对应的ConfigurationClass
          • 再扫描,扫描到的类都会生成对应的BeanDefinition,并且同时这些类也是ConfigurationClass
          • 再解析ConfigurationClass的其他信息,比如@ImportResource注解的处理,@Import注解的处理,@Bean注解的处理
        • 执行postProcessBeanDefinitionRegistry方法
          在这里插入图片描述
      • 执行实现了Ordered的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry 方法
        在这里插入图片描述

      • 执行没有实现任何优先级或者是顺序接口的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry 方法
        在这里插入图片描述

    • 执行BeanDefinitionRegistryPostProcessor的postProcessBeanFactory 方法
      因为BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子接口,因此也要调BeanFactoryPostProcessor的postProcessBeanFactory 方法
      在这里插入图片描述
  • 不是则直接执行invokeBeanFactoryPostProcessors

    invokeBeanFactoryPostProcessors((Collection)beanFactoryPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
    

BeanFactoryPostProcessor

  • 执行BeanFactoryPostProcessor部分
    • 获取所有BeanFactoryPostProcessor

      String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
      
    • 按是否实现了PriorityOrdered、Ordered、和未实现 进行分类
      注意这里的if (!processedBeans.contains(ppName)) 就会把之前的BeanDefinitionRegistryPostProcessor的排除 就不会再执行一遍了在这里插入图片描述

    • 按顺序执行BeanFactoryPostProcessors对应的postProcessBeanFactory方法
      在这里插入图片描述

registerBeanPostProcessors

详细过程的ioc容器创建部分 已经有完整的debug过程
注册BeanPostProcessors,拦截bean的创建过程

// Register bean processors that intercept bean creation
this.registerBeanPostProcessors(beanFactory);

registerBeanPostProcessors会调用PostProcessorRegistrationDelegate类的registerBeanPostProcessors
在这里插入图片描述

  • 获取所有BeanPostProcessor的名字

    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
    

    通过看BeanPostProcessor的子接口 可以看到,这些不同接口类型的BeanPostProcessor,的执行时机是不一样的
    在这里插入图片描述

  • 根据是否实现了PriorityOrdered、Ordered、MergedBeanDefinitionPostProcessor、没实现的给BeanPostProcess分类注册

    • 按分好类的优先级顺序 来注册PostProcessor
      • 其中会通过getBean 来创建PostProcessor对象
         pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
        
      • 通过registerBeanPostProcessors保存到beanFactory中
        registerBeanPostProcessors(beanFactory, (List)priorityOrderedPostProcessors);
        

initMessageSource()

初始化MessageSource组件,做国际化功能、消息绑定、消息解析等功能

//Initialize message source for this context
this.initMessageSource();

在这里插入图片描述

  • 获取BeanFactory
    ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
    
  • 看容器中是否有id为messageSource的对象
    • 有则赋值给this.messageSource
      this.messageSource = (MessageSource)beanFactory.getBean("messageSource", MessageSource.class);
      
    • 没有就创建 ,并把创建好的messageSource注册在容器中
      DelegatingMessageSource dms = new DelegatingMessageSource();
      beanFactory.registerSingleton("messageSource", this.messageSource);//注册到容器中
      
      注册在容器中,以后获取国际化配置文件的值的时候,就可以自动注入MessageSource,然后通过getMessage方法获取配置文件中某个key的值(并且能按照区域信息locale获取)

initApplicationEventMulticaster()

初始化事件派发器

//Initialize event multicaster for this context
initApplicationEventMulticaster()

initApplicationEventMulticaster() 方法:

  • 先去容器中找id=“applicationEventMulticaster”的
  • 容器中没有就创建SimpleApplicationEventMulticaster
  • 将创建好的加入到beanFactory
    在这里插入图片描述

onRefresh()

// Initialize other special beans in specific context subclasses
this.onRefresh();

留给子容器,子类重写这个方法,在容器刷新的时候就可以自定义逻辑
在这里插入图片描述

registerListeners()

将容器中的ApplicationListener注册近年来

//Check for listener beans and register them.
this.registerListeners();

在这里插入图片描述

finishBeanFactoryInitialization

实例化所有剩下的单实例bean

//Instantiate all remaining(non-lazy-init) singletons
this.finishBeanFactoryInitialization(beanFactory);

finishBeanFactoryInitialization中调用beanFactory.preInstantiateSingletons();实例化剩余的单实例
在这里插入图片描述
preInstantiateSingletons方法的流程:

  • 获取容器中所有的beanName
    List<String> beanNames = new ArrayList(this.beanDefinitionNames);
    
  • 获取bean的定义信息RootBeanDefinition
    RootBeanDefinition bd = this.getMergedLocalBeanDefinition(beanName);
    
  • 根据bd判断 bean 是否是抽象的、单实例的、懒加载的
    • 是抽象,不是单实例,是懒加载的
      在这里插入图片描述

    • 不是抽象,是单实例,不是懒加载的
      在这里插入图片描述

      • 是FactoryBean
        是FactoryBean的判断逻辑就是判断是不是FactoryBean类
        在这里插入图片描述

      • 不是FactoryBean
        通过getBean创建对象

        this.getBean(beanName);
        
  • 所有bean 创建完成后,判断每个bean是不是实现了SmartInitializingSingleton接口
    如果是SmartInitializingSingleton接口的,则执行afterSingletonsInstantiated方法
    这里完成的是标了@EventListener注解的监听器的部分在这里插入图片描述

getBean()

其中getBean() 如下:
调用doGetBean
在这里插入图片描述
doGetBean:

  • isPrototypeCurrentlyInCreation 判断是原型创建吗

    if (this.isPrototypeCurrentlyInCreation(beanName)) {
    	throw new BeanCurrentlyInCreationException(beanName);
     }
    
  • 找父工厂
    在这里插入图片描述

  • 标记当前bean已经被创建

    	  if (!typeCheckOnly) {
                this.markBeanAsCreated(beanName);
            }
    
  • 获取bean的定义信息

    		RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
            this.checkMergedBeanDefinition(mbd, beanName, args);
    
  • 获取当前Bean依赖的其他Bean
    按照getBean把依赖的那些Bean先创建出来
    在这里插入图片描述

  • 获取缓存中保存的单实例bean
    如果获取到了说明这个bean之前被创建过

     Object sharedInstance = this.getSingleton(beanName);
    

    是从singletonObjects中拿

    Object singletonObject = this.singletonObjects.get(beanName);
    

    singletonObjects是map,用来存放单实例objects:bean name–>bean instance

    private final Map<String, Object> singletonObjects = new ConcurrentHashMap(256);
    
  • 缓存中没有拿到,则开始bean的创建过程

     return this.createBean(beanName, mbd, args);
    
    • 创建bean实例

      • 通过createBean创建对象,具体流程在下面在这里插入图片描述
      • 创建好bean后,通过addSingleton 将创建好的对象添加到singletonObjects中
                 if (newSingleton) {
                    this.addSingleton(beanName, singletonObject);
                }
        
        addSingleton代码如下: 在这里插入图片描述
        所以其实ioc容器就是这些Map,这些Map里保存了单实例Bean,环境信息等等

createBean()

  • resolveBeforeInstantiation()给BeanPostProcessors 一个机会提前返回一个代理对象
    这个主要是为了解决依赖注入问题

    //Give BeanPostProcessors a chance to return a proxy instead of the target 
    beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
    if (beanInstance != null) {
        	return beanInstance;
    }
    

    用的是InstantiationAwareBeanPostProcessors这个类型的后置处理器
    在这里插入图片描述

    • 调每一个InstantiationAwareBeanPostProcessors的postProcessBeforeInstantiation方法
      在这里插入图片描述

    • 如果真的创建了bean,则调用applyBeanPostProcessorsAfterInitialization
      这个是BeanPostProcessors的初始化后方法

  • doCreateBean 创建对象
    上一步没有用代理创建对象后,就会调doCreateBean来创建

    beanInstance = this.doCreateBean(beanName, mbdToUse, args);
    
    • createBeanInstance创建bean实例

      instanceWrapper = this.createBeanInstance(beanName, mbd, args);
      

      利用工厂方法或对象的构造器创建出Bean实例,这个里面具体的流程没太看懂。

    • applyMergedBeanDefinitionPostProcessors

      this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
      

      得到所有的后置处理器,如果是MergedBeanDefinitionPostProcessor类型的就调用其postProcessMergedBeanDefinition方法
      在这里插入图片描述

    • cache singletons 这里是解决循环依赖的?

      在这里插入图片描述

    • bean属性赋值 populateBean

      this.populateBean(beanName, mbd, instanceWrapper);
      
      • 调所有InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation方法
        属性被赋值之前给每一个InstantiationAwareBeanPostProcessor机会去修改bean的状态
        可以用在support styles of field injection在这里插入图片描述

      • xml配置的属性填充

        • 利用这个迭代器存储,无论是autowireByName() 还是autowireByType() 都会存到里面 并没有完成反射赋值
          在这里插入图片描述
      • InstantiationAwareBeanPostProcessor的postProcessPropertyValues方法
        分别解析@Autowired、@Resource、@Value,得到属性值在这里插入图片描述

      • applyPropertyValues 给属性赋值
        这里才是为属性利用setter方法等进行赋值

              this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs);
        
    • initializeBean

      	exposedObject = this.initializeBean(beanName, exposedObject, mbd);
      
      • 执行xxxAware接口的方法

        this.invokeAwareMethods(beanName, bean);
        

        如果实现了BeanNameAware、BeanClassLoaderAware、BeanFactoryAware,则回调对应的方法在这里插入图片描述

      • 执行后置处理器初始化之前方法 applyBeanPostProcessorsBeforeInitialization
        执行所有后置处理器即BeanPostProcessor的postProcessBeforeInitialization方法在这里插入图片描述

      • 执行初始化方法invokeInitMethods

        this.invokeInitMethods(beanName, wrappedBean, mbd);
        

        由于有不同的初始化方式,所以会按下面几种情况进行初始化

        • 实现了InitializingBean接口
          调用这个接口的afterPropertiesSet方法进行初始化在这里插入图片描述

        • 自定义初始化方法
          在这里插入图片描述

      • 执行后置处理器初始化之后方法applyBeanPostProcessorsAfterInitialization

        wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        

        执行所有后置处理器的postProcessAfterInitialization方法在这里插入图片描述

    • getSingleton获取 没有
      在这里插入图片描述

    • 注册bean的销毁方法 registerDisposableBeanIfNecessary

      	 this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
      

      注意这里只是注册,而不是调用!

finishRefresh()

在这里插入图片描述

最后一步是发布相应的事件,就完成了IOC容器的创建

//Last step: publish corresponding event
this.finishRefresh();
  • 清缓存

    this.clearResourceCaches();
    
  • 初始化和生命周期有关的后置处理器

    //Initialize lifecycle processor for this context
     this.initLifecycleProcessor();
    

    initLifecycleProcessor:
    有我们自己定义的LifecycleProcessor的实现类就直接获取,没有再创建。
    这个LifecycleProcessor是监听BeanFactory生命周期的处理器在这里插入图片描述

    LifecycleProcessor类:
    在这里插入图片描述
    通过LifecycleProcessor的两个方法我们就可以定义

    • onRefresh方法
      Notification of context refresh。 可以用来做auto-starting components
    • onClose方法
      Notification of context close phase。 可以用来做auto-stopping components
  • 回调生命周期处理器的onRefresh方法

    //Propagate refresh to lifecycle processor first
    this.getLifecycleProcessor().onRefresh();
    
  • 发布容器刷新完成事件

    //publish the final event
    this.publishEvent((ApplicationEvent)(new ContextRefreshedEvent(this)));
    
  • 最后

    //Participate in LiveBeansView MBean,if active
    LiveBeansView.registerApplicationContext(this);
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值