Bean后置处理器
BeanPostProcessor
BeanPostProcessor 是一个接口类:
public interface BeanPostProcessor {
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
可以看到他有2个方法:
-
前者的生效时间为bean对象实例化、属性注入之后、初始化之前。
-
后者的生效时间为bean对象实例化、属性注入、初始化之后。
在Spring中使用这个接口有2个方式,要么是继承这个接口然后实现;要么是直接实现这个接口。
关于创建实例&推断构造:
AbstractAutowireCapableBeanFactory#doCreateBean
AbstractAutowireCapableBeanFactory#createBeanInstance
从BeanPostProcessor推断出构造方法:
// Candidate constructors for autowiring?
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName)
throws BeansException {
if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
//找出所有SmartInstantiationAwareBeanPostProcessor,然后通过Spring的算法来找出最匹配的构造
for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) { //determineCandidateConstructors里就是匹配算法,返回Constructor数组
Constructor<?>[] ctors = bp.determineCandidateConstructors(beanClass, beanName);
if (ctors != null) {
return ctors;
}
}
}
return null;
}
生命周期中的BeanPostProcessor
在生命周期中大概有以下的相关BeanPostProcessor可以进行拓展:
BeanPostProcessor相关拓展点:
-
InstantiationAwareBeanPostProcessor # postProcessBeforeInstantiation
-
SmartInstantiationAwareBeanPostProcessor # determineConstructorsFromBeanPostProcessors 推断构造方法
-
MergedBeanDefinitionPostProcessor # postProcessMergedBeanDefinition 合并BeanDefinition
-
SmartInstantiationAwareBeanPostProcessor # getEarlyBeanReference 解决循环依赖,获取一个拓展好的半成品的对象。
解决循环依赖用三级工厂的原因,就是需要遇到注入AOP Bean的时候,通过这个地方解决代理。
-
InstantiationAwareBeanPostProcessor # postProcessAfterInstantiation 在设置属性之前,修改来判断是否需要属性注入
-
InstantiationAwareBeanPostProcessor # postProcessProperties 填充属性
-
BeanPostProcessor # postProcessBeforeInitialization 执行一些Aware接口回调,和@PostConstruct方法
-
BeanPostProcessor # postProcessAfterInitialization 进行代理、检查是否FactoryBean
我能对上面的各种BeanPostProcessor来对Spring的Bean生命周期进行拓展。只需要实现某些接口,并放到Spring容器中(@Component)。在生命周期的对应阶段会进行调用。
继承关系
关于AOP的BeanPostProcessor:
【这个不重要】AbstractAutowireCapableBeanFactory#createBean里:
让BeanPostProcessor 有 机会能返回一个bean实例的代理类。
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
如果有循环依赖:
那么关于AOP代理的BeanPostProcessor是在getEarlyBeanReference
发生的:
SmartInstantiationAwareBeanPostProcessor # getEarlyBeanReference
获取一个拓展(进行了代理或其他)的半成品的对象。
如果没有循环依赖:
没有循环依赖的话,AOP就是发生在applyBeanPostProcessorsAfterInitialization
的
BeanPostProcessor # postProcessAfterInitialization
.
Spring代理:
JDK动态代理 :利用拦截器实现InvocationHandler,加上反射机制生成一个代理接口的匿名类。
cglib:利用ASM框架,对class文件加载进来,修改其字节码。
代理情况:
-
目标对象生成了接口 默认用JDK动态代理
-
如果目标对象使用了接口,可以强制使用cglib,在spring配置中加入
<aop:aspectj-autoproxy proxyt-target-class=”true”/>
-
如果目标对象没有实现接口,必须采用cglib
AOP源码逻辑从注解@EnableAspectJAutoProxy
看起,那么肯定会有导入某个类:@Import(AspectJAutoProxyRegistrar.class)
Spring会去引入,这个类肯定会把某个类注册到BeanDefinitionMap并让Spring对应创建Bean,我们主要看注册的AnnotationAwareAspectJAutoProxyCreator
这个类:
通过继承关系我们知道它是实现了BeanPostProcessor相关的接口,原来这就是我们要找的AOP的拓展BeanPostProcesor实现了。
其实主要的回调方法在AbstractAutoProxyCreator
里:getEarlyBeanReference、postProcessBeforeInstantiation等。
无论是那个关于需要代理类的回调方法,都会通过createProxy
方法来创建代理类,通过一些逻辑判断出对应的类加载器,通过传入类加载器给getProxy
来获取一个代理类。我们可以看到getProxy
的实现有也就对应的JDK动态代理,和Cglib代理。
我们看看JDK动态代理吧:
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
}
return Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this);
}
参考:
https://cloud.tencent.com/developer/article/1409315
https://zhuanlan.zhihu.com/p/38208324
https://www.cnblogs.com/sandaman2019/p/12636727.html