由Spring框架中的单例模式想到的

2018/03 16 10:03

本片博客直接把原来写过的代码拷贝过来

单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例

注:Spring源码的版本4.3.4

Spring依赖注入Bean实例默认是单例的,我们由此展开。

Spring的依赖注入(包括lazy-init方式)都是发生在AbstractBeanFactory的getBean里。getBean的doGetBean方法调用getSingleton进行bean的创建。lazy-init方式,在容器初始化时候进行调用,非lazy-init方式,在用户向容器第一次索要bean时进行调用

同步线程安全的单例核心代码:

从上面代码可以看到,spring依赖注入时,使用了双重判断加锁的单例模式,首先从缓存中获取bean实例,如果为null,对缓存map加锁,然后再从缓存中获取bean,如果继续为null,就创建一个bean。这样双重判断,能够避免在加锁的瞬间,有其他依赖注入引发bean实例的创建,从而造成重复创建的结果。

    在这里Spring并没有使用私有构造方法来创建bean,而是通过singletonFactory.getObject()返回具体beanName对应的ObjectFactory来创建bean。我们一路跟踪下去,发现实际上是调用了AbstractAutowireCapableBeanFactory的doCreateBean方法,返回了BeanWrapper包装并创建的bean实例。

(ObjectFactory主要检查是否有用户定义的BeanPostProcessor后处理内容,并在创建bean时进行处理,如果没有,就直接返回bean本身)

见如下代码:

512行创建bean实例返回给BeanWrapper

540行addSingletonFactory增加beanName和ObjectFactory的键值对应关系。

 

 

getEarlyBeanReference获取bean的所有后处理器,并进行处理。如果是SmartInstantiationAwareBeanPostProcessor类型,就进行处理,如果没有相关处理内容,就返回默认的实现。

 


 

 

彩蛋在此:

各种单例实现方式(5种):懒汉模式,饿汉线程非安全模式,饿汉线程安全模式,内部类模式,枚举模式。现在最推荐的方式是枚举单例模式。对这些模式的描述和介绍,请仔细看代码中的注释,会有意想不到的收获呦!

--转载请注明: https://www.guangboyuan.cn/%e7%94%b1spring%e6%a1%86%e6%9e%b6%e4%b8%ad%e7%9a%84%e5%8d%95%e4%be%8b%e6%a8%a1%e5%bc%8f%e6%83%b3%e5%88%b0%e7%9a%84/

发表回复

(必填)