在Spring源码系列:依赖注入(一)(AbstractBeanFactory-getBean)最后说道getBean是依赖注入的起点,bean的建立都是经过createBean来完成具体的建立的。createBean的具体实现是在AbstractAutowireCapableBeanFactory中的。本篇就捋一捋这个方法看下bean的建立过程。java
这个方法是AbstractAutowireCapableBeanFactory这个类的中心方法,其做用就是建立一个bean实例,填充bean实例,后置处理等。spring
在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》)bash
代码 1:微信
// 用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;
复制代码
代码 2:app
容许后处理器修改合并的bean定义。ide
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
//异常:Post-processing of merged bean definition failed
}
mbd.postProcessed = true;
}
}
复制代码
代码 3 :函数
即便被BeanFactoryAware等生命周期接口触发,也要尽快地缓存singletons 以便可以解析循环引用。post
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);
}
});
}
复制代码
代码 4:
这里是对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
}
}
复制代码
代码 5:
这里是注册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来指定的。
Spring中配置Bean的方式咱们经常使用的一种是经过xml文件来配置,还有就是经过注解的方式来配置。
<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中,关于这个过程在下一篇中来讲。
欢迎关注微信公众号