spring 源码分析二:ioc 容器的依赖注入的原理与源码分析

IOC和DI区别

(1)IOC: 控制反转,把对象创建交给spring进行配置
(2)DI: 依赖注入,向类里面的属性中设置值
(3)关系:依赖注入不能单独存在,需要在ioc基础之上完成操作

Spring源码解析三:IOC容器的依赖注入

一、Bean对象创建的时机

依赖注入是在Bean对象创建的时候完成的,那么第一个问题来了,Bean对象什么时候创建?

Bean对象的创建是在getBean方法被调用的时候发生的,而在Spring中有两个场景会触发getBean方法被调用。

1、单例模式并且是非延迟加载的对象,会在IOC容器初始化的时候被创建且初始化。

2、非单例模式或者是延迟加载的对象,是应用第一次向容器索要该Bean对象的时候被创建且初始化。

虽然入口场景不同,但是Bean对象创建的过程是一样的,都是调用AbstractBeanFactory中getBean方法。

 

我们来重点看下DefaultListableBeanFactory的preInstantiateSingletons 的源码,就能对前面提到的规则有一个很好的理解。

复制代码

 1 public void preInstantiateSingletons() throws BeansException {
 2         if (this.logger.isInfoEnabled()) {
 3             this.logger.info("Pre-instantiating singletons in " + this);
 4         }
 5 
 6         synchronized (this.beanDefinitionMap) {
 7             for (String beanName : this.beanDefinitionNames) {
 8                 RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
 9                 if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
10                     if (isFactoryBean(beanName)) {
11                         final FactoryBean factory = (FactoryBean) getBean(FACTORY_BEAN_PREFIX + beanName);
12                         boolean isEagerInit;
13                         if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
14                             isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
15                                 public Boolean run() {
16                                     return ((SmartFactoryBean) factory).isEagerInit();
17                                 }
18                             }, getAccessControlContext());
19                         }
20                         else {
21                             isEagerInit = factory instanceof SmartFactoryBean && ((SmartFactoryBean) factory).isEagerInit(); 
22                         }
23                         if (isEagerInit) {
24                             getBean(beanName);
25                         }
26                     }
27                     else {
28                         getBean(beanName);
29                     }
30                 }
31             }
32         }
33     }

复制代码

这里验证了第一个规则,容器初始化时,会对单例并且是非延迟加载的对象进行实例化。

二、依赖注入的源码分析

 这里以DefaultListableBeanFactory的基类AbstractBeanFactory中的getBean()方法来进行介绍。

public Object getBean(String name) throws BeansException {
        return doGetBean(name, null, null, false);
    }

复制代码

  1     protected <T> T doGetBean(
  2             final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
  3             throws BeansException {
  4 
  5         final String beanName = transformedBeanName(name);
  6         Object bean;
  7 
  8         // 先尝试从缓存中获取bean,对于那些单例模式的Bean,不需要重复创建。
  9         Object sharedInstance = getSingleton(beanName);
 10         if (sharedInstance != null && args == null) {
 11             if (logger.isDebugEnabled()) {
 12                 if (isSingletonCurrentlyInCreation(beanName)) {
 13                     logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
 14                             "' that is not fully initialized yet - a consequence of a circular reference");
 15                 }
 16                 else {
 17                     logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
 18                 }
 19             }
         //这里处理的是FactoryBean相关的处理,以取得FactoryBean的生产结果
 20             bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
 21         }
 22 
 23         else {
 24             // Fail if we're already creating this bean instance:
 25             // We're assumably within a circular reference.
 26             if (isPrototypeCurrentlyInCreation(beanName)) {
 27                 throw new BeanCurrentlyInCreationException(beanName);
 28             }
 29 
 30             //对IOC容器中BeanDefinition是否存在进行检查,如果在当前Bean工厂中找不到需要的Bean,则到双亲BeanFactory中去查找,依次类推
 31             BeanFactory parentBeanFactory = getParentBeanFactory();
 32             if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
 33                 // Not found -> check parent.
 34                 String nameToLookup = originalBeanName(name);
 35                 if (args != null) {
 36                     // Delegation to parent with explicit args.
 37                     return (T) parentBeanFactory.getBean(nameToLookup, args);
 38                 }
 39                 else {
 40                     // No args -> delegate to standard getBean method.
 41                     return parentBeanFactory.getBean(nameToLookup, requiredType);
 42                 }
 43             }
 44 
 45             if (!typeCheckOnly) {
 46                 markBeanAsCreated(beanName);
 47             }
 48             //根据BeanName取得BeanDefinition
 49             final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
 50             checkMergedBeanDefinition(mbd, beanName, args);
 51 
 52             // 获取当前Bean依赖的Bean,这里可能会触发getBean方法的递归调用,直到没有任何以来的Bean为止。
 53             String[] dependsOn = mbd.getDependsOn();
 54             if (dependsOn != null) {
 55                 for (String dependsOnBean : dependsOn) {
 56                     getBean(dependsOnBean);
 57                     registerDependentBean(dependsOnBean, beanName);
 58                 }
 59             }
 60 
 61             // Create bean instance.
 62             if (mbd.isSingleton()) {
 63                 sharedInstance = getSingleton(beanName, new ObjectFactory() {
 64                     public Object getObject() throws BeansException {
 65                         try {
 66                             return createBean(beanName, mbd, args);
 67                         }
 68                         catch (BeansException ex) {
 69                             // Explicitly remove instance from singleton cache: It might have been put there
 70                             // eagerly by the creation process, to allow for circular reference resolution.
 71                             // Also remove any beans that received a temporary reference to the bean.
 72                             destroySingleton(beanName);
 73                             throw ex;
 74                         }
 75                     }
 76                 });
 77                 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
 78             }
 79 
 80             else if (mbd.isPrototype()) {
 81                 // It's a prototype -> create a new instance.
 82                 Object prototypeInstance = null;
 83                 try {
 84                     beforePrototypeCreation(beanName);
 85                     prototypeInstance = createBean(beanName, mbd, args);
 86                 }
 87                 finally {
 88                     afterPrototypeCreation(beanName);
 89                 }
 90                 bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
 91             }
 92 
 93             else {
 94                 String scopeName = mbd.getScope();
 95                 final Scope scope = this.scopes.get(scopeName);
 96                 if (scope == null) {
 97                     throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'");
 98                 }
 99                 try {
100                     Object scopedInstance = scope.get(beanName, new ObjectFactory() {
101                         public Object getObject() throws BeansException {
102                             beforePrototypeCreation(beanName);
103                             try {
104                                 return createBean(beanName, mbd, args);
105                             }
106                             finally {
107                                 afterPrototypeCreation(beanName);
108                             }
109                         }
110                     });
111                     bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
112                 }
113                 catch (IllegalStateException ex) {
114                     throw new BeanCreationException(beanName,
115                             "Scope '" + scopeName + "' is not active for the current thread; " +
116                             "consider defining a scoped proxy for this bean if you intend to refer to it from a singleton",
117                             ex);
118                 }
119             }
120         }
121 
122         // 对新创建的Bean进行类型检查,如果没有问题就返回这个Bean,这个Bean此时已经包含了依赖关系的Bean
123         if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
124             throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
125         }
126         return (T) bean;
127     }

复制代码

 接下来看看Bean对象通过createBean方法是如何被创建的,在类AbstractAutowireCapableBeanFactory中createBean()调用doCreateBean()

复制代码

 1 protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
 2         // Instantiate the bean.
 3         BeanWrapper instanceWrapper = null;
           //如果是单例模式,现将缓存中的同名Bean删除
 4         if (mbd.isSingleton()) {
 5             instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
 6         }
 7         if (instanceWrapper == null) {
               //这里是创建Bean的地方
 8             instanceWrapper = createBeanInstance(beanName, mbd, args);
 9         }
10         final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
11         Class beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
12 
13         // Allow post-processors to modify the merged bean definition.
14         synchronized (mbd.postProcessingLock) {
15             if (!mbd.postProcessed) {
16                 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
17                 mbd.postProcessed = true;
18             }
19         }
20 
21         // Eagerly cache singletons to be able to resolve circular references
22         // even when triggered by lifecycle interfaces like BeanFactoryAware.
23         boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
24                 isSingletonCurrentlyInCreation(beanName));
25         if (earlySingletonExposure) {
26             if (logger.isDebugEnabled()) {
27                 logger.debug("Eagerly caching bean '" + beanName +
28                         "' to allow for resolving potential circular references");
29             }
30             addSingletonFactory(beanName, new ObjectFactory() {
31                 public Object getObject() throws BeansException {
32                     return getEarlyBeanReference(beanName, mbd, bean);
33                 }
34             });
35         }
36 
37         // 这里是对Bean初始化,依赖注入就是在这里完成的,exposedObject会作为Bean依赖注入完成后的对象返回
38         Object exposedObject = bean;
39         try {
40             populateBean(beanName, mbd, instanceWrapper);
41             if (exposedObject != null) {
42                 exposedObject = initializeBean(beanName, exposedObject, mbd);
43             }
44         }
45         catch (Throwable ex) {
46             if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
47                 throw (BeanCreationException) ex;
48             }
49             else {
50                 throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
51             }
52         }
53 
54         if (earlySingletonExposure) {
55             Object earlySingletonReference = getSingleton(beanName, false);
56             if (earlySingletonReference != null) {
57                 if (exposedObject == bean) {
58                     exposedObject = earlySingletonReference;
59                 }
60                 else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
61                     String[] dependentBeans = getDependentBeans(beanName);
62                     Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
63                     for (String dependentBean : dependentBeans) {
64                         if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
65                             actualDependentBeans.add(dependentBean);
66                         }
67                     }
68                     if (!actualDependentBeans.isEmpty()) {
69                         throw new BeanCurrentlyInCreationException(beanName,
70                                 "Bean with name '" + beanName + "' has been injected into other beans [" +
71                                 StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
72                                 "] in its raw version as part of a circular reference, but has eventually been " +
73                                 "wrapped. This means that said other beans do not use the final version of the " +
74                                 "bean. This is often the result of over-eager type matching - consider using " +
75                                 "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
76                     }
77                 }
78             }
79         }
80 
81         // Register bean as disposable.
82         try {
83             registerDisposableBeanIfNecessary(beanName, bean, mbd);
84         }
85         catch (BeanDefinitionValidationException ex) {
86             throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
87         }
88 
89         return exposedObject;
90     }

复制代码

代码片段中标记的两处,一个是Bean对象的生成;另一个Bean的初始化,即依赖注入。下面分别来这两个方法的实现:

1、createBeanInstance

复制代码

 1 protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
 2         // Make sure bean class is actually resolved at this point.
 3         Class beanClass = resolveBeanClass(mbd, beanName);
 4 
 5         if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
 6             throw new BeanCreationException(mbd.getResourceDescription(), beanName,
 7                     "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
 8         }
 9 
10         if (mbd.getFactoryMethodName() != null)  {
11             return instantiateUsingFactoryMethod(beanName, mbd, args);
12         }
13 
14         // Shortcut when re-creating the same bean...
15         boolean resolved = false;
16         boolean autowireNecessary = false;
17         if (args == null) {
18             synchronized (mbd.constructorArgumentLock) {
19                 if (mbd.resolvedConstructorOrFactoryMethod != null) {
20                     resolved = true;
21                     autowireNecessary = mbd.constructorArgumentsResolved;
22                 }
23             }
24         }
25         if (resolved) {
26             if (autowireNecessary) {
27                 return autowireConstructor(beanName, mbd, null, null);
28             }
29             else {
30                 return instantiateBean(beanName, mbd);
31             }
32         }
33 
34         // Need to determine the constructor...
35         Constructor[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
36         if (ctors != null ||
37                 mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
38                 mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
39             return autowireConstructor(beanName, mbd, ctors, args);
40         }
41 
42         // No special handling: simply use no-arg constructor.
43         return instantiateBean(beanName, mbd);
44     }

复制代码

这里实例化Bean有三种方式:工厂方法、构造函数以及默认的实例化策略CGLB。前两种方式我们都很熟悉,这个CGLB是一个常用的字节码生成器的类库,它提供了一系列的API来提供生成和转换JAVA的字节码的功能,在AOP中也是用CGLB对JAVA的字节码进行增强。

CGLB创建对象的过程在CglibSubclassingInstantiationStrategy中:

复制代码

 1 public Object instantiate(Constructor ctor, Object[] args) {
 2             Enhancer enhancer = new Enhancer();
 3             enhancer.setSuperclass(this.beanDefinition.getBeanClass());
 4             enhancer.setCallbackFilter(new CallbackFilterImpl());
 5             enhancer.setCallbacks(new Callback[] {
 6                     NoOp.INSTANCE,
 7                     new LookupOverrideMethodInterceptor(),
 8                     new ReplaceOverrideMethodInterceptor()
 9             });
10 
11             return (ctor == null) ? 
12                     enhancer.create() : 
13                     enhancer.create(ctor.getParameterTypes(), args);
14         }

复制代码

2、populateBean

复制代码

 1 protected void populateBean(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw) {
 2         PropertyValues pvs = mbd.getPropertyValues();
 3 
 4         if (bw == null) {
 5             if (!pvs.isEmpty()) {
 6                 throw new BeanCreationException(
 7                         mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
 8             }
 9             else {
10                 // Skip property population phase for null instance.
11                 return;
12             }
13         }
14 
15         // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
16         // state of the bean before properties are set. This can be used, for example,
17         // to support styles of field injection.
18         boolean continueWithPropertyPopulation = true;
19 
20         if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
21             for (BeanPostProcessor bp : getBeanPostProcessors()) {
22                 if (bp instanceof InstantiationAwareBeanPostProcessor) {
23                     InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
24                     if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
25                         continueWithPropertyPopulation = false;
26                         break;
27                     }
28                 }
29             }
30         }
31 
32         if (!continueWithPropertyPopulation) {
33             return;
34         }
           //开始进行依赖注入过程,先处理autoWire的注入
36         if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
37                 mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
38             MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
39 
40             // Add property values based on autowire by name if applicable.
41             if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
42                 autowireByName(beanName, mbd, bw, newPvs);
43             }
44 
45             // Add property values based on autowire by type if applicable.
46             if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
47                 autowireByType(beanName, mbd, bw, newPvs);
48             }
49 
50             pvs = newPvs;
51         }
52 
53         boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
54         boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
55 
56         if (hasInstAwareBpps || needsDepCheck) {
57             PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw);
58             if (hasInstAwareBpps) {
59                 for (BeanPostProcessor bp : getBeanPostProcessors()) {
60                     if (bp instanceof InstantiationAwareBeanPostProcessor) {
61                         InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
62                         pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
63                         if (pvs == null) {
64                             return;
65                         }
66                     }
67                 }
68             }
69             if (needsDepCheck) {
70                 checkDependencies(beanName, mbd, filteredPds, pvs);
71             }
72         }
73         //对属性进行注入
74         applyPropertyValues(beanName, mbd, bw, pvs);
75     }

复制代码

对属性进行注入:

复制代码

 1 protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
 2         if (pvs == null || pvs.isEmpty()) {
 3             return;
 4         }
 5 
 6         MutablePropertyValues mpvs = null;
 7         List<PropertyValue> original;
 8         
 9         if (System.getSecurityManager()!= null) {
10             if (bw instanceof BeanWrapperImpl) {
11                 ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
12             }
13         }
14 
15         if (pvs instanceof MutablePropertyValues) {
16             mpvs = (MutablePropertyValues) pvs;
17             if (mpvs.isConverted()) {
18                 // Shortcut: use the pre-converted values as-is.
19                 try {
20                     bw.setPropertyValues(mpvs);
21                     return;
22                 }
23                 catch (BeansException ex) {
24                     throw new BeanCreationException(
25                             mbd.getResourceDescription(), beanName, "Error setting property values", ex);
26                 }
27             }
28             original = mpvs.getPropertyValueList();
29         }
30         else {
31             original = Arrays.asList(pvs.getPropertyValues());
32         }
33 
34         TypeConverter converter = getCustomTypeConverter();
35         if (converter == null) {
36             converter = bw;
37         }
38         BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
39 
40         // Create a deep copy, resolving any references for values.
41         List<PropertyValue> deepCopy = new ArrayList<PropertyValue>(original.size());
42         boolean resolveNecessary = false;
43         for (PropertyValue pv : original) {
44             if (pv.isConverted()) {
45                 deepCopy.add(pv);
46             }
47             else {
48                 String propertyName = pv.getName();
49                 Object originalValue = pv.getValue();
                   //对BeanDefinition进行解析
50                 Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
           //解析后生成一个副本
51                 Object convertedValue = resolvedValue;
52                 boolean convertible = bw.isWritableProperty(propertyName) &&
53                         !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
54                 if (convertible) {
55                     convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
56                 }
57                 // Possibly store converted value in merged bean definition,
58                 // in order to avoid re-conversion for every created bean instance.
59                 if (resolvedValue == originalValue) {
60                     if (convertible) {
61                         pv.setConvertedValue(convertedValue);
62                     }
63                     deepCopy.add(pv);
64                 }
65                 else if (convertible && originalValue instanceof TypedStringValue &&
66                         !((TypedStringValue) originalValue).isDynamic() &&
67                         !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
68                     pv.setConvertedValue(convertedValue);
69                     deepCopy.add(pv);
70                 }
71                 else {
72                     resolveNecessary = true;
73                     deepCopy.add(new PropertyValue(pv, convertedValue));
74                 }
75             }
76         }
77         if (mpvs != null && !resolveNecessary) {
78             mpvs.setConverted();
79         }
80 
81         // 真正依赖注入的地方,实现类为WrapperImpl
82         try {
83             bw.setPropertyValues(new MutablePropertyValues(deepCopy));
84         }
85         catch (BeansException ex) {
86             throw new BeanCreationException(
87                     mbd.getResourceDescription(), beanName, "Error setting property values", ex);
88         }
89     }

复制代码

 在类BeanDefinitionValueResolver中对BeanDefinition进行解析

复制代码

  1 public Object resolveValueIfNecessary(Object argName, Object value) {
  2         // We must check each value to see whether it requires a runtime reference
  3         // to another bean to be resolved.
  4         if (value instanceof RuntimeBeanReference) {
  5             RuntimeBeanReference ref = (RuntimeBeanReference) value;
  6             return resolveReference(argName, ref);
  7         }
  8         else if (value instanceof RuntimeBeanNameReference) {
  9             String refName = ((RuntimeBeanNameReference) value).getBeanName();
 10             refName = String.valueOf(evaluate(refName));
 11             if (!this.beanFactory.containsBean(refName)) {
 12                 throw new BeanDefinitionStoreException(
 13                         "Invalid bean name '" + refName + "' in bean reference for " + argName);
 14             }
 15             return refName;
 16         }
 17         else if (value instanceof BeanDefinitionHolder) {
 18             // Resolve BeanDefinitionHolder: contains BeanDefinition with name and aliases.
 19             BeanDefinitionHolder bdHolder = (BeanDefinitionHolder) value;
 20             return resolveInnerBean(argName, bdHolder.getBeanName(), bdHolder.getBeanDefinition());
 21         }
 22         else if (value instanceof BeanDefinition) {
 23             // Resolve plain BeanDefinition, without contained name: use dummy name.
 24             BeanDefinition bd = (BeanDefinition) value;
 25             return resolveInnerBean(argName, "(inner bean)", bd);
 26         }
 27         else if (value instanceof ManagedArray) {
 28             // May need to resolve contained runtime references.
 29             ManagedArray array = (ManagedArray) value;
 30             Class elementType = array.resolvedElementType;
 31             if (elementType == null) {
 32                 String elementTypeName = array.getElementTypeName();
 33                 if (StringUtils.hasText(elementTypeName)) {
 34                     try {
 35                         elementType = ClassUtils.forName(elementTypeName, this.beanFactory.getBeanClassLoader());
 36                         array.resolvedElementType = elementType;
 37                     }
 38                     catch (Throwable ex) {
 39                         // Improve the message by showing the context.
 40                         throw new BeanCreationException(
 41                                 this.beanDefinition.getResourceDescription(), this.beanName,
 42                                 "Error resolving array type for " + argName, ex);
 43                     }
 44                 }
 45                 else {
 46                     elementType = Object.class;
 47                 }
 48             }
 49             return resolveManagedArray(argName, (List<?>) value, elementType);
 50         }
 51         else if (value instanceof ManagedList) {
 52             // May need to resolve contained runtime references.
 53             return resolveManagedList(argName, (List<?>) value);
 54         }
 55         else if (value instanceof ManagedSet) {
 56             // May need to resolve contained runtime references.
 57             return resolveManagedSet(argName, (Set<?>) value);
 58         }
 59         else if (value instanceof ManagedMap) {
 60             // May need to resolve contained runtime references.
 61             return resolveManagedMap(argName, (Map<?, ?>) value);
 62         }
 63         else if (value instanceof ManagedProperties) {
 64             Properties original = (Properties) value;
 65             Properties copy = new Properties();
 66             for (Map.Entry propEntry : original.entrySet()) {
 67                 Object propKey = propEntry.getKey();
 68                 Object propValue = propEntry.getValue();
 69                 if (propKey instanceof TypedStringValue) {
 70                     propKey = evaluate((TypedStringValue) propKey);
 71                 }
 72                 if (propValue instanceof TypedStringValue) {
 73                     propValue = evaluate((TypedStringValue) propValue);
 74                 }
 75                 copy.put(propKey, propValue);
 76             }
 77             return copy;
 78         }
 79         else if (value instanceof TypedStringValue) {
 80             // Convert value to target type here.
 81             TypedStringValue typedStringValue = (TypedStringValue) value;
 82             Object valueObject = evaluate(typedStringValue);
 83             try {
 84                 Class<?> resolvedTargetType = resolveTargetType(typedStringValue);
 85                 if (resolvedTargetType != null) {
 86                     return this.typeConverter.convertIfNecessary(valueObject, resolvedTargetType);
 87                 }
 88                 else {
 89                     return valueObject;
 90                 }
 91             }
 92             catch (Throwable ex) {
 93                 // Improve the message by showing the context.
 94                 throw new BeanCreationException(
 95                         this.beanDefinition.getResourceDescription(), this.beanName,
 96                         "Error converting typed String value for " + argName, ex);
 97             }
 98         }
 99         else {
100             return evaluate(value);
101         }
102     }

复制代码

 这里可以看到不同类型的属性,常见的list、map、array等,我们最关注的还是依赖的Bean是如何解析的,请看第6行:

复制代码

 1 private Object resolveReference(Object argName, RuntimeBeanReference ref) {
 2         try {
 3             String refName = ref.getBeanName();
 4             refName = String.valueOf(evaluate(refName));
               //如果引用的Bean在双亲容器中,就从双亲容器中查找
 5             if (ref.isToParent()) {
 6                 if (this.beanFactory.getParentBeanFactory() == null) {
 7                     throw new BeanCreationException(
 8                             this.beanDefinition.getResourceDescription(), this.beanName,
 9                             "Can't resolve reference to bean '" + refName +
10                             "' in parent factory: no parent factory available");
11                 }
12                 return this.beanFactory.getParentBeanFactory().getBean(refName);
13             }
               //如果在当前容器中获取Bean,会触发一个getBean的过程,如果依赖注入没有发生,也会相应触发该过程
14             else {
15                 Object bean = this.beanFactory.getBean(refName);
16                 this.beanFactory.registerDependentBean(refName, this.beanName);
17                 return bean;
18             }
19         }
20         catch (BeansException ex) {
21             throw new BeanCreationException(
22                     this.beanDefinition.getResourceDescription(), this.beanName,
23                     "Cannot resolve reference to bean '" + ref.getBeanName() + "' while setting " + argName, ex);
24         }
25     }

复制代码

 到这里已经将依赖注入所需要的数据全都准备OK,现在要做的就是将这些属性设置对应的Bean中。而属性设置发生在类BeanWrapperImpl中的setPropertyValue方法中

复制代码

 1 public void setPropertyValue(PropertyValue pv) throws BeansException {
 2         PropertyTokenHolder tokens = (PropertyTokenHolder) pv.resolvedTokens;
 3         if (tokens == null) {
 4             String propertyName = pv.getName();
 5             BeanWrapperImpl nestedBw;
 6             try {
 7                 nestedBw = getBeanWrapperForPropertyPath(propertyName);
 8             }
 9             catch (NotReadablePropertyException ex) {
10                 throw new NotWritablePropertyException(getRootClass(), this.nestedPath + propertyName,
11                         "Nested property in path '" + propertyName + "' does not exist", ex);
12             }
13             tokens = getPropertyNameTokens(getFinalPath(nestedBw, propertyName));
14             if (nestedBw == this) {
15                 pv.getOriginalPropertyValue().resolvedTokens = tokens;
16             }
17             nestedBw.setPropertyValue(tokens, pv);
18         }
19         else {
20             setPropertyValue(tokens, pv);
21         }
22     }

复制代码

属性设置的具体位置在第17行,有兴趣的可以进去看下。。。。。。。。

到此,我们已经完成了找到水源、将水装入木桶、对桶里的水进行处理,如消毒、煮沸。那么现在可以使用IOC容器中存在的Bean对象了。

猜你喜欢

转载自blog.csdn.net/qq_20610631/article/details/81252866