• Spring注解开发_Spring容器创建概述


    浅尝Spring注解开发_Spring容器创建概述

    浅尝Spring注解开发,基于Spring 4.3.12
    概述Spring容器创建的过程,包括12个方法的执行

    浅尝Spring注解开发_自定义注册组件、属性赋值、自动装配
    浅尝Spring注解开发_Bean生命周期及执行过程
    浅尝Spring注解开发_AOP原理及完整过程分析(源码)
    浅尝Spring注解开发_声明式事务及原理
    浅尝Spring注解开发_简单理解BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor、ApplicationListener
    Spring注解开发_Spring容器创建概述
    浅尝Spring注解开发_Servlet3.0与SpringMVC

    概述12个方法

    java
    	//获取ioc容器
    	AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfPropertyValues.class);
    java
    	/**
    	 * 创建一个新的AnnotationConfigApplicationContext,派生bean定义
    	 * 从给定的带注释的类,并自动刷新上下文。
    	 * @param 类一个或多个带注释的类
    	 * e.g. {@link Configuration @Configuration} classes
    	 */
    	public AnnotationConfigApplicationContext(Class... annotatedClasses) {
    		this();
    		register(annotatedClasses);
    		refresh();
    	}
    java
    	@Override
    	public void refresh() throws BeansException, IllegalStateException {
    		synchronized (this.startupShutdownMonitor) {
    			// 为刷新准备此上下文。
    			prepareRefresh();
    
    			// 告诉子类刷新内部bean工厂。
    			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    
    			// 准备在此上下文中使用bean工厂。
    			prepareBeanFactory(beanFactory);
    
    			try {
    				// 允许在上下文子类中对bean工厂进行后处理。
    				postProcessBeanFactory(beanFactory);
    
    				// 调用在上下文中注册为bean的工厂处理器。
    				invokeBeanFactoryPostProcessors(beanFactory);
    
    				// 注册拦截bean创建的bean处理器。
    				registerBeanPostProcessors(beanFactory);
    
    				// 初始化此上下文的消息源。
    				initMessageSource();
    
    				// 为此上下文初始化事件多播。
    				initApplicationEventMulticaster();
    
    				// 在特定的上下文子类中初始化其他特殊bean。
    				onRefresh();
    
    				// 检查监听器bean并注册它们。
    				registerListeners();
    
    				// 实例化所有剩余的(非lazy-init)单例。
    				finishBeanFactoryInitialization(beanFactory);
    
    				// 最后一步:发布相应的事件。
    				finishRefresh();
    			}
            	//...

    BeanFactory预处理

    BeanFactory的创建及预准备工作

    • BeanFactory 的作用是负责 bean 的创建、依赖注入和初始化,bean 的各项特征由 BeanDefinition 定义
    • BeanDefinition 作为 bean 的设计蓝图,规定了 bean 的特征,如单例多例、依赖关系、初始销毁方法等
    • BeanDefinition 的来源有多种多样,可以是通过 xml 获得、配置类获得、组件扫描获得,也可以是编程添加
    • 所有的 BeanDefinition 会存入 BeanFactory 中的 beanDefinitionMap 集合

    1、this()

    1. 先调用父类构造器
    2. 声明两个类,通过读取注解或者扫描类路径读取BeanDefinition
    3. 初始化了DefaultListableBeanFactory:基于bean定义元数据的成熟bean工厂,可通过后处理器进行扩展,内部定义了 BeanDefinitionMap属性名beanDefinitionMap,可以操作bean
    4. 注册了多个(6个)默认的后置处理器

    2、register(annotatedClasses)

    1. 校验传入的 JavaConfig.class配置类的注解(是否需要忽略)
    2. 处理通用注解
    3. 封装为BeanDefinitionHolder后,注册到容器中
    4. 相当于将JavaConfig配置类作为一个Bean注册到容器中

    3、Spring容器的refresh():创建刷新

    1. prepareRefresh():刷新前的预处理
      1. initPropertySources()[初始化属性源]:初始化一些属性设置,空方法,留给子类自定义个性化的属性设置方法
      2. getEnvironment().validateRequiredProperties():检验属性的合法等
      3. earlyApplicationEvents = new LinkedHashSet():保存容器中的一些早期的事件,一旦多播机可用就会发布
    2. obtainFreshBeanFactory()(//告诉子类刷新内部Bean工厂):获取新鲜的BeanFactory
      1. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory()类注释://大多数可列出的bean工厂要实现的配置接口。 除了 {@link ConfigurableBeanFactory} 之外,它还提供了以下工具: 分析和修改 bean 定义,并预实例化单例。
      2. refreshBeanFactory():刷新[创建]BeanFactory
        1. 创建了一个this.beanFactory = new DefaultListableBeanFactory()补充:这个方法在创建AnnotationConfigApplicationContext的父类GenericApplicationContext的无参构造时调用了,注释是//创建一个新的 GenericApplicationContext
        2. 设置id
      3. getBeanFactory():返回刚才GenericApplicationContext创建的BeanFactory对象
      4. 将创建的BeanFactory[类型:DefaultListableBeanFactory]返回
    3. prepareBeanFactory(beanFactory)BeanFactory的预准备工作(BeanFactory进行一些设置)
      1. 设置BeanFactory的类加载器、支持表达式解析器...
      2. 添加部分BeanPostProcessor[类型:ApplicationContextAwareProcessor]
      3. 设置忽略的自动装配的接口EnvironmentAwareEmbeddedValueResolverAwarexxx...
      4. 注册可以解析的自动装配;我们能直接在任何组件中自动注入:BeanFactoryResourceLoaderApplicationEventPublisherApplicationContext...
      5. 添加BeanPostProcessor[类型:ApplicationListenerDetector],将用于检测内部 bean 的早期后处理器注册为 ApplicationListener
      6. 添加编译时的AspectJ
      7. BeanFactory中注册一些能用的组件;
        1. ConfigurableEnvironment environmentapplication上下文环境
        2. Map systemProperties:系统属性
        3. Map systemEnvironment:系统环境变量
    4. postProcessBeanFactory(beanFactory)BeanFactory准备工作完成后进行的后置处理工作
      1. 子类通过重写这个方法来在BeanFactory创建并预准备完成以后做进一步的设置

    执行BeanFactoryPostProcessor

    BeanFactoryPostProcessor是beanFactory的后置处理器

    • BeanFactoryPostProcessor是beanFactory的后置处理器,在BeanFactory标准初始化之后调用,来定制和修改BeanFactory的内容,所有的bean定义已经保存加载到beanFactory,但是bean的实例还未创建

    • 执行BeanFactoryPostProcessor分两步,先执行BeanDefinitionRegistryPostProcessor,后执行BeanFactoryPostProcessor

    1. invokeBeanFactoryPostProcessors(beanFactory):执行BeanFactoryPostProcessor的方法。BeanFactoryPostProcessorBeanFactory的后置处理器。在BeanFactory标准初始化(以上4步)之后执行的,两个接口:BeanFactoryPostProcessorBeanDefinitionRegistryPostProcessor

      1. 执行BeanFactoryPostProcessor的方法

        • 先执行BeanDefinitionRegistryPostProcessor

          1. 获取所有的BeanDefinitionRegistryPostProcessor

          2. 看先执行实现了PriorityOrdered优先级接口的BeanDefinitionRegistryPostProcessor

            postProcessor.postProcessBeanDefinitionRegistry(registry)

          3. 再执行实现了Ordered顺序接口的BeanDefinitionRegistryPostProcessor

            postProcessor.postProcessBeanDefinitionRegistry(registry)

          4. 最后执行没有实现任何优先级或者是顺序接口的BeanDefinitionRegistryPostProcessors

            postProcessor.postProcessBeanDefinitionRegistry(registry)

        • 再执行BeanFactoryPostProcessor的方法

          1. 获取所有的BeanFactoryPostProcessor

          2. 看先执行实现了PriorityOrdered优先级接口的BeanFactoryPostProcessor

            postProcessor.postProcessBeanFactory()

          3. 再执行实现了Ordered顺序接口的BeanFactoryPostProcessor

            postProcessor.postProcessBeanFactory()

          4. 最后执行没有实现任何优先级或者是顺序接口的BeanFactoryPostProcessor

            postProcessor.postProcessBeanFactory()

    注册BeanPostProcessor

    按照优先级注册后置处理器,不执行

    1. registerBeanPostProcessors(beanFactory):注册BeanPostProcessor(Bean的后置处理器)拦截Bean的创建

      不同接口类型的BeanPostProcessor,在Bean创建前后的执行时机是不一样的

      • BeanPostProcessor后置处理器

      • DestructionAwareBeanPostProcessor销毁感知后置处理器

      • InstantiationAwareBeanPostProcessor实例化感知后置处理器

      • SmartInstantiationAwareBeanPostProcessor智能实例化感知后置处理器

      • MergedBeanDefinitionPostProcessor[internalPostProcessors]合并Bean定义信息后置处理器

      1. 获取所有的BeanPostProcessor,后置处理器都默认可以通过PriorityOrderedOrdered接口来执行优先级

      2. 先注册PriorityOrdered优先级接口的BeanPostProcessor

        把每一个BeanPostProcessor添加到BeanFactory中,beanFactory.addBeanPostProcessor(postProcessor)

      3. 再注册Ordered接口的

      4. 最后注册没有实现任何优先级接口的

      5. 最终注册MergedBeanDefinitionPostProcessor

      6. 注册一个ApplicationListenerDetector,来在Bean创建完成后检查是否是ApplicationListener,如果是就添加组件applicationContext.addApplicationListener((ApplicationListener) bean)

    初始化MessageSource

    国际化

    1. initMessageSource():初始化MessageSource组件(做国际化功能;消息绑定,消息解析)

      1. 获取BeanFactory

      2. 看容器中是否有id为messageSource的,类型是MessageSource的组件,如果有赋值给messageSource,如果没有自己创建一个DelegatingMessageSource

        MessageSource:取出国际化配置文件中的某个key的值;能按照区域信息获取

      3. 把创建好的MessageSource注册在容器中,以后获取国际化配置文件的值的时候,可以自动注入MessageSource

        beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource)

        MessageSource.getMessage(String code, Object[] args, String defaultMessage, Locale locale)

    初始化事件派发器、监听器

    1. initApplicationEventMulticaster():初始化事件派发器

      1. 获取BeanFactory
      2. BeanFactory中获取applicationEventMulticasterApplicationEventMulticaster
      3. 如果上一步没有配置,就创建一个SimpleApplicationEventMulticaster
      4. 将创建的ApplicationEventMulticaster添加到BeanFactory中,以后其他组件直接自动注入
    2. onRefresh():留给子容器(子类)

      1. 子类重写这个方法,在容器刷新的时候可以自定义逻辑;
    3. registerListeners():给容器中将所有项目里面的ApplicationListener注册进来;

      1. 从容器中拿到所有的ApplicationListener

      2. 将每个监听器添加到事件派发器中

        getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName)

      3. 派发之前步骤产生的事件

    创建Bean准备、完成

    有代理对象就用,没有就创建,然后在初始化前后准备各种后置处理器,创建完成后放入各种Map

    1. finishBeanFactoryInitialization(beanFactory):初始化所有剩下的单实例bean

      1. beanFactory.preInstantiateSingletons():初始化剩下的单实例bean

        1. 获取容器中的所有Bean,依次进行初始化和创建对象

        2. 获取Bean的定义信息:RootBeanDefinition

        3. 判断Bean不是抽象的,是单实例的,不是懒加载

          1. 判断是否是FactoryBean,是否是实现FactoryBean接口的Bean

          2. 如果不是工厂Bean。利用getBean(beanName):创建对象

            1. 这个getBean(beanName)就是平时测试类中用到的ioc.getBean()

            2. doGetBean(name, null, null, false)

            3. 先获取缓存中保存的单实例Bean。this.singletonObjects.get(beanName),如果能获取到说明这个Bean之前被创建过(所有创建过的单实例Bean都会被缓存起来)

              可以从private final Map singletonObjects = new ConcurrentHashMap(256)属性获取到

            4. 缓存中获取不到,开始Bean的创建对象流程,使用BeanFactory

            5. 标记当前bean已经被创建markBeanAsCreated(beanName)

            6. 获取Bean的定义信息

            7. 【获取当前Bean依赖的其他Bean,mbd.getDependsOn(),如果有按照就getBean()把依赖的Bean先创建出来】

            8. 启动单实例Bean的创建流程

              1. 进入匿名类的createBean(beanName, mbd, args)方法(可以打断点进入)

              2. Object bean = resolveBeforeInstantiation(beanName, mbdToUse)[给 BeanPostProcessors 一个返回代理而不是目标 Bean 实例的机会]:让BeanPostProcessor先拦截返回代理对象

                InstantiationAwareBeanPostProcessor提前执行,就是在AOP中先于BeanPostProcessor执行的那个组件】

                • 先触发:postProcessBeforeInstantiation()实例化前的后处理
                • 如果有返回值,触发:postProcessAfterInitialization()初始化后的后处理
              3. 如果前面的InstantiationAwareBeanPostProcessor没有返回代理对象,调用第4步创建Bean

              4. Object beanInstance = doCreateBean(beanName, mbdToUse, args):创建Bean

                1. 【创建Bean实例】createBeanInstance(beanName, mbd, args)

                  利用工厂方法或者对象的构造器创建出Bean实例

                2. applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName)[允许后处理器修改合并的 Bean 定义。]

                  调用MergedBeanDefinitionPostProcessorpostProcessMergedBeanDefinition(mbd, beanType, beanName)

                3. 【Bean属性赋值】populateBean(beanName, mbd, instanceWrapper)

                  赋值之前:

                  1. 拿到InstantiationAwareBeanPostProcessor后置处理器:

                    postProcessAfterInstantiation()实例化后的后处理(对应上面(8.2))

                  2. 拿到InstantiationAwareBeanPostProcessor后置处理器:

                    ibp.postProcessPropertyValues()后处理属性值

                  开始赋值:

                  1. 应用Bean属性的值;为属性利用setter方法等进行赋值:

                    applyPropertyValues(beanName, mbd, bw, pvs)

                4. 【Bean初始化】initializeBean(beanName, exposedObject, mbd)

                  1. 【执行Aware接口方法】invokeAwareMethods(beanName, bean):执行xxxAware接口的方法,如BeanNameAware、BeanClassLoaderAware、BeanFactoryAware

                  2. 【在初始化之前应用 BeanPostProcessors】applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName)

                    BeanPostProcessor.postProcessBeforeInitialization()

                  3. 【执行初始化方法】invokeInitMethods(beanName, wrappedBean, mbd)

                    1. 是否是InitializingBean接口的实现;执行接口规定的初始化
                    2. 是否自定义初始化方法
                  4. 【在初始化之后应用 BeanPostProcessors】applyBeanPostProcessorsAfterInitialization

                    BeanPostProcessor.postProcessAfterInitialization()

                5. 注册Bean的销毁方法

              5. 将创建的Bean添加到缓存中singletonObjects

    ioc容器就是这些Map,很多的Map,里面保存了单实例Bean,环境信息...

    所有Bean都利用getBean创建完成以后:检查所有的Bean是否是SmartInitializingSingleton[智能初始化单例]接口的,如果是,就执行afterSingletonsInstantiated()在单例实例化之后

    容器创建完成

    1. finishRefresh():完成BeanFactory的初始化创建工作,IOC容器就创建完成

      1. initLifecycleProcessor():初始化和生命周期有关的后置处理器:LifecycleProcessor

        1. 默认从容器中找是否有lifecycleProcessor的组件【LifecycleProcessor】;

        2. 如果没有new DefaultLifecycleProcessor();

        3. 加入到容器onRefresh()

          写一个LifecycleProcessor的实现类,可以在BeanFactory的生命周期onRefresh()onClose()处拦截

      2. getLifecycleProcessor().onRefresh()

        拿到前面定义的生命周期处理器(BeanFactory),回调onRefresh()

      3. publishEvent(new ContextRefreshedEvent(this)):发布容器刷新完成事件

      4. LiveBeansView.registerApplicationContext(this)


    __EOF__

  • 本文作者: 蔚然丶丶
  • 本文链接: https://www.cnblogs.com/wei-ran/p/16222835.html
  • 关于博主: 评论和私信会在第一时间回复。或者直接私信我。
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
  • 声援博主: 如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。
  • 相关阅读:
    Gitlab服务器切换来版本升级,执行漏洞修复
    MOSN 反向通道详解
    调优工具常用命令
    【浅学Java】排序大全
    Day50【动态规划】123.买卖股票的最佳时机III、188.买卖股票的最佳时机IV
    spring cloud gateway整合security实现统一权鉴
    dockerfile
    Aspx.net 上传图片并显示预览实现个人简历
    什么是Webpack的Tree Shaking?它的作用是什么?
    通过宽高自适应设计两栏布局和三栏布局
  • 原文地址:https://www.cnblogs.com/wei-ran/p/16222835.html