12-Spring源碼解析之refresh(5)——registerBeanPostProcessors

Spring版本:<version>5.2.1.RELEASE</version>

上一篇:11-Spring源碼解析之refresh(4)——invokeBeanFactoryPostProcessors(2)

上一篇,我們介紹完了Spring是如何註冊BeanFactoryPostProcessors,如何解析@Configuration註解標註的配置類,如何將配置類中的類信息放到beanFactory.beanDefinitionMap中。

本篇我們繼續講解refresh方法中調用的第六個方法:registerBeanPostProcessors -> 註冊BeanPostProcessor。注意,這裏是註冊,註冊!而不是調用,真正的調用是在Bean實例化階段進行的。BeanPostProcessor是Spring提供的擴展接口。

在講解registerBeanPostProcessors之前,我們需要先了解BeanPostProcessor的結構,以及他的功能是什麼。

一、 BeanPostProcessor簡介

public interface BeanPostProcessor {
	// bean初始化方法調用前被調用
	@Nullable
	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}
	
	// bean初始化方法調用後被調用
	@Nullable
	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

}

從上面可以看出,BeanPostProcessor接口只提供了兩個方法,這兩個方法分別是在Bean初始化前後調用。爲了更有力的說明BeanPostProcessor執行時機,我給出以下實例。

1. BeanPostProcessor實例

自定義後置處理器MyBeanPostProcessor


// 使用@Component將後置處理器加入到容器中
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
    // 初始化之前進行處理
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("beforeInitializtion....." + beanName);
        return bean;
    }
    // 初始化之後進行處理
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("afterInitializtion....." + beanName);
        return bean;
    }
}

注意:實現接口中的兩個方法的最後返回值不能返回null,如果返回null那麼在後續初始化方法將報空指針異常或者通過getBean()方法獲取不到bean實例對象,因爲後置處理器從Spring容器中取出bean實例對象沒有再次放回Spring容器中。

POJO


public class MathCalculator {
    private String name;

    public MathCalculator(String name) {
        this.name = name;
        System.out.println("pojo類的構造方法");
    }

    public void init() {
        System.out.println("pojo類的init方法");
    }

    public int div(int i, int j) {
        return i / j;
    }

    @Override
    public String toString() {
        return "MathCalculator{" +
                "name='" + name + '\'' +
                '}';
    }
}

該類有一個屬性name,一個有參構造器,爲了方便看BeanPostProcessor的執行順序,一個init方法,這個init在配置類中我會將其標誌爲初始化方法,一個toStrng,一個div方法,這個div方法是爲了測試AOP,這裏暫時用不到。

配置類Config_beanPostProcessor

@ComponentScan
@Configuration
public class Config_beanPostProcessor {
    @Bean(initMethod = "init")
    public Pojo pojo() {
        System.out.println("給容器中添加 Pojo");
        return new Pojo("pojo.Name屬性");
    }
}

測試類

public class beanPostProcessorTest {
    @SuppressWarnings("resource")
    @Test
    public void test01() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Config_beanPostProcessor.class);
        Pojo pojo = applicationContext.getBean(Pojo.class);
        System.out.println(pojo);
    }
}

輸出結果

在這裏插入圖片描述
我們可以看到BeanPostProcessor的實現類中的兩個方法在配置類和pojo類中都有調用。我們主要看在POJO類的調用順序:
這裏還涉及另外一個問題:因爲pojo類是由配置類通過@Bean方式加入到Spring容器中的,因此在做doCreateBean - > createBeanInstance 與普通的Bean不一樣。具體有什麼不同,在後面的文章會介紹。

另外,從上面輸出結果也可以看出,BeanPostProcessor實現類會攔截每一個Bean的創建,並在Bean的初始化前後調用postProcessBeforeInitializationpostProcessAfterInitialization方法。

回到上面的輸出結果,我們可以看出BeanPostProcessor類的方法的調用順序如下:

在這裏插入圖片描述

2. BeanPostProcessor的類結構

看完了BeanPostProcessor的執行順序,下面我們看一下SpringBeanPostProcessor的類結構

在這裏插入圖片描述

Spring中有5大類BeanPostProcessor,每一類在加載Bean的時候都起着十分重要的作用。這裏先不具體介紹,我們先把整體流程看完之後,在後面會具體總結每一個BeanPostProcessorSpring中的調用時機。

現在已經瞭解到BeanPostProcessor的結構以及調用順序了,我們就可以開始分析Spring是如何將BeanPostProcessor註冊到beanFactoy中的了。

二、BeanPostProcessor註冊

2.1 當前beanFactory中的值

終於來到了正題:refresh調用的第六個方法registerBeanPostProcessors。那麼在看這個方法的具體實現之前,我們還是得先看看當前beanFactory中都註冊了哪些beanDefinition,有哪些beanPostProcessor和已經創建了哪些Bean

在這裏插入圖片描述
從上圖可以看出有10個beanDefinition,其中

  • beanDefinition[0] -- beanDefinition[4]爲Spring內置的Bean
  • beanDefinition[5]爲我們自己寫的配置類,
  • beanDefinition[6]爲我們自己寫的實現了BeanPostProcessor的類,
  • beanDefinition[7]爲我們自己寫的pojo類,
  • beanDefinition[8]爲我們自己寫的切面類(爲了做AOP),
  • beanDefinition[9]Spring爲了實現AOP功能爲我們創建的內置類。

接下來看看當前BeanFactory中已經有哪些後置處理器
在這裏插入圖片描述

beanPostProcessors[0]beanPostProcessors[1]refresh()調用的prepareBeanFactory()方法中通過beanFactory.addBeanPostProcessor添加的。具體參見:9-Spring容器創建之refresh(3)——【prepareBeanFactory】與【postProcessBeanFactory】beanPostProcessor[2]refresh調用的invokeBeanFactoryPostProcessors()方法的時候調用beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));添加的。

繼續看當前BeanFactory已經創建好哪些Bean
在這裏插入圖片描述
看完了以上3個屬性之後,我們就可以開始分析registerBeanPostProcessors是如何實現的了!以及執行完registerBeanPostProcessors方法後,beanFactory中的以上三個屬性增加了些什麼。

2.2 registerBeanPostProcessors方法

	protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
	}

調用PostProcessorRegistrationDelegate類的方法registerBeanPostProcessors,記得在refresh調用第五個方法invokeBeanFactoryPostProcessors的時候嗎?也是調用了PostProcessorRegistrationDelegate類的方法,只不過那個時候調用的是:invokeBeanFactoryPostProcessors方法

	public static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
		// 根據BeanPostProcessor類型從beanFactory獲取beanName
		// 從2.1中的圖知道,beanFactory的10個bean中有4個是BeanPostProcessor類型的,具體哪4個在這一節最後的圖片中給出
		//   其中3個內置類已經註冊完了。
		String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

		// 向beanFactory中又註冊了一個BeanPostProcessorChecker類型的BeanPostProcessor
		// beanProcessorTargetCount:爲當前BeanPostProcessor總數+1(+1是剛剛又加了一個BeanPostProcessorChecker類型的BeanPostProcessor)
		int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
		beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

		// 將所有的BeanPostProcessor按照優先級(PriorityOrdered、Ordered)歸類
		List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
		List<String> orderedPostProcessorNames = new ArrayList<>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		for (String ppName : postProcessorNames) {
			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				// 內置類就正常按照doGetBean的順序進行創建
				BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
				priorityOrderedPostProcessors.add(pp);
				if (pp instanceof MergedBeanDefinitionPostProcessor) {
					internalPostProcessors.add(pp);
				}
			}
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		// First, register the BeanPostProcessors that implement PriorityOrdered.
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
// ---------------------------------2.2.1具體講解registerBeanPostProcessors方法
		registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// ---------------------------------2.2.2簡要介紹AOP的AnnotationAwareAspectJAutoProxyCreator----
		// Next, register the BeanPostProcessors that implement Ordered.
		// 注意,實現AOP功能的AnnotationAwareAspectJAutoProxyCreator類在這個地方被創建,
		// 在這裏創建的原因:因爲他是實現了Ordered接口的BeanPostProcessor
		// 這裏不詳細介紹,在AOP文章中會詳細介紹。但是在這裏給出一下AnnotationAwareAspectJAutoProxyCreator的類圖
		//----------------------------------AOP在這裏創建-------------------------------------
		List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
		for (String ppName : orderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			orderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, orderedPostProcessors);

		// Now, register all regular BeanPostProcessors.
		List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
		for (String ppName : nonOrderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			nonOrderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

		// Finally, re-register all internal BeanPostProcessors.
		sortPostProcessors(internalPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, internalPostProcessors);

		// Re-register post-processor for detecting inner beans as ApplicationListeners,
		// moving it to the end of the processor chain (for picking up proxies etc).
		// 最後又重新註冊了一次ApplicationListenerDetector,我們知道在refresh-> prepareBeanFactory方法中已經註冊過一次了
		// 那麼爲什麼還要再註冊一次呢?
		// 主要是想要將ApplicationListenerDetector放到所有的BeanPostProcessor最後
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
	}

registerBeanPostProcessors執行之前,我們看以下beanFactory中的beanDefinition中有哪些BeanPostProcessor。這些BeanPostProcessor還沒有被註冊。
在這裏插入圖片描述
從上面可以看出,registerBeanPostProcessors方法就是將beanFactorypostProcessor都註冊到BeanPostProcessor中。另外還給beanFactory多增加了一個BeanPostProcessor,即BeanPostProcessorChecker

在執行完registerBeanPostProcessors之後,我們看一下beanFactory中有哪些BeanPostProcessor

在這裏插入圖片描述

以上是調用registerBeanPostProcessors方法之前beanFactory中存在的BeanPostProcessor。下面我們看一下調用registerBeanPostProcessors之後beanFactory中存在的BeanPostProcessor

  • beanPostProcessor[3]beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));添加
  • beanPostProcessor[4]Ordered接口添加
  • beanPostProcessor[5]regular處添加
  • beanPostProcessor[6] - beanPostProcessor[7]PriorityOrdered接口添加

在執行完registerBeanPostProcessors方法後,beanFactory中已經創建的Bean如下:

在這裏插入圖片描述
其中myBeanPostProcessor爲我們自己寫的實現了BeanPostProcessor的類。

2.2.1 registerBeanPostProcessors方法

	private static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
		// 將每一個BeanPostProcessor添加到beanFactory的BeanPostProcessor中
		for (BeanPostProcessor postProcessor : postProcessors) {
			beanFactory.addBeanPostProcessor(postProcessor);
		}
	}
	public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
		Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
		// Remove from old position, if any
		this.beanPostProcessors.remove(beanPostProcessor);
		// 如果當前的beanPostProcessor是InstantiationAwareBeanPostProcessor類型,就要將beanFactory的hasInstantiationAwareBeanPostProcessors屬性設置爲true
		// 這個屬性在創建Bean的時候會用到: createBean -> resolveBeforeInstantiation
		if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
			this.hasInstantiationAwareBeanPostProcessors = true;
		}
		if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
			this.hasDestructionAwareBeanPostProcessors = true;
		}
		// Add to end of list
		// 將beanPostProcessor放到beanFactory的beanPostProcessors屬性中
		// private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>();
		this.beanPostProcessors.add(beanPostProcessor);
	}

2.2.2 AnnotationAwareAspectJAutoProxyCreator

這裏面涉及到AOP功能對應的AnnotationAwareAspectJAutoProxyCreator類型的Bean的創建,爲什麼在這裏呢?因爲實現AOP功能AnnotationAwareAspectJAutoProxyCreator就是一個實現了Ordered接口的BeanPostProcessor。這裏不詳細講解他的創建過程,在之後的AOP文章中具體介紹。

在這裏插入圖片描述

public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
		implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware

他的父類ProxyProcessorSupport實現了Ordered接口:

public class ProxyProcessorSupport extends ProxyConfig implements Ordered, BeanClassLoaderAware, AopInfrastructureBean

三、總結

  • registerBeanPostProcessors 的功能:
    • 【功能一】爲beanFactory直接添加 BeanPostProcessorChecker後置處理器
    • 【功能二】按照順序實例化BeanPostProcessors並將其添加到beanFactoryBeanPostProcessors
    • 【功能三】將ApplicationListenerDetector後置處理器移到後置處理器集合的最後

以上我們完成了registerBeanPostProcessors功能的分析,下一篇我們繼續分析refresh方法中的

  • 第七個方法initMessageSource
  • 第八個方法initApplicationEventMulticaster
  • 第九個方法onRefresh
  • 第十個方法registerListeners
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章