一般情况下,依赖注入的过程是发生在用户第一次向容器索要 Bean 是触发的,而触发依赖注入的地方就是 BeanFactory 的 getBean 方法。
这里以 DefaultListableBeanFactory 的基类 AbstractBeanFactory 中的 getBean() 方法来进行介绍。
- public Object getBean(String name) throws BeansException {
- return doGetBean(name, null, null, false);
- }
- 1 protected T doGetBean(2 final String name, final Class 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 actualDependentBeans = new LinkedHashSet(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 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 deepCopy = new ArrayList(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 对象了。
来源: http://www.cnblogs.com/dongguacai/