上一篇分析了XmlBeanFactory的初始化过程,此时配置的bean已注册到容器中,但也仅仅只是保存了bean的信息,并无产生bean实例。下面咱们以BeanFactory.getBean(String name)为出发点探索下bean的加载过程。缓存
AbstractBeanFactory实现了getBean方法,调用doGetBean真正开始获取bean。
首先是将参数name转化为beanName,若是是“&”开头的表明是FactoryBean(是特殊的bean,后面会讲到)须要把“&”去除;若是是别名就去寻找它最终指向的beanName。
而后从容器的单例注册中心尝试获取bean实例。顺序以下:从单例缓存中(容器的singletonObjects属性)尝试获取;若是没有就从提前曝光单例对象(容器的earlySingletonObjects属性)尝试获取;若是尚未,就从singletonFactories中尝试获取这个bean的ObjectFactory,再调用ObjectFactory.getObject()获取到bean,放入earlySingletonObjects,把ObjectFactory从singletonFactories中移除(是否是很混乱?别急,这是Spring为了不循环依赖作出的策略,后面咱们会解释)。
若是没有获取到,也就是说要新建一个,先检查bean是否已经在原型建立中(避免原型的循环依赖),再在容器中查找是否存在beanName对应的BeanDefinition,找不到的话就递归从父容器查找;而后若是BeanDefinition有依赖(也就是bean定义时有depends-n属性)就先把依赖关系注册到容器的dependentBeanMap,再递归加载依赖的bean;而后根据BeanDefinition设置的scope选择建立单例、原型仍是其余scope的bean实例。单例的话调用getSingleton建立单例;原型的须要先把beanName注册到容器的prototypesCurrentlyInCreation中(为了防止循环依赖)而后调用createBean建立bean实例,随后从prototypesCurrentlyInCreation找中移除beanName。建立出的实例跟前面在缓存中获取到的同样并不会直接返回,而是调用getObjectForBeanInstance,若是不是FactoryBean或者想要的就是FactoryBean自己(name是&开头)就直接返回;不然先从工厂建立bean缓存factoryBeanObjectCache中尝试获取,没有就调用getObjectFromFactoryBean方法建立一个bean实例(是单例还会存入factoryBeanObjectCache)返回。一大堆流程看下来是否是有点晕,让咱们再来简述下步骤:
一、name转化为beanName
二、尝试从缓冲中获取单例
2.一、单例缓存singletonObjects中查找(这个getSingleton只查找不建立)
2.二、提前曝光单例earlySingletonObjects中查找
2.三、singletonFactories中查找ObjectFactory并在生产bean放入earlySingletonObjects后移除
三、缓冲中获取不到,须要新建
3.一、当前容器中查找BeanDefinition
3.二、没有的话去父容器中查找BeanDefinition
3.三、递归加载设置过的依赖bean
3.四、根据scope建立bean实例
四、若是是工厂bean,返回生产的bean
4.一、尝试从缓存factoryBeanObjectCache中获取
4.二、调用BeanFactory.getObject()生产一个bean实例
4.三、若是不是应用程序自己的bean,调用后置处理器(这个后面会重点说)
4.四、是单例的话存入factoryBeanObjectCacheapp
如今咱们大体了解了向容器获取一个bean的主要步骤,可是咱们仍是不太清楚具体是怎么建立bean实例的,因此咱们还须要继续深刻:
前面说到若是是单例的话,调用getSingleton(String beanName, ObjectFactory<?> singletonFactory)(区别于2.1的getSingleton),先从singletonObjects查找,没有的话将beanName放入singletonsCurrentlyInCreation表示该bean正在加载;而后用参数singletonFactory的函数方法createBean(对,就是和原型同样的那个)建立一个bean;将beanName从singletonsCurrentlyInCreation中移除;最后将新创建的beanName和bean的映射关系保存到缓存singletonObjects和已注册registeredSingletons中,移除singletonFactories和earlySingletonObjects中的记录。步骤简述以下:
3.4.一、从singletonObjects查找
3.4.二、设置正在加载状态
3.4.三、createBean建立bean
3.4.四、移除正在加载状态
3.4.五、保存缓存,删除中间辅助状态ide
咱们再来看createBean。先从BeanDefinition中获取bean的Class,再对override属性(经过lookup-method和replace-method配置,后面实例化时会用到)进行标记和验证,而后给后置处理器一个机会直接返回bean代理,即若是容器中有注册InstantiationAwareBeanPostProcessor这类后置处理器的话,就分别执行它的postProcessBeforeInstantiation和全部后置处理器的postProcessAfterInstantiation,若是返回不为空就直接返回代理bean(AOP功能基于这里判断的);最后调用doCreateBean实例化bean。步骤简述以下:
3.4.3.一、从BeanDefinition中获取bean的Class对象
3.4.3.二、对override属性进行标记和验证
3.4.3.三、初始化前的短路判断
3.4.3.四、实例化bean函数
继续深刻doCreateBean,第一步判断若是是单例的话从factoryBeanInstanceCache中获取缓存的BeanWrapper(bean的包装类)并从中移除,若是没有则调用createBeanInstance建立一个BeanWrapper;而后应用MergedBeanDefinitionPostProcessor(AutowiredAnnotationBeanPostProcessor,Autowired);容许循环依赖的而且自身在建立中的单例,把此单例的ObjectFactory(SmartInstantiationAwareBeanPostProcessor,AOP)注册到singletonFactories,同时从earlySingletonObjects移除对应;而后调用populateBean对bean的属性进行填充,递归初始依赖的bean;再调用initializeBean执行初始化方法;对于容许循环依赖的而且自身在建立中的单例作循环依赖检查;最后注册DisposableBean。步骤简述以下:
3.4.3.4.一、尝试从factoryBeanInstanceCache中获取缓存BeanWrapper
3.4.3.4.二、建立一个bean实例返回BeanWrapper
3.4.3.4.三、应用MergedBeanDefinitionPostProcessor
3.4.3.4.四、依赖处理
3.4.3.4.五、属性填充
3.4.3.4.六、执行初始化方法
3.4.3.4.七、循环依赖检查
3.4.3.4.八、注册DisposableBean
首先咱们看如何建立一个bean实例。先是解析出Class,若是工厂方法不用空,即设置了factory-method,则使用工厂方法初始化策略;不然须要根据参数锁定构造函数,若是已经解析过了在缓存中能够找到锁定,不然进行解析锁定并加入缓存;没有锁定到有参数的构造函数的话,就使用默认构造器,若是有须要覆盖或动态替换的方法(override属性)须要使用CGLIB进行动态代理,不然就用反射的方式建立实例。
再来看一下属性填充。在属性设置前应用InstantiationAwareBeanPostProcessors的postProcessAfterInstantiation(能够控制是否继续填充),而后根据设置的自动注入方式(名称或者类型)获取属性bean(递归getBean)存入PropertyValues中,再应用InstantiationAwareBeanPostProcessors的postProcessProperties对填充前的属性进行处理(如对属性的验证),最后将全部PropertyValues中的属性填充到BeanWrapper中。
属性填充完以后就是initializeBean方法了。首先对实现XXAware接口的bean注入相应的资源(如实现了BeanFactoryAware的bean会注入当前BeanFactory的实例),而后就是注册了的BeanPostProcessor的postProcessBeforeInitialization,再是激活自定义的init方法,前后执行实现了InitializingBean的afterPropertiesSet方法和配置init-method方法。
最后看下DisposableBean的注册。注册DisposableBean的实现,在注销时执行来源于DestructionAwareBeanPostProcessors、实现的DisposableBean的destroy方法还有本身配置的destroy-method的处理。post