- 前言
- 第一部分 核心实现
- 第 1 章 Spring 整体架构和环境搭建
- 第 2 章 容器的基本实现
- 第 3 章 默认标签的解析
- 第 4 章 自定义标签的解析
- 第 5 章 bean 的加载
- 第 6 章 容器的功能扩展
- 第 7 章 AOP
- 第二部分 企业应用
- 第 8 章 数据库连接 JDBC
- 第 9 章 整合 MyBatis
- 第 10 章 事务
- 第 11 章 SpringMVC
- 第 12 章 远程服务
- 第 13 章 Spring 消息
5.7.3 属性注入
在了解循环依赖的时候,我们曾经反复提到了 populateBean 这个函数,也多少了解了这个函数的主要功能就是属性填充,那么究竟是如何实现填充的呢?
protected void populateBean(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw) {
PropertyValues pvs = mbd.getPropertyValues();
if (bw == null) {
if (!pvs.isEmpty()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property
values to null instance");
}
else {
//没有可填充的属性
return;
}
}
//给 InstantiationAwareBeanPostProcessors 最后一次机会在属性设置前来改变 bean
//如:可以用来支持属性注入的类型
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
PostProcessor) bp;
InstantiationAwareBeanPostProcessor ibp = (Instantiation AwareBean
//返回值为是否继续填充 bean
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(),
beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
//如果后处理器发出停止填充命令则终止后续的执行
if (!continueWithPropertyPopulation) {
return;
}
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
//根据名称自动注入
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
//根据类型自动注入
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
//后处理器已经初始化
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
//需要依赖检查
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.
DEPENDENCY_CHECK_NONE);
if (hasInstAwareBpps || needsDepCheck) {
PropertyDescriptor[] filteredPds = filterPropertyDescriptors ForDependency
Check(bw);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBean
PostProcessor) bp;
//对所有需要依赖检查的属性进行后处理
pvs = ibp.postProcessPropertyValues(pvs, filteredPds,
bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
//依赖检查,对应 depends-on 属性,3.0 已经弃用此属性
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
//将属性应用到 bean 中
applyPropertyValues(beanName, mbd, bw, pvs);
}
在 populateBean 函数中提供了这样的处理流程。
(1)InstantiationAwareBeanPostProcessor 处理器的 postProcessAfterInstantiation 函数的应用,此函数可以控制程序是否继续进行属性填充。
(2)根据注入类型(byName/byType),提取依赖的 bean,并统一存入 PropertyValues 中。
(3)应用 InstantiationAwareBeanPostProcessor 处理器的 postProcessPropertyValues 方法,对属性获取完毕填充前对属性的再次处理,典型应用是 RequiredAnnotationBeanPostProcessor 类中对属性的验证。
(4)将所有 PropertyValues 中的属性填充至 BeanWrapper 中。
在上面的步骤中有几个地方是我们比较感兴趣的,它们分别是依赖注入( autowire ByName/autowireByType)以及属性填充,那么,接下来进一步分析这几个功能的实现细节。
1.autowireByName
上文提到根据注入类型(byName/byType),提取依赖的 bean,并统一存入 PropertyValues 中,那么我们首先了解下 byName 功能是如何实现的。
protected void autowireByName(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutableProperty
Values pvs) {
//寻找 bw 中需要依赖注入的属性
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
if (containsBean(propertyName)) {
//递归初始化相关的 bean
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");
}
}
}
}
如果读者之前了解了 autowire 的使用方法,相信理解这个函数的功能不会太困难,无非是在传入的参数 pvs 中找出已经加载的 bean,并递归实例化,进而加入到 pvs 中。
2.autowireByType
autowireByType 与 autowireByName 对于我们理解与使用来说复杂程度都很相似,但是其实现功能的复杂度却完全不一样。
protected void autowireByType(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutableProperty Values pvs) {
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
Set<String> autowiredBeanNames = new LinkedHashSet<String>(4);
//寻找 bw 中需要依赖注入的属性
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())) {
//探测指定属性的 set 方法
MethodParameter methodParam = BeanUtils.getWriteMethod Parameter(pd);
boolean eager = !PriorityOrdered.class. isAssignableFrom (bw.get
WrappedClass());
DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor
(methodParam, eager);
//解析指定 beanName 的属性所匹配的值,并把解析到的属性名称存储在
autowiredBeanNames 中,当属性存在多个封装 bean 时如:
//@Autowired private List<A> aList; 将会找到所有匹配 A 类型的 bean 并
将其注入
Object autowiredArgument = resolveDependency(desc, beanName,
autowiredBeanNames, converter);
if (autowiredArgument != null) {
pvs.add(propertyName, autowiredArgument);
}
for (String autowiredBeanName : autowiredBeanNames) {
//注册依赖
registerDependentBean(autowiredBeanName, beanName);
if (logger.isDebugEnabled()) {
beanName + "' via property '" +
logger.debug("Autowiring by type from bean name '" +
propertyName + "' to bean named '" +
autowiredBeanName + "'");
}
}
autowiredBeanNames.clear();
}
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(mbd.getResourceDescription(),
beanName, propertyName, ex);
}
}
}
实现根据名称自动匹配的第一步就是寻找 bw 中需要依赖注入的属性,同样对于根据类型自动匹配的实现来讲第一步也是寻找 bw 中需要依赖注入的属性,然后遍历这些属性并寻找类型匹配的 bean,其中最复杂的就是寻找类型匹配的 bean。同时,Spring 中提供了对集合的类型注入的支持,如使用注解的方式:
@Autowired
private List<Test> tests;
Spring 将会把所有与 Test 匹配的类型找出来并注入到 tests 属性中,正是由于这一因素,所以在 autowireByType 函数中,新建了局部遍历 autowiredBeanNames,用于存储所有依赖的 bean,如果只是对非集合类的属性注入来说,此属性并无用处。
对于寻找类型匹配的逻辑实现封装在了 resolveDependency 函数中。
DefaultListableBeanFactory.java
public Object resolveDependency(DependencyDescriptor descriptor, String beanName,
Set<String> autowiredBeanNames, TypeConverter typeConverter) throws
BeansException {
descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
if (descriptor.getDependencyType().equals(ObjectFactory.class)) {
//ObjectFactory 类注入的特殊处理
return new DependencyObjectFactory(descriptor, beanName);
}
else if (descriptor.getDependencyType().equals(javaxInjectProviderClass)) {
//javaxInjectProviderClass 类注入的特殊处理
beanName);
return new DependencyProviderFactory().createDependencyProvider (descriptor,
}
else {
//通用处理逻辑
return doResolveDependency(descriptor, descriptor.getDependencyType(),
beanName, autowiredBeanNames, typeConverter);
}
}
protected Object doResolveDependency(DependencyDescriptor descriptor, Class<?> type,
String beanName,
Set<String> autowiredBeanNames, TypeConverter typeConverter) throws
BeansException {
/*
* 用于支持 Spring 中新增的注解 @Value
*/
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
if (value != null) {
if (value instanceof String) {
String strVal = resolveEmbeddedValue((String) value);
BeanDefinition bd = (beanName != null && containsBean(beanName) ?
getMergedBeanDefinition(beanName) : null);
value = evaluateBeanDefinitionString(strVal, bd);
}
TypeConverter converter = (typeConverter != null ? typeConverter :
getTypeConverter());
return converter.convertIfNecessary(value, type);
}
//如果解析器没有成功解析,则需要考虑各种情况
//属性是数组类型
if (type.isArray()) {
Class<?> componentType = type.getComponentType();
//根据属性类型找到 beanFacotry 中所有类型的匹配 bean,
//返回值的构成为:key=匹配的 beanName,value=beanName 对应的实例化后的 bean(通过
getBean(beanName) 返回)
Map<String, Object> matchingBeans = findAutowireCandidates(beanName,
componentType, descriptor);
if (matchingBeans.isEmpty()) {
//如果 autowire 的 require 属性为 true 而找到的匹配项却为空则只能抛出异常
if (descriptor.isRequired()) {
raiseNoSuchBeanDefinitionException(componentType, "array of " +
componentType.getName(), descriptor);
}
return null;
}
if (autowiredBeanNames != null) {
autowiredBeanNames.addAll(matchingBeans.keySet());
}
TypeConverter converter = (typeConverter != null ? typeConverter :
getTypeConverter());
//通过转换器将 bean 的值转换为对应的 type 类型
return converter.convertIfNecessary(matchingBeans.values(), type);
}
//属性是 Collection 类型
else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {
Class<?> elementType = descriptor.getCollectionType();
if (elementType == null) {
if (descriptor.isRequired()) {
throw new FatalBeanException("No element type declared for
collection [" + type.getName() + "]");
}
return null;
}
Map<String, Object> matchingBeans = findAutowireCandidates(beanName,
elementType, descriptor);
if (matchingBeans.isEmpty()) {
if (descriptor.isRequired()) {
raiseNoSuchBeanDefinitionException(elementType, "collection of "
+ elementType.getName(), descriptor);
}
return null;
}
if (autowiredBeanNames != null) {
autowiredBeanNames.addAll(matchingBeans.keySet());
}
TypeConverter converter = (typeConverter != null ? typeConverter :
getTypeConverter());
return converter.convertIfNecessary(matchingBeans.values(), type);
}
//属性是 Map 类型
else if (Map.class.isAssignableFrom(type) && type.isInterface()) {
Class<?> keyType = descriptor.getMapKeyType();
if (keyType == null || !String.class.isAssignableFrom(keyType)) {
if (descriptor.isRequired()) {
throw new FatalBeanException("Key type [" + keyType + "] of map
[" + type.getName() +
"] must be assignable to [java.lang.String]");
}
return null;
}
Class<?> valueType = descriptor.getMapValueType();
if (valueType == null) {
if (descriptor.isRequired()) {
throw new FatalBeanException("No value type declared for map ["
+ type.getName() + "]");
}
return null;
}
Map<String, Object> matchingBeans = findAutowireCandidates(beanName,
valueType, descriptor);
if (matchingBeans.isEmpty()) {
if (descriptor.isRequired()) {
raiseNoSuchBeanDefinitionException(valueType, "map with value
type " + valueType.getName(), descriptor);
}
return null;
}
if (autowiredBeanNames != null) {
autowiredBeanNames.addAll(matchingBeans.keySet());
}
return matchingBeans;
}else {
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type,
descriptor);
if (matchingBeans.isEmpty()) {
if (descriptor.isRequired()) {
raiseNoSuchBeanDefinitionException(type, "", descriptor);
}
return null;
}
if (matchingBeans.size() > 1) {
String primaryBeanName = determinePrimaryCandidate(matchingBeans,
descriptor);
if (primaryBeanName == null) {
matching bean but found " +
throw new NoSuchBeanDefinitionException(type, "expected single
matchingBeans.size() + ": " + matchingBeans.keySet());
}
if (autowiredBeanNames != null) {
autowiredBeanNames.add(primaryBeanName);
}
return matchingBeans.get(primaryBeanName);
}
//已经可以确定只有一个匹配项
next();
Map.Entry<String, Object> entry = matchingBeans.entrySet(). iterator().
if (autowiredBeanNames != null) {
autowiredBeanNames.add(entry.getKey());
}
return entry.getValue();
}
}
寻找类型的匹配执行顺序时,首先尝试使用解析器进行解析,如果解析器没有成功解析,那么可能是使用默认的解析器没有做任何处理,或者是使用了自定义的解析器,但是对于集合等类型来说并不在解析范围之内,所以再次对不同类型进行不同情况的处理,虽说对于不同类型处理方式不一致,但是大致的思路还是很相似的,所以函数中只对数组类型进行了详细地注释。
3.applyPropertyValues
程序运行到这里,已经完成了对所有注入属性的获取,但是获取的属性是以 PropertyValues 形式存在的,还并没有应用到已经实例化的 bean 中,这一工作是在 applyPropertyValues 中。
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw,
PropertyValues pvs) {
if (pvs == null || pvs.isEmpty()) {
return;
}
MutablePropertyValues mpvs = null;
List<PropertyValue> original;
if (System.getSecurityManager()!= null) {
if (bw instanceof BeanWrapperImpl) {
((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
}
}
if (pvs instanceof MutablePropertyValues) {
mpvs = (MutablePropertyValues) pvs;
//如果 mpvs 中的值已经被转换为对应的类型那么可以直接设置到 beanwapper 中
if (mpvs.isConverted()) {
// Shortcut: use the pre-converted values as-is.
try {
bw.setPropertyValues(mpvs);
return;
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting
property values", ex);
}
}
original = mpvs.getPropertyValueList();
}else {
//如果 pvs 并不是使用 MutablePropertyValues 封装的类型,那么直接使用原始的属性获取方法
original = Arrays.asList(pvs.getPropertyValues());
}
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
//获取对应的解析器
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) {
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) {
bw, converter);
convertedValue = convertForProperty(resolvedValue, propertyName,
}
if (resolvedValue == originalValue) {
if (convertible) {
pv.setConvertedValue(convertedValue);
}
deepCopy.add(pv);
}
else if (convertible && originalValue instanceof TypedStringValue &&
!((TypedStringValue) originalValue).isDynamic() &&
(convertedValue))) {
!(convertedValue instanceof Collection || ObjectUtils.isArray
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));
}
catch (BeansException ex) {
throw new BeanCreationException(
values", ex);
mbd.getResourceDescription(), beanName, "Error setting property
}
}
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论