spring 源码解读-DI
一、DI 发生的时间
当SpringIOC容器完成了Bean定义资源的定位、加载、解析、注册之后,IOC容器中已经管理类的Bean定义的相关数据,但是这个时候IOC容器还没有对所管理的Bean进行依赖注入。依赖注入发生的时间:
- 第一次getBean()方法时,IOC触发依赖注入;
- 当配置文件中将bean 元素配置了lazy-init = false 属性,即让容器在解析注册bean定义时进行实例化,触发依赖注入。
BeanFactory 接口定义了Spring IOC 容器基本功能和规范,BeanFactory 接口定义了几个getBean()方法。
二、getBean()触发依赖注入
在BeanFactory 中可以看到getBean()方法,它具体的实现在AbstractBeanFactory 中。
1、寻找getBean入口
public Object getBean(String name) throws BeansException {
return this.doGetBean(name, (Class)null, (Object[])null, false);
}
protected <T> T doGetBean(String name, Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {
//根据指定名称获取被管理的bean的名称
//如果指定别名,将别名转换成规范的bean的名称
final String beanName = this.transformedBeanName(name);
//先从缓存中取是否已经有被创建过的单例类型的bean
//对应单例的bean,整个IOC容器只需要创建一次
Object sharedInstance = this.getSingleton(beanName);
Object bean;
//IOC容器创建单例bean的实例
if (sharedInstance != null && args == null) {
if (this.logger.isDebugEnabled()) {
//指定的名称的bean,已经有被创建过的单例类型的bean,直接返回已经创建的bean
if (this.isSingletonCurrentlyInCreation(beanName)) {
this.logger.debug("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference");
} else {
this.logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
//获取bean的实例对象,主要是完成FactoryBean的相关处理
//FactoryBean是创建对象的工厂bean,而BeanFactory是管理容器中Bean的工厂
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
} else {//缓存中没有创建过的单例类型的bean
//缓存中已经有创建过的原型模式bean
//但是由于循环引用问题,导致实例化对象失败
if (this.isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
//对IOC容器中是否存在指定名称的BeanDefinition进行检查,先检查当前BeanFactory 中获取所需要的Bean,如果没有则
//当前容器的父容器去查找,如果还是没有则继续向上查找。
BeanFactory parentBeanFactory = this.getParentBeanFactory();
//当前容器的父容器存在,并且当前容器不存在指定名称的bean
if (parentBeanFactory != null && !this.containsBeanDefinition(beanName)) {
String nameToLookup = this.originalBeanName(name);
if (args != null) {
return parentBeanFactory.getBean(nameToLookup, args);
}
//委派父容器查找
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
//创建bean是否需要进行类型验证
if (!typeCheckOnly) {
this.markBeanAsCreated(beanName);
}
try {
//根据指定的bean名称获取其父级的bean的定义,主要是解决继承时子类合并父类公共属性
final RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
this.checkMergedBeanDefinition(mbd, beanName, args);
//获取当前bean所依赖的bean
String[] dependsOn = mbd.getDependsOn();
String[] var11;
//如果当前bean有依赖的bean
if (dependsOn != null) {
var11 = dependsOn;
int var12 = dependsOn.length;
for(int var13 = 0; var13 < var12; ++var13) {
String dependsOnBean = var11[var13];
if (this.isDependent(beanName, dependsOnBean)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dependsOnBean + "'");
}
//递归调用getBean方法,获取当前bean的依赖bean
this.registerDependentBean(dependsOnBean, beanName);
//当被依赖的bean注册给当前依赖的bean
this.getBean(dependsOnBean);
}
}
//创建单例bean
if (mbd.isSingleton()) {
//这里是一个匿名内部类,创建bean的实例对象,并注册给所依赖的bean
sharedInstance = this.getSingleton(beanName, new ObjectFactory<Object>() {
public Object getObject() throws BeansException {
try {
//创建一个指定bean的实例对象,如果有父级继承,则合并子类和父类的定义
return AbstractBeanFactory.this.createBean(beanName, mbd, args);
} catch (BeansException var2) {
//异常,显示的容器单例bean缓存中,清除实例对象
AbstractBeanFactory.this.destroySingleton(beanName);
throw var2;
}
}
});
//获取给定的bean的实例对象
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} else if (mbd.isPrototype()) {//创建原型模式的实例对象
var11 = null;
//原型模式,每次都会创建一个新的对象
Object prototypeInstance;
try {
//回调beforePrototypeCreation方法,默认是当前创建的原型对象
this.beforePrototypeCreation(beanName);
//创建指定bean 实例对象
prototypeInstance = this.createBean(beanName, mbd, args);
} finally {
//回调afterPrototypeCreation
this.afterPrototypeCreation(beanName);
}
//获取指定bean 实例对象
bean = this.getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
} else {//要创建的bean不是单例也不是原型,则根据bean定义资源中配置的生命周期范围,如:request、session
String scopeName = mbd.getScope();
Scope scope = (Scope)this.scopes.get(scopeName);
//如果没有定义生命周期范围,则bean不合法
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
//这里还是一个内部类,获取指定生命周期范围的实例
Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
public Object getObject() throws BeansException {
AbstractBeanFactory.this.beforePrototypeCreation(beanName);
Object var1;
try {
var1 = AbstractBeanFactory.this.createBean(beanName, mbd, args);
} finally {
AbstractBeanFactory.this.afterPrototypeCreation(beanName);
}
return var1;
}
});
//获取指定bean 实例对象
bean = this.getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
} catch (IllegalStateException var21) {
throw new BeanCreationException(beanName, "Scope '" + scopeName + "' is not active for the current thread; consider " + "defining a scoped proxy for this bean if you intend to refer to it from a singleton", var21);
}
}
} catch (BeansException var23) {
this.cleanupAfterBeanCreationFailure(beanName);
throw var23;
}
}
//对创建的bean实例进行类型检查
if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
try {
return this.getTypeConverter().convertIfNecessary(bean, requiredType);
} catch (TypeMismatchException var22) {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Failed to convert bean '" + name + "' to required type [" + ClassUtils.getQualifiedName(requiredType) + "]", var22);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
} else {
return bean;
}
}
通过上面IOC容器获取bean方法分析,可以看到在如果bean定义是单例模式,则容器在创建之前先从缓存中查找,以确保容器中只存在一个实例对象。如果是原型模式,则容器每次都会创建一下新的实例对象,除此之外还可以扩展为指定的生命周期范围。
具体的bean的实例创建过程由ObjectFactory接口匿名内部类的createBean()方法完成,ObjectFactory使用了委派模式,具体 的bean的实例创建过程由其实现类AbstractAutowireCapableBeanFactory
完成。
2、实例化
其创建bean的实例对象源码如下:
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
//判断创建的bean是否可以实例化,是否可以通过当前的类加载器加载
Class<?> resolvedClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
//校验和准备bean中的方法覆盖
try {
mbdToUse.prepareMethodOverrides();
} catch (BeanDefinitionValidationException var7) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", var7);
}
Object beanInstance;
try {
//如果bean配置了初始化前和初始化后的处理器,则试图返回一个需要创建bean的代理对象
beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
if (beanInstance != null) {
return beanInstance;
}
} catch (Throwable var8) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", var8);
}
beanInstance = this.doCreateBean(beanName, mbdToUse, args);
if (this.logger.isDebugEnabled()) {
this.logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
//真正创建bean的方法
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, Object[] args) {
//封装被创建的bean的对象
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null;
//获取实例化对象的类型
Class<?> beanType = instanceWrapper != null ? instanceWrapper.getWrappedClass() : null;
//调用PostProcessor 后置处理器
synchronized(mbd.postProcessingLock) {
if (!mbd.postProcessed) {
this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
mbd.postProcessed = true;
}
}
//向容器中缓存单例模式的bean的对象,以防循环引用
boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences &&
this.isSingletonCurrentlyInCreation(beanName);
if (earlySingletonExposure) {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
}
//匿名内部类,防止循环引用,今早持有对象的引用
this.addSingletonFactory(beanName, new ObjectFactory<Object>() {
public Object getObject() throws BeansException {
return AbstractAutowireCapableBeanFactory.this.getEarlyBeanReference(beanName, mbd, bean);
}
});
}
//bean的对象初始化,依赖注入在此触发
//这个exposedObject 在初始化完成之后返回作为依赖注入完成后的bean
Object exposedObject = bean;
try {
//将bean实例对象封装起来,并且bean定义中的配置属性赋值给实例对象
this.populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
//初始化对象
exposedObject = this.initializeBean(beanName, exposedObject, mbd);
}
} catch (Throwable var17) {
if (var17 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var17).getBeanName())) {
throw (BeanCreationException)var17;
}
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var17);
}
if (earlySingletonExposure) {
//获取指定名称已经注册的单例模式的bean对象
Object earlySingletonReference = this.getSingleton(beanName, false);
if (earlySingletonReference != null) {
//获取已经注册的bean和正在实例化的bean是同一个
if (exposedObject == bean) {
//当前实例化的bean 初始化完成
exposedObject = earlySingletonReference;
//当前bean依赖其他的bean,并且发送循环引用时,不容许新创建实例对象
} else if (!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {
String[] dependentBeans = this.getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet(dependentBeans.length);
String[] var12 = dependentBeans;
int var13 = dependentBeans.length;
//获取当前bean所依赖的其他bean
for(int var14 = 0; var14 < var13; ++var14) {
String dependentBean = var12[var14];
//对依赖的bean进行类型检查
if (!this.removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been " + "wrapped. This means that said other beans do not use the final version of the " + "bean. This is often the result of over-eager type matching - consider using " + "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
try {
//注册---完成依赖注入的bean
this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
return exposedObject;
} catch (BeanDefinitionValidationException var16) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16);
}
}
具体的依赖注入实现其实就是两个方法:
- createBeanInstance()方法,生产bean所包含的java对象实例;
- populateBean()方法,对bean属性的依赖注入处理。
3、选择bean实例化策略,执行实例化
在createBeanInstance()方法中,根据指定的初始化策略,使用简单工厂、工厂方法或者容器的自动装配特性生成java实例对象。源码如下:
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
// 使用工厂对bean实例化
Class<?> beanClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
} else if (mbd.getFactoryMethodName() != null) {
//调用工厂方法创建实例
return this.instantiateUsingFactoryMethod(beanName, mbd, args);
} else {
//使用容器的自动装配的方法进行实例化
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized(mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
//调用自动装配的特性,调用匹配的构造方法实例化
return autowireNecessary ? this.autowireConstructor(beanName, mbd, (Constructor[])null, (Object[])null) : this.instantiateBean(beanName, mbd);
} else {
//使用bean的构造方法创建
Constructor<?>[] ctors = this.determineConstructorsFromBeanPostProcessors(beanClass, beanName);
return ctors == null && mbd.getResolvedAutowireMode() != 3 && !mbd.hasConstructorArgumentValues() && ObjectUtils.isEmpty(args) ? this.instantiateBean(beanName, mbd) : this.autowireConstructor(beanName, mbd, ctors, args);
}
}
}
对于使用工厂方法和自动装特性的bean的实例化相等清楚,调用构造方法即可完成实例化,但是对最常用的无参构造方法就是使用相应的初始化策略(JDK反射机制)来进行初始化,在方法this.instantiateBean(beanName, mbd)
中就具体实现类使用策略实例化。
4、准备依赖注入
上面说过
- createBeanInstance()方法,生产bean所包含的java对象实例;
- populateBean()方法,对bean属性的依赖注入处理。
AbstractAutowireCapableBeanFactory中的populateBean()方法源码如下:
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
PropertyValues pvs = mbd.getPropertyValues();
if (bw == null) {
if (!((PropertyValues)pvs).isEmpty()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
} else {
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
Iterator var6 = this.getBeanPostProcessors().iterator();
while(var6.hasNext()) {
BeanPostProcessor bp = (BeanPostProcessor)var6.next();
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
if (continueWithPropertyPopulation) {
if (mbd.getResolvedAutowireMode() == 1 || mbd.getResolvedAutowireMode() == 2) {
MutablePropertyValues newPvs = new MutablePropertyValues((PropertyValues)pvs);
if (mbd.getResolvedAutowireMode() == 1) {
this.autowireByName(beanName, mbd, bw, newPvs);
}
if (mbd.getResolvedAutowireMode() == 2) {
this.autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
boolean hasInstAwareBpps = this.hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = mbd.getDependencyCheck() != 0;
if (hasInstAwareBpps || needsDepCheck) {
PropertyDescriptor[] filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
Iterator var9 = this.getBeanPostProcessors().iterator();
while(var9.hasNext()) {
BeanPostProcessor bp = (BeanPostProcessor)var9.next();
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
pvs = ibp.postProcessPropertyValues((PropertyValues)pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
this.checkDependencies(beanName, mbd, filteredPds, (PropertyValues)pvs);
}
}
//对属性进行依赖注入
this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs);
}
}
}
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
if (pvs != null && !pvs.isEmpty()) {
MutablePropertyValues mpvs = null;
if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
((BeanWrapperImpl)bw).setSecurityContext(this.getAccessControlContext());
}
List original;
if (pvs instanceof MutablePropertyValues) {
mpvs = (MutablePropertyValues)pvs;
//属性值已经转换
if (mpvs.isConverted()) {
try {
//为实例化对象设置属性值
bw.setPropertyValues(mpvs);
return;
} catch (BeansException var18) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Error setting property values", var18);
}
}
//获取属性值对象的原始类型
original = mpvs.getPropertyValueList();
} else {
original = Arrays.asList(pvs.getPropertyValues());
}
//获取用户自定义转换类型
TypeConverter converter = this.getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
//创建一个定义属性值的解析器,将Bean定义中的属性值解析为bean实例对象的实际值
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, (TypeConverter)converter);
List<PropertyValue> deepCopy = new ArrayList(original.size());
boolean resolveNecessary = false;
Iterator var11 = original.iterator();
while(true) {
while(var11.hasNext()) {
PropertyValue pv = (PropertyValue)var11.next();
if (pv.isConverted()) {
deepCopy.add(pv);
} else {
String propertyName = pv.getName();
Object originalValue = pv.getValue();
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
Object convertedValue = resolvedValue;
boolean convertible = bw.isWritableProperty(propertyName) && !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
if (convertible) {
convertedValue = this.convertForProperty(resolvedValue, propertyName, bw, (TypeConverter)converter);
}
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));
}
}
}
if (mpvs != null && !resolveNecessary) {
mpvs.setConverted();
}
//进行属性依赖注入
try {
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
return;
} catch (BeansException var19) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Error setting property values", var19);
}
}
}
}
对属性依赖注入分以下两种情况:
1、属性值类型不需要强制转换时,不需要解析属性值,直接准备进行依赖注入。
2、属性值类型需要强制转换时,首先需要解析属性值,然后对解析后的属性值进行依赖注入。
5、注入赋值
实际注入赋值是AbstractNestablePropertyAccessor 来实现的
BeanWrapperImpl extends AbstractNestablePropertyAccessor implements BeanWrapper
protected void setPropertyValue(AbstractNestablePropertyAccessor.PropertyTokenHolder tokens, PropertyValue pv) throws BeansException {
String propertyName = tokens.canonicalName;
String actualName = tokens.actualName;
Object propValue;
if (tokens.keys != null) {
AbstractNestablePropertyAccessor.PropertyTokenHolder getterTokens = new AbstractNestablePropertyAccessor.PropertyTokenHolder();
getterTokens.canonicalName = tokens.canonicalName;
getterTokens.actualName = tokens.actualName;
getterTokens.keys = new String[tokens.keys.length - 1];
System.arraycopy(tokens.keys, 0, getterTokens.keys, 0, tokens.keys.length - 1);
try {
propValue = this.getPropertyValue(getterTokens);
} catch (NotReadablePropertyException var20) {
throw new NotWritablePropertyException(this.getRootClass(), this.nestedPath + propertyName, "Cannot access indexed value in property referenced in indexed property path '" + propertyName + "'", var20);
}
String key = tokens.keys[tokens.keys.length - 1];
if (propValue == null) {
if (!this.isAutoGrowNestedPaths()) {
throw new NullValueInNestedPathException(this.getRootClass(), this.nestedPath + propertyName, "Cannot access indexed value in property referenced in indexed property path '" + propertyName + "': returned null");
}
int lastKeyIndex = tokens.canonicalName.lastIndexOf(91);
getterTokens.canonicalName = tokens.canonicalName.substring(0, lastKeyIndex);
propValue = this.setDefaultValue(getterTokens);
}
Class requiredType;
Object convertedValue;
Object newArray;
AbstractNestablePropertyAccessor.PropertyHandler ph;
if (propValue.getClass().isArray()) {
ph = this.getLocalPropertyHandler(actualName);
requiredType = propValue.getClass().getComponentType();
int arrayIndex = Integer.parseInt(key);
Object oldValue = null;
try {
if (this.isExtractOldValueForEditor() && arrayIndex < Array.getLength(propValue)) {
oldValue = Array.get(propValue, arrayIndex);
}
convertedValue = this.convertIfNecessary(propertyName, oldValue, pv.getValue(), requiredType, ph.nested(tokens.keys.length));
int length = Array.getLength(propValue);
if (arrayIndex >= length && arrayIndex < this.autoGrowCollectionLimit) {
Class<?> componentType = propValue.getClass().getComponentType();
newArray = Array.newInstance(componentType, arrayIndex + 1);
System.arraycopy(propValue, 0, newArray, 0, length);
this.setPropertyValue(actualName, newArray);
propValue = this.getPropertyValue(actualName);
}
Array.set(propValue, arrayIndex, convertedValue);
} catch (IndexOutOfBoundsException var19) {
throw new InvalidPropertyException(this.getRootClass(), this.nestedPath + propertyName, "Invalid array index in property path '" + propertyName + "'", var19);
}
} else {
Object convertedValue;
if (propValue instanceof List) {
ph = this.getPropertyHandler(actualName);
requiredType = ph.getCollectionType(tokens.keys.length);
List<Object> list = (List)propValue;
int index = Integer.parseInt(key);
convertedValue = null;
if (this.isExtractOldValueForEditor() && index < list.size()) {
convertedValue = list.get(index);
}
convertedValue = this.convertIfNecessary(propertyName, convertedValue, pv.getValue(), requiredType, ph.nested(tokens.keys.length));
int size = list.size();
if (index >= size && index < this.autoGrowCollectionLimit) {
for(int i = size; i < index; ++i) {
try {
list.add((Object)null);
} catch (NullPointerException var18) {
throw new InvalidPropertyException(this.getRootClass(), this.nestedPath + propertyName, "Cannot set element with index " + index + " in List of size " + size + ", accessed using property path '" + propertyName + "': List does not support filling up gaps with null elements");
}
}
list.add(convertedValue);
} else {
try {
list.set(index, convertedValue);
} catch (IndexOutOfBoundsException var17) {
throw new InvalidPropertyException(this.getRootClass(), this.nestedPath + propertyName, "Invalid list index in property path '" + propertyName + "'", var17);
}
}
} else {
if (!(propValue instanceof Map)) {
throw new InvalidPropertyException(this.getRootClass(), this.nestedPath + propertyName, "Property referenced in indexed property path '" + propertyName + "' is neither an array nor a List nor a Map; returned value was [" + propValue + "]");
}
ph = this.getLocalPropertyHandler(actualName);
requiredType = ph.getMapKeyType(tokens.keys.length);
Class<?> mapValueType = ph.getMapValueType(tokens.keys.length);
Map<Object, Object> map = (Map)propValue;
TypeDescriptor typeDescriptor = TypeDescriptor.valueOf(requiredType);
convertedValue = this.convertIfNecessary((String)null, (Object)null, key, requiredType, typeDescriptor);
Object oldValue = null;
if (this.isExtractOldValueForEditor()) {
oldValue = map.get(convertedValue);
}
newArray = this.convertIfNecessary(propertyName, oldValue, pv.getValue(), mapValueType, ph.nested(tokens.keys.length));
map.put(convertedValue, newArray);
}
}
} else {
AbstractNestablePropertyAccessor.PropertyHandler ph = this.getLocalPropertyHandler(actualName);
if (ph == null || !ph.isWritable()) {
if (pv.isOptional()) {
if (logger.isDebugEnabled()) {
logger.debug("Ignoring optional value for property '" + actualName + "' - property not found on bean class [" + this.getRootClass().getName() + "]");
}
return;
} else {
throw this.createNotWritablePropertyException(propertyName);
}
}
propValue = null;
PropertyChangeEvent propertyChangeEvent;
try {
Object originalValue = pv.getValue();
Object valueToApply = originalValue;
if (!Boolean.FALSE.equals(pv.conversionNecessary)) {
if (pv.isConverted()) {
valueToApply = pv.getConvertedValue();
} else {
if (this.isExtractOldValueForEditor() && ph.isReadable()) {
try {
propValue = ph.getValue();
} catch (Exception var21) {
Exception ex = var21;
if (var21 instanceof PrivilegedActionException) {
ex = ((PrivilegedActionException)var21).getException();
}
if (logger.isDebugEnabled()) {
logger.debug("Could not read previous value of property '" + this.nestedPath + propertyName + "'", ex);
}
}
}
valueToApply = this.convertForProperty(propertyName, propValue, originalValue, ph.toTypeDescriptor());
}
pv.getOriginalPropertyValue().conversionNecessary = valueToApply != originalValue;
}
ph.setValue(this.wrappedObject, valueToApply);
} catch (TypeMismatchException var22) {
throw var22;
} catch (InvocationTargetException var23) {
propertyChangeEvent = new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, propValue, pv.getValue());
if (var23.getTargetException() instanceof ClassCastException) {
throw new TypeMismatchException(propertyChangeEvent, ph.getPropertyType(), var23.getTargetException());
}
Throwable cause = var23.getTargetException();
if (cause instanceof UndeclaredThrowableException) {
cause = cause.getCause();
}
throw new MethodInvocationException(propertyChangeEvent, cause);
} catch (Exception var24) {
propertyChangeEvent = new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, propValue, pv.getValue());
throw new MethodInvocationException(propertyChangeEvent, var24);
}
}
}
属性依赖注入到bean的实例对象中过程:
1、对于集合类型的属性,将其属性值解析为目标类型的集合后直接赋值给属性
2、对于非集合类型的属性,大量的使用了JDK反射机制,通过属性的getter()方法获取指定属性注入以前的值,同时调用属性的setter()方法为属性设置注入后的值。
这个就是Spring 的setter() 注入原理。