PostProcessor系列接口
一共有3种PostProcessor接口,分别是:
BeanDefinitionRegistryPostProcessor
BeanFactoryPostProcessor
BeanPostProcessor
它们都是在容器进行refrush
的时候,在不同阶段进行调用,其相对的调用顺序是: 1->2->3
提供的这三种PostProcessor使得我们更好的能够定制化我们的Bean对象,例如,当我们希望通过搜索第三方项目里的Class然后将其作为Bean注册到容器中,这个时候就可以通过BeanDefinitionRegistryPostProcessor
接口,在重写其方法时,利根据Class对象生成BeanDefinition,然后再利用提供的registery来给注册到容器中(实际上,Mybatis框架里就是这么玩的); 再比如,在实现AOP对对象进行方法增强的时候,也可以使用 BeanPostProcessor
接口暴露的方法来做,这个再后续说明AOP源码的时候再说.
总之,这三个接口实际上就是让我们能够在Bean的不同生命周期阶段,利用Spring的底层资源插手来做一些事情, 下面来逐个了解一下.
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);
}
......
......
}
为了展示 BeanDefinitionRegistryPostProcessor
和 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
,我们也可以用这个参数做一些事,这里就不多说了,思想是类似的.
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接口的时候,也是使用这个接口来实现的.