Spring IOC(三)依賴注入


本系列目錄:

Spring IOC(一)概覽

Spring IOC(二)容器初始化

Spring IOC(三)依賴注入

Spring IOC(四)總結

目錄

1.AbstractBeanFactory設計類圖

2.模擬容器獲取Bean,源碼剖析

3.總結

=====正文分割線=============

前面一章講解的高級容器ApplicationContext的接口設計和ClassPathXmlApplicationContext實現類從xml文件中載入bean的過程,其它實現類大同小異。

光生成Bean還不夠,還得在需要使用的地方獲取到才能使用,即依賴注入。主要涉及源碼AbstractBeanFactory。本章先分析AbstractBeanFactory類的類圖,再結合例子看源碼如何獲取bean.

一、核心類圖

 

如上圖,核心類AbstractBeanFactory,相關接口描述:

AliasRegistry接口:別名注冊接口。聲明了別名的注冊、移除、判斷是否別名、獲取接口。

SimpleAliasRegistry類:簡單別名注冊器,實現了AliasRegistry接口。維護了一個ConcurrentHashMap,key是別名,value是bean name。

SingletonBeanRegistry接口:單例bean注冊接口。聲明了對單例bean的對象獲取、名稱獲取、注冊、判斷包含、計數。獲取單例互斥量對象。

DefaultSingletonBeanRegistry類:默認單例Bean注冊器,繼承自SimpleAliasRegistry。同時實現了SingletonBeanRegistry接口。即同時具有別名注冊+單例bean注冊的功能。並且拓展了對單例的一系列操作。拓展維護了11個集合用以存儲各種業務數據。(例如緩存了單例對象、單例工廠、注冊過的單例、正在創建中的單例)

FactoryBeanRegistrySupport類:工廠bean注冊支持類,繼承自DefaultSingletonBeanRegistry。拓展維護一個ConcurrentHashMap<String, Object>,key是工廠bean名稱,value是bean對象,作為工廠bean創建的bean對象緩存使用。

ConfigurableBeanFactory接口:可配置bean工廠接口。繼承自HierarchicalBeanFactory、SingletonBeanRegistry接口。拓展維護了父類工廠、工廠的類加載器、值解析器、類型轉換器、bean后處理器、注冊scope、bean表達式解析器等等。

AbstractBeanFactory類繼承自FactoryBeanRegistrySupport,實現了ConfigurableBeanFactory接口。拓展了containsBeanDefinition、getBeanDefinition、createBean3個抽象方法,供子類實現。

AutowireCapableBeanFactory接口:自動裝備bean工廠接口。聲明了bean的創建、自動裝配、配置、初始化bean、初始化前后bean處理器、銷毀bean。

AbstractAutowireCapableBeanFactory類:繼承自AbstractBeanFactory,實現了AutowireCapableBeanFactory接口。即支持了bean生命周期的各種細粒度的實現。

二、模擬容器獲取Bean,源碼剖析

1     public static void main(String[] args) {
2         //源碼入口,從類路徑下讀取xml
3         ApplicationContext ac1 = new ClassPathXmlApplicationContext("aop.xml");
4         Dao dao = (Dao)ac1.getBean("daoImpl",Dao.class);//根據名稱和class獲取Bean
5         dao.select();//執行Bean實例方法    
      }

 debug運行,F6單步跳過,F5進入方法,發現最終執行的AbstractBeanFactorydoGetBean方法,源碼如下:

  1 protected <T> T doGetBean(
  2             final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
  3             throws BeansException {
  4         //獲取規范的bean name
  5         final String beanName = transformedBeanName(name);
  6         Object bean;
  7 
  8         // 1.從緩存中獲取bean實例
  9         Object sharedInstance = getSingleton(beanName);
//能獲取到
10 if (sharedInstance != null && args == null) { 11 if (logger.isDebugEnabled()) { 12 if (isSingletonCurrentlyInCreation(beanName)) {//debug循環引用 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 }
//bean實例--》bean
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 //2.從父容器中直接獲取bean. 31 BeanFactory parentBeanFactory = getParentBeanFactory();
//當前容器的父容器存在,且當前容器中不存在指名的Bean
32 if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { 33 // 解析Bean的原始名. 34 String nameToLookup = originalBeanName(name); 35 if (args != null) { 36 //委派給父類容器查找,根據指定的名稱和顯示參數. 37 return (T) parentBeanFactory.getBean(nameToLookup, args); 38 } 39 else { 40 // 委派給父類容器查找,根據指定的名稱和類型. 41 return parentBeanFactory.getBean(nameToLookup, requiredType); 42 } 43 } 44 //創建的Bean是否需要進行驗證,一般不需要 45 if (!typeCheckOnly) {
//添加進已創建set
46 markBeanAsCreated(beanName); 47 } 48 49 try {
//根據Bean的名字獲取BeanDefinition
50 final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); 51 checkMergedBeanDefinition(mbd, beanName, args); 52 53 // 初始化依賴bean 54 String[] dependsOn = mbd.getDependsOn(); 55 if (dependsOn != null) { 56 for (String dep : dependsOn) { 57 if (isDependent(beanName, dep)) { 58 throw new BeanCreationException(mbd.getResourceDescription(), beanName, 59 "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); 60 } 61 registerDependentBean(dep, beanName); 62 getBean(dep);//遞歸 63 } 64 } 65 66 // 3.單例模式獲取bean 67 if (mbd.isSingleton()) {
              // 使用一個內部匿名類,創建Bean實例對象,並且注冊對所依賴的對象
68 sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() { 69 @Override 70 public Object getObject() throws BeansException { 71 try {
                      // 創建一個指定Bean實例對象,如果有父級繼承,則合並
72 return createBean(beanName, mbd, args); 73 } 74 catch (BeansException ex) { 75 // Explicitly remove instance from singleton cache: It might have been put there 76 // eagerly by the creation process, to allow for circular reference resolution. 77 // Also remove any beans that received a temporary reference to the bean. 78 destroySingleton(beanName); 79 throw ex; 80 } 81 } 82 });
               // 獲取給定Bean實例對象FactoryBean-》bean
83 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); 84 } 85 //4.原型模式獲取bean 86 else if (mbd.isPrototype()) { 87 // 每次創建新對象實例 88 Object prototypeInstance = null; 89 try {
                 // 回調方法,注冊原型對象
90 beforePrototypeCreation(beanName);
// 創建指定Bean對象實例
91 prototypeInstance = createBean(beanName, mbd, args); 92 } 93 finally {
                  // 回調方法,Bean無法再次創建
94 afterPrototypeCreation(beanName); 95 }
// 獲取給定Bean實例對象FactoryBean-》bean
96 bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); 97 } 98 //5.從scope中獲取bean 99 else { 100 String scopeName = mbd.getScope(); 101 final Scope scope = this.scopes.get(scopeName); 102 if (scope == null) { 103 throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'"); 104 } 105 try {
// 從scope中獲取bean
106 Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() { 107 @Override 108 public Object getObject() throws BeansException { 109 beforePrototypeCreation(beanName); 110 try { 111 return createBean(beanName, mbd, args); 112 } 113 finally { 114 afterPrototypeCreation(beanName); 115 } 116 } 117 }); 118 bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); 119 } 120 catch (IllegalStateException ex) { 121 throw new BeanCreationException(beanName, 122 "Scope '" + scopeName + "' is not active for the current thread; consider " + 123 "defining a scoped proxy for this bean if you intend to refer to it from a singleton", 124 ex); 125 } 126 } 127 } 128 catch (BeansException ex) { 129 cleanupAfterBeanCreationFailure(beanName); 130 throw ex; 131 } 132 } 133 134 // 對創建的Bean進行類型檢查,如果沒有問題,就返回這個新建的Bean,這個Bean已經包含了依賴關系. 135 if (requiredType != null && bean != null && !requiredType.isInstance(bean)) { 136 try { 137 return getTypeConverter().convertIfNecessary(bean, requiredType); 138 } 139 catch (TypeMismatchException ex) { 140 if (logger.isDebugEnabled()) { 141 logger.debug("Failed to convert bean '" + name + "' to required type '" + 142 ClassUtils.getQualifiedName(requiredType) + "'", ex); 143 } 144 throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); 145 } 146 } 147 return (T) bean; 148 }

AbstractBeanFactory的doGetBean方法獲取bean有5種方法如下:

  1. 從緩存中獲取bean
  2. 父容器中直接獲取bean
  3. 單例模式獲取bean
  4. 原型模式獲取bean
  5. 從scope中獲取bean

其中,除了從父容器中直接獲取bean外,其它4種方法都包含2個步驟:createBeanbean實例的創建和初始化、getObjectForBeanInstance從bean實例中獲取bean對象下面詳細追一下源碼。

1.bean實例的創建和初始化

createBean(beanName, mbd, args),這就是核心方法了。AbstractBeanFactory的createBean只是一個聲明,在子類AbstractAutowireCapableBeanFactory中覆蓋實現,源碼如下:

 1 @Override
 2     protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
 3         if (logger.isDebugEnabled()) {
 4             logger.debug("Creating instance of bean '" + beanName + "'");
 5         }
 6         RootBeanDefinition mbdToUse = mbd;
 7 
 8         // 確保bean的類解析完畢,如果是動態解析類型,不會存儲合並到bean定義中。克隆一份bean定義。
11         Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
12         if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
13             mbdToUse = new RootBeanDefinition(mbd);
14             mbdToUse.setBeanClass(resolvedClass);
15         }
16 
17         // Prepare method overrides.
18         try {
19             mbdToUse.prepareMethodOverrides();
20         }
21         catch (BeanDefinitionValidationException ex) {
22             throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
23                     beanName, "Validation of method overrides failed", ex);
24         }
25 
26         try {
27             // 如果Bean配置了實例化前處理器,則返回一個Bean對象
28             Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
29             if (bean != null) {
30                 return bean;
31             }
32         }
33         catch (Throwable ex) {
34             throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
35                     "BeanPostProcessor before instantiation of bean failed", ex);
36         }
37         // 核心方法
38         Object beanInstance = doCreateBean(beanName, mbdToUse, args);
39         if (logger.isDebugEnabled()) {
40             logger.debug("Finished creating instance of bean '" + beanName + "'");
41         }
42         return beanInstance;
43     }

進入doCreateBean

  1 /**
  2      * Actually create the specified bean. Pre-creation processing has already happened
  3      * at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks.
  4      * <p>Differentiates between default bean instantiation, use of a
  5      * factory method, and autowiring a constructor.
  6      * @param beanName the name of the bean
  7      * @param mbd the merged bean definition for the bean
  8      * @param args explicit arguments to use for constructor or factory method invocation
  9      * @return a new instance of the bean
 10      * @throws BeanCreationException if the bean could not be created
 11      * @see #instantiateBean
 12      * @see #instantiateUsingFactoryMethod
 13      * @see #autowireConstructor
 14      */
 15     protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
 16             throws BeanCreationException {
 17 
 18         // Instantiate the bean.
 19         BeanWrapper instanceWrapper = null;
 20         if (mbd.isSingleton()) {// 單例模式,清除緩存bean
 21             instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
 22         }
 23         if (instanceWrapper == null) {
 24             instanceWrapper = createBeanInstance(beanName, mbd, args);
 25         }
 26         final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
 27         Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
 28         mbd.resolvedTargetType = beanType;
 29 
 30         // 允許處理器修改合並bean定義
 31         synchronized (mbd.postProcessingLock) {
 32             if (!mbd.postProcessed) {
 33                 try {
 34                     applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
 35                 }
 36                 catch (Throwable ex) {
 37                     throw new BeanCreationException(mbd.getResourceDescription(), beanName,
 38                             "Post-processing of merged bean definition failed", ex);
 39                 }
 40                 mbd.postProcessed = true;
 41             }
 42         }
 43 
 44         // 如果是單例模式,且允許循環引用,且當前單列正在創建中,則返回之前的bean引用
 46         boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
 47                 isSingletonCurrentlyInCreation(beanName));
 48         if (earlySingletonExposure) {
 49             if (logger.isDebugEnabled()) {
 50                 logger.debug("Eagerly caching bean '" + beanName +
 51                         "' to allow for resolving potential circular references");
 52             }
 53             addSingletonFactory(beanName, new ObjectFactory<Object>() {
 54                 @Override
 55                 public Object getObject() throws BeansException {
 56                     return getEarlyBeanReference(beanName, mbd, bean);
 57                 }
 58             });
 59         }
 60 
 61         // 初始化(依賴注入)
 62         Object exposedObject = bean;
 63         try {
 64  populateBean(beanName, mbd, instanceWrapper);// 數據填充進實例
 65             if (exposedObject != null) {
 66                 exposedObject = initializeBean(beanName, exposedObject, mbd);
 67             }
 68         }
 69         catch (Throwable ex) {
 70             if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
 71                 throw (BeanCreationException) ex;
 72             }
 73             else {
 74                 throw new BeanCreationException(
 75                         mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
 76             }
 77         }
 78         // 早期已注冊的單例bean生成方案,有依賴的注入依賴,無依賴的直接返回引用
 79         if (earlySingletonExposure) {
 80             Object earlySingletonReference = getSingleton(beanName, false);
 81             if (earlySingletonReference != null) {
 82                 if (exposedObject == bean) {
 83                     exposedObject = earlySingletonReference;
 84                 }
 85                 else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
 86                     String[] dependentBeans = getDependentBeans(beanName);
 87                     Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
 88                     for (String dependentBean : dependentBeans) {
 89                         if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
 90                             actualDependentBeans.add(dependentBean);
 91                         }
 92                     }
 93                     if (!actualDependentBeans.isEmpty()) {
 94                         throw new BeanCurrentlyInCreationException(beanName,
 95                                 "Bean with name '" + beanName + "' has been injected into other beans [" +
 96                                 StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
 97                                 "] in its raw version as part of a circular reference, but has eventually been " +
 98                                 "wrapped. This means that said other beans do not use the final version of the " +
 99                                 "bean. This is often the result of over-eager type matching - consider using " +
100                                 "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
101                     }
102                 }
103             }
104         }
105 
106         // 注冊完成依賴注入的Bean.(如果有銷毀方法添加銷毀方法等待回調)
107         try {
108  registerDisposableBeanIfNecessary(beanName, bean, mbd);
109         }
110         catch (BeanDefinitionValidationException ex) {
111             throw new BeanCreationException(
112                     mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
113         }
114 
115         return exposedObject;
116     }

如上圖,doCreateBean方法是中重要的方法:
1)createBeanInstance 創建bean實例對象instanceWrapper
2)populateBean bean定義中配置的屬性注入實例對象instanceWrapper
3)initializeBean 初始化bean

1.createBeanInstance有三種實例化方法:

1.工廠方法

2.容器自動裝配

3.使用構造函數實例化。

源碼如下:

 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         // 1.這里使用工廠方法對Bean進行實例化
10         if (mbd.getFactoryMethodName() != null)  {
11             return instantiateUsingFactoryMethod(beanName, mbd, args);
12         }
13 
14         // 2.使用容器自動裝配方法進行實例化
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         // 3.使用構造函數進行實例化
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     }

上面的源碼中instantiateBean:最終調用SimpleInstantiationStrategy.instantiate方法來生成Bean對象實例,它提供了兩種方式

1.BeanUtils,是jvm的反射機制

2.cglib。這里就是典型的策略模式。

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                 constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
 7                 if (constructorToUse == null) {
 8                     final Class<?> clazz = bd.getBeanClass();
 9                     if (clazz.isInterface()) {
10                         throw new BeanInstantiationException(clazz, "Specified class is an interface");
11                     }
12                     try {
13                         if (System.getSecurityManager() != null) {
14                             constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor<?>>() {
15                                 @Override
16                                 public Constructor<?> run() throws Exception {
17                                     return clazz.getDeclaredConstructor((Class[]) null);
18                                 }
19                             });
20                         }
21                         else {
22                             constructorToUse =    clazz.getDeclaredConstructor((Class[]) null);
23                         }
24                         bd.resolvedConstructorOrFactoryMethod = constructorToUse;
25                     }
26                     catch (Throwable ex) {
27                         throw new BeanInstantiationException(clazz, "No default constructor found", ex);
28                     }
29                 }
30             }
31             // 1.通過BeanUtils進行實例化,利用反射機制獲取:java.lang.reflect.Constructor
32             return BeanUtils.instantiateClass(constructorToUse);
33         }
34         else {
35             // 2.使用CGLIB來實例化對象
36             return instantiateWithMethodInjection(bd, beanName, owner);
37         }
38     }

2.populateBean:屬性依賴注入方法

 1 protected void populateBean(String beanName, RootBeanDefinition 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             // 根據Bean的名字自動裝配注入
41             if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
42  autowireByName(beanName, mbd, bw, newPvs);
43             }
44 
45             // 根據Bean的類型自動裝配注入
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         // 有實例化bean處理器/需要依賴檢查
56         if (hasInstAwareBpps || needsDepCheck) {
57             PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
58             if (hasInstAwareBpps) {// 實例化bean處理器
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     }

最終追蹤到applyPropertyValues方法,源碼如下:

 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());// 設置安全上下文,JDK安全機制
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();
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         // 依賴注入屬性值
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     }

setPropertyValues該方法:AbstractPropertyAccessor實現類注入依賴的屬性。

3.初始化initializeBean

 1 protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
 2         if (System.getSecurityManager() != null) {
 3             AccessController.doPrivileged(new PrivilegedAction<Object>() {
 4                 @Override
 5                 public Object run() {
 6                     invokeAwareMethods(beanName, bean);
 7                     return null;
 8                 }
 9             }, getAccessControlContext());
10         }
11         else {
12  invokeAwareMethods(beanName, bean);// Aware接口 設置bean name、factory、classloader13         }
14 
15         Object wrappedBean = bean;
16         if (mbd == null || !mbd.isSynthetic()) {
17             wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);// bea后處理器-初始化之前
18         }
19 
20         try {
21  invokeInitMethods(beanName, wrappedBean, mbd);// 執行初始化方法(InitializingBean
22         }
23         catch (Throwable ex) {
24             throw new BeanCreationException(
25                     (mbd != null ? mbd.getResourceDescription() : null),
26                     beanName, "Invocation of init method failed", ex);
27         }
28 
29         if (mbd == null || !mbd.isSynthetic()) {
30             wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);//bea后處理器-初始化之后
31         }
32         return wrappedBean;
33     }
34 
35     private void invokeAwareMethods(final String beanName, final Object bean) {
36         if (bean instanceof Aware) {
37             if (bean instanceof BeanNameAware) {
38                 ((BeanNameAware) bean).setBeanName(beanName);//設置bean 名稱
39             }
40             if (bean instanceof BeanClassLoaderAware) {
41                 ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());//設置bean類加載器
42             }
43             if (bean instanceof BeanFactoryAware) {
44                 ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);//設置bean 工廠
45             }
46         }
47     }
invokeInitMethods初始化方法如下:
 1 protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)
 2             throws Throwable {
 3 
 4         boolean isInitializingBean = (bean instanceof InitializingBean);
 5         if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
 6             if (logger.isDebugEnabled()) {
 7                 logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
 8             }
 9             if (System.getSecurityManager() != null) {//有安全策略
10                 try {
11                     AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
12                         @Override
13                         public Object run() throws Exception {
14                             ((InitializingBean) bean).afterPropertiesSet();//回調屬性設置完后方法
15                             return null;
16                         }
17                     }, getAccessControlContext());
18                 }
19                 catch (PrivilegedActionException pae) {
20                     throw pae.getException();
21                 }
22             }
23             else {//安全策略,直接執行
24                 ((InitializingBean) bean).afterPropertiesSet();//回調屬性設置完后方法 
25             }
26         }
27 
28         if (mbd != null) {
29             String initMethodName = mbd.getInitMethodName();
30             if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
31                     !mbd.isExternallyManagedInitMethod(initMethodName)) {
32  invokeCustomInitMethod(beanName, bean, mbd);
33             }
34         }
35     }

2.從bean實例中獲取bean對象

AbstractBeanFactory.getObjectForBeanInstance(Object beanInstance, String name, String beanName, RootBeanDefinition mbd),源碼如下:

 1 protected Object getObjectForBeanInstance(
 2             Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {
 3 
 4         // Don't let calling code try to dereference the factory if the bean isn't a factory.
 5         if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
 6             throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
 7         }
 8 
 9         // 這個bean實例可能是一個普通bean或者是一個工廠Bean.
10         // 如果bean實例不是工廠bean且這個name也不是工廠解引用(工廠本身,name以"&"開頭),即已經是一個普通bean實例了直接返回即可
12         if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
13             return beanInstance;
14         }
15 
16         Object object = null;
17         if (mbd == null) {// bean定義為空,從緩存中獲取bean
18             object = getCachedObjectForFactoryBean(beanName);
19         }
20         if (object == null) {// 緩存中沒有bean實例
21             // 強轉成工廠bean
22             FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
23             // 獲取bean,單例的就緩存進concurrenthashmap
24             if (mbd == null && containsBeanDefinition(beanName)) {
25                 mbd = getMergedLocalBeanDefinition(beanName);
26             }
27             boolean synthetic = (mbd != null && mbd.isSynthetic());
28             object = getObjectFromFactoryBean(factory, beanName, !synthetic);// 核心方法入口
29         }
30         return object;
31     }

 getObjectFromFactoryBean:根據"工廠bean"、name、"是否有后置處理器"3個參數獲取bean

 1 protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
 2         if (factory.isSingleton() && containsSingleton(beanName)) {
 3             synchronized (getSingletonMutex()) {
 4                 Object object = this.factoryBeanObjectCache.get(beanName);
 5                 if (object == null) {
 6                     object = doGetObjectFromFactoryBean(factory, beanName);
 7                     // Only post-process and store if not put there already during getObject() call above
 8                     // (e.g. because of circular reference processing triggered by custom getBean calls)
 9                     Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
10                     if (alreadyThere != null) {
11                         object = alreadyThere;
12                     }
13                     else {
14                         if (object != null && shouldPostProcess) {
15                             try {
16                                 object = postProcessObjectFromFactoryBean(object, beanName);
17                             }
18                             catch (Throwable ex) {
19                                 throw new BeanCreationException(beanName,
20                                         "Post-processing of FactoryBean's singleton object failed", ex);
21                             }
22                         }
23                         this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
24                     }
25                 }
26                 return (object != NULL_OBJECT ? object : null);
27             }
28         }
29         else {
30             Object object = doGetObjectFromFactoryBean(factory, beanName);
31             if (object != null && shouldPostProcess) {
32                 try {
33                     object = postProcessObjectFromFactoryBean(object, beanName);
34                 }
35                 catch (Throwable ex) {
36                     throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
37                 }
38             }
39             return object;
40         }
41     }
1.doGetObjectFromFactoryBean核心方法:根據工廠bean和名稱獲取bean
 1 private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
 2             throws BeanCreationException {
 3 
 4         Object object;
 5         try {// 配置了安全管理器
 6             if (System.getSecurityManager() != null) {
 7                 AccessControlContext acc = getAccessControlContext();
 8                 try {
 9                     object = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
10                         @Override
11                         public Object run() throws Exception {
12                                 return factory.getObject();
13                             }
14                         }, acc);
15                 }
16                 catch (PrivilegedActionException pae) {
17                     throw pae.getException();
18                 }
19             }
20             else {// 未配置安全管理器,直接獲取對象
21                 object = factory.getObject();
22             }
23         }
24         catch (FactoryBeanNotInitializedException ex) {
25             throw new BeanCurrentlyInCreationException(beanName, ex.toString());
26         }
27         catch (Throwable ex) {
28             throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
29         }
30 
31         // Do not accept a null value for a FactoryBean that's not fully
32         // initialized yet: Many FactoryBeans just return null then.
33         if (object == null && isSingletonCurrentlyInCreation(beanName)) {
34             throw new BeanCurrentlyInCreationException(
35                     beanName, "FactoryBean which is currently in creation returned null from getObject");
36         }
37         return object;
38     }

2.postProcessObjectFromFactoryBean:執行“初始化之后的后處理器“”

 1 protected Object postProcessObjectFromFactoryBean(Object object, String beanName) {
 2         return applyBeanPostProcessorsAfterInitialization(object, beanName);//這里是接口AutowireCapableBeanFactory定義的方法
 3     }
 4 
 5 public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
 6             throws BeansException {
 7 
 8         Object result = existingBean;
 9         for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
10             result = beanProcessor.postProcessAfterInitialization(result, beanName);
11             if (result == null) {
12                 return result;
13             }
14         }
15         return result;
16     }

可以看到最后調用了BeanPostProcessor接口來處理。這里不再拓展,將來會開一篇專門講解BeanPostProcessor接口的各種實現。

三、總結

 通過分析跟蹤IOC容器依賴注入這一部分,發現主要與AbstractBeanFactoryAutowireCapableBeanFactory這兩個類相關。實現了5種獲取bean的方案。

  1. 從緩存中獲取bean
  2. 父容器中直接獲取bean
  3. 單例模式獲取bean
  4. 原型模式獲取bean
  5. 從scope中獲取bean

除了從父容器中直接獲取bean外,其它4種方法都包含2個步驟:bean實例的創建和初始化、從bean實例中獲取bean對象

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM