Spring IOC容器bean初始化源码分析

来源:互联网 发布:安广网络宽带怎么办理 编辑:程序博客网 时间:2024/04/28 19:30

上一篇分析对bean定义的解析源码进行了分析,这个过程的最终结果是把xml文件中bean的定义解析成一个个的BeanDefinition对象并且注册到容器中,在Spring IOC容器启动简介篇中分析,在容器启动的最后会对容器中的所有bean进行初始化,利用之前解析出的BeanDefinition对象,创建一个个最终的bean对象,并且完成bean之间的依赖注入,本篇从源码的角度分析在容器启动时所有bean的初始化过程,bean初始化的粗略序列图如下:

初始化bean

按照作用域划分bean有如下几个作用域

singleton

prototype

自定义作用域

关于bean的初始化,几种作用域的bean基本上是相同的,所以下面主要分析singleton作用域bean初始化,可能会稍微提到其它作用域。

合并BeanDefinition

遍历所有已经注册到容器中的bean名称,因为在bean定义解析完成之后所有解析出的bean名称和bean名称和BeanDefinition之间的映射关系都已经注册到容器中,所以根据bean名称可以定位到响应的BeanDefinition,定位到BeanDefinition之后,接下来需要合并BeanDefinition,因为bean定义中可能会有parent属性表示该bean继承某个bean,所有要把父bean的一些属性拷贝到子bean中,代码在AbstractBeanDefinition中,该方法会把当前bean定义中一些属性复制到other bean定义中。

public void overrideFrom(BeanDefinition other) {if (StringUtils.hasLength(other.getBeanClassName())) {setBeanClassName(other.getBeanClassName());}if (StringUtils.hasLength(other.getFactoryBeanName())) {setFactoryBeanName(other.getFactoryBeanName());}if (StringUtils.hasLength(other.getFactoryMethodName())) {setFactoryMethodName(other.getFactoryMethodName());}if (StringUtils.hasLength(other.getScope())) {setScope(other.getScope());}setAbstract(other.isAbstract());setLazyInit(other.isLazyInit());setRole(other.getRole());getConstructorArgumentValues().addArgumentValues(other.getConstructorArgumentValues());getPropertyValues().addPropertyValues(other.getPropertyValues());setSource(other.getSource());copyAttributesFrom(other);if (other instanceof AbstractBeanDefinition) {AbstractBeanDefinition otherAbd = (AbstractBeanDefinition) other;if (otherAbd.hasBeanClass()) {setBeanClass(otherAbd.getBeanClass());}setAutowireCandidate(otherAbd.isAutowireCandidate());setAutowireMode(otherAbd.getAutowireMode());copyQualifiersFrom(otherAbd);setPrimary(otherAbd.isPrimary());setDependencyCheck(otherAbd.getDependencyCheck());setDependsOn(otherAbd.getDependsOn());setNonPublicAccessAllowed(otherAbd.isNonPublicAccessAllowed());setLenientConstructorResolution(otherAbd.isLenientConstructorResolution());if (StringUtils.hasLength(otherAbd.getInitMethodName())) {setInitMethodName(otherAbd.getInitMethodName());setEnforceInitMethod(otherAbd.isEnforceInitMethod());}if (StringUtils.hasLength(otherAbd.getDestroyMethodName())) {setDestroyMethodName(otherAbd.getDestroyMethodName());setEnforceDestroyMethod(otherAbd.isEnforceDestroyMethod());}getMethodOverrides().addOverrides(otherAbd.getMethodOverrides());setSynthetic(otherAbd.isSynthetic());setResource(otherAbd.getResource());}else {setResourceDescription(other.getResourceDescription());}}
bean定义合并完成之后生成一个RootBeanDefinition对象返回给容器。如果bean没有继承其它的bean,那么把原始的BeanDefinition封装到RootBeanDefinition对象中返回给容器。

protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd, BeanDefinition containingBd)throws BeanDefinitionStoreException {synchronized (this.mergedBeanDefinitions) {RootBeanDefinition mbd = null;...if (mbd == null) {if (bd.getParentName() == null) {// Use copy of given root bean definition.if (bd instanceof RootBeanDefinition) {mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();}else {mbd = new RootBeanDefinition(bd);}}else {// Child bean definition: needs to be merged with parent.BeanDefinition pbd;...mbd = new RootBeanDefinition(pbd);mbd.overrideFrom(bd);}...}return mbd;}}


区分工厂bean

容器启动时会初始化所有非抽象并且非懒加载的单例bean,接下来区分bean的类型是不是FactoryBean,FactoryBean比较特殊,因为FactoryBean是用来生成其它bean的,所以如果在容器中定义了FactoryBean时,通过该FactoryBean的id或别名获取的不是FactoryBean本身而是它生产的bean,触发FactoryBean.getObject方法,并且默认情况下FactoryBean.getObject不会被提前触发必须通过应用层调用触发,容器中的处理是,如果bean是FactoryBean,通过在beanName前加上&符号让容器初始化FactoryBean的真正实例,并且判断该FactoryBean的目标bean是否需要提前初始化,默认情况下时不需要,但是可以通过SmartFactoryBean接口来进行扩展,如果需要初始化,调用bean的初始化bean实例getBean方法。如果bean是普通的bean直接调用bean的初始化getBean方法,代码在DefaultListableBeanFactory的preInstantiateSingletons方法中:

public void preInstantiateSingletons() throws BeansException {...for (String beanName : beanNames) {RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {if (isFactoryBean(beanName)) {final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);boolean isEagerInit;if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {public Boolean run() {return ((SmartFactoryBean<?>) factory).isEagerInit();}}, getAccessControlContext());}else {isEagerInit = (factory instanceof SmartFactoryBean &&((SmartFactoryBean<?>) factory).isEagerInit());}if (isEagerInit) {getBean(beanName);}}else {getBean(beanName);}}}}


获取bean实例

无论是容器启动触发的bean初始化还是应用层触发的bean初始化,代码都是重用的,都是通过getBean方法获取bean的实例,获取bean实例时先检查bean是否已经实例化过并且注册到容器中了,包括两种情况:

  1. 所有初始化操作已经完成,所有bean的依赖关系已经注入。
  2. 提前暴露的bean,这种bean的某些依赖关系还没有注入完成,之所以出现这种情况是因为bean存在循环依赖,为了避免死循环需要提前暴露bean的实例,通过ObjectFactory.getObject创建bean实例。

如果bean已经被实例化过直接使用该bean,代码在DefaultSingletonBeanRegistry类的getSingleton方法,所有初始化完成的bean存储在singletonObjects哈希表中,提前暴露的bean存储在earlySingletonObjects哈希表中。

protected Object getSingleton(String beanName, boolean allowEarlyReference) {Object singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {synchronized (this.singletonObjects) {singletonObject = this.earlySingletonObjects.get(beanName);if (singletonObject == null && allowEarlyReference) {ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);if (singletonFactory != null) {singletonObject = singletonFactory.getObject();this.earlySingletonObjects.put(beanName, singletonObject);this.singletonFactories.remove(beanName);}}}}return (singletonObject != NULL_OBJECT ? singletonObject : null);}
如果bean没有实例化过,执行bean的实例化初始化,如果bean的作用域时prototype并且和其它bean发生了循环引用,初始化失败抛出BeanCurrentlyInCreationException异常。

因为填充bean的属性时,如果bean的属性也引用了一个bean,那么此时同样也会触发getBean方法,如果当前引用的bean在当前容器中不存在,那么把初始化该bean的动过委托给父容器,也就是从父容器中查找这个bean,比如属性的引用标签是<ref parent="xxxx">这种形式时,那么初始化xxxx这个bean的动过只能交给父容器。相关代码片段在AbstractBeanFactory的doGetBean方法中:

protected <T> T doGetBean(final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)throws BeansException {...Object sharedInstance = getSingleton(beanName);if (sharedInstance != null && args == null) {...}else {...// Check if bean definition exists in this factory.BeanFactory parentBeanFactory = getParentBeanFactory();if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {// Not found -> check parent.String nameToLookup = originalBeanName(name);if (args != null) {// Delegation to parent with explicit args.return (T) parentBeanFactory.getBean(nameToLookup, args);}else {// No args -> delegate to standard getBean method.return parentBeanFactory.getBean(nameToLookup, requiredType);}}...}...return (T) bean;}
如果bean是当前容器的bean,那么继续初始化逻辑,在初始化之前先给bean打上标记,标识当前bean已经被创建,标识信息存在alreadyCreated哈希表中。校验bean定义,是否是抽象bean,或者传了arg参数但是bean不是prototype,当需要根据动态参数实例化bean时,该bean的作用域只能是prototype。

protected void checkMergedBeanDefinition(RootBeanDefinition mbd, String beanName, Object[] args)throws BeanDefinitionStoreException {// check if bean definition is not abstractif (mbd.isAbstract()) {throw new BeanIsAbstractException(beanName);}// Check validity of the usage of the args parameter. This can// only be used for prototypes constructed via a factory method.if (args != null && !mbd.isPrototype()) {throw new BeanDefinitionStoreException("Can only specify arguments for the getBean method when referring to a prototype bean definition");}}


检查当前bean是否有依赖的bean,也就是说bean是否定义了depends-on属性,如果有的话先初始化这些依赖bean,并且注册bean的依赖关系到容器中,包含两个结构,一个是bean的依赖列表dependentBeanMap,另一个是bean的被依赖列表dependenciesForBeanMap,存储dependentBeanMap的目的是在销毁该bean时直接遍历该哈希表把所有依赖的bean都销毁掉,dependenciesForBeanMap这个结构目前还没有发现有什么用途,相关代码片段如下:

protected <T> T doGetBean(final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)throws BeansException {...try {...// Guarantee initialization of beans that the current bean depends on.String[] dependsOn = mbd.getDependsOn();if (dependsOn != null) {for (String dependsOnBean : dependsOn) {getBean(dependsOnBean);registerDependentBean(dependsOnBean, beanName);}}...}catch (BeansException ex) {cleanupAfterBeanCreationFailure(beanName);throw ex;}    ...return (T) bean;}


创建bean实例

检查当前是否正在销毁所有的单例bean,如果是的话报错抛出BeanCreationNotAllowedException异常,只有等销毁操作完成之后才能进行bean初始化动作。

存储标记到singletonsCurrentlyInCreation哈希表中标识bean正在被创建,这个标识将会被用来处理循环引用。接下来创建bean实例,对Class、MethodOverride做一些准备处理,然后进行实例化前处理操作,检查容器中的所有BPP(BeanPostProcessor)中是否有实现了InstantiationAwareBeanPostProcessor接口的,如果有的话触发它的postProcessBeforeInstantiation方法看看该方法是否产生了非空的bean实例,如果有的话中断BPP的遍历,继续遍历触发BPP的postProcessAfterInitialization方法,如果有BPP返回了null实例,中断遍历,代码在AbstractAutowireCapableBeanFactory类:

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {Object bean = null;if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {// Make sure bean class is actually resolved at this point.if (mbd.hasBeanClass() && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {bean = applyBeanPostProcessorsBeforeInstantiation(mbd.getBeanClass(), beanName);if (bean != null) {bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);}}mbd.beforeInstantiationResolved = (bean != null);}return bean;}protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName)throws BeansException {for (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof InstantiationAwareBeanPostProcessor) {InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);if (result != null) {return result;}}}return null;}public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)throws BeansException {Object result = existingBean;for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {result = beanProcessor.postProcessAfterInitialization(result, beanName);if (result == null) {return result;}}return result;}
如果上述前处理中产生了非空的bean,实例初始化结束直接返回,这一步非常重要,AOP就是利用这个过程偷梁换柱把bean实例换成bean的代理对象。
如果没有BPP拦截bean的实例化,那么进入bean真正的实例化过程:

首先实例化bean,实例化有几种方式:

  • 工厂方法
  • 自定义构造子
  • 默认构造子

检查bean是否定义了factory-method,如果有factory-method使用该工厂方法实例化bean,存在两种方式,一种是定义factory-bean,通过指定的其它bean的非静态方法初始化该bean;另一种是定义class,通过该class的静态方法实例化该bean,此时factory-method必须是静态方法。如果工厂方法中有参数,那么会在工厂方法参数和构造子参数之间进行匹配,这种情况下目标bean的作用域必须是prototype,应用代码在调用getBean向容器请求bean实例时必须要传入相应的参数,下面是个简单的例子:

类定义:

public class ItemFactory {public ItemBean getItem(String name) {ItemBean item = new ItemBean(name);return item;}}public class ItemBean {private String name;public ItemBean(String name) {super();this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}}
bean定义:

<bean id="factory" class="spring.beans.factory.ItemFactory"></bean><bean id="item1" factory-bean="factory" factory-method="getItem"scope="prototype"><constructor-arg value="name1"></constructor-arg></bean>
调用代码:
ApplicationContext ctx = new ClassPathXmlApplicationContext("spring/beans/factory/factory.xml");ItemBean item = (ItemBean) ctx.getBean("item1", "name11");


工厂方法实例化bean的逻辑在ConstructorResolver类的instantiateUsingFactoryMethod方法中,这里因为是singleton作用域的bean实例化,所以不会涉及到工厂方法的参数处理,args参数是null值。

如果bean定义为构造子注入或者装配模式是构造子,那么通过自定义构造子实例化bean并且完成构造子相关的依赖注入,如果没有定义工厂方法factory-method,检查自定义了构造子,完成构造子依赖注入的代码在ConstructorResolver类的autowireConstructor方法中,这个方法完成的功能是,解析出构造子和构造子参数,并对参数求值,如果出现了EL表达式对EL表示进行解析并且计算出结果,根据结果值的类型求对应的值,如果是引用类型那么首先实例化被引用的bean,调用BeanFactory的getBean,如果是字符类型那么根据参数的实际类型转换成对应的值,需要借助PropertyEditor,代码片段如下:

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {...// Need to determine the constructor...Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);if (ctors != null ||mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {return autowireConstructor(beanName, mbd, ctors, args);}...}


框架使用BeanWrapper来封装实例化的bean,在autowireConstructor方法的开始调用了initBeanWrapper方法,来看看这个方法:

protected void initBeanWrapper(BeanWrapper bw) {bw.setConversionService(getConversionService());registerCustomEditors(bw);}protected void registerCustomEditors(PropertyEditorRegistry registry) {PropertyEditorRegistrySupport registrySupport =(registry instanceof PropertyEditorRegistrySupport ? (PropertyEditorRegistrySupport) registry : null);if (registrySupport != null) {registrySupport.useConfigValueEditors();}if (!this.propertyEditorRegistrars.isEmpty()) {for (PropertyEditorRegistrar registrar : this.propertyEditorRegistrars) {try {registrar.registerCustomEditors(registry);}catch (BeanCreationException ex) {Throwable rootCause = ex.getMostSpecificCause();if (rootCause instanceof BeanCurrentlyInCreationException) {BeanCreationException bce = (BeanCreationException) rootCause;if (isCurrentlyInCreation(bce.getBeanName())) {if (logger.isDebugEnabled()) {logger.debug("PropertyEditorRegistrar [" + registrar.getClass().getName() +"] failed because it tried to obtain currently created bean '" +ex.getBeanName() + "': " + ex.getMessage());}onSuppressedException(ex);continue;}}throw ex;}}}if (!this.customEditors.isEmpty()) {for (Map.Entry<Class<?>, Class<? extends PropertyEditor>> entry : this.customEditors.entrySet()) {Class<?> requiredType = entry.getKey();Class<? extends PropertyEditor> editorClass = entry.getValue();registry.registerCustomEditor(requiredType, BeanUtils.instantiateClass(editorClass));}}}
这个方法的功能是把容器中默认的PropertyEditor和注册到容器中的自定义PropertyEditor复制到BeanWrapper中,来辅助构造子注入时的值转换操作以及为后面其它属性的注入值转换做准备,为什么要把这些PropertyEditor复制到各个BeanWrapper中?我的理解是,PropertyEditor是有状态非线程安全的,每个BeanWrapper复制一份可以消除高并发下的状态同步开销。

上面提到的instantiateUsingFactoryMethod方法功能也类似,只不过instantiateUsingFactoryMethod是要解析工厂方法和参数,如果工厂方法是非静态的那么会多一步实例化工厂方法所在的bean。

无论是构造子还是工厂方法,在解析完之后都会把处理结果保存下来,RootBeanDefinition中有两个属性resolvedConstructorOrFactoryMethod和constructorArgumentsResolved,分别用来保存之前解析出的构造子/工厂方法和参数,下次在处理同样的bean时可以直接复用之前的解析结果,缓存代码在ArgumentsHolder类的storeCache方法中:

public void storeCache(RootBeanDefinition mbd, Object constructorOrFactoryMethod) {synchronized (mbd.constructorArgumentLock) {mbd.resolvedConstructorOrFactoryMethod = constructorOrFactoryMethod;mbd.constructorArgumentsResolved = true;if (this.resolveNecessary) {mbd.preparedConstructorArguments = this.preparedArguments;}else {mbd.resolvedConstructorArguments = this.arguments;}}}

如果即没有工厂方法又没有自定义构造子,那么使用默认构造子实例化bean,进入AbstractAutowireCapableBeanFactory的instantiateBean方法,实例化过程时序图如下:

默认构造子初始化bean

SimpleInstantiationStrategy创建bean实例,首先检查bean是否定义了方法覆盖(lookup-method或replaced-method),如果未定义方法覆盖那么直接创建bean对应的class的实例。如果定义了方法覆盖,那么会使用CGLIB动态的生成class的一个子类,创建该子类的对象作为bean实例,下面两个内部类是lookup-method和replaced-method的CGLIB回调,从代码中可以看到当调用被lookup-mothod覆盖的方法时,会从容器中获取一个bean返回,而调用被replaced-method覆盖的方法时会调用MethodReplacer接口替换实现:

/** * CGLIB MethodInterceptor to override methods, replacing them with an * implementation that returns a bean looked up in the container. */private class LookupOverrideMethodInterceptor extends CglibIdentitySupport implements MethodInterceptor {public Object intercept(Object obj, Method method, Object[] args, MethodProxy mp) throws Throwable {// Cast is safe, as CallbackFilter filters are used selectively.LookupOverride lo = (LookupOverride) beanDefinition.getMethodOverrides().getOverride(method);return owner.getBean(lo.getBeanName());}}/** * CGLIB MethodInterceptor to override methods, replacing them with a call * to a generic MethodReplacer. */private class ReplaceOverrideMethodInterceptor extends CglibIdentitySupport implements MethodInterceptor {public Object intercept(Object obj, Method method, Object[] args, MethodProxy mp) throws Throwable {ReplaceOverride ro = (ReplaceOverride) beanDefinition.getMethodOverrides().getOverride(method);// TODO could cache if a singleton for minor performance optimizationMethodReplacer mr = (MethodReplacer) owner.getBean(ro.getMethodReplacerBeanName());return mr.reimplement(obj, method, args);}}
实例创建成功之后,把创建好的实例封装到BeanWrapper中,并且调用initBeanWrapper方法把PropertyEditor都添加到BeanWrapper中为后面的属性值转换做准备。

接下来触发所有BPP的扩展MergedBeanDefinitionPostProcessor,挨个调用它们的postProcessMergedBeanDefinition方法。

检查是否发生了循环引用,如果存在循环引用提前缓存实例到容器中,代码片段在AbstractAutowireCapableBeanFactory类的doCreateBean方法中:

boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&isSingletonCurrentlyInCreation(beanName));if (earlySingletonExposure) {if (logger.isDebugEnabled()) {logger.debug("Eagerly caching bean '" + beanName +"' to allow for resolving potential circular references");}addSingletonFactory(beanName, new ObjectFactory<Object>() {public Object getObject() throws BeansException {return getEarlyBeanReference(beanName, mbd, bean);}});}
在getEarlyBeanReference方法中会触发SmartInstantiationAwareBeanPostProcessor,可以在这一步把bean换掉,AOP就是在这里把Bean换成代理的。

protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {Object exposedObject = bean;if (bean != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {for (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);if (exposedObject == null) {return exposedObject;}}}}return exposedObject;}


注入bean属性

接下来是填充bean的属性,在属性填充之前先检查是否有自定义的InstantiationAwareBeanPostProcessor的实现的postProcessAfterInstantiation方法返回了false,如果有跳过属性填充,这个特性可以被用来实现属性注入。
如果bean设置了自动装配,则处理自动装配:

下面代码是byName模式的处理,从代码中可以看出,遍历所有属性,从容器中获取和属性名称相同的bean并且添加到PropertyValues结构中,并且调用registerDependentBean注册依赖关系:

protected void autowireByName(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);for (String propertyName : propertyNames) {if (containsBean(propertyName)) {Object bean = getBean(propertyName);pvs.add(propertyName, bean);registerDependentBean(propertyName, beanName);if (logger.isDebugEnabled()) {logger.debug("Added autowiring by name from bean name '" + beanName +"' via property '" + propertyName + "' to bean named '" + propertyName + "'");}}else {if (logger.isTraceEnabled()) {logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +"' by name: no matching bean found");}}}}

下面代码是byType模式的处理,首先通过属性名称查找出对应的set方法,然后根据set方法中的参数类型向容器获取对应的bean,获取到的bean添加到

PropertyValues结构中,并且调用registerDependentBean注册依赖关系:

protected void autowireByType(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {TypeConverter converter = getCustomTypeConverter();if (converter == null) {converter = bw;}Set<String> autowiredBeanNames = new LinkedHashSet<String>(4);String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);for (String propertyName : propertyNames) {try {PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);// Don't try autowiring by type for type Object: never makes sense,// even if it technically is a unsatisfied, non-simple property.if (!Object.class.equals(pd.getPropertyType())) {MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);// Do not allow eager init for type matching in case of a prioritized post-processor.boolean eager = !PriorityOrdered.class.isAssignableFrom(bw.getWrappedClass());DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);if (autowiredArgument != null) {pvs.add(propertyName, autowiredArgument);}for (String autowiredBeanName : autowiredBeanNames) {registerDependentBean(autowiredBeanName, beanName);if (logger.isDebugEnabled()) {logger.debug("Autowiring by type from bean name '" + beanName + "' via property '" +propertyName + "' to bean named '" + autowiredBeanName + "'");}}autowiredBeanNames.clear();}}catch (BeansException ex) {throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);}}}
触发容器中注册的InstantiationAwareBeanPostProcessor,调用它们的postProcessPropertyValues方法,如果当有返回null值的,那么填充过程结束。

检查bean是否设置了依赖模式(dependency-check),如果设置的依赖模式非none,那么进行依赖检查,当bean定义的property属性在对应的class中既没有相应的设值方法,也没有相对应的属性名时不同的模式处理如下:

  • none:不检查
  • simple:如果该属性类型是简单类型或数组类型,抛出异常UnsatisfiedDependencyException
  • object:如果该属性类型是复杂引用类型,抛出异常UnsatisfiedDependencyException
  • all:所有类型都抛出异常UnsatisfiedDependencyException

相关代码在AbstractAutowireCapableBeanFactory类的checkDependencies方法中:

protected void checkDependencies(String beanName, AbstractBeanDefinition mbd, PropertyDescriptor[] pds, PropertyValues pvs)throws UnsatisfiedDependencyException {int dependencyCheck = mbd.getDependencyCheck();for (PropertyDescriptor pd : pds) {if (pd.getWriteMethod() != null && !pvs.contains(pd.getName())) {boolean isSimple = BeanUtils.isSimpleProperty(pd.getPropertyType());boolean unsatisfied = (dependencyCheck == RootBeanDefinition.DEPENDENCY_CHECK_ALL) ||(isSimple && dependencyCheck == RootBeanDefinition.DEPENDENCY_CHECK_SIMPLE) ||(!isSimple && dependencyCheck == RootBeanDefinition.DEPENDENCY_CHECK_OBJECTS);if (unsatisfied) {throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, pd.getName(),"Set this property value or disable dependency checking for this bean.");}}}}
依赖检查完成之后,把bean定义中所有的property,即BeanDefinition中的PropertyValue结构这只到BeanWrapper中,调用BeanWrapper.setProperyValues,在这个过程中会查找所有属性的set方法并且处理property对应值,利用之前注册到BeanWrapper中的PropertyEditor,如果是引用类型还需要向容器请求对应的bean,在处理时还会缓存之前的处理结果到PropertyValue的resolvedDescriptor属性。

bean初始化

到这里bean的属性填充工作已经完成了,接下来调用initializeBean方法来完成一些初始化工作:

  • 激活Aware接口

private void invokeAwareMethods(final String beanName, final Object bean) {if (bean instanceof Aware) {if (bean instanceof BeanNameAware) {((BeanNameAware) bean).setBeanName(beanName);}if (bean instanceof BeanClassLoaderAware) {((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());}if (bean instanceof BeanFactoryAware) {((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);}}}

  • 调用所有已注册的BPP的postProcessBeforeInitialization

public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)throws BeansException {Object result = existingBean;for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {result = beanProcessor.postProcessBeforeInitialization(result, beanName);if (result == null) {return result;}}return result;}

  • 如果实现了InitializingBean接口,调用afterPropertiesSet方法,如果定义了init-mothod,调用对应的方法

protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)throws Throwable {boolean isInitializingBean = (bean instanceof InitializingBean);if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {if (logger.isDebugEnabled()) {logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");}if (System.getSecurityManager() != null) {try {AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {public Object run() throws Exception {((InitializingBean) bean).afterPropertiesSet();return null;}}, getAccessControlContext());}catch (PrivilegedActionException pae) {throw pae.getException();}}else {((InitializingBean) bean).afterPropertiesSet();}}if (mbd != null) {String initMethodName = mbd.getInitMethodName();if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&!mbd.isExternallyManagedInitMethod(initMethodName)) {invokeCustomInitMethod(beanName, bean, mbd);}}}

  • 调用所有已注册BPP的postProcessAfterInitialization方法

public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)throws BeansException {Object result = existingBean;for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {result = beanProcessor.postProcessAfterInitialization(result, beanName);if (result == null) {return result;}}return result;}

注册析构回调

bean析构回调主要有一下几种方式:

  • DestructionAwareBeanPostProcessor的postProcessBeforeDestruction方法,注册这种特殊的BPP到容器
  • DisposableBean的destroy方法,bean实现DisposableBean接口
  • bean定义指定destroy-method

注册一个实现了DisposableBean接口的DisposableBeanAdapter类到容器中,bean销毁时会触发该类的destroy方法,在destroy方法中一次触发上面列出的析构回调:

public void destroy() {if (this.beanPostProcessors != null && !this.beanPostProcessors.isEmpty()) {for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {processor.postProcessBeforeDestruction(this.bean, this.beanName);}}if (this.invokeDisposableBean) {if (logger.isDebugEnabled()) {logger.debug("Invoking destroy() on bean with name '" + this.beanName + "'");}try {if (System.getSecurityManager() != null) {AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {public Object run() throws Exception {((DisposableBean) bean).destroy();return null;}}, acc);}else {((DisposableBean) bean).destroy();}}catch (Throwable ex) {String msg = "Invocation of destroy method failed on bean with name '" + this.beanName + "'";if (logger.isDebugEnabled()) {logger.warn(msg, ex);}else {logger.warn(msg + ": " + ex);}}}if (this.destroyMethod != null) {invokeCustomDestroyMethod(this.destroyMethod);}else if (this.destroyMethodName != null) {Method methodToCall = determineDestroyMethod();if (methodToCall != null) {invokeCustomDestroyMethod(methodToCall);}}}


注册bean

bean的实例化初始化工作已经完成之后把bean注册到容器中:

  • 把bean名称从singletonsCurrentlyInCreation哈希表中删除
  • 把bean实例注册到容器中,添加到singletonObjects哈希表中
protected void addSingleton(String beanName, Object singletonObject) {synchronized (this.singletonObjects) {this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT));this.singletonFactories.remove(beanName);this.earlySingletonObjects.remove(beanName);this.registeredSingletons.add(beanName);}}protected void afterSingletonCreation(String beanName) {if (!this.inCreationCheckExclusions.containsKey(beanName) &&!this.singletonsCurrentlyInCreation.remove(beanName)) {throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");}}

返回bean

bean创建工作完成之后接下来的工作是把bean返回给应用层:

  • 如果bean不是FactoryBean或者bean名称是以&开头,那么直接返回bean实例给应用层
  • 如果bean是FactoryBean,那么调用FactoryBean.getObject,把返回的对象返回给应用层。

代码在AbstractBeanFactory的getObjectForBeanInstance方法:

protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {// Don't let calling code try to dereference the factory if the bean isn't a factory.if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());}// Now we have the bean instance, which may be a normal bean or a FactoryBean.// If it's a FactoryBean, we use it to create a bean instance, unless the// caller actually wants a reference to the factory.if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {return beanInstance;}Object object = null;if (mbd == null) {object = getCachedObjectForFactoryBean(beanName);}if (object == null) {// Return bean instance from factory.FactoryBean<?> factory = (FactoryBean<?>) beanInstance;// Caches object obtained from FactoryBean if it is a singleton.if (mbd == null && containsBeanDefinition(beanName)) {mbd = getMergedLocalBeanDefinition(beanName);}boolean synthetic = (mbd != null && mbd.isSynthetic());object = getObjectFromFactoryBean(factory, beanName, !synthetic);}return object;}
至此bean的初始化代码分析就全部完成了,代码太多,感觉文章写得有点乱,抽空再整理整理

0 0
原创粉丝点击