对于Spring框架底层的剖析(一)Bean

        Spring是Java生态中最成功的框架之一,其中所蕴含的思想非常经典,如果想提升Java的编程思维和学会灵活运用设计模式和规范设计,阅读Spring源码或看相关博客不失为一种良好的选择。若觉得源码上手难度大可以阅读我写的这个系列,该系列深入浅出地将Spring的Bean,事件机制,事务机制等的逻辑阐述清楚,相信读完会有不错的收获,再将来读源码也会较好上手。

目录

一.Bean的实现原理

二.IoC容器的底层实现

三.Spring中Bean的实现逻辑

四.Bean拓展机制的实现概览

五.可能遇到的问题即解决方法


一.Bean的实现原理

        Spring 中的Bean指的是被IoC容器所管理的对象。Bean的生命周期为对 Bean构造函数的实现,对Bean进行依赖注入,为Bean接入Aware接口, 在Bean的初始化的同时为Bean进行再加工。

        图1为Bean的生命周期。

图                                                        图1  Bean的生命周期

         Bean实现的最主要的原理是IoC,即控制反转。IoC可以很好的降低各个关联对象的耦合度,也方便摸清各个对象的关联逻辑。在Spring中是使用工厂模式来对其进行实现的。

        总之Bean是基于IoC的特例依赖注入(DI)实现的,即首先需要构建管理Bean的容器,在容器中进行Bean的依赖注入,并对Bean的生命周期进行管理。故总体上我们需要实现IoC容器和Bean。

二.IoC容器的底层实现

        IoC的实现依赖于dom4j解析xml文档,工厂模式,反射设计模式(创建对象)这三个技术,其中工厂模式是IoC思想的体现。IoC容器的初始化包括 BeanDefinition 的 Resource 定位、加载和注册这三个基本的过程,初始化后会对Bean资源进行相应的实例化并进行管理。

        Spring中有很多的容器,在此以ApplicationContextHolder为切入点,ApplicationContextHolder类依赖了ApplicationContextAware,其服务的ApplicationContext类的继承图如图2所示,其顶层接口为BeanFactory。故在此说明Spring中ApplicationContext(即项目中使用到的IoC容器)的实现。

                                                     图2 ApplicationContext的继承树

        

        ApplicationContext 是 Spring 提供的一个高级的 IoC 容器,它除了能够提供 IoC 容器的基本功能外,还为用户提供了以下的附加服务。 从 ApplicationContext 接口的实现,可以看出其特点:

1、支持信息源,可以实现国际化(实现 MessageSource 接口)

2、访问资源(实现 ResourcePatternResolver 接口)

3、支持应用事件(实现 ApplicationEventPublisher 接口)

ApplicationContext中的getAutowireCapableBeanFactory方法(ApplicationContext主要调用的方法)获取的是DefaultListableBeanFactory类(继承自AutowireCapableBeanFactory类),此类为IoC容器实现的关键所在,故在开发中将围绕着此进行重点构建。图3为其继承树。

                                             图3 DefaultListableBeanFactory的继承树    

        其继承的ListableBeanFactory接口使Bean是可列表化的,HierarchicalBeanFactory接口使Bean是有继承关系的,AutowireCapableBeanFactory 接口定义了Bean的自动装配规则。

        其继承关系及方法实现均非常复杂,故在此不再进行具体地分析。

三.Spring中Bean的实现逻辑

  为实现整个Bean,需要以下步骤: 

  1. 在扫描路径下查找并加载相应的Bean对象,并将其实例化
  2. 将Bean的引用和值注入到Bean的属性中
  3. 该Bean实现了BeanNameAware,BeanFactoryAware,ApplicationContextAware,postProcessBeforeInitialization,InitializingBean,postProcessAfterInitialization这些接口或方法后,将相关接口的方法进行调用
  4. Bean准备完毕,可以被程序调用。若需要执行一些任务或启动需要的异步服务,则调用实现了SmartLifecycle接口的类来实现
  5. 调用destroy()方法销毁Bean

  为此,我们需要实现的有:

  1. IoC容器,如Spring中的BeanFactory和ApplicationContext容器
  2. 查找并加载Bean的方法,如通过注解或XML文件配置等方式实现
  3. BeanNameAware,BeanFactoryAware,ApplicationContextAware,BeanPostProcessor,InitializingBean,SmartLifecycle接口
  4. Bean的destroy()方法

  以上需要实现的接口方法都涉及到了很多底层知识,如BeanPostProcessor接口是为了对Bean进行后处理或者说实现Bean的AOP,其包括加载注册和对此方法的调用两个主要步骤,流程如下:

  1. 找到所有实现BeanPostProcessor接口的实现类
  2. 将其实现类进行分类,以特定的顺序进行排序
  3. 保存操作,至此BeanPostProcessor已注册好
  4. 在Bean加载的过程中的resolveBeforeInstantiation进行调用,resolveBeforeInstantiation使用复杂的判断验证逻辑来使BeanPostProcessor正常运作

  若需详细地阐明每一个接口的实现原理将占用大量篇幅,故在此不做详细的说明。

四.Bean拓展机制的实现概览

        Spring中的拓展机制可以在不修改Spring框架源代码的情况下,对框架和其管理的Bean进行自定义和扩展,实现与其他框架相结合等特性。常用的扩展机制有BeanPostProcessor,Aware接口等。该板块将通过IoC容器的初始化流程来对拓展机制进行说明。

        在上文中已经对IoC容器初始化的流程进行了说明,在AbstractApplicationContext中的refresh方法定义了容器如何进行刷新,其中的BeanDefinition和BeanPostProcessor是常见的拓展方法。BeanPostProcessor的AOP逻辑会在下文的AOP板块进行说明,故在此进行对BeanDefinition实现的解释。

        BeanDefinition即描述Bean信息的方法,加载此方法有通过XML schema扩展和注解两种方式,其中注解是基于XML schema实现的,在此只对XML schema进行说明。

        

        Spring允许开发者定义XML的的结构并且可以用自定义的Bean解析器进行解析,其通过4个步骤实现XML schema拓展机制:

    • 编写XML schema文件描述节点元素
    • 编写NamespaceHandler的实现类
    • 编写BeanDefinitionParser 的实现,此为该拓展机制的关键
    • 注册上述的 schema 和 handler

        基于此拓展机制的还有AOP , MVC , Spring-Cache以及一些开源框架比如Dubbo等。

五.可能遇到的问题即解决方法

        在实现Bean的生命周期中,可能会面临循环依赖的问题,故还需要实现三级缓存逻辑来解决循环依赖问题,大致框架如下:

①实现一级缓存:单例池,缓存已经经历了完整的生命周期,已经初始化完成的Bean对象

②实现二级缓存:缓存早期的Bean对象

③实现三级缓存:缓存的是ObjectFactory,即对象工厂

  • 15
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值