Spring的后置处理器,在应用Spring框架开发中非常重要,Spring底层的核心,就通过各种后置处理器去完成IOC容器的启动,AOP代理对象的创建。
Spring的后置处理器有两大类,
BeanFactory
与
Bean
。
BeanFactory
Bean 工厂方面的后置处理器
-
BeanFactoryPostProcessor
获取IOC容器
-
BeanDefinitionRegistryPostProcessor
向容器注册Bean
1:
BeanFactoryPostProcessor
可以拿到Spring的IOC容器。ConfigurableListableBeanFactory
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
2:
BeanDefinitionRegistryPostProcessor
BeanDefinitionRegistry Spring注册Bean的工具类,可以向容器手动注册Bean。
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
例如:
Bean
Bean 方面的后置处理器
-
SmartInstantiationAwareBeanPostProcessor
设置Bean的类型,构造函数
-
InstantiationAwareBeanPostProcessor
Bean实例化之前,属性赋值之前的处理器
-
MergedBeanDefinitionPostProcessor
再添加或修改Bean的定义信息
-
BeanPostProcessor
Bean初始化之后的处理器,所有后置处理器的顶级接口。可以修改Bean实例的信息,甚至修改Bean的引用指向。
1:
SmartInstantiationAwareBeanPostProcessor
设置Bean的类型,构造函数。
基于Spring开发框架使用,平时开发不要使用。
public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor {
/**
* 设置 Bean 的类型
*/
default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
/**
* 设置创建 Bean用到的 构造函数
*/
@Nullable
default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)
throws BeansException {
return null;
}
/**
* 循环引用从此处获取 Bean实例
*/
default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
return bean;
}
}
假如在创建一个
UserService.class
的Bean,如下我指定成
EmployeeService.class
,构造函数也是
EmployeeService
的无参构造函数,那么创建
UserService Bean
实例就会变成
EmployeeService
的实例。
default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
if (beanName.equals("userService")) {
return EmployeeService.class;
}
return null;
}
/**
* 设置创建 Bean用到的 构造函数
*/
@Nullable
default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)
throws BeansException {
if (beanName.equals("userService")) {
try {
return new Constructor[]{EmployeeService.class.getConstructor()};
} catch (Exception e) {
}
}
return null;
}
2:
InstantiationAwareBeanPostProcessor
postProcessBeforeInstantiation
:Bean实例化之前执行此方法,如果返回不为
null
,则替代当前准备实例化的Bean,Spring将不再自动实例化对象了。
postProcessAfterInstantiation
:如果返回 true,执行
postProcessProperties
方法。
postProcessProperties
:设置实例化Bean需要的属性,调用 set 方法赋值,如果指定的属性名没有set方法,则报错。
/**
* 在Spring实例化Bean之前调用,该方法如果返回结果不为空,
* 这个返回值可以用来代替原本该生成的目标对象的实例(比如代理对象)。
* 如果该方法的返回值代替原本该生成的目标对象,
* 后续只有postProcessAfterInitialization方法会调用,其它方法不再调用;否则按照正常的流程走
*
* @param beanClass Spring当前正在创建的Bean的类型
* @param beanName Spring当前正在创建的Bean的name
* @return
* @throws BeansException
*/
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
/**
* 在目标对象实例化之后调用,这个时候对象已经被实例化,但是该实例的属性还未被设置,都是null。
*
* 如果返回 true 调用 postProcessProperties设置属性值,然后 set 方法赋值
* @return
* @throws BeansException
*/
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if (beanName.equals("userService")) {
return true;
}
return false;
}
/**
* 设置属性值 为 Bean的 set 方法赋值
*
* 例如 添加了一个属性 password,会调用 bean的 setPassword方法,如果该方法没有,会报错
*/
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
if (beanName.equals("userService")) {
( (MutablePropertyValues) pvs).addPropertyValue(new PropertyValue("password", "123"));
return pvs;
}
return null;
}
3:
MergedBeanDefinitionPostProcessor
再添加或修改Bean的定义信息
/**
* @param beanDefinition 当前正在创建Bean的定义信息,可以用它再添加或修改一些定义信息
* beanDefinition.setLazyInit(true); 设置懒加载为 true
*/
void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);
/**
* 如果修改了当前正在创建的Bean的 name 会执行
* @param beanName
*/
default void resetBeanDefinition(String beanName) {
}
4:
BeanPostProcessor
postProcessBeforeInitialization
Bean初始化方法之前执行,可以返回一个对象,替代Spring当前的Bean实例。
postProcessAfterInitialization
Bean初始化最后的一个处理方法,可以返回一个对象,替代Spring当前的Bean实例。
AOP代理在此创建
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
Spring底层源码的总结:
看过Spring源码的,就会知道Spring的启动流程,只是提供了一个注册特定的组件(后置处理器),及实例化Bean的模板功能。其他功能:依赖注入,AOP切面,事务管理,异步执行…等等一系列的拓展功能,都是在后置处理器中执行。所以要学好Spring,就必选要搞懂它提供的后置处理器功能。