【源码】Spring AOP 12 原理解读一
前言
这章节开始,基于之前的学习,我会结合部分源码了解一下 Spring AOP
是如何实现的
ProxyConfig
public class ProxyConfig implements Serializable {
// 是否代理目标类,决定代理方式
private boolean proxyTargetClass = false;
// 是否进行优化,默认 false,如果 exposeProxy 设置为 true,该属性的 true 也将不起作用
private boolean optimize = false;
// 是否允许代理对象强转为 Advised 对象,默认 false
boolean opaque = false;
// 是否将代理对象暴露至 AopContext
boolean exposeProxy = false;
// 是否冻结配置信息
private boolean frozen = false;
}
代理配置信息基类,这些属性主要是干涉或决定最终的代理方式,具体可参考 DefaultAopProxyFactory#createAopProxy
方法,之前也了解过
ProxyProcessorSupport
public class ProxyProcessorSupport extends ProxyConfig implements Ordered, BeanClassLoaderAware, AopInfrastructureBean {
// ...
protected void evaluateProxyInterfaces(Class<?> beanClass, ProxyFactory proxyFactory) {
// 获取指定 bean 的所有接口
Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, getProxyClassLoader());
boolean hasReasonableProxyInterface = false;
/**
* 只要目标接口:
* 1)非 InitializingBean DisposableBean Closeable AutoCloseable Aware族
* & 2)不是一些指定接口比如 groovy.lang.GroovyObject
* & 3)不是空方法
* 这里就会标记 hasReasonableProxyInterface,这意味着会被添加为代理接口
* 否则会标记 proxyFactory.setProxyTargetClass(true)
* 这影响到最终使用哪种代理方式
*/
for (Class<?> ifc : targetInterfaces) {
if (!isConfigurationCallbackInterface(ifc) && !isInternalLanguageInterface(ifc) &&
ifc.getMethods().length > 0) {
hasReasonableProxyInterface = true;
break;
}
}
if (hasReasonableProxyInterface) {
for (Class<?> ifc : targetInterfaces) {
proxyFactory.addInterface(ifc);
}
}
else {
proxyFactory.setProxyTargetClass(true);
}
}
// ...
}
这是一个后处理阶段代理的基类:
- 提供了
evaluateProxyInterfaces
方法,主要用于推断目标类的接口,往本质了说就是觉得最终使用哪种代理方式 - 它有两个核心的分支:
AbstractAdvisingBeanPostProcessor
,该分支主要是提供一个指定的Advisor
,作为一个BeanPostProcessor
在合适的后处理阶段创建对应的代理对象AbstractAutoProxyCreator
,本文要了解的重点,也是Spring AOP
的关键类
AbstractAutoProxyCreator
这个类的内容稍微有点多,为了方便阅读分成几个部分了解
1
// 从 proxyTypes 中获取
// 在代理对象创建后根据类型记录到 proxyTypes 中
@Override
@Nullable
public Class<?> predictBeanType(Class<?> beanClass, String beanName) {
if (this.proxyTypes.isEmpty()) {
return null;
}
Object cacheKey = getCacheKey(beanClass, beanName);
return this.proxyTypes.get(cacheKey);
}
// 不用推断构造方法
@Override
@Nullable
public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) {
return null;
}
/**
* 提前暴露的的代理过的实例
* 如果一个 bean 被循环依赖了,那这个地方可能就提前给它创建
* 代理对象了,就记录到 earlyProxyReferences 中
*/
@Override
public Object getEarlyBeanReference(Object bean, String beanName) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
this.earlyProxyReferences.put(cacheKey, bean);
return wrapIfNecessary(bean, beanName, cacheKey);
}
/**
* 在 postProcessBeforeInstantiation 阶段
* 如果发现有自定义的 TargetSourceCreator[] customTargetSourceCreators 属性,
* 则会基于此获取 TargetSource 对象,然后代理返回
* 如果在此处被代理,就记录到 targetSourcedBeans 中
* 从 Spring 生命周期来看,如果此处返回一个非空实例,则生命周期被短路,直接执行
* postProcessAfterInitialization 阶段
*/
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
// ...
}
// 属性不做处理
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
return pvs;
}
/**
* 大多数情况下,代理过程是在这个阶段发生的
*/
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// 没有被循环引用过,意味着可能还没代理
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
// 开始代理
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
首先,AbstractAutoProxyCreator
是一个 SmartInstantiationAwareBeanPostProcessor
,这意味着它会参与 bean
的生命周期,在适当的阶段干涉 bean
,作为一个 SmartInstantiationAwareBeanPostProcessor
,结合以上代码,它参与的生命周期各阶段行为有:
predictBeanType
:该方法主要用于获取bean
的类型,此处是基于一个缓存属性proxyTypes
,那它的插入时机必然就是代理对象创建后,代理对象的创建时机可以继续往下看postProcessBeforeInstantiation
:这是第一处可能创建代理对象的方法,当我们指定了TargetSourceCreator[] customTargetSourceCreators
属性时,此处会基于此获取TargetSource
然后创建代理对象,同时被记入targetSourcedBeans
属性。另外从bean
的生命周期角度来说,此处如果创建代理对象,则生命周期被短路至postProcessAfterInitialization
determineCandidateConstructors
:推断构造方法,此处无动作getEarlyBeanReference
:提前暴露实例,这个方法主要是用来解决循环依赖的,作用是提前暴露一个实例,而此处自然就是暴露代理过的实例,所以这是第二处可能创建代理对象的地方,这地方代理过的bean
被记入earlyProxyReferences
属性postProcessAfterInstantiation
:无动作postProcessProperties
:无动作postProcessBeforeInitialization
:无动作postProcessAfterInitialization
:大多数bean
发生代理是在这个阶段,代理方法为wrapIfNecessary
关于 SmartInstantiationAwareBeanPostProcessor
如果有疑问,可以了解该文章:
Spring —— BeanPostProcessor 后处理器梳理
2
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// 在 targetSourcedBeans 阶段被创建过代理
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
// 在 targetSourcedBeans 阶段校验不需要生成代理
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
/**
* isInfrastructureClass: 是否 AOP 组件类,比如 Advice Pointcut Advisor
* 或者实现了 AopInfrastructureBean
* shouldSkip:子类可以拓展,此处主要是跳过后缀 .ORIGINAL 的 beanName
*/
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
/**
* 此类暴露的核心抽象方法:getAdvicesAndAdvisorsForBean,有子类实现
* 主要是获取当前 bean 对应的 Interceptors Chain
*/
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
// 创建代理
this.advisedBeans.put(cacheKey, Boolean.TRUE);
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
// 子类判断该 bean 不需要代理,比如没有适合它的 Interceptor
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
- 做了一些前置处理,代理过或者之前推断过不需要代理的就不继续了
- 如果是代理基础组件或者基于
shouldSkip
方法判断不需要代理,也就不继续了,子类可以复写shouldSkip
方法 - 接下来就准备开始代理了,在这之前,我们要获取当前
bean
上的所有拦截器,因此此处暴露了一个主要的抽象方法getAdvicesAndAdvisorsForBean
供子类实现,主要用于返回符合当前bean
的所有Interceptors
- 如果子类返回
DO_NOT_PROXY
那就不代理了,否则就开始创建,对应方法createProxy
3
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
// ...
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
// ...
/**
* 基于获取的 Interceptors 构建 Advisors 用于 proxyFactory
* 这里主要是把用户指定的 interceptorNames 也加进来,通常没有,当然最后
* 也要基于 DefaultAdvisorAdapterRegistry#wrap 包装成 Advisor
*/
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
// 子类定制
customizeProxyFactory(proxyFactory);
// ...
// 创建代理
return proxyFactory.getProxy(classLoader);
}
简化了一下代码,可以看到:
Spring AOP
创建代理用的Advised
是ProxyFactory
,之前了解过的- 处理一些
ProxyFactory
的属性后,把之前针对这个bean
获取的Interceptors
包装成Advisor
s 返回,另外这里也会把指定的interceptorNames
属性的Interceptors
也加进来,作为通用拦截器,不过一般情况下没有 Interceptors
包装成Advisor
s 由DefaultAdvisorAdapterRegistry#wrap
方法完成,之前了解过的
4
@Nullable
protected abstract Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName,
@Nullable TargetSource customTargetSource) throws BeansException;
至此,整个代理的基调已经定下来了,具体代不代理目标 bean
、赋予什么行为,则是由子类实现的 getAdvicesAndAdvisorsForBean
方法决定的
序列图
总结
在本章节代理的基调了解的差不多了,笼统的概括:
在每个 bean
合适的生命周期阶段为其创建代理对象,但具体是哪些 bean
、赋予那些行为,则由子类决定
上一篇:【源码】Spring AOP 11 AopProxyFactory AopProxy
参考
【小家Spring】Spring AOP的核心类:AbstractAdvisorAutoProxy自动代理创建器深度剖析(AnnotationAwareAspectJAutoProxyCreator)