zoukankan      html  css  js  c++  java
  • 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对象了。

  • 相关阅读:
    【转】理清基本的git(github)流程
    GIT CHEAT SHEET
    failed to push some refs to 'git@github.com:*/learngit.git'
    catch(…) vs catch(CException *)?
    char[]与TCHAR[]互相转换引发的一个问题!
    关于 AfxSocketInit()
    href="#"与href="javascript:void(0)"的区别
    Camera帧率和AE的关系(转)
    详细的摄像头模组工作原理!!!(转)
    高清摄像头MIPI接口与ARM处理器的连接(转)
  • 原文地址:https://www.cnblogs.com/dongguacai/p/6438603.html
Copyright © 2011-2022 走看看