@Autowire的实现方式name与type
@Autowire装配本身有两种形式byName 与 byType,上一篇博文写了他们的用法以及使用的场景,现在来看看他们是怎么实现的,首先看populateBean方法,他是spring进行属性注入的方法,@Autowire本身就是属性注入的一部分
/**
* 属性注入
*/
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
if (bw == null) {
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
} else {
if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
Iterator var4 = this.getBeanPostProcessorCache().instantiationAware.iterator();
while(var4.hasNext()) {
InstantiationAwareBeanPostProcessor bp = (InstantiationAwareBeanPostProcessor)var4.next();
if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
PropertyValues pvs = mbd.hasPropertyValues() ? mbd.getPropertyValues() : null;
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == 1 || resolvedAutowireMode == 2) {
MutablePropertyValues newPvs = new MutablePropertyValues((PropertyValues)pvs);
if (resolvedAutowireMode == 1) {
// 根据name自动注入
this.autowireByName(beanName, mbd, bw, newPvs);
}
if (resolvedAutowireMode == 2) {
// 根据Type自动注入
this.autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
boolean hasInstAwareBpps = this.hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = mbd.getDependencyCheck() != 0;
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
PropertyValues pvsToUse;
for(Iterator var9 = this.getBeanPostProcessorCache().instantiationAware.iterator(); var9.hasNext(); pvs = pvsToUse) {
InstantiationAwareBeanPostProcessor bp = (InstantiationAwareBeanPostProcessor)var9.next();
pvsToUse = bp.postProcessProperties((PropertyValues)pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = bp.postProcessPropertyValues((PropertyValues)pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
}
}
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
this.checkDependencies(beanName, mbd, filteredPds, (PropertyValues)pvs);
}
if (pvs != null) {
// 将上面得到的依赖转化到已经实例化的bean中
this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs);
}
}
}
上面的代码是在scope为单例模式下,进行的属性注入源码,这段源码中有两个人方法,就是@Autowire中byName和byType的实现
if (resolvedAutowireMode == 1) {
// 根据name自动注入
this.autowireByName(beanName, mbd, bw, newPvs);
}
if (resolvedAutowireMode == 2) {
// 根据Type自动注入
this.autowireByType(beanName, mbd, bw, newPvs);
}
autowireByName
protected void autowireByName(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { // 寻找BeanWrapper bw中需要依赖注入的属性 String[] propertyNames = this.unsatisfiedNonSimpleProperties(mbd, bw); String[] var6 = propertyNames; int var7 = propertyNames.length; for(int var8 = 0; var8 < var7; ++var8) { String propertyName = var6[var8]; if (this.containsBean(propertyName)) { // 递归初始化相关的bean Object bean = this.getBean(propertyName); pvs.add(propertyName, bean); // 注册依赖 this.registerDependentBean(propertyName, beanName); if (this.logger.isTraceEnabled()) { this.logger.trace("Added autowiring by name from bean name '" + beanName + "' via property '" + propertyName + "' to bean named '" + propertyName + "'"); } } else if (this.logger.isTraceEnabled()) { this.logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName + "' by name: no matching bean found"); } } }
- 寻找BeanWrapper bw中需要依赖注入的属性
- 循环遍历将这些属性放到MutablePropertyValues对象中,注意这里其实是传入了临时变量,并且改变了临时变量,在重构·代码的设计之道中要求尽量不要传入临时变量,但是在实际的工作中还是有很多场景要通过这种形式来实现,可见代码的设计是不拘一格的。
autowireByType
protected void autowireByType(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { TypeConverter converter = this.getCustomTypeConverter(); if (converter == null) { converter = bw; } Set<String> autowiredBeanNames = new LinkedHashSet(4); // 寻找BeanWrapper bw中需要依赖注入的属性 String[] propertyNames = this.unsatisfiedNonSimpleProperties(mbd, bw); String[] var8 = propertyNames; int var9 = propertyNames.length; for(int var10 = 0; var10 < var9; ++var10) { String propertyName = var8[var10]; try { PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName); if (Object.class != pd.getPropertyType()) { MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd); boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered); DependencyDescriptor desc = new AbstractAutowireCapableBeanFactory.AutowireByTypeDependencyDescriptor(methodParam, eager); Object autowiredArgument = this.resolveDependency(desc, beanName, autowiredBeanNames, (TypeConverter)converter); if (autowiredArgument != null) { pvs.add(propertyName, autowiredArgument); } Iterator var17 = autowiredBeanNames.iterator(); while(var17.hasNext()) { // 注册依赖 this.registerDependentBean(autowiredBeanName, beanName); if (this.logger.isTraceEnabled()) { this.logger.trace("Autowiring by type from bean name '" + beanName + "' via property '" + propertyName + "' to bean named '" + autowiredBeanName + "'"); } } autowiredBeanNames.clear(); } } catch (BeansException var19) { throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, var19); } } }
byType比byname相对复杂,因为byType要考虑到注入的对象是集合的情况,如
@Autowired
private List<Test> tests;
所以出现了autowiredBeanNames属性。
- 属性处理
上面的方法,无论是byName和byType其实都是对依赖属性的获取,并且把这些属性放到了MutablePropertyValues对象中,并没有应用到已经实例化的bean中这个bean在上面的方法中可以理解为BeanWrapper对象。
而转化是在this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs)方法
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
if (!pvs.isEmpty()) {
if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
((BeanWrapperImpl)bw).setSecurityContext(this.getAccessControlContext());
}
MutablePropertyValues mpvs = null;
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;
}
// 获取对应解析器
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();
if (originalValue == AutowiredPropertyMarker.INSTANCE) {
Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();
if (writeMethod == null) {
throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);
}
originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);
}
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 {
// 将MutablePropertyValues对象转换到BeanWrapper中
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
return;
} catch (BeansException var19) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Error setting property values", var19);
}
}
}
}