一、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()方法来进行介绍。

  1. public Object getBean(String name) throws BeansException {
  2. return doGetBean(name, null, null, false);
  3. }
  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. }
  35. //开始进行依赖注入过程,先处理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对象了。

Spring源码解析三:IOC容器的依赖注入的更多相关文章

  1. spring源码解析之IOC容器(一)

    学习优秀框架的源码,是提升个人技术水平必不可少的一个环节.如果只是停留在知道怎么用,但是不懂其中的来龙去脉,在技术的道路上注定走不长远.最近,学习了一段时间的spring源码,现在整理出来,以便日后温 ...

  2. spring源码解析之IOC容器(三)——依赖注入

    上一篇主要是跟踪了IOC容器对bean标签进行解析之后存入Map中的过程,这些bean只是以BeanDefinition为载体单纯的存储起来了,并没有转换成一个个的对象,今天继续进行跟踪,看一看IOC ...

  3. spring源码解析之IOC容器(二)------加载和注册

    上一篇跟踪了IOC容器对配置文件的定位,现在我们继续跟踪代码,看看IOC容器是怎么加载和注册配置文件中的信息的.开始之前,首先我们先来了解一下IOC容器所使用的数据结构-------BeanDefin ...

  4. spring源码解析之IOC容器(四)——属性注入

    上一篇跟踪了bean的创建过程,接下来,我们继续跟踪bean的属性填充的过程.先回到doCreateBean方法,代码如下: protected Object doCreateBean(final S ...

  5. 【spring源码分析】IOC容器初始化(三)

    前言:在[spring源码分析]IOC容器初始化(二)中已经得到了XML配置文件的Document实例,下面分析bean的注册过程. XmlBeanDefinitionReader#registerB ...

  6. 【spring源码分析】IOC容器初始化(总结)

    前言:在经过前面十二篇文章的分析,对bean的加载流程大致梳理清楚了.因为内容过多,因此需要进行一个小总结. 经过前面十二篇文章的漫长分析,终于将xml配置文件中的bean,转换成我们实际所需要的真正 ...

  7. 【spring源码分析】IOC容器初始化(四)

    前言:在[spring源码分析]IOC容器初始化(三)中已经分析了BeanDefinition注册之前的一些准备工作,下面将进入BeanDefinition注册的核心流程. //DefaultBean ...

  8. 转 Spring源码剖析——核心IOC容器原理

    Spring源码剖析——核心IOC容器原理 2016年08月05日 15:06:16 阅读数:8312 标签: spring源码ioc编程bean 更多 个人分类: Java https://blog ...

  9. 【spring源码分析】IOC容器初始化(二)

    前言:在[spring源码分析]IOC容器初始化(一)文末中已经提出loadBeanDefinitions(DefaultListableBeanFactory)的重要性,本文将以此为切入点继续分析. ...

  10. 【spring源码分析】IOC容器初始化(七)

    前言:在[spring源码分析]IOC容器初始化(六)中分析了从单例缓存中加载bean对象,由于篇幅原因其核心函数 FactoryBeanRegistrySupport#getObjectFromFa ...

随机推荐

  1. dom对象中的this和event.target区别

    1.this是事件冒泡,动态变化.先触发内部事件,由内到外的执行. <script> function testdiv(val){ console.log(val.id); } funct ...

  2. MySQL数据库面试

    1. MySql的存储引擎的不同 特点 Myisam BDB Memory InnoDB Archive 存储限制 没有 没有 有 64TB 没有 事务安全   支持   支持   锁机制 表锁 页锁 ...

  3. UVa 10132 - File Fragmentation

    题目大意:有n个相同的文件,每个文件从中间分为两半,现在给你这2n个文件碎片,求原来完整的文件. 找出文件碎片长度的最大值和最小值,二者相加可得到原来文件的长度len.然后逐个进行拼接,将拼接后长度等 ...

  4. 【MongoDb基础】插入数据

    以mydb为事例数据库. 切换到mydb数据库. use mydb 1. insert函数. db.users.insert({name:"Derek",age:18}) 该函数会 ...

  5. 建立ipython集群

    启动controller ipcontroller -- ip = ipaddress 设置ssh免登陆 因为需要分发文件,采用ssh通信,所以需要配置ssh免登陆 分发配置文件 scp contro ...

  6. php循环生成的表单如何获得其各项值案例

    思路:输入框和按钮是用for循环生成的,不但要获取输入框里的各项值,并且要获取点击按钮的值,要知道是那个按钮被点击了,这里以生成5个为例.如图: 这是提交页面,点击的是“小米”. 这是显示结果,测试显 ...

  7. 配置Log4J(转载)

    Log4J的配置文件(Configuration File)就是用来设置记录器的级别.存放器和布局的,它可接key=value格式的设置或xml格式的设置信息.通过配置,可以创建出Log4J的运行环境 ...

  8. Delphi 常用API 函数

    Delphi 常用API 函数 AdjustWindowRect 给定一种窗口样式,计算获得目标客户区矩形所需的窗口大小 AnyPopup 判断屏幕上是否存在任何弹出式窗口 ArrangeIconic ...

  9. Eclipse 打开文件所在文件夹

    右击文件 > Show In > System Explorer

  10. mfix模拟流化床燃烧帮助收敛的方法

    1.在反应速率里用rate_limit函数:2.初始床料中可以添加一部分碳和灰.下面给出详细解释: 1.c3m生成的化学反应速率中有一个这样的函数: double precision function ...