《系列二》-- 7、後置處理器-PostProcessor

閱讀之前要注意的東西:本文就是主打流水賬式的源碼閱讀,主導的是一個參考,主要內容需要看官自己去源碼中驗證。全系列文章基於 spring 源碼 5.x 版本。

寫在開始前的話:

閱讀spring 源碼實在是一件龐大的工作,不說全部內容,單就最基本核心部分包含的東西就需要很長時間去消化了:

  • beans
  • core
  • context

實際上我在博客裏貼出來的還只是一部分內容,更多的內容,我放在了個人,fork自 spring 官方源碼倉了; 而且對源碼的學習,必須是要跟着實際代碼層層遞進的,不然只是乾巴巴的文字味同嚼蠟。

https://gitee.com/bokerr/spring-framework-5.0.x-study

這個倉設置的公共倉,可以直接拉取。



Spring源碼閱讀系列--全局目錄.md



什麼是後置處理器

這裏引入spring 的一個 重要部件 PostProcessor, 我習慣把它叫做:後置處理器;

通俗來說,就是:定義一個 XxxPostProcessor 接口,定義一組行爲;而後在具體的bean加載過程中,我們可以在 BeanFactory 初始化時,根據自己的實際需要,向BeanFactory 中注入相關的 PostProcessor;
而後在某些特殊節點(時機),獲取某一類的 "後置處理器" 並全部執行之即可。

這裏需要注意的是:後置處理器,一般需要被理解成,某某行爲-後置處理器;它可能是對某某行爲返回結果的校驗,也可能是對其的包裝,(希望你瞭解設計模式之:包裝器模式)。

spring 源碼中已知的,頂級PostProcessor

img.png

全局一共6個,那麼我們通過,其中跟我們當前分析的代碼關聯度最高的, BeanPostProssor 來做個介紹:


package org.springframework.beans.factory.config;

import org.springframework.beans.BeansException;
import org.springframework.lang.Nullable;

/**
 * Factory hook that allows for custom modification of new bean instances,
 * e.g. checking for marker interfaces or wrapping them with proxies.
 *
 * <p>ApplicationContexts can autodetect BeanPostProcessor beans in their
 * bean definitions and apply them to any beans subsequently created.
 * Plain bean factories allow for programmatic registration of post-processors,
 * applying to all beans created through this factory.
 *
 * <p>Typically, post-processors that populate beans via marker interfaces
 * or the like will implement {@link #postProcessBeforeInitialization},
 * while post-processors that wrap beans with proxies will normally
 * implement {@link #postProcessAfterInitialization}.
 */
public interface BeanPostProcessor {

	/**
	 * Apply this BeanPostProcessor to the given new bean instance <i>before</i> any bean
	 * initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
	 * or a custom init-method). The bean will already be populated with property values.
	 * The returned bean instance may be a wrapper around the original.
	 * <p>The default implementation returns the given {@code bean} as-is.
	 * @param bean the new bean instance
	 * @param beanName the name of the bean
	 * @return the bean instance to use, either the original or a wrapped one;
	 */
	@Nullable
	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

	/**
	 * Apply this BeanPostProcessor to the given new bean instance <i>after</i> any bean
	 * initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
	 * or a custom init-method). The bean will already be populated with property values.
	 * The returned bean instance may be a wrapper around the original.
	 * <p>In case of a FactoryBean, this callback will be invoked for both the FactoryBean
	 * instance and the objects created by the FactoryBean (as of Spring 2.0). The
	 * post-processor can decide whether to apply to either the FactoryBean or created
	 * objects or both through corresponding {@code bean instanceof FactoryBean} checks.
	 * <p>This callback will also be invoked after a short-circuiting triggered by a
	 * in contrast to all other BeanPostProcessor callbacks.
	 * <p>The default implementation returns the given {@code bean} as-is.
	 * @param bean the new bean instance
	 * @param beanName the name of the bean
	 * @return the bean instance to use, either the original or a wrapped one;
	 */
	@Nullable
	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}
}

可以看接口中的這倆方法名:

  • postProcessBeforeInitialization: 後置處理器 of 初始化前
    所有bean在"初始化前"都會執行,實現了接口BeanPostProcessor 的後置處理器,所實現的 postProcessBeforeInitialization 方法。
    該方法返回的可能是該bean的實例,也可能是被代理包裝後的該bean

  • postProcessAfterInitialization: 後置處理器 of 初始化後
    所有bean在 "初始化後" 都會執行,實現了接口BeanPostProcessor 的後置處理器,所實現的 postProcessBeforeInitialization 方法。
    該方法返回的可能是該bean的實例,也可能是被代理包裝後的該bean

我這裏的翻譯較爲縮略,英文尚可的夥計可以自取源碼中的註釋。

其它 "後置處理器"

其實大同小異,其它的就不再展開介紹。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章