黄色网页视频 I 影音先锋日日狠狠久久 I 秋霞午夜毛片 I 秋霞一二三区 I 国产成人片无码视频 I 国产 精品 自在自线 I av免费观看网站 I 日本精品久久久久中文字幕5 I 91看视频 I 看全色黄大色黄女片18 I 精品不卡一区 I 亚洲最新精品 I 欧美 激情 在线 I 人妻少妇精品久久 I 国产99视频精品免费专区 I 欧美影院 I 欧美精品在欧美一区二区少妇 I av大片网站 I 国产精品黄色片 I 888久久 I 狠狠干最新 I 看看黄色一级片 I 黄色精品久久 I 三级av在线 I 69色综合 I 国产日韩欧美91 I 亚洲精品偷拍 I 激情小说亚洲图片 I 久久国产视频精品 I 国产综合精品一区二区三区 I 色婷婷国产 I 最新成人av在线 I 国产私拍精品 I 日韩成人影音 I 日日夜夜天天综合

Spring開閉原則的表現-BeanPostProcessor的擴展

系統 2249 0

?


上接 Spring事務處理時自我調用的解決方案及一些實現方式的風險 繼續分析,在分析上篇的問題之前,我們需要了解下BeanPostProcessor概念和Spring容器創建Bean的流程。

?

一、BeanPostProcessor是什么

接口定義

    package org.springframework.beans.factory.config;
public interface BeanPostProcessor {
    Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
    Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
  

BeanPostProcessor Spring 容器的一個擴展點,可以進行自定義的實例化、初始化、依賴裝配、依賴檢查等流程,即可以覆蓋默認的實例化,也可以增強初始化、依賴注入、依賴檢查等流程,其 javadoc 有如下描述:

???? e.g. checking for marker interfaces or wrapping them with proxies.

???? 大體意思是可以檢查相應的標識接口完成一些自定義功能實現,如包裝目標對象到代理對象。

我們可以看到 BeanPostProcessor 一共有兩個回調方法 postProcessBeforeInitialization postProcessAfterInitialization ,那這兩個方法會在什么 Spring 執行流程中的哪個步驟執行呢?還有目前 Spring 提供哪些相應的實現呢?

?

Spring 還提供了 BeanPostProcessor 一些其他接口實現,來完成除實例化外的其他功能,后續詳細介紹。

?

?

?

二、通過源代碼看看創建一個Bean實例的具體執行流程:


Spring開閉原則的表現-BeanPostProcessor的擴展點-1

?

AbstractApplicationContext 內部使用 DefaultListableBeanFactory ,且 DefaultListableBeanFactory 繼承 AbstractAutowireCapableBeanFactory ,因此我們此處分析 AbstractAutowireCapableBeanFactory 即可。

?

一、 AbstractAutowireCapableBeanFactory createBean 方法代碼如下:

    protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) throws BeanCreationException {
    resolveBeanClass(mbd, beanName); /1解析Bean的class
    mbd.prepareMethodOverrides(); //2 方法注入準備
    Object bean = resolveBeforeInstantiation(beanName, mbd); //3 第一個BeanPostProcessor擴展點
    if (bean != null) { //4 如果3處的擴展點返回的bean不為空,直接返回該bean,后續流程不需要執行
	    return bean;
    } 
    Object beanInstance = doCreateBean(beanName, mbd, args); //5 執行spring的創建bean實例的流程啦
    return beanInstance;
}

  

? 0.3? 第一個 BeanPostProcessor 擴展點(只有 InstantiationAwareBeanPostProcessor 接口的實現才會被調用)

?

二、 AbstractAutowireCapableBeanFactory resolveBeforeInstantiation 方法代碼如下:

    protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
		Object bean = null;
		if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
			// Make sure bean class is actually resolved at this point.
			if (mbd.hasBeanClass() && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
				//3.1、執行InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation回調方法
				bean = applyBeanPostProcessorsBeforeInstantiation(mbd.getBeanClass(), beanName);
				if (bean != null) {
					//3.2、執行InstantiationAwareBeanPostProcessor的postProcessAfterInitialization回調方法
					bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
				}
			}
			mbd.beforeInstantiationResolved = (bean != null);
		}
		return bean;
} 
  

?

通過如上代碼可以進行實例化的預處理(自定義實例化 bean ,如創建相應的代理對象)和后處理(如進行自定義實例化的 bean 的依賴裝配)。

?

三、 AbstractAutowireCapableBeanFactory doCreateBean 方法 代碼如下:

    		// 6、通過BeanWrapper實例化Bean 
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
		Class beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);

		//7、執行MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition流程
		synchronized (mbd.postProcessingLock) {
			if (!mbd.postProcessed) {
				applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				mbd.postProcessed = true;
			}
		}
		// 8、及早暴露單例Bean引用,從而允許setter注入方式的循環引用
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		if (earlySingletonExposure) {
			//省略log
			addSingletonFactory(beanName, new ObjectFactory() {
				public Object getObject() throws BeansException {
					//8.1、調用SmartInstantiationAwareBeanPostProcessor的getEarlyBeanReference返回一個需要暴露的Bean(例如包裝目標對象到代理對象)
					return getEarlyBeanReference(beanName, mbd, bean);
				}
			});
		}
		
		Object exposedObject = bean;
		try {
			populateBean(beanName, mbd, instanceWrapper); //9、組裝-Bean依賴
			if (exposedObject != null) {
				exposedObject = initializeBean(beanName, exposedObject, mbd); //10、初始化Bean
			}
		}
		catch (Throwable ex) {
		    //省略異常
		}


		//11如果是及早暴露單例bean,通過getSingleton觸發3.1處的getEarlyBeanReference調用獲取要及早暴露的單例Bean
	 	if (earlySingletonExposure) {
			Object earlySingletonReference = getSingleton(beanName, false);
			if (earlySingletonReference != null) {
				if (exposedObject == bean) {
					exposedObject = earlySingletonReference;
				}
				else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
					String[] dependentBeans = getDependentBeans(beanName);
					Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
					for (String dependentBean : dependentBeans) {
						if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
							actualDependentBeans.add(dependentBean);
						}
					}
					if (!actualDependentBeans.isEmpty()) {
						throw new BeanCurrentlyInCreationException(beanName,
								"Bean with name '" + beanName + "' has been injected into other beans [" +
								StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
								"] in its raw version as part of a circular reference, but has eventually been " +
								"wrapped. This means that said other beans do not use the final version of the " +
								"bean. This is often the result of over-eager type matching - consider using " +
								"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
					}
				}
			}
		}
		//12、注冊Bean的銷毀回調
		try {
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
		}
  

?

四、 AbstractAutowireCapableBeanFactory populateBean 方法代碼如下:

    	//9、組裝-Bean
	protected void populateBean(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw) {
		PropertyValues pvs = mbd.getPropertyValues();
		//省略部分代碼
		//9.1、通過InstantiationAwareBeanPostProcessor擴展點允許自定義裝配流程(如@Autowired支持等)
		//執行InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation
		boolean continueWithPropertyPopulation = true;
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
						continueWithPropertyPopulation = false;
						break;
					}
				}
			}
		}
		if (!continueWithPropertyPopulation) {
			return;
		}
		if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
				mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
			// 9. 2、自動裝配(根據name/type)
			if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
				autowireByName(beanName, mbd, bw, newPvs);
			}
			if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
				autowireByType(beanName, mbd, bw, newPvs);
			}
			pvs = newPvs;
		}
		boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
		boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);


	  	//9. 3、執行InstantiationAwareBeanPostProcessor的postProcessPropertyValues
	  	if (hasInstAwareBpps || needsDepCheck) {
			PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw);
			if (hasInstAwareBpps) {
				for (BeanPostProcessor bp : getBeanPostProcessors()) {
					if (bp instanceof InstantiationAwareBeanPostProcessor) {
						InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
						pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
						if (pvs == null) {
							return;
						}
					}
				}
			}
			//9. 4、執行依賴檢查
			if (needsDepCheck) {
				checkDependencies(beanName, mbd, filteredPds, pvs);
			}
		}
		//9. 5、應用依賴注入
		applyPropertyValues(beanName, mbd, bw, pvs);
	}
  

?

五、 AbstractAutowireCapableBeanFactory initializeBean 方法代碼如下:

           //10、實例化Bean
       protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
		//10.1、調用Aware接口注入(BeanNameAware、BeanClassLoaderAware、BeanFactoryAware)
		invokeAwareMethods(beanName, bean);//此處省略部分代碼
		//10.2、執行BeanPostProcessor擴展點的postProcessBeforeInitialization進行修改實例化Bean
		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}
		//10.3、執行初始化回調(1、調用InitializingBean的afterPropertiesSet  2、調用自定義的init-method)
		try {
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		catch (Throwable ex) {
			//異常省略
		}
		//10.4、執行BeanPostProcessor擴展點的postProcessAfterInitialization進行修改實例化Bean
		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}
		return wrappedBean;
	}
  

三、創建一個Bean實例的執行流程簡化:

protected Object createBean(final String beanN am e, final RootBeanDefinition mbd, fi nal Object[] args); ? 創建 Be an

1 resolveBeanClass(mbd, beanName);? 解析 Bean class ,若 class 配置錯誤將拋出 CannotLoadBeanClassException

?

2 mbd.prepareMethodOverrides();? 準備和驗證配置的方法注入,若驗證失敗拋出 BeanDefinitionValidationException

有關方法注入知識請參考 【第三章】?DI?之?3.3?更多DI的知識?——跟我學spring3 ?3.3.5? 方法注入;

?

3 Object bean = resolveBeforeInstantiation(beanName, mbd);? 第一個 BeanPostProcessor 擴展點,此處只執行 InstantiationAwareBeanPostProcessor 類型的 BeanPostProcessor Bean

3. 1 bean = applyBeanPostProcessorsBeforeInstantiation(mbd.getBe anClass(), beanName); 執行 InstantiationAwareBeanPostProcessor 的實例化的預處理回調方法 postProcessBeforeInstantiation (自定義的實例化,如創建代理);

3.2 bean = applyBeanPostProcessorsAft erInitia lization(bean, beanName); 執行 InstantiationAwareBeanPostProcessor 的實例化的后處理回調方法 postProcessAfterInitialization (如依賴注入),如果 3.1 處返回的 Bean 不為 null 才執行;

?

4 、如果 3 處的擴展點返回的 bean 不為空,直接返回該 bean ,后續流程不需要執行;

?

5 Object beanInstance = doCreateBean(beanName, mbd, args);? 執行 spring 的創建 bean 實例的流程;

?

?

6 createBeanInstance(beanName, mbd, args);? 實例化 Bean

6.1 insta ntiateUsingFactoryMethod? 工廠方法實例化;請參考【 http://jinnianshilongnian.iteye.com/blog/1413857

6.2 、構造器實例化 ,請參考【 http://jinnianshilongnian.iteye.com/blog/1413857 】;

6.2.1 如果之前已經解析過構造器

6.2.1.1 auto wireConstructor :有參調用 autowireConstructor 實例化

6.2.1.2 instantiateBe an :無參調用 instantiateBean 實例化;

6.2.2 如果之前沒有解析過構造器:

?

6.2.2.1 、通過 SmartInstantiationAwareBeanPostProcessor determineCandidateConstructors 回調方法解析構造器,第二個 BeanPostProcessor 擴展點,返回第一個解析成功(返回值不為 null )的構造器組,如 AutowiredAnnotationBeanPostProcessor 實現將自動掃描通過 @Autowired/@Value 注解的構造器從而可以完成構造器注入,請參考 【第十二章】零配置?之?12.2?注解實現Bean依賴注入?——跟我學spring3 ?

6.2.2.2 au towireConstructor :如果( 6.2.2.1 返回的不為 null ,且是有參構造器,調用 autowireConstructor 實例化;

6.2.2.3 instantiat eBean ? 否則調用無參構造器實例化;

?

7 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); 第三個 BeanPostProcessor 擴展點,執行 Bean 定義的合并;

7.1 、執行 MergedBeanDefinitionPostProcessor postProcessMergedBeanDefinition 回調方法,進行 bean 定義的合并;

?

8 addSingletonFactory(beanName, new ObjectFactory() {

??????????????????????????? public Object getObject() throws BeansException {

?????????????????????????????????? return getEarlyBeanReference(beanName, mbd, bean);

??????????????????????????? }

???????????????????? });? ? 及早暴露單例 Bean 引用,從而允許 setter 注入方式的循環引用

8.1 SmartInstantiationAwareBeanPostProcessor getE arlyBeanReference ;第四個 BeanPostProcessor 擴展點,當存在循環依賴時,通過該回調方法獲取及早暴露的 Bean 實例;

?

9 populateBean(beanName, mbd, instanceWrapper); 裝配 Bean 依賴

9.1 InstantiationAwareBeanPostProcessor p ostProcessAfterInstantiation ;第五個 BeanPostProcessor 擴展點,在實例化 Bean 之后,所有其他裝配邏輯之前執行,如果 false 將阻止其他的 InstantiationAwareBeanPostProcessor postProcessAfterInstantiation 的執行和從( 9.2 到( 9.5 的執行,通常返回 true

9.2 autowireByName autowireB yType :根據名字和類型進行自動裝配,自動裝配的知識請參考 【第三章】 ?DI? ?3.3? 更多 DI 的知識 ?—— 跟我學 spring3 ? 3.3.3?? 自動裝配;

9.3 InstantiationAwareBeanPostProcessor postProc essPropertyValues :第六個 BeanPostProcessor 擴展點,完成其他定制的一些依賴注入,如 AutowiredAnnotationBeanPostProcessor 執行 @Autowired 注解注入, CommonAnnotationBeanPostProcessor 執行 @Resource 等注解的注入, PersistenceAnnotationBeanPostProcessor 執行 @ PersistenceContext JPA 注解的注入, RequiredAnnotationBeanPostProcessor 執行 @ Required 注解的檢查等等,請參考 【第十二章】零配置?之?12.2?注解實現Bean依賴注入?——跟我學spring3

9.4 check Dependencies :依賴檢查,請參考 【第三章】 ?DI? ?3.3? 更多 DI 的知識 ?—— 跟我學 spring3 ? 3.3.4?? 依賴檢查;

9.5 applyProperty Values :應用明確的 setter 屬性注入,請參考 【第三章】?DI?之?3.1 DI的配置使用?——跟我學spring3?

?

10 exposedObject = initializeBean(beanName, exposedObject, mbd);? 執行初始化 Bean 流程;

10.1 invokeAwareMethods BeanNameAware BeanClassLoaderAware BeanFactoryAware :調用一些 Aware 標識接口注入如 BeanName BeanFactory

10.2 BeanPostProcessor po stProcessBeforeInitialization :第七個擴展點,在調用初始化之前完成一些定制的初始化任務,如 BeanValidationPostProcessor 完成 JSR-303 @Valid 注解 Bean 驗證, InitDestroyAnnotationBeanPostProcessor 完成 @PostConstruct 注解的初始化方法調用, ApplicationContextAwareProcessor 完成一些 Aware 接口的注入(如 EnvironmentAware ResourceLoaderAware ApplicationContextAware ),其返回值將替代原始的 Bean 對象;

10.3 invokeInitMethods? :?調用初始化方法;

10.3.1 InitializingBean afterProperties Set? :調用 InitializingBean afterPropertiesSet 回調方法;

10.3.2 、通過 xml 指定的自定義 init-metho d? :調用通過 xml 配置的自定義 init-method

10.3.3 BeanPostProcessor postProcessAfterInitializati on? :第八個擴展點, AspectJAwareAdvisorAutoProxyCreator (完成 xml 風格的 AOP 配置 (<aop:config>) 的目標對象包裝到 AOP 代理對象)、 AnnotationAwareAspectJAutoProxyCreator (完成 @Aspectj 注解風格( <aop:aspectj-autoproxy> @Aspect )的 AOP 配置的目標對象包裝到 AOP 代理對象),其返回值將替代原始的 Bean 對象;

?

11 if (earlySingletonExposure) {

???????????????????? Object earlySingletonReference = getSingleton(beanName, false);

???????????? ……

????? }? :如果是 earlySingleExposure ,調用 getSingle 方法獲取 Bean 實例;

earlySingleExposure =(mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName))

只要單例 Bean 且允許循環引用(默認 true )且當前單例 Bean 正在創建中

11.1 、如果是 earlySingletonExposure 調用 getSingleton 將觸發【 8 】處 ObjectFactory.getObject() 的調用,通過【 8.1 】處的 getEarlyBeanReference 獲取相關 Bean (如包裝目標對象的代理 Bean );(在循環引用 Bean 時可能引起 Spring事務處理時自我調用的解決方案及一些實現方式的風險 );

?

12 registerDisposableBeanIfNecessary(beanName, bean, mbd)? ?注冊 Bean 的銷毀方法(只有非原型 Bean 可注冊);

12.1 、單例 Bean 的銷毀流程

12.1.1 DestructionAwareBeanPostProcessor post ProcessBeforeDestruction? :?第九個擴展點,如 InitDestroyAnnotationBeanPostProcessor 完成 @PreDestroy 注解的銷毀方法注冊和調用;

12.1.2 DisposableBean de stroy :注冊 / 調用 DisposableBean destroy 銷毀方法;

12.1.3 、通過 xml 指定的自定義 destroy-m ethod? ? 注冊 / 調用通過 XML 指定的 destroy-method 銷毀方法;

12.1.2 Scope regis terDestructionCallback :注冊自定義的 Scope 的銷毀回調方法,如 RequestScope SessionScope 等;其流程和【 12.1? 單例 Bean 的銷毀流程一樣】,關于自定義 Scope 請參考 【第三章】?DI?之?3.4 Bean的作用域?——跟我學spring3

?

13 、到此 Bean 實例化、依賴注入、初始化完畢可以返回創建好的 bean 了。

?

? 從上面的流程我們可以看到 BeanPostProcessor 一個使用了九個擴展點,其實還一個擴展點( SmartInstantiationAwareBeanPostProcessor predictBeanType 在下一篇介紹),接下來我們看看 BeanPostProcessor 這些擴展點都主要完成什么功能及常見的 BeanPostProcessor

?

我將在下一帖子中使用例子來解析這八個擴展點的主要功能,及一些Spring默認提供的BeanPostProcessor主要作用。

?

?


上接 Spring事務處理時自我調用的解決方案及一些實現方式的風險 繼續分析,在分析上篇的問題之前,我們需要了解下BeanPostProcessor概念和Spring容器創建Bean的流程。

?

Spring開閉原則的表現-BeanPostProcessor的擴展點-1


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論