• 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

  • 相关阅读:
    LeetCode173. 二叉搜索树迭代器
    LeetCode172. 阶乘后的零
    电商系统 SKU 设计和优化2
    电商系统 SKU 设计和优化
    JQuery/JS插件 排列组合 前端实现
    开源框架 码云 推荐项目
    Java idea 打包 编码问题 解决
    Java 基础 MyBatis-Plus 组装查询条件
    Java 基础 list 排序
    Java 基础 list 查询 ids
  • 原文地址:https://www.cnblogs.com/ulysses-you/p/9880866.html
Copyright © 2020-2023  润新知