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

本文内容纲要:

- 一、Bean对象创建的时机

- 二、依赖注入的源码分析

一、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对象了。

本文内容总结:一、Bean对象创建的时机,二、依赖注入的源码分析,

原文链接:https://www.cnblogs.com/dongguacai/p/6438603.html

以上是 Spring源码解析三:IOC容器的依赖注入 的全部内容, 来源链接: utcz.com/z/362621.html

回到顶部