Spring的重要拓展点BeanPostProcessor

目录

BeanPostProcessor的作用

BeanPostProcessor接口定义

postProcessBeforeInitialization

postProcessAfterInitialization

接口方法调用逻辑

如何添加BeanPostProcessor

Spring提供的BeanPostProcessor直接实现类

ApplicationContextAwareProcessor

BeanPostProcessor的子类接口

1. InstantiationAwareBeanPostProcessor

postProcessBeforeInstantiation

postProcessAfterInstantiation

postProcessProperties

重要实现类

2. SmartInstantiationAwareBeanPostProcessor

predictBeanType

determineCandidateConstructors

getEarlyBeanReference

重要实现类

3. MergedBeanDefinitionPostProcessor

调用入口

重要实现类

4. DestructionAwareBeanPostProcessor

重要实现类


​​​​​​​​​​​​​​

BeanPostProcessor的作用

bean的后置处理器,spring ioc容器管理bean最重要的一个拓展机制,通过向BeanFactory中添加自定义的BeanPostProcessor,就能够在bean的生命周期内对bean的实例化、属性注入、初始化等进行自定义修改

例如:在bean的实例化过程,spring默认会调用bean的无参构造函数通过反射进行实例化,而开发者想自定义选择构造函数,则可以通过实现BeanPostProcessor来完成。

再或者spring的AOP,本质上也是通过BeanPostProcessor在bean实例化好后,对其进行代理增强,得到其代理类

BeanPostProcessor接口定义

public interface BeanPostProcessor {

	/**
	 * Apply this {@code 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;
	 * if {@code null}, no subsequent BeanPostProcessors will be invoked
	 * @throws org.springframework.beans.BeansException in case of errors
	 * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
	 */
	@Nullable
	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

	/**
	 * Apply this {@code 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
	 * {@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation} method,
	 * in contrast to all other {@code 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;
	 * if {@code null}, no subsequent BeanPostProcessors will be invoked
	 * @throws org.springframework.beans.BeansException in case of errors
	 * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
	 * @see org.springframework.beans.factory.FactoryBean
	 */
	@Nullable
	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

}

postProcessBeforeInitialization

  1. 实现该方法就能拿到实例化的bean,该方法返回结果也是一个bean,因此可以对传入的bean进行自定义修改后返回
  2. 在一些bean的初始化回调前进行调用,例如InitializingBean的afterPropertiesSet方法前或者自定义的的init-method前。
  3. 该方法拿到的bean是已经经过了属性填充的bean。

postProcessAfterInitialization

  1. 实现该方法就能拿到实例化的bean,该方法返回结果也是一个bean,因此可以对传入的bean进行自定义修改后返回
  2. 在一些bean的初始化回调后进行调用,例如InitializingBean的afterPropertiesSet方法后或者自定义的的init-method后。

接口方法调用逻辑

调用入口:

AbstractAutowireCapableBeanFactory#initializeBean()

通过调用入口initializeBean方法,我们知道是在bean初始化阶段会回调这两个接口方法,分别在执行invokeInitMethods方法前后调用。

image

applyBeanPostProcessorsBeforeInitialization和applyBeanPostProcessorsAfterInitialization执行的逻辑非常简单,就是遍历AbstractBeanFactory#beanPostProcessors保存的BeanPostProcessor进行调用。

	/** BeanPostProcessors to apply in createBean. */
	private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>();
	public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
			throws BeansException {

		Object result = existingBean;
		for (BeanPostProcessor processor : getBeanPostProcessors()) {
		    //传入一个bean得到一个bean
			Object current = processor.postProcessBeforeInitialization(result, beanName);
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}
	
	public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {

		Object result = existingBean;
		for (BeanPostProcessor processor : getBeanPostProcessors()) {
			Object current = processor.postProcessAfterInitialization(result, beanName);
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}

如何添加自定义的BeanPostProcessor

  • 方式一:手动添加,调用如下方法

AbstractBeanFactory#addBeanPostProcessor

@Override
	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);
	}

通过调用该方法将beanPostProcessor保存到集合变量beanPostProcessors中


/** BeanPostProcessors to apply in createBean. */
	private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>();
	
  • 方式二:按照添加一个普通bean的方式添加。

​​​​​​​​​​​​​​例如通过spring的注解、xml、BeanDefinitionRegistry.registerBeanDefinition等

Spring提供的BeanPostProcessor直接实现类

spring本身提供直接实现BeanPostProcessor接口很少(主要是间接实现),我们看个比较重要的直接实现类:ApplicationContextAwareProcessor。

  • ApplicationContextAwareProcessor

实现了postProcessBeforeInitialization方法,在初始化前,判断bean是否是ApplicationContext相关的Aware接口实现,如果是,则执行拓展逻辑回调相关Aware方法。

class ApplicationContextAwareProcessor implements BeanPostProcessor {
    //。。

	@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)){
			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) {
		if (bean instanceof EnvironmentAware) {
			((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
		}
		if (bean instanceof EmbeddedValueResolverAware) {
			((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
		}
		if (bean instanceof ResourceLoaderAware) {
			((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
		}
		if (bean instanceof ApplicationEventPublisherAware) {
			((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
		}
		if (bean instanceof MessageSourceAware) {
			((MessageSourceAware) bean).setMessageSource(this.applicationContext);
		}
		if (bean instanceof ApplicationContextAware) {
			((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
		}
	}

}

看到这里似乎我们似乎没有看到BeanPostProcessor有多重要,直接实现BeanPostProcessor仅仅只能在bean初始化前后进行一些逻辑处理,那如何在bean实例化过程进行自定义呢?

答案在BeanPostProcessor的子类接口们,往下看

BeanPostProcessor的子类接口

BeanPostProcessor提供了很多非常重要的子类接口,对BeanPostProcessor只能在bean初始化阶段拓展的不足做了增强。

1. InstantiationAwareBeanPostProcessor

BeanPostProcessor的子接口,添加了在bean实例化前后的回调方法,同时还提供了拿到bean的属性回调方法。

image

postProcessBeforeInstantiation

default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
		return null;
}

通过实现该接口方法能够直接在这里自定义创建bean的实例,从而跳过spring内部实例化的过程。

调用入口:

AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation

--》AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInstantiation

	protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
		Object bean = null;
		if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
			// 判断是否存在InstantiationAwareBeanPostProcessor,存在则applyBeanPostProcessorsBeforeInstantiation
			if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
				Class<?> targetType = determineTargetType(beanName, mbd);
				if (targetType != null) {
					bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
					//如果拿到的bean不为null,代表已经实例化了,直接这里执行bean的初始化过程
					if (bean != null) {
						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
					}
				}
			}
			mbd.beforeInstantiationResolved = (bean != null);
		}
		return bean;
	}
	

遍历AbstractBeanFactory#beanPostProcessors,如果是InstantiationAwareBeanPostProcessor,则执行postProcessBeforeInstantiation方法

	protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof InstantiationAwareBeanPostProcessor) {
				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
				Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
				if (result != null) {
					return result;
				}
			}
		}
		return null;
	}

postProcessAfterInstantiation

default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
		return true;
	}

bean实例化紧接着对bean属性赋值过程会调用,通过实现postProcessAfterInstantiation并返回false时,则可以自定义跳过Spring内部属性的赋值操作。

调用入口:

AbstractAutowireCapableBeanFactory#populateBean

populateBean方法是bean实例化后对bean的属性赋值,在该方法内会遍历调用postProcessAfterInstantiation方法,如果返回fase则直接return,阻止后续的操作

image

postProcessProperties

	default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
			throws BeansException {

		return null;
	}

bean属性赋值前,回调postProcessProperties,传递PropertyValues对象,PropertyValues中保存了bean实例对象中所有属性值的设置,通过修改PropertyValues可以修改属性值。

调用入口:

AbstractAutowireCapableBeanFactory#populateBean

同postProcessAfterInstantiation一样,也是在属性赋值方法中进行回调。

image

重要实现类

AutowiredAnnotationBeanPostProcessor

自动注入非常重要的一个后置器,实现的postProcessProperties会对@Autowired、@Value标注的字段、方法注入值。

具体分析见我这篇文章:Spring Bean后置处理器之AutowiredAnnotationBeanPostProcessor

CommonAnnotationBeanPostProcessor

对@Resource标注的字段和方法注入值。

具体分析见我这篇文章:Spring Bean后置处理器之CommonAnnotationBeanPostProcessor

2. SmartInstantiationAwareBeanPostProcessor

InstantiationAwareBeanPostProcessor的子接口。增加了3个方法。

predictBeanType

预测Bean的类型,返回第一个预测成功的Class类型,如果不能预测返回null

default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
		return null;
}

determineCandidateConstructors

	default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)
			throws BeansException {

		return null;
	}

bean实例化前,通过回调该方法,从而可以实现自定义选择构造器。

调用入口

 AbstractAutowireCapableBeanFactory#determineConstructorsFromBeanPostProcessors

遍历SmartInstantiationAwareBeanPostProcessor,调用determineCandidateConstructors返回构造函数

    /**/
	@Nullable
	protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName)
			throws BeansException {

		if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
					SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
					Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
					if (ctors != null) {
						return ctors;
					}
				}
			}
		}
		return null;
	}

getEarlyBeanReference

获得提前暴露的bean引用。主要用于解决循环引用的问题。

重要实现类

AnnotationAwareAspectJAutoProxyCreator

@EnableAspectJAutoProxy会在spring容器中注册一个bean,AOP的实现,对符合条件的bean,自动生成代理对象。

具体分析见我这篇文章:Spring Bean后置处理器之AnnotationAwareAspectJAutoProxyCreator 

3. MergedBeanDefinitionPostProcessor

BeanPostProcessor的子接口,增加了postProcessMergedBeanDefinition方法。

用于处理合并后的BeanDefinition,在bean实例化后、属性赋值前回调。

	void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);

调用入口

AbstractAutowireCapableBeanFactory#doCreateBean
    ->AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors
	protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof MergedBeanDefinitionPostProcessor) {
				MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
				bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
			}
		}
	}

重要实现类

AutowiredAnnotationBeanPostProcessor

在 postProcessMergedBeanDefinition 方法中对 @Autowired、@Value 标注的方法、字段进行缓存,为后续属性赋值阶段的AutowiredAnnotationBeanPostProcessor处理做准备

CommonAnnotationBeanPostProcessor

在 postProcessMergedBeanDefinition 方法中对 @Resource 标注的字段、@Resource 标注的方法、 @PostConstruct 标注的字段、 @PreDestroy标注的方法进行缓存

4. DestructionAwareBeanPostProcessor

BeanPostProcessor的子接口,增加了postProcessBeforeDestruction,用于bean销毁前的回调。

重要实现类

CommonAnnotationBeanPostProcessor

CommonAnnotationBeanPostProcessor#postProcessBeforeDestruction方法中会调用bean中所有标注了@PreDestroy的方法

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值