上一篇跟蹤了bean的建立過程,接下來,我們繼續跟蹤bean的屬性填充的過程。先回到doCreateBean方法,程式碼如下:
1 protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) 2 throws BeanCreationException { 3 4 // Instantiate the bean. 5 BeanWrapper instanceWrapper = null; 6 if (mbd.isSingleton()) { 7 //如果是單例,先把快取中的同名Bean清除 8 instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); 9 } 10 //如果快取中沒有 11 if (instanceWrapper == null) { 12 //則建立一個例項 13 instanceWrapper = createBeanInstance(beanName, mbd, args); 14 } 15 final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null); 16 Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null); 17 mbd.resolvedTargetType = beanType; 18 19 // Allow post-processors to modify the merged bean definition. 20 synchronized (mbd.postProcessingLock) { 21 if (!mbd.postProcessed) { 22 try { 23 //使用後置處理器進行處理 24 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); 25 } 26 catch (Throwable ex) { 27 throw new BeanCreationException(mbd.getResourceDescription(), beanName, 28 "Post-processing of merged bean definition failed", ex); 29 } 30 mbd.postProcessed = true; 31 } 32 } 33 34 // Eagerly cache singletons to be able to resolve circular references 35 // even when triggered by lifecycle interfaces like BeanFactoryAware. 36 //這裡是對單例的迴圈引用的處理,單例&&允許迴圈依賴&&正在被建立同時滿足,才為true 37 boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && 38 isSingletonCurrentlyInCreation(beanName)); 39 if (earlySingletonExposure) { 40 if (logger.isDebugEnabled()) { 41 logger.debug("Eagerly caching bean '" + beanName + 42 "' to allow for resolving potential circular references"); 43 } 44 addSingletonFactory(beanName, new ObjectFactory<Object>() { 45 @Override 46 public Object getObject() throws BeansException { 47 return getEarlyBeanReference(beanName, mbd, bean); 48 } 49 }); 50 } 51 52 //這裡是對bean的初始化,依賴注入往往是在這裡進行的,這個exposedObject在初始化完成之後會作為依賴注入完成之後的Bean 53 // Initialize the bean instance. 54 Object exposedObject = bean; 55 try { 56 //屬性的填充 57 populateBean(beanName, mbd, instanceWrapper); 58 if (exposedObject != null) { 59 exposedObject = initializeBean(beanName, exposedObject, mbd); 60 } 61 } 62 catch (Throwable ex) { 63 if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) { 64 throw (BeanCreationException) ex; 65 } 66 else { 67 throw new BeanCreationException( 68 mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex); 69 } 70 } 71 72 if (earlySingletonExposure) { 73 Object earlySingletonReference = getSingleton(beanName, false); 74 if (earlySingletonReference != null) { 75 if (exposedObject == bean) { 76 exposedObject = earlySingletonReference; 77 } 78 else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { 79 String[] dependentBeans = getDependentBeans(beanName); 80 Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length); 81 for (String dependentBean : dependentBeans) { 82 if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { 83 actualDependentBeans.add(dependentBean); 84 } 85 } 86 if (!actualDependentBeans.isEmpty()) { 87 throw new BeanCurrentlyInCreationException(beanName, 88 "Bean with name '" + beanName + "' has been injected into other beans [" + 89 StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + 90 "] in its raw version as part of a circular reference, but has eventually been " + 91 "wrapped. This means that said other beans do not use the final version of the " + 92 "bean. This is often the result of over-eager type matching - consider using " + 93 "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example."); 94 } 95 } 96 } 97 } 98 99 // Register bean as disposable. 100 try { 101 registerDisposableBeanIfNecessary(beanName, bean, mbd); 102 } 103 catch (BeanDefinitionValidationException ex) { 104 throw new BeanCreationException( 105 mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); 106 } 107 108 return exposedObject; 109 }
對於bean的建立,IOC容器其實是採用反射和cglib技術來生成的,我們可以跟蹤一下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 //使用工廠方法對Bean進行例項化 11 if (mbd.getFactoryMethodName() != null) { 12 return instantiateUsingFactoryMethod(beanName, mbd, args); 13 } 14 15 // Shortcut when re-creating the same bean... 16 boolean resolved = false; 17 boolean autowireNecessary = false; 18 if (args == null) { 19 synchronized (mbd.constructorArgumentLock) { 20 if (mbd.resolvedConstructorOrFactoryMethod != null) { 21 resolved = true; 22 autowireNecessary = mbd.constructorArgumentsResolved; 23 } 24 } 25 } 26 if (resolved) { 27 if (autowireNecessary) { 28 return autowireConstructor(beanName, mbd, null, null); 29 } 30 else { 31 return instantiateBean(beanName, mbd); 32 } 33 } 34 35 //使用建構函式對Bean例項化 36 // Need to determine the constructor... 37 Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); 38 if (ctors != null || 39 mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR || 40 mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { 41 return autowireConstructor(beanName, mbd, ctors, args); 42 } 43 44 //使用預設的建構函式對Bean進行例項化 45 // No special handling: simply use no-arg constructor. 46 return instantiateBean(beanName, mbd); 47 }
1、如果指定了工廠方法,則使用工廠進行建立;
2、如果沒有指定工廠方法,則看有沒指定某個構造器進行例項化;
3、都沒有,則採用預設的構造器進行例項化。進入預設的構造器方法:
1 protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) { 2 try { 3 Object beanInstance; 4 final BeanFactory parent = this; 5 if (System.getSecurityManager() != null) { 6 beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() { 7 @Override 8 public Object run() { 9 return getInstantiationStrategy().instantiate(mbd, beanName, parent); 10 } 11 }, getAccessControlContext()); 12 } 13 else { 14 beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent); 15 } 16 BeanWrapper bw = new BeanWrapperImpl(beanInstance); 17 initBeanWrapper(bw); 18 return bw; 19 } 20 catch (Throwable ex) { 21 throw new BeanCreationException( 22 mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex); 23 } 24 }
雖然getInstantiationStrategy()方法獲取的是CglibSubclassingInstantiationStrategy例項,但是CglibSubclassingInstantiationStrategy中只有一個instantiate帶一個引數和一個可變引數的方法,和這裡呼叫的並不是同一個方法,所以,這裡呼叫的是它的父類SimpleInstantiationStrategy中的instantiate方法,進入:
1 public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) { 2 // Don't override the class with CGLIB if no overrides. 3 if (bd.getMethodOverrides().isEmpty()) { 4 Constructor<?> constructorToUse; 5 synchronized (bd.constructorArgumentLock) { 6 //這裡取得指定的構造器或者生產物件的工廠方法來對Bean進行例項化 7 constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod; 8 if (constructorToUse == null) { 9 final Class<?> clazz = bd.getBeanClass(); 10 if (clazz.isInterface()) { 11 throw new BeanInstantiationException(clazz, "Specified class is an interface"); 12 } 13 try { 14 if (System.getSecurityManager() != null) { 15 constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor<?>>() { 16 @Override 17 public Constructor<?> run() throws Exception { 18 return clazz.getDeclaredConstructor((Class[]) null); 19 } 20 }); 21 } 22 else { 23 constructorToUse = clazz.getDeclaredConstructor((Class[]) null); 24 } 25 bd.resolvedConstructorOrFactoryMethod = constructorToUse; 26 } 27 catch (Throwable ex) { 28 throw new BeanInstantiationException(clazz, "No default constructor found", ex); 29 } 30 } 31 } 32 //使用反射進行例項化 33 return BeanUtils.instantiateClass(constructorToUse); 34 } 35 else { 36 //使用cglb進行例項化 37 // Must generate CGLIB subclass. 38 return instantiateWithMethodInjection(bd, beanName, owner); 39 } 40 }
這段程式碼可以看到,IOC是使用反射和cglib來進行例項化物件的。好了,我們回到之前的方法,到populateBean(beanName, mbd, instanceWrapper)方法進行跟蹤:
1 protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) { 2 //在前面解析的過程中,XML中設定的屬性已經填充到beanDefinition 的propertyValues屬性中 3 PropertyValues pvs = mbd.getPropertyValues(); 4 5 if (bw == null) { 6 if (!pvs.isEmpty()) { 7 throw new BeanCreationException( 8 mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance"); 9 } 10 else { 11 // Skip property population phase for null instance. 12 return; 13 } 14 } 15 16 // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the 17 // state of the bean before properties are set. This can be used, for example, 18 // to support styles of field injection. 19 boolean continueWithPropertyPopulation = true; 20 21 if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { 22 for (BeanPostProcessor bp : getBeanPostProcessors()) { 23 if (bp instanceof InstantiationAwareBeanPostProcessor) { 24 InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; 25 if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { 26 continueWithPropertyPopulation = false; 27 break; 28 } 29 } 30 } 31 } 32 33 if (!continueWithPropertyPopulation) { 34 return; 35 } 36 37 //開始進行依賴注入的操作 38 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME || 39 mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { 40 MutablePropertyValues newPvs = new MutablePropertyValues(pvs); 41 42 //按屬性的名字來進行注入 43 // Add property values based on autowire by name if applicable. 44 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) { 45 autowireByName(beanName, mbd, bw, newPvs); 46 } 47 48 //按屬性的型別來進行注入 49 // Add property values based on autowire by type if applicable. 50 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { 51 autowireByType(beanName, mbd, bw, newPvs); 52 } 53 54 pvs = newPvs; 55 } 56 57 boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); 58 boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE); 59 60 if (hasInstAwareBpps || needsDepCheck) { 61 PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); 62 if (hasInstAwareBpps) { 63 for (BeanPostProcessor bp : getBeanPostProcessors()) { 64 if (bp instanceof InstantiationAwareBeanPostProcessor) { 65 InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; 66 pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); 67 if (pvs == null) { 68 return; 69 } 70 } 71 } 72 } 73 if (needsDepCheck) { 74 checkDependencies(beanName, mbd, filteredPds, pvs); 75 } 76 } 77 78 //對屬性進行注入 79 applyPropertyValues(beanName, mbd, bw, pvs); 80 }
可以看到:
1、我們可以在XML中指定autowired的值,是按名稱還是型別來進行注入;
2、真正進行屬性注入的是applyPropertyValues方法,進入:
1 protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) { 2 if (pvs == null || pvs.isEmpty()) { 3 return; 4 } 5 6 if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) { 7 ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext()); 8 } 9 10 MutablePropertyValues mpvs = null; 11 List<PropertyValue> original; 12 13 if (pvs instanceof MutablePropertyValues) { 14 mpvs = (MutablePropertyValues) pvs; 15 if (mpvs.isConverted()) { 16 // Shortcut: use the pre-converted values as-is. 17 try { 18 bw.setPropertyValues(mpvs); 19 return; 20 } 21 catch (BeansException ex) { 22 throw new BeanCreationException( 23 mbd.getResourceDescription(), beanName, "Error setting property values", ex); 24 } 25 } 26 original = mpvs.getPropertyValueList(); 27 } 28 else { 29 original = Arrays.asList(pvs.getPropertyValues()); 30 } 31 32 TypeConverter converter = getCustomTypeConverter(); 33 if (converter == null) { 34 converter = bw; 35 } 36 //獲取解析器 37 BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter); 38 39 // Create a deep copy, resolving any references for values. 40 List<PropertyValue> deepCopy = new ArrayList<PropertyValue>(original.size()); 41 boolean resolveNecessary = false; 42 for (PropertyValue pv : original) { 43 //如果已經轉換過,就直接存入 44 if (pv.isConverted()) { 45 deepCopy.add(pv); 46 } 47 else { 48 //獲取屬性名稱 49 String propertyName = pv.getName(); 50 //獲取屬性值 51 Object originalValue = pv.getValue(); 52 //將值進行轉換,比如屬性的值有可能是陣列、集合,或者物件,並且該物件也需要進行屬性的注入, 53 //那麼還會進行遞迴呼叫getBean方法,將該物件生成好之後再注入給當前的屬性 54 Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue); 55 Object convertedValue = resolvedValue; 56 boolean convertible = bw.isWritableProperty(propertyName) && 57 !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName); 58 if (convertible) { 59 convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter); 60 } 61 // Possibly store converted value in merged bean definition, 62 // in order to avoid re-conversion for every created bean instance. 63 if (resolvedValue == originalValue) { 64 if (convertible) { 65 pv.setConvertedValue(convertedValue); 66 } 67 deepCopy.add(pv); 68 } 69 else if (convertible && originalValue instanceof TypedStringValue && 70 !((TypedStringValue) originalValue).isDynamic() && 71 !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) { 72 pv.setConvertedValue(convertedValue); 73 deepCopy.add(pv); 74 } 75 else { 76 resolveNecessary = true; 77 deepCopy.add(new PropertyValue(pv, convertedValue)); 78 } 79 } 80 } 81 if (mpvs != null && !resolveNecessary) { 82 mpvs.setConverted(); 83 } 84 85 //設定依賴注入的地方 86 // Set our (possibly massaged) deep copy. 87 try { 88 bw.setPropertyValues(new MutablePropertyValues(deepCopy)); 89 } 90 catch (BeansException ex) { 91 throw new BeanCreationException( 92 mbd.getResourceDescription(), beanName, "Error setting property values", ex); 93 } 94 }
至此,一個完整的bean就算建立完成了,要用的時候,直接找IOC容器拿就行了。