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