Spring 源码解析 - BeanPostProcessor 扩展接口

一、BeanPostProcessor 扩展接口

BeanPostProcessorSpring中的一个扩展接口,它可以在Spring容器实例化bean之后,在执行 bean的初始化方法前后,允许我们自定义修改新的 bean实例。比如修改 bean 的属性,将 bean 替换为动态代理等。其中 AOP 的底层创建代理实例,就是通过实现 BeanPostProcessor 来实现的。

BeanPostProcessor 包含两个方法:

public interface BeanPostProcessor {
	/**
	 *  实例化及依赖注入完成后、bean 初始化方法触发之前执行
	 */
	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

	/**
	 *  bean 初始化方法触发后执行
	 */
	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

}

如果在 Bean 实例化、配置和其他初始化过程中有任何错误,由 Spring 抛出 BeansException 异常。由于 BeanPostProcessor 可以干预 Bean 实例化、配置和初始化的每个阶段,因此实现过程需要非常谨慎。

BeanPostProcessor 是怎么干预 Bean 实例化的呢?可以通过下面这个案例感受一下:

这里我们创建一个测试 bean

@Component
public class Test {
    public void test() {
        System.out.println("test...");
    }
}

下面创建一个类实现 BeanPostProcessor 接口,在后通知中使用 CGLIB 创建一个动态代理对象:

@Component
public class TestBeanPostProcessor implements BeanPostProcessor {

    /**
     * 实例化及依赖注入完成后、bean 初始化方法触发之前执行
     */
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
       return bean;
    }

    /**
     * bean 初始化方法触发后执行
     */
    public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException {
        Class beanClass = bean.getClass();
        if (beanClass == Test.class) {
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(beanClass);
            enhancer.setCallback((MethodInterceptor) (o, method, objects, methodProxy) -> {
                System.out.println("<目标方法之前开始执行....>");
                Object result = methodProxy.invokeSuper(o, objects);
                System.out.println("<目标方法之后开始执行....>");
                return result;
            });
            return enhancer.create();
        }
        return bean;
    }
}

下面测试下效果:

public class App {

    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext("com.example.demo.beanpost");
        Test hello = (Test) context.getBean("test");
        hello.test();
    }
}

在这里插入图片描述

这样是不是就感受到 BeanPostProcessor 扩展接口的强大之处了吧,可以看出它可以干预 Bean 的实例化,因此使用的话需要非常谨慎。

下面从源码角度分析下,在 Spring 中是如何使用 BeanPostProcessor 进行扩展的。

二、BeanPostProcessor 的注册

从上面的实例中可以感觉出来,我们并没有对 BeanPostProcessor 进行特殊处理,仅仅将其加入 Spring 容器中即会生效,那 Spring 是如何读取BeanPostProcessor 呢?

在本专栏的其他 Spring 源码分析的文章中,分析的入口都是基于 AbstractApplicationContext 中的 refresh() 方法,那现在也是从这里入手,主要逻辑在该方法下触发的 registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) 方法:

在这里插入图片描述

主要逻辑则在 PostProcessorRegistrationDelegate 下的 registerBeanPostProcessors 方法,源码如下:

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

	// 从bean工厂中获取到所有实现了 BeanPostProcessor 接口的 beanName
	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;
	// 往bean工厂中添加一个BeanPostProcessor -> BeanPostProcessorChecker
	// BeanPostProcessorChecker 是一个在创建bean期间记录信息消息的 BeanPostProcessor
	beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

	// Separate between BeanPostProcessors that implement PriorityOrdered,
	// Ordered, and the rest.
	// 存放实现了PriorityOrdered接口的BeanPostProcessor
	List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
	// 存放实现了MergedBeanDefinitionPostProcessor接口的BeanPostProcessor
	List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
	// 存放实现了Ordered接口的BeanPostProcessor
	List<String> orderedPostProcessorNames = new ArrayList<String>();
	// 存放普通的BeanPostProcessor
	List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
	for (String ppName : postProcessorNames) {
		// 如果实现了PriorityOrdered接口
		if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
			// 从工厂中获取对应的 Bean实例
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			priorityOrderedPostProcessors.add(pp);

			// 如果同时实现了MergedBeanDefinitionPostProcessor接口
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		// 如果实现了Ordered接口
		else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
			orderedPostProcessorNames.add(ppName);
		}
		// 普通的 BeanPostProcessor
		else {
			nonOrderedPostProcessorNames.add(ppName);
		}
	}

	// 排序
	sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
	// 注册实现了PriorityOrdered 接口的 BeanPostProcessor
	registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

	// Next, register the BeanPostProcessors that implement Ordered.
	List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
	for (String ppName : orderedPostProcessorNames) {
		BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
		orderedPostProcessors.add(pp);
		// 如果同时实现了MergedBeanDefinitionPostProcessor接口
		if (pp instanceof MergedBeanDefinitionPostProcessor) {
			internalPostProcessors.add(pp);
		}
	}
	// 排序
	sortPostProcessors(beanFactory, orderedPostProcessors);
	//  注册实现了Ordered接口的BeanPostProcessor
	registerBeanPostProcessors(beanFactory, orderedPostProcessors);

	// Now, register all regular BeanPostProcessors.
	// 注册其他普通的BeanPostProcessor
	List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
	for (String ppName : nonOrderedPostProcessorNames) {
		BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
		nonOrderedPostProcessors.add(pp);
		// 如果实现了 MergedBeanDefinitionPostProcessor 接口
		if (pp instanceof MergedBeanDefinitionPostProcessor) {
			internalPostProcessors.add(pp);
		}
	}
	// 通过 beanFactory.addBeanPostProcessor(postProcessor) 添加 BeanPostProcessor
	registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

	// Finally, re-register all internal BeanPostProcessors.
	// 排序
	sortPostProcessors(beanFactory, internalPostProcessors);
	// 通过beanFactory.addBeanPostProcessor(postProcessor)添加BeanPostProcessor
	// 注册所有 BeanPostProcessor
	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).
	// 往bean工厂中添加一个BeanPostProcessor -> ApplicationListenerDetector
	// ApplicationListenerDetector主要是检测bean是否实现了ApplicationListener接口
	beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

三、BeanPostProcessor 触发点

BeanPostProcessor 与 bean 的实例化过程息息相关,因此可以从 bean 实例化的入口 AbstractAutowireCapableBeanFactory 类的 createBean 方法入手:

3.1 resolveBeforeInstantiation

首先看到 createBean 方法下触发的 resolveBeforeInstantiation 方法,主要是针对于 InstantiationAwareBeanPostProcessor 类型的 BeanPostProcessor ,并且使用是 postProcessBeforeInstantiation 和 postProcessAfterInitialization 方法,也是一种扩展通知,并且如果返回 bean 不为空则直接跳过 Spring 的实例化过程:

在这里插入图片描述

在这会尝试通过 BeanPostProcessors 获取一个对象,这个可能是代理实例也可能是其他实例:

在这里插入图片描述

在这里插入图片描述

这里判断如果有 InstantiationAwareBeanPostProcessor 类型的 BeanPostProcessor ,则尝试使用 postProcessBeforeInstantiation 方法获取一个代理实例。

3.2 getEarlyBeanReference

如果上面没有生成代理实例的话,再回到 createBean 方法中,在 doCreateBean 方法下,创建实例后,会曝光至三级缓存中:

在这里插入图片描述

在 getEarlyBeanReference 方法中,会尝试使用 SmartInstantiationAwareBeanPostProcessor 类型的 BeanPostProcessor 创建一个早期的实例,虽说 SmartInstantiationAwareBeanPostProcessor 没有直接实现 BeanPostProcessor 但其父类 InstantiationAwareBeanPostProcessor 实现了 BeanPostProcessor :

在这里插入图片描述

Spring AOP 代理对象就是在此处获取,因此三级缓存存入ObjectFactory<?>而不是具体的 bean 的意义在此。

3.3 initializeBean

上面都是对特殊类型的 BeanPostProcessor 进行触发,在 doCreateBean 的 initializeBean 中则触发了全部的BeanPostProcessor :

在这里插入图片描述

这里在 invokeInitMethods 方法前后触发了 BeanPostProcessor 的 postProcessBeforeInitialization 和 postProcessAfterInitialization

在这里插入图片描述

在这里插入图片描述

四、Spring 中的 BeanPostProcessor 常用子类

从上面的触发点源码中,可以看出有些地方是触发的特定类型的 BeanPostProcessor 子类,而这些子类又有着不同的用途。

4.1 InstantiationAwareBeanPostProcessor

在这里插入图片描述

可以在Bean生命周期实例化Bean之前和实例化Bean之后对Bean进行操作,比如在上面源码中 createBean 方法下触发的 resolveBeforeInstantiation 方法。

InstantiationAwareBeanPostProcessor 类型的子类,会在目标Bean实例化之前尝试使用该类型的实例生成一个代理对象,如果方法返回的是一个非空对象, 将会跳过后续 Spring 默认的创建流程:

public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {

	// 在目标Bean实例化之前执行尝试使用该类型的生成一个代理对象,如果方法返回的是一个非空对象, 将会跳过后续 Spring 默认的创建流程
	@Nullable
	default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
		return null;
	}

	// 在目标Bean实例化之后、属性填充前执行,如果方法返回false,将会跳过后续的属性填充过程,通常情况下返回true
	default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
		return true;
	}

	// 允许对填充前的属性进行处理,比如对属性进行验证
	@Nullable
	default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
			throws BeansException {

		return null;
	}

	// 对属性值进行修改,通过基于原始的PropertyValues创建一个新的MutablePropertyValues实例,添加或删除特定的值
	// 已标记过期,官方推荐使用 postProcessProperties()方法
	@Deprecated
	@Nullable
	default PropertyValues postProcessPropertyValues(
            PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
		return pvs;
	}
}

4.2 SmartInstantiationAwareBeanPostProcessor

在这里插入图片描述

SmartInstantiationAwareBeanPostProcessor 也是一个接口继承了上面的 InstantiationAwareBeanPostProcessor 因此拥有 InstantiationAwareBeanPostProcessor 的特征,在此之外又提供了获取早期实例的方法。

在 Spring 的三级缓存中则会尝试使用 getEarlyBeanReference 获取一个早期实例。

public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor {

	//在 Bean 实例化前预测最终返回的 Class 类型,触发时机是在InstantiationAwareBeanPostProcessor的 postProcessBeforeInstantiation()之前
	@Nullable
	default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
		return null;
	}

	//决定使用哪个构造器构造Bean,如果不指定,默认为null,即bean的无参构造方法;
	@Nullable
	default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)
			throws BeansException {

		return null;
	}

	//获得提前暴露的bean引用,主要用于 Spring 循环依赖问题的解决
	default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
		return bean;
	}

}

4.3 ApplicationContextAwareProcessor

在这里插入图片描述

应用上下文感知Bean后置处理器,在postProcessBeforeInitialization方法中通过invokeAwareInterfaces方法给目标 Bean 注入指定的属性值:

class ApplicationContextAwareProcessor implements BeanPostProcessor {

	private final ConfigurableApplicationContext applicationContext;

	private final StringValueResolver embeddedValueResolver;


	/**
	 * Create a new ApplicationContextAwareProcessor for the given context.
	 */
	public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) {
		this.applicationContext = applicationContext;
		this.embeddedValueResolver = new EmbeddedValueResolver(applicationContext.getBeanFactory());
	}


	@Override
	@Nullable
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
				bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
				bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware ||
				bean instanceof ApplicationStartupAware)) {
			return bean;
		}

		AccessControlContext acc = null;

		if (System.getSecurityManager() != null) {
			acc = this.applicationContext.getBeanFactory().getAccessControlContext();
		}

		if (acc != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareInterfaces(bean);
				return null;
			}, acc);
		}
		else {
			invokeAwareInterfaces(bean);
		}

		return bean;
	}

	private void invokeAwareInterfaces(Object bean) {
		// 给bean设置Environment属性
		if (bean instanceof EnvironmentAware) {
			((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
		}
		// 给bean设置EmbeddedValueResolver属性
		if (bean instanceof EmbeddedValueResolverAware) {
			((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
		}
		// 给bean设置ResourceLoader属性
		if (bean instanceof ResourceLoaderAware) {
			((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
		}
		// 给bean设置ApplicationEventPublisher属性
		if (bean instanceof ApplicationEventPublisherAware) {
			((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
		}
		// 给bean设置MessageSource属性
		if (bean instanceof MessageSourceAware) {
			((MessageSourceAware) bean).setMessageSource(this.applicationContext);
		}
		// 给bean设置 ApplicationStartupAware属性
		if (bean instanceof ApplicationStartupAware) {
			((ApplicationStartupAware) bean).setApplicationStartup(this.applicationContext.getApplicationStartup());
		}
		// 给bean设置ApplicationContext属性
		if (bean instanceof ApplicationContextAware) {
			((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
		}
	}

}

4.4 ApplicationListenerDetector

在这里插入图片描述

判断目标 Bean 是否实现 ApplicationListener ,如果有则注册事件:

class ApplicationListenerDetector implements DestructionAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor {

	private static final Log logger = LogFactory.getLog(ApplicationListenerDetector.class);

	private final transient AbstractApplicationContext applicationContext;

	private final transient Map<String, Boolean> singletonNames = new ConcurrentHashMap<>(256);


	public ApplicationListenerDetector(AbstractApplicationContext applicationContext) {
		this.applicationContext = applicationContext;
	}


	@Override
	public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
		if (ApplicationListener.class.isAssignableFrom(beanType)) {
			this.singletonNames.put(beanName, beanDefinition.isSingleton());
		}
	}

	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) {
		return bean;
	}

	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) {
		if (bean instanceof ApplicationListener) {
			// potentially not detected as a listener by getBeanNamesForType retrieval
			Boolean flag = this.singletonNames.get(beanName);
			if (Boolean.TRUE.equals(flag)) {
				// 添加事件
				this.applicationContext.addApplicationListener((ApplicationListener<?>) bean);
			}
			else if (Boolean.FALSE.equals(flag)) {
				if (logger.isWarnEnabled() && !this.applicationContext.containsBean(beanName)) {
					// inner bean with other scope - can't reliably process events
					logger.warn("Inner bean '" + beanName + "' implements ApplicationListener interface " +
							"but is not reachable for event multicasting by its containing ApplicationContext " +
							"because it does not have singleton scope. Only top-level listener beans are allowed " +
							"to be of non-singleton scope.");
				}
				this.singletonNames.remove(beanName);
			}
		}
		return bean;
	}

	@Override
	public void postProcessBeforeDestruction(Object bean, String beanName) {
		if (bean instanceof ApplicationListener) {
			try {
				ApplicationEventMulticaster multicaster = this.applicationContext.getApplicationEventMulticaster();
				multicaster.removeApplicationListener((ApplicationListener<?>) bean);
				multicaster.removeApplicationListenerBean(beanName);
			}
			catch (IllegalStateException ex) {
				// ApplicationEventMulticaster not initialized yet - no need to remove a listener
			}
		}
	}

	@Override
	public boolean requiresDestruction(Object bean) {
		return (bean instanceof ApplicationListener);
	}


	@Override
	public boolean equals(@Nullable Object other) {
		return (this == other || (other instanceof ApplicationListenerDetector &&
				this.applicationContext == ((ApplicationListenerDetector) other).applicationContext));
	}

	@Override
	public int hashCode() {
		return ObjectUtils.nullSafeHashCode(this.applicationContext);
	}

}
posted @ 2024-10-30 14:42  CharyGao  阅读(9)  评论(0编辑  收藏  举报