注册 BeanPostProcessor 后置处理器
BeanPostProcessor
Spring 核心方法中 registerBeanPostProcessors(beanFactory);
BeanPostProcessor 后置处理器的注册。此方法就是把实现 BeanPostProcessor 接口的类,提前实例化,这个接口类里面有两个方法,可以进行相应的操作。
bean 实例化前的操作,以及 bean 实例化后的操作,这个实例化在其他正常的实例化方法之前,比如可以阻止其他 bean 的 IOC 依赖注入。
把实现了 BeanPostProcessor 接口的类实例化,并且加入 到 BeanFactory 中。
获取到实例化的 bean 对象,可以对其属性值等做修改操作。 比如,拿到 bean 对象,可以判断其类上有没有特定的注解等,根据自己的条件,可以创建一个代理对象,然后返回,这样就对每个 bean 做了这样的后置增强处理。
public interface BeanPostProcessor {
@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 完成 bean 实例化和依赖注入后,调用后置处理器的。
├─finishBeanFactoryInitialization(beanFactory); Spring 核心方法中的
│ ├─beanFactory.preInstantiateSingletons();
│ │ ├─getBean(beanName);
│ │ │ ├─doGetBean(name, null, null, false);
│ │ │ │ ├─if (mbd.isSingleton()) {
│ │ │ │ │ ├─下面的 getSingleton 方法传入了一个 Lambda 表达式,并在 getSingleton 中调用了传入的 lambda 表达式,创建了 bean 实例。
│ │ │ │ │ ├─sharedInstance = getSingleton(beanName, () -> {
│ │ │ │ │ │ ├─return createBean(beanName, mbd, args);
│ │ │ │ │ │ │ ├─Object beanInstance = doCreateBean(beanName, mbdToUse, args);
│ │ │ │ │ │ │ │ ├─instanceWrapper = createBeanInstance(beanName, mbd, args);
│ │ │ │ │ │ │ │ ├─下面是依赖注入的核心方法(非常重要)
│ │ │ │ │ │ │ │ ├─populateBean(beanName, mbd, instanceWrapper);
│ │ │ │ │ │ │ │ ├─下面是依赖注入完成后的调用(非常重要)
│ │ │ │ │ │ │ │ ├─exposedObject = initializeBean(beanName, exposedObject, mbd);
│ │ │ │ │ │ │ │ │ ├─这里调用 before 方法
│ │ │ │ │ │ │ │ │ ├─wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
│ │ │ │ │ │ │ │ │ ├─invokeInitMethods(beanName, wrappedBean, mbd);
│ │ │ │ │ │ │ │ │ ├─这里调用 after 方法,就是这里完成了 AOP 代理功能
│ │ │ │ │ │ │ │ │ ├─wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
常见的子类
InstantiationAwareBeanPostProcessor
InstantiationAwareBeanPostProcessor 继承自 BeanPostProcessor 接口。主要多提供了以下三个方法:
- postProcessBeforeInstantiation:该方法是在 Bean 实例化目标对象之前调用,返回的 Bean 对象可以代理目标,从而有效的阻止了目标 Bean 的默认实例化。
- postProcessAfterInstantiation:该方法执行在通过构造函数或工厂方法在实例化 bean 之后但在发生 Spring 属性填充(通过显式属性或自动装配)之前执行操作。这是在 Spring 的自动装配开始之前对给定的 bean 实例执行自定义字段注入的理想回调。如果该方法返回 false,那么它会阻断后续 InstantiationAwareBeanPostProcessor 后置处理器的执行,并且会阻止后续属性填充的执行逻辑。
- postProcessPropertyValues:在工厂将给定属性值应用于给定 bean 之前,对它们进行后处理。允许检查是否满足所有依赖关系,例如基于 bean 属性设置器上的“ Required”注解。还允许替换要应用的属性值,通常是通过基于原始 PropertyValues 创建新的 MutablePropertyValues 实例,添加或删除特定值来实现。
这个接口是在哪儿调用的?
├─finishBeanFactoryInitialization(beanFactory); Spring 核心方法中的
│ ├─beanFactory.preInstantiateSingletons();
│ │ ├─getBean(beanName);
│ │ │ ├─doGetBean(name, null, null, false);
│ │ │ │ ├─if (mbd.isSingleton()) {
│ │ │ │ │ ├─下面的 getSingleton 方法传入了一个 Lambda 表达式,并在 getSingleton 中调用了传入的 lambda 表达式,创建了 bean 实例。
│ │ │ │ │ ├─sharedInstance = getSingleton(beanName, () -> {
│ │ │ │ │ │ ├─return createBean(beanName, mbd, args);
│ │ │ │ │ │ │ ├─Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
- TargetSource 接口的运用,可以在用改一个类实现该接口,然后在里面定义实例化对象的方式,然后返回
- 也就是说不需要 spring 帮助我们实例化对象
- 这里可以直接返回实例本身
- 这个代码不用看,实际开发过程中用不到,我会做为一个甜点分享
其他地方的调用
├─finishBeanFactoryInitialization(beanFactory); Spring 核心方法中的
│ ├─beanFactory.preInstantiateSingletons();
│ │ ├─getBean(beanName);
│ │ │ ├─doGetBean(name, null, null, false);
│ │ │ │ ├─if (mbd.isSingleton()) {
│ │ │ │ │ ├─下面的 getSingleton 方法传入了一个 Lambda 表达式,并在 getSingleton 中调用了传入的 lambda 表达式,创建了 bean 实例。
│ │ │ │ │ ├─sharedInstance = getSingleton(beanName, () -> {
│ │ │ │ │ │ ├─return createBean(beanName, mbd, args);
│ │ │ │ │ │ │ ├─Object beanInstance = doCreateBean(beanName, mbdToUse, args);
│ │ │ │ │ │ │ │ ├─instanceWrapper = createBeanInstance(beanName, mbd, args);
│ │ │ │ │ │ │ │ ├─populateBean(beanName, mbd, instanceWrapper);
│ │ │ │ │ │ │ │ │ ├─if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
这个地方的调用就很有意思了,populateBean 是用来做依赖注入的。而这里的代码如下:
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw){
// 此处省略前面的代码
if(!mbd.isSynthetic()&&hasInstantiationAwareBeanPostProcessors()){
for(InstantiationAwareBeanPostProcessor bp:getBeanPostProcessorCache().instantiationAware){
if(!bp.postProcessAfterInstantiation(bw.getWrappedInstance(),beanName)){
return;
}
}
}
// 此处省略后面的代码
}
可以看出,假如我们写了一个类实现了 InstantiationAwareBeanPostProcessor,并在 postProcessAfterInstantiation 返回 false,如下:
@Component
public class DemoInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
@Override
public boolean postProcessAfterInstantiation(Object object, String beanName) {
return false;
}
}
那么程序执行到上面的 populateBean 方法时, 就直接 return 了,意味着后面的依赖注入都不会进行了。如果恶意人员使用这一点,就会造成项目工程异常。
SmartInstantiationAwareBeanPostProcessor
SmartInstantiationAwareBeanPostProcessor 继承了 InstantiationAwareBeanPostProcessor。
智能实例化 Bean 的后处理器,主要提供了三个方法:
- predictBeanType:预测从此处理器的 postProcessBeforeInstantiation 回调最终返回的 bean 的类型。
- determineCandidateConstructors:确定合适的实例化 Bean 的构造函数。
- getEarlyBeanReference:获取提早暴露的 Bean 的引用,提早暴露的 Bean 就是只完成了实例化,还未完成属性赋值和初始化的 Bean。
这个接口是在哪儿调用的?
├─finishBeanFactoryInitialization(beanFactory); Spring 核心方法中的
│ ├─beanFactory.preInstantiateSingletons();
│ │ ├─getBean(beanName);
│ │ │ ├─doGetBean(name, null, null, false);
│ │ │ │ ├─if (mbd.isSingleton()) {
│ │ │ │ │ ├─下面的 getSingleton 方法传入了一个 Lambda 表达式,并在 getSingleton 中调用了传入的 lambda 表达式,创建了 bean 实例。
│ │ │ │ │ ├─sharedInstance = getSingleton(beanName, () -> {
│ │ │ │ │ │ ├─return createBean(beanName, mbd, args);
│ │ │ │ │ │ │ ├─Object beanInstance = doCreateBean(beanName, mbdToUse, args);
│ │ │ │ │ │ │ │ ├─instanceWrapper = createBeanInstance(beanName, mbd, args);
│ │ │ │ │ │ │ │ │ ├─Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
/**
* 返回前正在实例化的bean中有@Autowired注解的构造函数
*/
protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName)
throws BeansException {
if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
// 拿到 BeanPostProcessor 的所有接口,遍历
for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) {
// 获取到有@Autowired注解信息的构造函数
Constructor<?>[] ctors = bp.determineCandidateConstructors(beanClass, beanName);
if (ctors != null) {
return ctors;
}
}
}
return null;
}
AutowiredAnnotationBeanPostProcessor
AutowiredAnnotationBeanPostProcessor 继承了 SmartInstantiationAwareBeanPostProcessor。
TIP
SmartInstantiationAwareBeanPostProcessor 类中的 determineCandidateConstructors 方法,会调用其子类 AutowiredAnnotationBeanPostProcessor 中的 determineCandidateConstructors 方法,来获取到有@Autowired 注解信息的构造函数。
AutowiredAnnotationBeanPostProcessor 类会完成 @Autowired 和 @value 两个注解的扫描。
MergedBeanDefinitionPostProcessor
合并 Bean 的定义信息的后处理方法,该方法是在 Bean 的实例化之后设置值之前调用。