本系列目錄:
目錄
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進入方法,發現最終執行的AbstractBeanFactory的doGetBean方法,源碼如下:
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種方法如下:
- 從緩存中獲取bean
- 從父容器中直接獲取bean
- 單例模式獲取bean
- 原型模式獲取bean
- 從scope中獲取bean
其中,除了從父容器中直接獲取bean外,其它4種方法都包含2個步驟:createBean即bean實例的創建和初始化、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容器依賴注入這一部分,發現主要與AbstractBeanFactory、AutowireCapableBeanFactory這兩個類相關。實現了5種獲取bean的方案。
- 從緩存中獲取bean
- 從父容器中直接獲取bean
- 單例模式獲取bean
- 原型模式獲取bean
- 從scope中獲取bean
除了從父容器中直接獲取bean外,其它4種方法都包含2個步驟:bean實例的創建和初始化、從bean實例中獲取bean對象。