Spring擴展點之BeanPostProcessor

前言

BeanPostProcessor接口是Spring中一個很是重要的接口,它的接口定義以下app

public interface BeanPostProcessor {

    Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
    
    Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}

當你實現了這個接口的時候,Spring會保證在每個bean對象初始化方法調用以前調用postProcessBeforeInitialization方法,在初始化方法調用以後調用postProcessAfterInitializationide

BeanPostProcessor的註冊

看過我以前寫的IOC源碼分析系列文章的同窗應該對這個都比較有印象 1 Spring在執行到這的時候會把全部實現BeanPostProcessor接口的實現類都註冊到BeanFactory中,一塊兒來看一下實現的細節源碼分析

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
	}
public static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
		//獲取全部BeanPostProcessor的實現類
		String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);


		int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
		beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

	      // 這裏把實現PriorityOrdered接口,Ordered 接口的BeanPostProcessors 和其餘類型的BeanPostProcessors 區分開
		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)) {
				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);
			}
		}

		//對實現了PriorityOrdered接口的按優先級排序
		sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
       //這裏就是註冊了,下面會說
		registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

		
		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(beanFactory, orderedPostProcessors);
       //註冊
		registerBeanPostProcessors(beanFactory, orderedPostProcessors);

		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);

		// 最後註冊常規的
		sortPostProcessors(beanFactory, internalPostProcessors);
		registerBeanPostProcessors(beanFactory, internalPostProcessors);

		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
	}

能夠看到上方的代碼就是把這些BeanPostProcessor分爲了幾類,而後分別根據規則排序後註冊進BeanFactory中,而BeanFactory中其實就只是維護了一個BeanPostProcessor的列表而已post

private final List<BeanPostProcessor> beanPostProcessors = new ArrayList();

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

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

public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
        Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
        this.beanPostProcessors.remove(beanPostProcessor);
        this.beanPostProcessors.add(beanPostProcessor);
        if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
            this.hasInstantiationAwareBeanPostProcessors = true;
        }

        if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
            this.hasDestructionAwareBeanPostProcessors = true;
        }

    }

執行原理

咱們知道Bean的初始化是在定義在容器的刷新過程當中,而具體的實現則是由AbstractAutowireCapableBeanFactory.initializeBean()方法完成的。在這個方法中就包含了BeanPostProcessor的調用邏輯this

protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged(new PrivilegedAction<Object>() {
				@Override
				public Object run() {
					invokeAwareMethods(beanName, bean);
					return null;
				}
			}, getAccessControlContext());
		}
		else {
			invokeAwareMethods(beanName, bean);
		}
 
		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
            // BeanPostProcessors 的Before 方法
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}
 
		try {
            // 調用初始化方法
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					(mbd != null ? mbd.getResourceDescription() : null),
					beanName, "Invocation of init method failed", ex);
		}
 
		if (mbd == null || !mbd.isSynthetic()) {
            // BeanPostProcessors 的After方法
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}
		return wrappedBean;
	}

而這裏面的執行邏輯咱們也能夠猜到,無非就是循環遍歷全部的BeanPostProcessor,而後一一執行code

public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
        throws BeansException {

    Object result = existingBean;
    for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
        result = beanProcessor.postProcessBeforeInitialization(result, beanName);
        if (result == null) {
            return result;
        }
    }
    return result;}

其中applyBeanPostProcessorsAfterInitialization的實現內容跟這個是同樣的對象

可是這裏面有一個主意的點,那就是若是具體的實現一但返回null,那麼就會跳出for循環,後面的就得不到機會執行了blog

常見用例

查看這個接口的繼承體系,能夠看到這個接口的實現類是很是多的,各個實現類的功能若是感興趣你們能夠去慢慢挖掘一下 2排序

1

相關文章
相關標籤/搜索