zoukankan      html  css  js  c++  java
  • Spring-IOC

    前言

    IOC的全称是Inversion of Control,可以理解为控制反转,控制的是bean,反转的是bean的生命周期由使用者变为Spring框架。IOC是Spring的核心,使用者无需再手动创建对象,Spring定义出Bean容器的概念,负责管理对象的生命周期,下面结合代码对IOC核心流程进行分析。

    Bean容器初始化流程

    Bean容器初始化流程,包括bean配置的解析,bean生命周期管理,也是IOC开始的地方。核心流程在AbstractApplicationContext.refresh(),refresh可以理解为刷新,包含两部分,1. 如果有已经存在的那么先销毁;2. 创建新的。下面对refresh的代码函数进行分析。

        1.prepareRefresh()

    准备,这个方法主要完成一些准备工作,包括容器的状态初始化,环境配置校验

        2.obtainFreshBeanFactory()

    通知子类完成刷新,主要实现是类AbstractRefreshableApplication,其中核心逻辑是判断当前是否已经有beanFactory,如果有那么先销毁,并且释放所有的bean,然后再创建出一个新的beanFactory

        3.prepareBeanFactory()

    准备beanFactory,主要工作是将相关实体set到beanFactory,比如classLoader,beanPostProcessor等,beanPostProcessor是spring留出的一个hook,可以让使用者在bean实例化的过程中做定制化,详细可以看`BeanPostProcessor`,提供了实例化bean之前和之后的回调方法。

         4.postProcessBeanFactory()

    留出给子类修改beanFactory的入口,注意这不是BeanFactory,常见的有GenericWebApplicationContext,会为web环境增加额外bean的scope,我们知道容器原生支持bean的scope是singleton和prototype,显然这对web应用来说是不满足的,所以针对web应用,增加了request,session和global_session,3种类型的bean scope。

         5.invokeBeanFactoryPostProcessors()

    核心流程参考`PostProcessorRegistrationDelegate`,主要功能是触发所有` BeanFactoryPostProcessor.postProcessBeanFactory()`

         6.registerBeanPostProcessor()

    注册拦截Bean创建的Bean处理器,即注册BeanPostProcessor,不是BeanFactoryPostProcessor,注意两者的区别,这里仅仅是注册,并不会执行对应的方法,将在bean的实例化时执行对应的方法

         7.initMessageSource()

    详细作用参考类MessageSource

         8.initApplicationEventMulticaster()

    初始化事件广播器,Spring提供了事件-监听机制,用于管理对不同事件发生时的处理流程,常见的事件比如容器启动事件,结束事件等。而广播器用来控制和维护监听以及事件。

         9.onfresh()

    预留给子类扩展

         10.registerListeners()

    在所有bean中查找listener bean,然后注册到广播器中,spring提供了事件-监听机制,使用者可以注册自己的监听器到spring中。

         11.finishBeanFactoryInitialization()

    对那些是scope是singleton,且不是抽象类,并且不做懒加载的bean进行初始化,也就是预加载,从而加快该bean首次被调用的响应时间,否则到使用中调用getBean()的时候bean才会被正真的实例化。singleton表示单例,可以进行预加载,protptype作用域就不行。

         12.finishRefresh()

    初始化生命周期处理器DefaultLifecycleProcessor,DefaultLifecycleProcessor含有start方法和stop方法,spring启动的时候调用start方法开始生命周期, spring关闭的时候调用stop方法来结束生命周期,通常用来配置后台程序,启动有一直运行,如一直轮询kafka启动所有实现了Lifecycle接口的类通过spring的事件发布机制发布ContextRefreshedEvent事件,以保证对应的监听器做进一步的处理,即对那种在spring启动后需要处理的一些类,这些类实现了ApplicationListener<ContextRefreshedEvent> ,这里就是要触发这些类的执行(执行onApplicationEvent方法)另外,spring的内置Event有ContextClosedEvent、ContextRefreshedEvent、ContextStartedEvent、ContextStoppedEvent、RequestHandleEvent完成初始化,通知生命周期处理器lifeCycleProcessor刷新过程,同时发出ContextRefreshEvent通知其他监听。

    依赖和注入

        1.如何实例化bean

    Spring对bean进行实例化,同样也提供了两种基础的方案,基于java和基于cglib,默认采用cglib方案 `CglibSubclassingInstantiationStrategy`,通过对Enhancer的使用,基于动态代理生成一个新的类,再通过对构造函数的反射实例化对象。

         2.如何注入bean的属性

    参考类AbstractAutoWireCapableBeanFactory.populateBean(),其中核心思路是基于name或者基于type的注入,如果冲突可以根据配置选择是否覆盖。实际注入的操作在`InjectionMetadata`,目前支持两种注入,1. 基于Field的注入,也就是通过java反射将实际的对象赋值给字段;2. 方法触发,通过java反射调用方法。当然spring在实际注入之前,还有很多细节操作,比如类型转换,参考接口`TypeConverter`。

    总结

    Spring依赖注入的核心思路是围绕着Bean展开的,首先是Bean的声明解析,包括基于XML,基于注解,然后是Bean如何实例化和注入,直接相关的有BeanFactory,也就是管理Bean整个生命周期的容器,还有由BeanFactory引申出的BeanFactoryPostProcessor,用于对BeanFactory个性化处理,同样对Bean实例化过程中也有个性化的方案BeanPostProcessor。以及对Bean以及相关依赖进行封装的BeanWrapper。另外对Bean的生命周期管理必然会有很多事件,引申出了监听-事件机制。从逻辑角度来理解Bean的生命周期,能更好的理解IOC的本质。

    参考

    // 非常详细的代码分析

    https://www.cnblogs.com/ITtangtang/p/3978349.html

  • 相关阅读:
    树链剖分 (模板) 洛谷3384
    ST表 (模板) 洛谷3865
    IOI 2005 River (洛谷 3354)
    IOI 2005 River (洛谷 3354)
    poj1094 Sorting It All Out
    poj1094 Sorting It All Out
    spfa(模板)
    HAOI 2006 受欢迎的牛 (洛谷2341)
    HAOI 2006 受欢迎的牛 (洛谷2341)
    洛谷1850(NOIp2016) 换教室——期望dp
  • 原文地址:https://www.cnblogs.com/ulysses-you/p/9880866.html
Copyright © 2011-2022 走看看