欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring的IOC底层原理

程序员文章站 2022-07-12 11:23:06
...

基于注解的IOC容器流程

Spring基于注解的开发方式,获取IOC容器。

AnnotationConfigApplicationContext是一个用来管理注解bean的容器,继承GenericApplicationContext这个通用应用上下文。

Spring的IOC底层原理

接下来我们就看看 AnnotationConfigApplicationContext 是怎么实现Bean的创建-初始化等一系列工作。

我们进入 AnnotationConfigApplicationContext 的源码:

Spring的IOC底层原理

Spring 容器中的refresh()方法,主要通过这个方法对IOC容器进行创建和刷新。

1. refresh中的 prepareRefresh() 方法进行刷新前的预处理工作。

   1)initPropertySources() 初始化一些属性设置,子类实现这个方法自定义个性化的属性设置。

   2)getEnvironment().validateRequiredProperties() 检验属性的合法

   3)earlyApplicationEvents= new LinkedHashSet<ApplicationEvent>() 保存容器中的一些早期的事件

2. refresh中的 obtainFreshBeanFactory(),此方法获取BeanFactory对象

Spring的IOC底层原理

   1)refreshBeanFactory() 创建 BeanFactory

在 GenericApplicationContext 类中通过构造方法创建BeanFactory对象。

Spring的IOC底层原理

   2)getBeanFactory() 返回刚才GenericApplicationContext创建的BeanFactory对象;

Spring的IOC底层原理

   3)最终将创建的 BeanFactory 对象返回

3. prepareBeanFactory(beanFactory)  对BeanFactory进行一些设置

Spring的IOC底层原理

   1)设置BeanFactory 的类加载器

   2)添加部分BeanPostProcessor【ApplicationContextAwareProcessor】 判断是否实现了ApplicationContext接口

   3)设置忽略的自动装配的接口 EnvironmentAware、EmbeddedValueResolverAware

   4)注册可以解析的自动装配,我们能直接在任何组件中自动注入:
            BeanFactory、ResourceLoader、ApplicationEventPublisher(事件派发器)、ApplicationContext

   5)添加BeanPostProcessor【ApplicationListenerDetector】监听器

   6)添加编译时的AspectJ支持

   7)给BeanFactory中注册一些能用的组件

Spring的IOC底层原理

4. postProcessBeanFactory(beanFactory) 对BeanFactory进行后置处理工作

Spring的IOC底层原理

子类通过重写这个方法来在 BeanFactory创建 并预准备完成以后做进一步的设置。

5. invokeBeanFactoryPostProcessors(beanFactory) 执行BeanFactoryPostProcessor的方法。

  BeanFactoryPostProcessor:BeanFactory的后置处理器。在BeanFactory标准初始化之后执行。

   1)执行BeanFactoryPostProcessor

Spring的IOC底层原理

   先执行BeanDefinitionRegistryPostProcessor

   获取所有的BeanDefinitionRegistryPostProcessor,按照优先级顺序,先执行实现了PriorityOrdered优先级接口的,再执行实现了Ordered顺序接口的,最后执行没有实现任何优先级或者是顺序接口的BeanDefinitionRegistryPostProcessors。

   Spring的IOC底层原理

Spring的IOC底层原理

    再执行BeanFactoryPostProcessor

Spring的IOC底层原理

    同样按照BeanDefinitionRegistryPostProcessor流程进行执行。

6. registerBeanPostProcessors(beanFactory) 注册BeanPostProcessor(Bean的后置处理器)【拦截bean的创建过程】

Spring的IOC底层原理

不同接口类型的BeanPostProcessor,在Bean创建前后的执行时机不一样。
        BeanPostProcessor、
        DestructionAwareBeanPostProcessor、
        InstantiationAwareBeanPostProcessor、
        SmartInstantiationAwareBeanPostProcessor、
        MergedBeanDefinitionPostProcessor

   1)获取所有的 BeanPostProcessor 后置处理器默认都可以通过PriorityOrdered、Ordered接口来执行优先级

   2)先注册PriorityOrdered优先级接口的BeanPostProcessor。
            把每一个BeanPostProcessor;添加到BeanFactory中
            beanFactory.addBeanPostProcessor(postProcessor);

   3)再注册Ordered接口的

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

   5)最终注册MergedBeanDefinitionPostProcessor;

   6)注册一个ApplicationListenerDetector;来在Bean创建完成后检查是否是ApplicationListener,如果是
        调用 applicationContext.addApplicationListener((ApplicationListener<?>) bean) 注册进监听器列表。

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

Spring的IOC底层原理

   1)获取BeanFactory

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

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

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

Spring的IOC底层原理

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

Spring的IOC底层原理

   1)获取BeanFactory

   2)从BeanFactory中获取applicationEventMulticaster的ApplicationEventMulticaster

   3)如果上一步没有配置;创建一个SimpleApplicationEventMulticaster

   4)将创建的ApplicationEventMulticaster添加到BeanFactory中,以后其他组件直接自动注入

9. onRefresh() 留给子容器(子类)

Spring的IOC底层原理

   子类重写这个方法,在容器刷新的时候可以自定义逻辑。

10. registerListeners() 将所有ApplicationListener注册进容器

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

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

         getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);

    3)派发之前产生的事件。

Spring的IOC底层原理

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

Spring的IOC底层原理

11.1)beanFactory.preInstantiateSingletons() 初始化后剩下的单实例bean

Spring的IOC底层原理

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

   2)获取bean的定义信息,RootBeanDefinition

   3)判断 bean是否满足:不是抽象的,是单实例的,不是懒加载的

        3.1)判断是否是FactoryBean(实现了FactoryBean的bean),工厂bean调用工厂bean的逻辑创建对象

        3.2)不是工厂bean,利用getBean(beanName) 创建对象

              1. ioc.getBean(beanName),ioc为创建的容器。

              2. getBean中调用doGetBean() 方法

          Spring的IOC底层原理

   public void preInstantiateSingletons() throws BeansException {
        if (this.logger.isDebugEnabled()) {
            this.logger.debug("Pre-instantiating singletons in " + this);
        }

        // Iterate over a copy to allow for init methods which in turn register new bean definitions.
        // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
        List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

        // Trigger initialization of all non-lazy singleton beans...
        //1. 获取容器中的所有bean,依次进行初始化和创建对象
        for (String beanName : beanNames) {
            //2. 拿到bean的定义信息
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            //3. 判断bean 不是抽象的,是单实例的,不是懒加载(用到的时候才创建对象)
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                //3.1 判断是否FactoryBean,是否是实现FactoryBean接口的,如果是工厂bean按照工厂方法创建对象
                if (isFactoryBean(beanName)) {
                    final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
                    boolean isEagerInit;
                    if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                        isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>) () ->
                                        ((SmartFactoryBean<?>) factory).isEagerInit(),
                                getAccessControlContext());
                    } else {
                        isEagerInit = (factory instanceof SmartFactoryBean &&
                                ((SmartFactoryBean<?>) factory).isEagerInit());
                    }
                    if (isEagerInit) {
                        getBean(beanName);
                    }
                } else {
                    //3.2 不是工厂bean,调用getBean
                    getBean(beanName);
                }
            }
        }

        // Trigger post-initialization callback for all applicable beans...
        for (String beanName : beanNames) {
            Object singletonInstance = getSingleton(beanName);
            if (singletonInstance instanceof SmartInitializingSingleton) {
                final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
                if (System.getSecurityManager() != null) {
                    AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                        smartSingleton.afterSingletonsInstantiated();
                        return null;
                    }, getAccessControlContext());
                } else {
                    smartSingleton.afterSingletonsInstantiated();
                }
            }
        }
    }

               3. 先获取缓存中保存的单实例bean,如果能获取到说明创建过(创建过的单实例bean都会被缓存起来)

            缓存在 singletonObjects 中

             Spring的IOC底层原理

                4. 缓存中拿不到,开始Bean的创建对象流程:

                5. markBeanAsCreated(beanName),标记当前bean已经创建了,防止多线程重复创建

                 获取bean的定义信息

              Spring的IOC底层原理

                6. 获取当前bean的其他bean依赖,如果有通过getBean()把依赖的bean先创建出来。

             Spring的IOC底层原理

                 7. 启动单实例bean的创建流程:

                    7.1)调用 createBean()创建bean

                    Spring的IOC底层原理

                    7.2)让BeanPostProcessor 先拦截返回代理对象

                       【InstantiationAwareBeanPostProcessor】:进行拦截
                        先触发:postProcessBeforeInstantiation();
                        如果有返回值:触发postProcessAfterInitialization();

                    Spring的IOC底层原理

                    7.3)前面的InstantiationAwareBeanPostProcessor没有返回代理对象

                    7.4)调用 doCreateBean(beanName, mbdToUse, args) 创建Bean

                           7.4.1)【创建Bean实例】;createBeanInstance(beanName, mbd, args)

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

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

                           7.4.3)【进行Bean属性赋值】为属性利用setter方法等进行赋值
                                       applyPropertyValues(beanName, mbd, bw, pvs);   

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

                                        1)【 执行Aware接口方法】invokeAwareMethods(beanName, bean)

                                        2)【执行后置处理器初始化之前的方法】

                                               BeanPostProcessor.postProcessBeforeInitialization();

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

                                        4)【执行后置处理器初始化之后】BeanPostProcessor.postProcessAfterInitialization()

                            7.4.5) 注册bean的销毁方法

                      7.5)将创建的Bean添加到缓存中singletonObjects中

                       ioc容器就是singletonObjects 这些map,保存了很多的单实例bean,环境信息。

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

         Spring的IOC底层原理

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

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

至此IOC容器创建完成。

总结:

1. Spring 容器在启动时,首先会保存所有注册进来的Bean的定义信息,

         1)基于xml的方式:<bean>

         2)基于注解的方式:@Service、@Component、@Bean、@Controller等

2. Spring 容器会在合适的时机创建这些bean

         1)用到某个bean的时候,利用getBean创建bean,创建好保存在容器中。

         2)统一创建剩下所有的bean的时候 调用:finishBeanFactoryInitialization() 上面的第11点。

3.  后置处理器:BeanPostProcessor

         每一个bean创建、初始化前后都会使用各种后置处理器进行处理,来增强bean的功能。  

4. 事件驱动模型:

        ApplicationListener;事件监听;
        ApplicationEventMulticaster;事件派发:

       

ApplicationContext中Bean的生命周期

首先:InstantiationAwareBeanPostProcessor 是 BeanPostProcessor的子接口主要作用是目标对象的实例化过程中需要处理的事情,包括实例化对象的前后过程以及实例的属性设置。

1. 启动容器,调用BeanFactoryPostProcessor的postProcessBeanFactory()对工厂定义信息进行后处理。

2.通过getBean()调用某一个bean。

3. 调用 InstantiationAwareBeanPostProcessor postProcessBeforeInstantiation(),该方法在bean实例化之前进行后置处理工作。如果返回为null,调用doCreateBean(),创建bean。返回不为null,表示生成了代理对象,则执行初始化之后的postProcessAfterInitialization,跳过实例化之后的postProcessAfterInstantiation()和初始化之前的postProcessBeforeInitialization

4. bean进行实例化

5. 调用 InstantiationAwareBeanPostProcessor postProcessAfterInstantiation(),在实例化之后进行后置工作。

6. 调用 InstantiationAwareBeanPostProcessor postProcessPropertyValues() 方法进行属性值的修改。

7. 调用 BeanNameAware 接口的 setBeanName()方法,将名称设置到bean中。

8. 调用 BeanFactoryAware 接口的 setBeanFactory() 方法,将BeanFactory容器的实例设置到bean中。

9. 调用 BeanPostProcessor postProcessBeforeInitialization 方法,进行初始化前的后置处理工作。

10. 调用 InInitializingBean 接口 afterPropertiesSet()方法。

11. 通过 init-method 属性配置的初始化方法,执行初始化逻辑。

12. 调用 BeanPostProcessorpostProcessAfterInitialization()方法,进行初始化后的后置处理工作。

13. 如果是单实例bean,则将bean放进IOC容器缓存池,将bean的引用返回,如果是多实例bean,将该bean返回给调用者。

14. 如果是单实例bean,实现了 DisposableBean 接口,当容器关闭的时候调用 destory 方法,然后调用 destory-method 属性指定的销毁方法。