Spring源码阅读——PostProcessor(一)

PostProcessor系列接口

一共有3种PostProcessor接口,分别是:

  1. BeanDefinitionRegistryPostProcessor
  2. BeanFactoryPostProcessor
  3. BeanPostProcessor

它们都是在容器进行refrush的时候,在不同阶段进行调用,其相对的调用顺序是: 1->2->3

提供的这三种PostProcessor使得我们更好的能够定制化我们的Bean对象,例如,当我们希望通过搜索第三方项目里的Class然后将其作为Bean注册到容器中,这个时候就可以通过BeanDefinitionRegistryPostProcessor接口,在重写其方法时,利根据Class对象生成BeanDefinition,然后再利用提供的registery来给注册到容器中(实际上,Mybatis框架里就是这么玩的); 再比如,在实现AOP对对象进行方法增强的时候,也可以使用 BeanPostProcessor接口暴露的方法来做,这个再后续说明AOP源码的时候再说.

总之,这三个接口实际上就是让我们能够在Bean的不同生命周期阶段,利用Spring的底层资源插手来做一些事情, 下面来逐个了解一下.

  • BeanDefinitionRegistryPostProcessor

public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {

	/**
	 * Modify the application context's internal bean definition registry after its
	 * standard initialization. All regular bean definitions will have been loaded,
	 * but no beans will have been instantiated yet. This allows for adding further
	 * bean definitions before the next post-processing phase kicks in.
	 * @param registry the bean definition registry used by the application context
	 * @throws org.springframework.beans.BeansException in case of errors
	 */
	void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;

}

自定义的类可以实现该接口的postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)方法,在方法内部得到需要注册的类的Class,然后生成BeanDefinition进行注册,使用示例如下:

@Configuration
public class CustomizeBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
	@Override
	public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
		// 得到Class对象
		Class<?> clazz = User.class; // (*********)
		// 使用builder来生成对应的BeanDefinition
		BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(clazz);
		GenericBeanDefinition beanDefinition = (GenericBeanDefinition) builder.getRawBeanDefinition();
		利用registery进行注册
		registry.registerBeanDefinition("user", beanDefinition);
		System.out.println("注册完毕");
	}

	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		System.out.println("~~~~~~~");
	}
}

这样,就可以在把指定Class对象给注册到IOC容器中了! 下面来看看它的调用时期,在上面代码的(*********)处打上断点,来剥一下.
在这里插入图片描述
在这里插入图片描述

PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
public static void invokeBeanFactoryPostProcessors(
		ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
		......
		......
		// 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);
			// 在这里调用BeanDefinitionRegistryPostProcessors接口的方法!!!!!!!!!!!!
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			currentRegistryProcessors.clear();
		}
		
		// 在这里回调BeanFactoryPostProcessors接口的方法!!!!!!!!!!!!!
		invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
	}

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

为了展示 BeanDefinitionRegistryPostProcessorBeanFactoryPostProcessor调用的相对关系,这里只展示了 代码片段,实际上在上面这个函数中做的事情是很多的.

  • BeanFactoryPostProcessor

@FunctionalInterface
public interface BeanFactoryPostProcessor {

	/**
	 * Modify the application context's internal bean factory after its standard
	 * initialization. All bean definitions will have been loaded, but no beans
	 * will have been instantiated yet. This allows for overriding or adding
	 * properties even to eager-initializing beans.
	 * @param beanFactory the bean factory used by the application context
	 * @throws org.springframework.beans.BeansException in case of errors
	 */
	void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}

作用实际上和BeanDefinitionRegistryPostProcessor类似,只不过提供的工具参数不同,BeanDefinitionRegistryPostProcessor里提供的是registry,我们可以用来进行注册。 而BeanFactoryPostProcessor提供的是ConfigurableListableBeanFactory beanFactory,我们也可以用这个参数做一些事,这里就不多说了,思想是类似的.

  • 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;
	}
}

我们通过实现这个接口就可以在 bean实例化之后还没有进行初始化的时候,在初始化之前,初始化之后来做一些事情。

提供给我们的是实例化好的bean对象和对应的BeanName,我们可以对其进行一些方法增强,然后再返回出去(到AOP再说); 在实现Aware接口的时候,也是使用这个接口来实现的.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值