在 Spring源码系列:依赖注入(一)(AbstractBeanFactory-getBean) 最后说道getBean是依赖注入的起点,bean的创建都是通过createBean来完成具体的创建的。createBean的具体实现是在AbstractAutowireCapableBeanFactory中的。本篇就捋一捋这个方法看下bean的创建过程。
这个方法是AbstractAutowireCapableBeanFactory这个类的中心方法,其作用就是创建一个bean实例,填充bean实例,后置处理等。
在createBean中主要做了三件事:
具体来看方法:
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException { if (logger.isDebugEnabled()) { logger.debug("Creating instance of bean '" + beanName + "'"); } RootBeanDefinition mbdToUse = mbd; // Make sure bean class is actually resolved at this point, and // clone the bean definition in case of a dynamically resolved Class // which cannot be stored in the shared merged bean definition. //判断需要创建的Bean是否可以实例化,这个类是否可以通过类装载器来载入 Class<?> resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } // Prepare method overrides. try { mbdToUse.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { //异常:Validation of method overrides failed } try { // Give BeanPostProcessors a chance to return a proxy instead of the target //bean instance. //是否配置了后置处理器相关处理(如果配置了则返回一个代理) Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) { return bean; } } catch (Throwable ex) { //异常:BeanPostProcessor before instantiation of bean failed } //创建Bean Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isDebugEnabled()) { logger.debug("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; }
从上面的代码中可以看到,创建bean是交给doCreateBean方法来创建的。继续看doCreateBean这个方法: (这里面涉及到一个BeanWrapper这个接口,小伙伴可以移步了解一下《 Spring源码系列:BeanWrapper 》)
// 用BeanWrapper来持有创建出来的Bean对象 BeanWrapper instanceWrapper = null; //如果是单例的话,则先把缓存中的同名bean清除 if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } //实际创建的交给createBeanInstance来完成, //bean的生成,这里会使用默认的类生成器,包装成BeanWrapperImpl类, //为了下面的populateBean方法的属性注入做准备 if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); } final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null); Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null); mbd.resolvedTargetType = beanType;
允许后处理器修改合并的bean定义。
synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { try { applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } catch (Throwable ex) { //异常:Post-processing of merged bean definition failed } mbd.postProcessed = true; } }
即使被BeanFactoryAware等生命周期接口触发,也要尽快地缓存singletons 以便能够解析循环引用。
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>() { @Override public Object getObject() throws BeansException { return getEarlyBeanReference(beanName, mbd, bean); } }); }
这里是对bean的初始化的地方,一般情况下依赖注入就在这里发生;这个exposedObject变量保存的是在初始化处理完以后返回的作为依赖注入完成之后的bean。
// Initialize the bean instance. Object exposedObject = bean; try { populateBean(beanName, mbd, instanceWrapper); if (exposedObject != null) { exposedObject = initializeBean(beanName, exposedObject, mbd); } } catch (Throwable ex) { //抛出 if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) { throw (BeanCreationException) ex; } else { //异常:Initialization of bean failed } }
这里是注册bean
try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { //异常处理 } //返回结果 return exposedObject;
上面的5个代码段均是doCreateBean中的处理逻辑,有兴趣的小伙伴可以自行查阅源码。从上面的代码中我们依然没有得到具体创建的过程,因为在doCreateBean中又依赖: createBeanInstance
和 populateBean
两个方法。
在 createBeanInstance
中生成了Bean所包含的java对象。来看是怎么生成的:
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) { // 确保bean类实际上已经解析过了,可以实例化 Class<?> beanClass = resolveBeanClass(mbd, beanName); if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) { //异常:Bean class isn't public, and non-public access not allowed:beanName } //1. 使用工厂方法来进行bean的实例化 if (mbd.getFactoryMethodName() != null) { return instantiateUsingFactoryMethod(beanName, mbd, args); } // 重新创建相同的bean时快捷方式... boolean resolved = false; boolean autowireNecessary = false; if (args == null) { synchronized (mbd.constructorArgumentLock) { if (mbd.resolvedConstructorOrFactoryMethod != null) { resolved = true; autowireNecessary = mbd.constructorArgumentsResolved; } } } if (resolved) { if (autowireNecessary) { return autowireConstructor(beanName, mbd, null, null); } else { return instantiateBean(beanName, mbd); } } // 2.需要确定构造函数...,使用构造函数进行bean实例化 Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); if (ctors != null || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { return autowireConstructor(beanName, mbd, ctors, args); } //3.没有特殊的处理:只需使用无参数构造函数。(默认构造函数) return instantiateBean(beanName, mbd); }
从上面这段代码可以看出,对象的生成有许多不同的方式,有通过工厂的,也有通过容器的autowire特性生成的。当然这些生成方式都是由相关的BeanDefinition来指定的。
<bean id="user" class="com.glmapper.test.User"> <property name="name" value="glmapper"></property> </bean>
这种方式,通过class提供的权限定名,spring就可以利用反射机制创建这个bean。
<bean id="user" class="com.glmapper.test.UserFactory" factory-method="getUser"> <constructor-arg value="glmapper"></constructor-arg> </bean>
这种是利用静态工厂方法来创建的,提供的class并非是类的权限定名, 而是静态工厂的全类名;除此之外还需要指定获取bean的方法(此处是getUser)和参数(参数是glmapper)。
<bean id="userFactory" class="com.glmapper.test.UserInstanceFactory"> <!--用一个集合来保存我当前的对象实例--> <property name="map"> <map> <entry key="user1"> <bean class="com.glmapper.test.User"> <property name="name" value="glmapper1"></property> </bean> </entry> <entry key="user2"> <bean class="com.glmapper.test.User"> <property name="name" value="glmapper2"></property> </bean> </entry> </map> </property> </bean> //实例1 <bean id="user1" factory-bean="userFactory" factory-method="getUserInstance"> <constructor-arg value="user1"></constructor-arg> </bean> //实例2 <bean id="user2" factory-bean="userFactory" factory-method="getUserInstance"> <constructor-arg value="user2"></constructor-arg> </bean
这种方式和静态工厂的区别在于我们需要先实例化一个工厂对象,然后才能使用这个工厂对象来创建我们的bean。getUserInstance通过key值来获取我们已经实例化好的对象(当然方式有很多,此处以map来举个例子)。 关于注解的和使用FactoryBean接口的这里就暂时不说,后期再聊
OK,继续来分钟,上面说到的是以工厂方法创建bean,具体的源码有点长,这里就不放了,大概思路就如上面所提到的那几种方式。接下来看下常见的使用instantiateBean方式(使用它的默认构造函数)来构建bean的代码:
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) { try { Object beanInstance; final BeanFactory parent = this; //获取系统安全接口。 //如果已经为当前应用程序建立了安全管理器,则返回该安全管理器; //否则,返回null。 if (System.getSecurityManager() != null) { beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() { @Override public Object run() { return getInstantiationStrategy().instantiate(mbd, beanName, parent); } }, getAccessControlContext()); } else { beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent); } BeanWrapper bw = new BeanWrapperImpl(beanInstance); initBeanWrapper(bw); return bw; } catch (Throwable ex) { //异常:Instantiation of bean failed } }
可以看出,上面的创建都是通过:
getInstantiationStrategy().instantiate(mbd, beanName, parent);
这样一段代码来完成的,是的,这里已经快接近真相了。从语义上来分析,先是获取了一种策略,然后利用当前获取的策略再去执行实例化。OK,我们看下getInstantiationStrategy()拿到的是什么:
//返回实例化策略用于创建bean实例。 protected InstantiationStrategy getInstantiationStrategy() { return this.instantiationStrategy; } //默认的实例化测试是使用CGLIB代理 private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();
看到这里我们清楚了,默认构造函数的情况下,在spring中会使用Cglib来进行bean的实例化(关于cglib此处不再赘述)。我们看下CglibSubclassingInstantiationStrategy这个类的申明:
public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationStrategy
它继承自SimpleInstantiationStrategy ,这个又是什么鬼呢?
SimpleInstantiationStrategy是Spring用来生成Bean对象的默认类,在这个类中提供了两种实例化java对象的方法,一种是基于java自身反射机制的BeanUtils,还有一种就是基于Cglib
。
如何创建的就不说了;到这里createBeanInstance就说完了(Bean已经创建了);但是仅仅是创建,spring还没有处理它们,比如说bean对象的属性,依赖关系等等。这些就是上面提到的另外一个方法populateBean;
这个方法其实就做了一件事:**使用bean定义中的属性值在给定的BeanWrapper中填充bean实例。**分段来看: 下面这段代码是先将BeanDefinition中设置的property值封装成PropertyValues,然后检测我们的BeanWrapper是否为Null,如果为null则抛出异常或者跳过当前空实例赋值阶段
//获取到BeanDefinition中设置的property值,封装成PropertyValues PropertyValues pvs = mbd.getPropertyValues(); if (bw == null) { if (!pvs.isEmpty()) { //异常:Cannot apply property values to null instance } else { // Skip property population phase for null instance. return; } }
下面这段代码的意思是给任何InstantiationAwareBeanPostProcessors提供在设置属性之前修改bean状态的机会。
boolean continueWithPropertyPopulation = true; if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { continueWithPropertyPopulation = false; break; } } } } if (!continueWithPropertyPopulation) { return; }
下面就是对具体注入方式的处理:
//处理autowire的注入;可以根据bean的名称和类型来注入 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs); // 则根据名称添加基于自动装配的属性值。 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs); } // 根据类型添加基于自动装配的属性值。 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { autowireByType(beanName, mbd, bw, newPvs); } pvs = newPvs; }
两个判断条件,在满足的情况下做的处理分别是:
//返回这个工厂是否拥有一个InstantiationAwareBeanPostProcessor boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); //返回依赖检查代码。 boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE); if (hasInstAwareBpps || needsDepCheck) { //从给定的BeanWrapper中提取一组已过滤的PropertyDescriptors, //不包括在被忽略的依赖性接口上定义的被忽略的依赖类型或属性(译注)。 PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); if (hasInstAwareBpps) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvs == null) { return; } } } } if (needsDepCheck) { checkDependencies(beanName, mbd, filteredPds, pvs); } }
最后是对属性进行注入:
applyPropertyValues(beanName, mbd, bw, pvs);
这个方法描述的是对属性进行解析然后注入的过程;先来分析下applyPropertyValues的申明:
protected void applyPropertyValues(String beanName , BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs)
代码分段来看:
if (pvs == null || pvs.isEmpty()) { return; }
if (pvs instanceof MutablePropertyValues) { mpvs = (MutablePropertyValues) pvs; if (mpvs.isConverted()) { // 使用预先转换后的值。 try { bw.setPropertyValues(mpvs); return; } catch (BeansException ex) { //异常:Error setting property values } } original = mpvs.getPropertyValueList(); } else { original = Arrays.asList(pvs.getPropertyValues()); }
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
// Create a deep copy, resolving any references for values. List<PropertyValue> deepCopy = new ArrayList<PropertyValue>(original.size());
boolean resolveNecessary = false; for (PropertyValue pv : original) { //返回此持有者是否已经包含转换后的值(true),还是需要转换值(false)。 if (pv.isConverted()) { deepCopy.add(pv); } else { String propertyName = pv.getName(); Object originalValue = pv.getValue(); //看下面的注释resolveValueIfNecessary Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue); Object convertedValue = resolvedValue; boolean convertible = bw.isWritableProperty(propertyName) && !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName); if (convertible) { convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter); } // 可能将转换的值存储在合并的bean定义中,以避免为每个创建的bean实例重新转换。 if (resolvedValue == originalValue) { if (convertible) { pv.setConvertedValue(convertedValue); } deepCopy.add(pv); } else if (convertible && originalValue instanceof TypedStringValue && !((TypedStringValue) originalValue).isDynamic() && !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) { pv.setConvertedValue(convertedValue); deepCopy.add(pv); } else { resolveNecessary = true; deepCopy.add(new PropertyValue(pv, convertedValue)); } } }
resolveValueIfNecessary
给定一个PropertyValue,返回一个value,必要时解析对工厂中其他bean的引用。value可以是:
下面这段代码时依赖注入发生的地方,其实际上是在BeanWrapperImpl中来完成。
try { bw.setPropertyValues(new MutablePropertyValues(deepCopy)); } catch (BeansException ex) { //异常:Error setting property values }
上面说到spring是通过BeanDefinitionValueResolver来解析BeanDefinition的,然后再注入到property中,关于这个过程在下一篇中来说。
欢迎关注微信公众号