1. 程式人生 > 其它 >Spring原始碼解析之BeanPostProcessor

Spring原始碼解析之BeanPostProcessor

前言

AbstractApplicationContext類

refresh()方法

spring在bean的註冊與例項化之間會出現如下程式碼

//bean的註冊
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

//1. Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);

//2. Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);

//3. Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);

//bean的例項化
finishBeanFactoryInitialization(beanFactory);

1.在AbstractApplicationContext為一個空方法,其子類對該方法進行了重寫
2.BeanDefinitionRegistryPostProcessor與BeanFactoryPostProcessor介面的呼叫
3.把實現了BeanPostProcessor介面的類例項化,並且加入到BeanFactory中

invokeBeanFactoryPostProcessors()的原始碼分析

看個例子

BeanDefinitionTest類

@Component
public class BeanDefinitionTest implements BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
        GenericBeanDefinition genericBeanDefinition = new GenericBeanDefinition();
        genericBeanDefinition.setBeanClass(BeanClass.class);
        MutablePropertyValues propertyValues = genericBeanDefinition.getPropertyValues();
        propertyValues.addPropertyValue("username", "蔡徐坤");
        beanDefinitionRegistry.registerBeanDefinition("beanClass", genericBeanDefinition);
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        BeanClass beanClass = (BeanClass) configurableListableBeanFactory.getBean("beanClass");
        System.out.println("postProcessBeanFactory="+beanClass.getUsername());
    }
}

BeanClass類

@Data
public class BeanClass {
    private String username;
}

測試方法

 @Test
    public void test5() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext("cn.com.dq");
        BeanClass beanClass = (BeanClass) applicationContext.getBean("beanClass");
        System.out.println(beanClass.getUsername());
    }

結果輸出

從上述例子我們來看invokeBeanFactoryPostProcessors()的原始碼

PostProcessorRegistrationDelegate類

invokeBeanFactoryPostProcessors()方法

public static void invokeBeanFactoryPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

		// Invoke BeanDefinitionRegistryPostProcessors first, if any.
		Set<String> processedBeans = new HashSet<>();

		if (beanFactory instanceof BeanDefinitionRegistry) {
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					BeanDefinitionRegistryPostProcessor registryProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
					registryProcessor.postProcessBeanDefinitionRegistry(registry);
					registryProcessors.add(registryProcessor);
				}
				else {
					regularPostProcessors.add(postProcessor);
				}
			}

			// Do not initialize FactoryBeans here: We need to leave all regular beans
			// uninitialized to let the bean factory post-processors apply to them!
			// Separate between BeanDefinitionRegistryPostProcessors that implement
			// PriorityOrdered, Ordered, and the rest.
			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

			//獲取實現了BeanDefinitionRegistryPostProcessor介面的所有類的BeanDefinition物件的beanName
			// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				//判斷是否實現了排序介面 PriorityOrdered
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}

			//排序
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			registryProcessors.addAll(currentRegistryProcessors);

			//呼叫過程
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			currentRegistryProcessors.clear();

			// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {

				//判斷是否是實現的Ordered介面
				if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			registryProcessors.addAll(currentRegistryProcessors);
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			currentRegistryProcessors.clear();

			//沒實現排序介面的呼叫
			// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
			boolean reiterate = true;
			while (reiterate) {
				reiterate = false;
				postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
				for (String ppName : postProcessorNames) {
					if (!processedBeans.contains(ppName)) {
						currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
						processedBeans.add(ppName);
						reiterate = true;
					}
				}
				sortPostProcessors(currentRegistryProcessors, beanFactory);
				registryProcessors.addAll(currentRegistryProcessors);
				//
				invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
				currentRegistryProcessors.clear();
			}

			//呼叫postProcessBeanFactory方法
			// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
			invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
		}

		else {
			// Invoke factory processors registered with the context instance.
			invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
		}

		//獲取實現了BeanFactoryPostProcessor介面的類,獲取beanDefinition的名稱
		// Do not initialize FactoryBeans here: We need to leave all regular beans
		// uninitialized to let the bean factory post-processors apply to them!
		String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

		// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
		// Ordered, and the rest.
		List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		List<String> orderedPostProcessorNames = new ArrayList<>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		for (String ppName : postProcessorNames) {
			if (processedBeans.contains(ppName)) {
				// skip - already processed in first phase above
			}
			//實現了PriorityOrdered介面的
			else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
			}
			//實現了Ordered介面的
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
				//沒實現介面的
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		//排序
		// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);

		//呼叫
		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

		// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
		List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
		for (String postProcessorName : orderedPostProcessorNames) {
			orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

		// Finally, invoke all other BeanFactoryPostProcessors.
		List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
		for (String postProcessorName : nonOrderedPostProcessorNames) {
			nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

		// Clear cached merged bean definitions since the post-processors might have
		// modified the original metadata, e.g. replacing placeholders in values...
		beanFactory.clearMetadataCache();
	}

上述程式碼執行過程:
1.獲取所有實現BeanDefinitionRegistryPostProcessor介面的beanName
2.注意這行程式碼

currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));

我們知道beanFactory.getBean()是bean的例項化,這裡是優先將實現BeanDefinitionRegistryPostProcessor介面的bean進行例項化,然後加入到currentRegistryProcessors容器中
3.接下來執行了這行程式碼

invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);

private static void invokeBeanDefinitionRegistryPostProcessors(
			Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {

		for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
			postProcessor.postProcessBeanDefinitionRegistry(registry);
		}
	}

我們可以看到最終是執行了BeanDefinitionRegistryPostProcessor 介面的postProcessBeanDefinitionRegistry方法
4.我們回過來看我們寫的demo類

我們在postProcessBeanDefinitionRegistry方法中重新註冊了一個我們新建立的bean叫做beanClass,並且給beanClass裡的屬性賦值了蔡徐坤
5.執行完所有的有關BeanDefinitionRegistryPostProcessor 介面的postProcessBeanDefinitionRegistry方法呼叫後
接著呼叫瞭如下程式碼

invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);

private static void invokeBeanFactoryPostProcessors(
			Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {

		for (BeanFactoryPostProcessor postProcessor : postProcessors) {
			postProcessor.postProcessBeanFactory(beanFactory);
		}
	}

從上面可以看出 是執行了BeanDefinitionRegistryPostProcessor 介面的postProcessBeanFactory方法
BeanDefinitionRegistryPostProcessor介面繼承了BeanFactoryPostProcessor介面,postProcessBeanFactory方法為
BeanFactoryPostProcessor中的方法
6.回到demo

我們在這個方法中通過getBean操作例項化了beanClass然後列印了該例項中的屬性,因此能解釋我們寫的demo控制檯的輸出
7.通過與BeanDefinitionRegistryPostProcessor 相同的方式,處理了實現BeanFactoryPostProcessor介面的bean的postProcessBeanFactory方法的呼叫

registerBeanPostProcessors方法的原始碼分析

PostProcessorRegistrationDelegate類

registerBeanPostProcessors方法

public static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

		//拿到工程裡面所有實現了BeanPostProcessor介面的類,獲取到BeanDefinition的名稱
		String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

		// Register BeanPostProcessorChecker that logs an info message when
		// a bean is created during BeanPostProcessor instantiation, i.e. when
		// a bean is not eligible for getting processed by all BeanPostProcessors.
		int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
		beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

		// Separate between BeanPostProcessors that implement PriorityOrdered,
		// Ordered, and the rest.
		List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
		List<String> orderedPostProcessorNames = new ArrayList<>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();

		//提前例項化BeanPostProcessor型別的bean,然後bean進行排序
		for (String ppName : postProcessorNames) {
			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {

				//getBean是例項化方法,後面我們在講bean例項化過程
				BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
				priorityOrderedPostProcessors.add(pp);

				//判斷型別是否是MergedBeanDefinitionPostProcessor,如果是則程式碼是內部使用的
				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);

		//註冊到BeanFactory中
		registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

		// Next, register the BeanPostProcessors that implement Ordered.
		List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
		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<>();
		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).
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
	}

1.拿到工程裡面所有實現了BeanPostProcessor介面的類,獲取到BeanDefinition的名稱
2.遍歷所有的beanName,在迴圈中,我們看到一個比較重要的程式碼

BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);

我們知道beanFactory.getBean()是bean的例項化,所以,我們可以得到spring容器在例項化bean的時候,優先例項化的是BeanPostProcessor型別的bean,為什麼要優先例項化BeanPostProcessor型別的bean,因為其他bean的例項化需要呼叫BeanPostProcessor裡面的方法
3.例項化BeanPostProcessor型別的bean以後,接下來會將這些bean註冊到beanFactory的beanPostProcessors容器中

registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

private static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {

		for (BeanPostProcessor postProcessor : postProcessors) {
			beanFactory.addBeanPostProcessor(postProcessor);
		}
	}

AbstractBeanFactory類
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
		Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
		// Remove from old position, if any
		this.beanPostProcessors.remove(beanPostProcessor);
		// Track whether it is instantiation/destruction aware
		if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
			this.hasInstantiationAwareBeanPostProcessors = true;
		}
		if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
			this.hasDestructionAwareBeanPostProcessors = true;
		}
		// Add to end of list
		this.beanPostProcessors.add(beanPostProcessor);
	}

這裡有一個比較有意思的變數hasInstantiationAwareBeanPostProcessors ,在bean例項化的時候,會利用到這個變數
在bean例項化的時候會解釋這個變數的作用

總結

1.invokeBeanFactoryPostProcessors方法首先是對實現了BeanDefinitionRegistryPostProcessor介面的bean進行了例項化,接著對BeanDefinitionRegistryPostProcessor中的postProcessBeanDefinitionRegistry方法進行了呼叫,然後對BeanDefinitionRegistryPostProcessor中的 postProcessBeanFactory方法進行了呼叫
2.invokeBeanFactoryPostProcessors 接下來對實現了BeanFactoryPostProcessor介面的bean進行了例項化,然後對BeanFactoryPostProcessor中的postProcessBeanFactory方法進行了呼叫
3.registerBeanPostProcessors()提前對所有實現了BeanPostProcessor 介面的bean進行例項化,然後將這些bean註冊到beanFactory的beanPostProcessors容器中
4.spring在bean的例項化過程中,優先例項化的是實現了BeanDefinitionRegistryPostProcessor的bean,其次是實現了
BeanFactoryPostProcessor介面的bean,再次是實現了BeanPostProcessor 介面的bean,最後是普通bean