spring的依赖注入是spring的依赖的一个很重要的特性,本文详细介绍了spring在进行属性注入的几种方式以及spring源码中是怎么完成这些属性注入的。
spring中对属性的赋值操作主要是在populateBean这个方法来完成的。可以看到这个populateBean主要做了四件事。
这四件事中第一件事调用afterInstantiation主要是正在属性赋值之前进行的操作,其提供了一个返回值标识是否需要进行后续的属性赋值。第二件事则是通过属性名或者属性类型来直接进行赋值,这种赋值方式则需要将依赖注入方式配置为AUTOWIRE_BY_NAME或者AUTOWIRE_BY_TYPE这两种方式,默认配置的bean是AUTOWIRE_NO,即不会进行这种方式的注入,而第三件事则是调用InstantiationAwareBeanPostProcessor 的postProcessPropertyValues方法来进行属性处理,这种方式提供了外部属性赋值的扩展,并且@Autowired等注解的注入实现则是在此处完成的,最后则是将PropertyValues利用BeanWraper赋值到对应的bean,不过在具体赋值之前会将RuntimeBeanReference这些配置中的ref这些标识beanName的属性从beanFactory中获取对应的bean。
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
PropertyValues pvs = mbd.getPropertyValues();
... //检查bw空
//调用afterInstantiation这个process,
//表示不止在doCreateBean这个创建bean的方法会调用afterInstantiation
//对于autowireBean这些依赖注入的方法也会调用其生命周期中的afterInstantiation
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
}
//直接根据属性来进行注入
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
//直接根据属性名查询对应的bean
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
//直接根据属性类型查询对应的bean
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
//利用postProcessPropertyValues方法提供外部对属性的注入操作
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
if (hasInstAwareBpps || needsDepCheck) {
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//@Autowire则是通过此处进行注册的
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
//进行属性赋值,主要是对RuntimeBeanReference这些运行时的数据进行相应的处理
applyPropertyValues(beanName, mbd, bw, pvs);
}
可以看到对于依赖注入其对应的依赖的bean的获取方式主要是三种:
这种方式的注入方式主要是在BeanDefinition的配置中将其autowireMode配置为byName或者byType类型,即下面这种配置方式。主要在autowire配置为byName或者byType。
public class TestBean {
private TestDe1 t1 ;
private TestDe2 t2 ;
public TestDe1 getT1() {
return t1;
}
public void setT1(TestDe1 t1) {
this.t1 = t1;
}
public TestDe2 getT2() {
return t2;
}
public void setT2(TestDe2 t2) {
this.t2 = t2;
}
}
public class TestDe1 {
}
public class TestDe2 {
}
这种注入的主要的对应的实现是在autowireByName和autowireByType方法中进行实现的,下面来详细介绍一下这两个方法。
可以看到这个方法的对应的主要逻辑是获取属性中满足条件的名字,并且通过名字获取对应的bean,将其加入到PropertyVaules中,并将对应的依赖关系注册到容器中。
protected void autowireByName(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
//获取mbd中的pvs没有数据,并且不是简单类,并且不是cglib定义的类,
//并且不是ignoredDependencyTypes中的类型,并且不是ignoredDependencyInterfaces的方法
//的对应的属性名称
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
//直接用属性名作为beanName找其对应的bean注入
for (String propertyName : propertyNames) {
if (containsBean(propertyName)) {
Object bean = getBean(propertyName);
pvs.add(propertyName, bean);
//注册dependentBean
registerDependentBean(propertyName, beanName);
...
}
else {
...
}
}
}
这个方法和autowireByName方法类似,其主要的区别是autowireByName是直接可以通过name从beanFactory获取对应的bean,而对于autowireByType则是利用resolveDependency来解析对应类型的bean。
protected void autowireByType(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
Set autowiredBeanNames = new LinkedHashSet(4);
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
try {
PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
if (Object.class != pd.getPropertyType()) {
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
// Do not allow eager init for type matching in case of a prioritized post-processor.
boolean eager = !PriorityOrdered.class.isAssignableFrom(bw.getWrappedClass());
DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
//查询对应的依赖
Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
if (autowiredArgument != null) {
pvs.add(propertyName, autowiredArgument);
}
//注册依赖
for (String autowiredBeanName : autowiredBeanNames) {
registerDependentBean(autowiredBeanName, beanName);
}
autowiredBeanNames.clear();
}
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
}
}
}
这里分了几种特殊类型的需要解析的type,对其进行了不同程度的包装,不过最终执行的操作都是doResolveDependency来完成对应的依赖的解析。
@Override
public Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName,
Set autowiredBeanNames, TypeConverter typeConverter) throws BeansException {
descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
if (javaUtilOptionalClass == descriptor.getDependencyType()) {
return new OptionalDependencyFactory().createOptionalDependency(descriptor, requestingBeanName);
}
else if (ObjectFactory.class == descriptor.getDependencyType() ||
ObjectProvider.class == descriptor.getDependencyType()) {
return new DependencyObjectProvider(descriptor, requestingBeanName);
}
else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
return new Jsr330ProviderFactory().createDependencyProvider(descriptor, requestingBeanName);
}
else {
//这里对于@Lazy注解是会创建一个代理,在真正用到对应的依赖的bean时在进行对应的依赖解析
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
if (result == null) {
//真正的进行依赖解析
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
}
}
可以看到这个方法中的依赖的获取方式主要有三种:
对于从beanFactory查询的对应类型的beanName,如果需要注入的是集合,则可以直接将结合直接返回,如果不是则则根据是否有唯一的配置了primary或者是否有最高优先级的bean来确定唯一的bean进行返回。
public Object doResolveDependency(DependencyDescriptor descriptor, String beanName,
Set autowiredBeanNames, TypeConverter typeConverter) throws BeansException {
InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
try {
//对于ShortcutDependencyDescriptor实现了这个方法,主要是对在DependencyDescriptor中直接可以进行缓存解析的返回对应的值
//像AutowiredAnnotationBeanPostProcessor则会创建ShortcutDependencyDescriptor缓存对应的beanName
Object shortcut = descriptor.resolveShortcut(this);
if (shortcut != null) {
return shortcut;
}
Class> type = descriptor.getDependencyType();
//主要是作为methodParameter时其对应的method上的@Value注解可以获取对应的值
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
if (value != null) {
if (value instanceof String) {
//利用StringValueResolver解析对应的字符串
String strVal = resolveEmbeddedValue((String) value);
BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null);
//利用beanExpressionResolver解析对应的字符串
value = evaluateBeanDefinitionString(strVal, bd);
}
//利用TypeConverter进行类型转换
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
return (descriptor.getField() != null ?
converter.convertIfNecessary(value, type, descriptor.getField()) :
converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
}
//处理List,Set这种集合形式的注入
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
return multipleBeans;
}
//获取type类型的所有候选的bean
//这里获取可能是对象,也有可能是对应的bean的类型
Map matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
//没有数据但是是required则抛出异常
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
return null;
}
String autowiredBeanName;
Object instanceCandidate;
if (matchingBeans.size() > 1) {
//确定唯一的对应类型的bean,主要是检查primary或者实现了OrderComparator找highestPriority的bean
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
//是必须的并且不是List这种集合形式的,则有descriptor尝试处理不唯一的情况
if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
return descriptor.resolveNotUnique(type, matchingBeans);
}
else {
return null;
}
}
//选择对应的值
instanceCandidate = matchingBeans.get(autowiredBeanName);
}
else {
// 只有一个匹配的则直接选这个
Map.Entry entry = matchingBeans.entrySet().iterator().next();
autowiredBeanName = entry.getKey();
instanceCandidate = entry.getValue();
}
if (autowiredBeanNames != null) {
autowiredBeanNames.add(autowiredBeanName);
}
//这里的instanceCandidate可能只是类型,所有需要进行resolveCandidate操作,获取真正的实例
return (instanceCandidate instanceof Class ?
descriptor.resolveCandidate(autowiredBeanName, type, this) : instanceCandidate);
}
finally {
ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
}
}
这个方法可以看到对应的依赖的beanName主要是从resolvableDependencies配置的bean,或者利用type查找到所有符合这个类型的beanName中查找,不过这些候选beanName主要进行三种限制:
protected Map findAutowireCandidates(
String beanName, Class> requiredType, DependencyDescriptor descriptor) {
//查询这个type下所有的beanName,其主要是调用所有的本地beanFactory以及父beanFactory
String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this, requiredType, true, descriptor.isEager());
Map result = new LinkedHashMap(candidateNames.length);
//从resolvableDependencies中进行对应的依赖查找
for (Class> autowiringType : this.resolvableDependencies.keySet()) {
if (autowiringType.isAssignableFrom(requiredType)) {
Object autowiringValue = this.resolvableDependencies.get(autowiringType);
autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
if (requiredType.isInstance(autowiringValue)) {
result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
break;
}
}
}
for (String candidate : candidateNames) {
//beanName和candidate是一样的
//或者对应的baneName或者factoryBean的对应的beanName是一样的
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
//将对应的类型或者对应的bean加入到result中
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
//利用fallbackDescriptor再做一次尝试
if (result.isEmpty() && !indicatesMultipleBeans(requiredType)) {
DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();
for (String candidate : candidateNames) {
//isAutowireCandidate这里主要做了泛型的检查(如Bean,和Bean的类型都是Bean,但是不应该能作为对应的依赖),以及@Qualifier的检查
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, fallbackDescriptor)) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
//对isSelfReference放宽限制不检查factoryMethod对应的bean
if (result.isEmpty()) {
for (String candidate : candidateNames) {
if (isSelfReference(beanName, candidate) &&
(!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) &&
isAutowireCandidate(candidate, fallbackDescriptor)) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
}
}
return result;
}
对于@Autowired和@Value的注入主要是利用AutowiredAnnotationBeanPostProcessor这个BeanPostProcessor来完成的。其主要的注入逻辑实在postProcessPropertyValues方法中,具体的配置方式为。
public class TestBean {
@Autowired
private TestDe1 t1 ;
@Value("t2")
private TestDe2 t2 ;
public TestDe1 getT1() {
return t1;
}
public void setT1(TestDe1 t1) {
this.t1 = t1;
}
public TestDe2 getT2() {
return t2;
}
public void setT2(TestDe2 t2) {
this.t2 = t2;
}
}
AutowiredAnnotationBeanPostProcessor主要是对@Autowired和@Value这两个注解下的属性和方法进行相应的注入操作,并对@Lookup下的方法注册lookup-method的操作,并且根据@Autowired或@Value决定相应的构造器的操作。
其下维护的属性中injectionMetadataCache主要是维护了有@Autowired和@Value注解的对应的方法或属性的meta数据,最终的属性注入则是利用InjectionMetadata进行操作。candidateConstructorCache则是对对应的beanClass中的选择的Constructor的缓存。lookupMethodsChecked则是表示的是beanName的对应的bean是否检查了对应的@Lookup的注解
public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
private final Set> autowiredAnnotationTypes =
new LinkedHashSet>(4);
//它的排序是最后-2,而RequiredAnnotationBeanPostProcessor是-1
//表示这个beanPostProcessor默认是排在RequiredAnnotationBeanPostProcessor前面
private int order = Ordered.LOWEST_PRECEDENCE - 2;
private ConfigurableListableBeanFactory beanFactory;
//标识对应的beanName是否检查了@lookup注解
private final Set lookupMethodsChecked =
Collections.newSetFromMap(new ConcurrentHashMap(256));
//beanClass-->Constructor[] 的缓存
private final Map, Constructor>[]> candidateConstructorsCache =
new ConcurrentHashMap, Constructor>[]>(256);
//beanName-->InjectionMetadata 注册的对应的metadata的缓存
private final Map injectionMetadataCache =
new ConcurrentHashMap(256);
}
其posrProcessPropertyValues方法逻辑其实很简单,就是将当前beanName和beanClass直接获取对应的InjectionMetadata这个meta,然后将其对应的注入操作委托给这个metadata数据,这个InjectionMetadata其实是通过解析对应的class中属性和方法是否有@Value,@Autowired等注解,并将每个属性或者方法解析为InjectedElement,最终是利用这些InjectedElement来进行注入操作。
postProcessMergedBeanDefinition方法也是获取InjectionMetadata,然后调用InjectionMetadata的checkConfigMembers方法来确定
@Override
public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
metadata.inject(bean, beanName, pvs);
}
catch (BeanCreationException ex) {
... throw
}
return pvs;
}
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class> beanType, String beanName) {
if (beanType != null) {
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
}
InjectionMetadata其实主要是维护了injectedElements和checkedElements这两个集合,其中injectedElements集合是注入的,而checkedElements这个集合则是方法checkConfigMembers这个方法调用时将InjectedElement中的field或者method注册到beanDefinition成功时加入的,主要作用应该是防止对相应的属性的重复注入。最终对field或method的注入也是InjectedElement来完成的
public class InjectionMetadata {
//目标class
private final Class> targetClass;
//从targetClass解析出的IbjectedElement
private final Collection injectedElements;
//调用checkConfigMembers加入的真正的调用的InjectedElement
private volatile Set checkedElements;
//主要是过滤beanDefinition中已经注册了的属性或者对象
public void checkConfigMembers(RootBeanDefinition beanDefinition) {
Set checkedElements = new LinkedHashSet(this.injectedElements.size());
for (InjectedElement element : this.injectedElements) {
Member member = element.getMember();
if (!beanDefinition.isExternallyManagedConfigMember(member)) {
beanDefinition.registerExternallyManagedConfigMember(member);
checkedElements.add(element);
}
}
this.checkedElements = checkedElements;
}
//对经历了checkConfigMembers的使用checkedElements集合中的InjectedElement进行处理
//否则用注册的injectedElements进行处理
public void inject(Object target, String beanName, PropertyValues pvs) throws Throwable {
Collection elementsToIterate =
(this.checkedElements != null ? this.checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
for (InjectedElement element : elementsToIterate) {
element.inject(target, beanName, pvs);
}
}
}
}
AutowiredFieldElement和AutowiredMethodElement是两个最终执行注入操作的InjectedElement的子类,其主要是通过filed,或者方法中的methodParameter构建出DependencyDescriptor利用beanFactory获取对应的依赖bean,并对其进行缓存,依赖关系注册到beanFactory以及进行属性赋值的操作。
这里是直接进行属性和方法赋值,而不是将依赖bean放入到PropertyValues中,因此对属性的注入不需要get,set方法,并且也不会走BeanWrapperImpl属性赋值的类型转换逻辑,并且@Required等注解的检查还是会生效。
可以看到这里也是通过type获取对应的依赖bean,其最终获取其依赖的bean还是通过 resolveDependency来完成的。
private class AutowiredFieldElement extends InjectionMetadata.InjectedElement {
//是否必须
private final boolean required;
//是否已经缓存标志
private volatile boolean cached = false;
//缓存的DependencyDescriptor
private volatile Object cachedFieldValue;
@Override
protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable {
Field field = (Field) this.member;
Object value;
if (this.cached) {
//利用缓存的DependencyDescriptor从beanFactory中获取对应的依赖bean
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
else {
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
desc.setContainingClass(bean.getClass());
Set autowiredBeanNames = new LinkedHashSet(1);
TypeConverter typeConverter = beanFactory.getTypeConverter();
try {
//通过filed获取对应的依赖bean
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
... throws
}
//缓存处理
synchronized (this) {
if (!this.cached) {
if (value != null || this.required) {
this.cachedFieldValue = desc;
//第一次将对应的依赖关系注册到容器中
registerDependentBeans(beanName, autowiredBeanNames);
if (autowiredBeanNames.size() == 1) {
String autowiredBeanName = autowiredBeanNames.iterator().next();
if (beanFactory.containsBean(autowiredBeanName) &&
beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
//这里只有一个候选bean,并且其对应的候选的beanName是当前的bean
//依赖的类型匹配,则用ShortcutDependencyDescriptor进行缓存,
//在进行下次依赖查找时直接返回这个beanName
this.cachedFieldValue = new ShortcutDependencyDescriptor(
desc, autowiredBeanName, field.getType());
}
}
}
else {
this.cachedFieldValue = null;
}
this.cached = true;
}
}
}
if (value != null) {
ReflectionUtils.makeAccessible(field);
//这里是直接进行了赋值操作,而不是放入到PropertyValues中
field.set(bean, value);
}
}
}
对于直接配置的依赖,其主要是在配置时以RuntimeBeanReference,BeanDefinitionHolder等形式存在于PropertyValues的对应的vaule中,并最终在AbstractAutowireCapableBeanFactory#applyPropertyValues下将对应的RuntimeBeanReference解析成对应的bean,下面的配置是对bean的属性的各种类型的配置方式,并用注释标注了其最终在PropertyValues中存在的类型。
#{1+2}
value
applyPropertyValues的主要操作是利用BeanDefinitionValueResolver进行类型转换,并在必要情况下调用TypeConverter进行类型转换操作。
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
if (pvs == null || pvs.isEmpty()) {
return;
}
MutablePropertyValues mpvs = null;
List original;
if (System.getSecurityManager() != null) {
if (bw instanceof BeanWrapperImpl) {
((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
}
}
//已经完成转换的直接利用BeanWrapper赋值
if (pvs instanceof MutablePropertyValues) {
mpvs = (MutablePropertyValues) pvs;
if (mpvs.isConverted()) {
// Shortcut: use the pre-converted values as-is.
try {
bw.setPropertyValues(mpvs);
return;
}
catch (BeansException ex) {
... throw
}
}
original = mpvs.getPropertyValueList();
}
else {
original = Arrays.asList(pvs.getPropertyValues());
}
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
//主要操作是利用BeanDefinitionValueResolver进行类型转换
List deepCopy = new ArrayList(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) {
convertedValue = convertForProperty(resolvedValue, propertyName, bw, 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();
}
// Set our (possibly massaged) deep copy.
try {
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
BeanDefinitionValueResolver主要是对beanFactory的相应的reference的操作,其主要是利用给的beanName从beanFactory中获取对应的bean。
其主要的操作有三种
注意:这里的利用BeanDefinition的方式创建的bean没有注册进入beanFactory中。只是利用beanFactory创建了对应的bean
上面三种主要是最终三种对三种基础类型(string,RuntimeBeanReference,BeanDefinition)进行的操作,其他如ManagedList,ManagedSet这些集合最终都会进行递归调用resolveValueIfNessary这个方法从而转为这几种基础类型进行操作
注意:这里的RuntimeBeanReference和RuntimeBeanNameReference的主要区别是前一个返回的是bean这个Object对象,而后一个返回的最终还是一个字符串,只是这个字符串进行了是否是beanName的检查以及evaluate操作
public Object resolveValueIfNecessary(Object argName, Object value) {
if (value instanceof RuntimeBeanReference) {
RuntimeBeanReference ref = (RuntimeBeanReference) value;
return resolveReference(argName, ref);
}
else if (value instanceof RuntimeBeanNameReference) {
String refName = ((RuntimeBeanNameReference) value).getBeanName();
refName = String.valueOf(doEvaluate(refName));
if (!this.beanFactory.containsBean(refName)) {
... throw
}
return refName;
}
else if (value instanceof BeanDefinitionHolder) {
BeanDefinitionHolder bdHolder = (BeanDefinitionHolder) value;
return resolveInnerBean(argName, bdHolder.getBeanName(), bdHolder.getBeanDefinition());
}
else if (value instanceof BeanDefinition) {
BeanDefinition bd = (BeanDefinition) value;
String innerBeanName = "(inner bean)" + BeanFactoryUtils.GENERATED_BEAN_NAME_SEPARATOR +
ObjectUtils.getIdentityHexString(bd);
return resolveInnerBean(argName, innerBeanName, bd);
}
else if (value instanceof ManagedArray) {
ManagedArray array = (ManagedArray) value;
Class> elementType = array.resolvedElementType;
if (elementType == null) {
String elementTypeName = array.getElementTypeName();
if (StringUtils.hasText(elementTypeName)) {
try {
elementType = ClassUtils.forName(elementTypeName, this.beanFactory.getBeanClassLoader());
array.resolvedElementType = elementType;
}
catch (Throwable ex) {
... throw
}
}
else {
elementType = Object.class;
}
}
return resolveManagedArray(argName, (List>) value, elementType);
}
else if (value instanceof ManagedList) {
// May need to resolve contained runtime references.
return resolveManagedList(argName, (List>) value);
}
else if (value instanceof ManagedSet) {
// May need to resolve contained runtime references.
return resolveManagedSet(argName, (Set>) value);
}
else if (value instanceof ManagedMap) {
// May need to resolve contained runtime references.
return resolveManagedMap(argName, (Map, ?>) value);
}
//注意这里的properties是不能设置ref这种bean的方式
else if (value instanceof ManagedProperties) {
Properties original = (Properties) value;
Properties copy = new Properties();
for (Map.Entry