概述
AnnotationAwareAspectJAutoProxyCreator 是 Spring 框架中一个用于支持面向切面编程(AOP)的组件。它主要用于自动检测和处理使用注解定义的切面,从而在 Spring 应用程序上下文中创建 AOP 代理。
AnnotationAwareAspectJAutoProxyCreator 继承自 AspectJAwareAdvisorAutoProxyCreator,是一个具体的 BeanPostProcessor 实现。它主要负责:
- 在 Spring 应用上下文中查找所有切面(通常是使用 @Aspect 注解标记的类)。
- 为这些切面创建代理对象。
- 将代理对象注册到 Spring 应用上下文中,以便在运行时能够正确地拦截和处理方法调用。
AnnotationAwareAspectJAutoProxyCreator 的主要作用包括:
- 自动代理创建:自动为 Spring 应用上下文中的符合条件的 Bean 创建代理,无需手动配置代理。
- 注解处理:专门处理基于注解的 Aspect 切面定义(如 @Aspect),简化了 AOP 的配置和使用。
- 方法拦截:在方法执行前后或抛出异常时,执行切面中定义的通知方法(如 @Before、@After、@AfterReturning、@AfterThrowing 和 @Around)。
- 增强功能:通过面向切面编程,实现横切关注点(如事务管理、日志记录、安全检查等)的分离和模块化。
类结构分析
AnnotationAwareAspectJAutoProxyCreator 的类图如下:
查看继承关系可以发现,此类实现了 Aware 与 BeanPostProcessor 接口,这两个接口都和 Spring Bean 的初始化有关,由此推测此类主要处理方法都来自这两个接口的实现方法。同时该类也实现了 Ordered 方法。
AbstractAutoProxyCreator
在 AnnotationAwareAspectJAutoProxyCreator 类的继承关系上可以看出,是在 AbstractAutoProxyCreator 类开始实现 SmartInstantiationAwareBeanPostProcessor 接口和 BeanFactoryAware 接口的。AbstractAutoProxyCreator 类都是直接实现了这两个接口。
既然 AbstractAutoProxyCreator 实现了 BeanFactoryAware 接口, 那么 AbstractAutoProxyCreator 类中就一定存在 setBeanFactory() 方法,如下所示:
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
// ...
@Override
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
@Nullable
protected BeanFactory getBeanFactory() {
return this.beanFactory;
}
// ...
}
在 AbstractAutoProxyCreator 类中还存在与 BeanPostProcessor 后置处理器有关的方法,分别为:postProcessBeforeInstantiation()、postProcessAfterInstantiation()、postProcessProperties()、postProcessBeforeInitialization()、postProcessAfterInitialization()。整体源代码如下所示:
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
// ...
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
Object cacheKey = getCacheKey(beanClass, beanName);
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
// Create proxy here if we have a custom TargetSource.
// Suppresses unnecessary default instantiation of the target bean:
// The TargetSource will handle target instances in a custom fashion.
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
if (StringUtils.hasLength(beanName)) {
this.targetSourcedBeans.add(beanName);
}
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
return null;
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) {
return true;
}
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
return pvs;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
return bean;
}
/**
* Create a proxy with the configured interceptors if the bean is
* identified as one to proxy by the subclass.
* @see #getAdvicesAndAdvisorsForBean
*/
@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 类中看到了 BeanFactoryAware 的实现和 BeanPostProcessor后置处理器的实现。
AbstractAdvisorAutoProxyCreator
我们再来看看 AbstractAutoProxyCreator 的子类 AbstractAdvisorAutoProxyCreator 类。
public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator {
// ...
@Override
public void setBeanFactory(BeanFactory beanFactory) {
super.setBeanFactory(beanFactory);
if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
throw new IllegalArgumentException(
"AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: " + beanFactory);
}
initBeanFactory((ConfigurableListableBeanFactory) beanFactory);
}
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
this.advisorRetrievalHelper = new BeanFactoryAdvisorRetrievalHelperAdapter(beanFactory);
}
// ...
}
此段代码说明在 AbstractAdvisorAutoProxyCreator 类中重写了 setBeanFactory() 方法。并且在 AbstractAdvisorAutoProxyCreator 类的 setBeanFactory() 方法中,首先会调用 AbstractAutoProxyCreator 类中的 setBeanFactory() 方法。
另外,我们并没有在 AbstractAdvisorAutoProxyCreator 类中找到与后置处理器相关的方法。
AspectJAwareAdvisorAutoProxyCreator
通过查看 AspectJAwareAdvisorAutoProxyCreator 类的源码,我们得知,在 AspectJAwareAdvisorAutoProxyCreator 类中没有与后置处理器相关的代码。所以,我们继续向下分析 AspectJAwareAdvisorAutoProxyCreator 类的子类 AnnotationAwareAspectJAutoProxyCreator。
AnnotationAwareAspectJAutoProxyCreator
在 AnnotationAwareAspectJAutoProxyCreator 类中,我们可以找到一个 initBeanFactory() 方法,如下所示:
public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator {
// ...
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
super.initBeanFactory(beanFactory);
if (this.aspectJAdvisorFactory == null) {
this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
}
this.aspectJAdvisorsBuilder = new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
}
// ...
}
看到这里,对于 setBeanFactory 的调用流程有点清晰了吧?其实 setBeanFactory() 的调用流程为:
- 首先会执行 AbstractAdvisorAutoProxyCreator 类中的 setBeanFactory() 方法
- 在 AbstractAdvisorAutoProxyCreator 类中的 setBeanFactory() 方法中会调用其父类 AbstractAutoProxyCreator 中的 setBeanFactory() 方法
- 然后在 AbstractAdvisorAutoProxyCreator 类中的 setBeanFactory() 方法中调用 initBeanFactory() 方法。
- 由于在子类 AnnotationAwareAspectJAutoProxyCreator 中重写了 initBeanFactory() 方法,最终调用的就是 AnnotationAwareAspectJAutoProxyCreator 类中的 initBeanFactory() 方法。
- 在 AnnotationAwareAspectJAutoProxyCreator 中首先会执行调用父类 AbstractAdvisorAutoProxyCreator 的 initBeanFactory() 方法。
初始化过程
通过查看 @EnableAspectJAutoProxy 注解的源码,如下所示:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
boolean proxyTargetClass() default false;
boolean exposeProxy() default false;
}
@EnableAspectJAutoProxy 注解是通过使用 @Import(AspectJAutoProxyRegistrar.class) 给容器中注册一个名字叫做 internalAutoProxyCreator = AnnotationAwareAspectJAutoProxyCreator 的组件。
源码剖析
代理创建流程
创建代理的核心逻辑是在 postProcessAfterInitialization 方法中,也就是初始化完成后,通过 BeanPostProcessor 的后置处理器完成代理对象的创建。
核心代码位于 AbstractAutoProxyCreator 类中,他是 AnnotationAwareAspectJAutoProxyCreator 的父父父类。
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
// ...
/**
* bean 是原始对象,beanName 是原始对象的 ID 值
*/
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// 解决循环引用的问题,之前循环引用的处理也是可以提前通过 Lambda 创建代理对象的,如果之前已经创建过,则直接返回
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
// 真正创建代理的核心,判断是否需要代理并进行代理包装
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// 进行安全性的校验
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
// 这里是解决事务的情况
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// 下面这一段是创建代理的核心逻辑
// 获取当前 Bean 的拦截器(其实就是我们的切面和额外功能)通过当前 Bean,获取能否拦截的切面
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != null) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 创建代理对象
Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
// 返回代理对象
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
// 通过代理工厂创建代理对象
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
// 为代理工厂设置额外功能
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
// 为代理工厂设置原始对象
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
// 冻结所有的配置
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
// 根据现有的工厂策略创建代理对象
return proxyFactory.getProxy(getProxyClassLoader());
}
// ...
}
如何选择使用 JDK 动态代理或 CGLIB 动态代理?
代理工厂在创建代理对象的时候,也就对应上面代码的最后一行,这里在 createAopProxy 的时候,就会根据实际的情况来选择创建 CglibAopProxy 还是 JdkDynamicAopProxy。
public class ProxyFactory extends ProxyCreatorSupport {
// ...
public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
// ...
}
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
// 如果有接口,就用 JDK 动态代理
return new JdkDynamicAopProxy(config);
}
// 使用 CGLIB 动态代理
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
总结一下代理对象的创建过程:
- Spring 代理对象的创建是通过 BeanPostProcessor 的后置处理器,也就是初始化后完成代理对象的创建的,具体是 AnnotationAwareAspectJAutoProxyCreator 处理。
- 代理对象的创建是 AnnotationAwareAspectJAutoProxyCreator 的父类 AbstractAutoProxyCreator 完成。
- 首先在创建代理对象的时候先考虑到了循环引用的问题,因为在发生循环引用的时候,代理对象的创建可能会提前,在处理循环引用的时候有个 Lambda 表达式也可以提前把代理对象创建出来,如果之前已经创建过了,那么直接就返回就行,不需要重新再创建。
- 之后获取原始对象能够匹配的拦截器(切面),如果有切面则会进行代理的创建,没有的话直接返回。
- 在创建代理的时候底层是交给了 ProxyFactory 来处理,再往底层会根据情况(比如是否原始对象有接口)来选择使用 JDK 还是 CGLIB。这两类动态代理底层都有一个 AopProxy 的实现类。
代理生效流程
实际上代理的生效是动态的,单纯通过源码我们是无法看出动态的效果,所以我们需要搭配 Debug 来观察。
如果我们已经为某个 Bean 配置了 AOP 的切面和额外功能,那么我们在从上下文中获取的时候获得的就是代理对象。
实际调用代理对象的方法的时候,就会执行代理的逻辑,根据策略的不同,可能是 JdkDynamicAopProxy / CglibAopProxy。
这两种代理生效的过程都非常的类似,执行的大概逻辑如下:
- 进行一些安全性的校验:处理代理的方法是 Object 顶级类的方法,例如 equals、hashCode 等,这些方法是不需要执行代理的逻辑的。
- 判断是否开启了暴露代理的配置:@EnableAspectJAutoProxy 如果配置了 proxyTargetClass = true,则将代理对象放入 ThreadLocal,以方便后续获取,解决代理对象的方法中调用本来其他方法代理失效的问题。
- 获取原始对象的信息。
- 获取拦截器(额外功能)链:获取符合 AOP 配置切入点的拦截器链,同一个方法可以设置多个 AOP 切入点,多个切入点的顺序可以使用 @Ordered 注解指定,越小越优先。如何判断是否满足切入点的配置?底层是通过 Pointcut 接口的 AspectJExpressionPointcut 来进行条件的判断,先匹配类型,再匹配方法
- 整合原始方法和额外功能:创建 MethodInvocation 对象,将代理对象、原始对象、代理方法、参数、原始目标类、额外功能链路都统一的整合到一起。
- 执行上面创建的 MethodInvocation:按照顺序逐个执行拦截器链中每个拦截器的逻辑,这里面是一个链式调用。会在原始方法执行前,按照顺序调用所有前置的额外功能,在原始方法执行后,按照顺序执行所有后置的额外功能。
JDK 动态代理的生效
使用 JDK 动态代理创建的对象,当调用代理对象的代理的方法的时候,会进入 JdkDynamicAopProxy 的 invoke 方法。
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
// ...
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
TargetSource targetSource = this.advised.targetSource;
Object target = null;
// 处理代理的方法是 Object 顶级类的方法,例如 equals、hashCode 等,这些方法是不需要执行代理的逻辑的
try {
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
return equals(args[0]);
}
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
return hashCode();
}
else if (method.getDeclaringClass() == DecoratingProxy.class) {
return AopProxyUtils.ultimateTargetClass(this.advised);
}
else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
Object retVal;
if (this.advised.exposeProxy) {
// @EnableAspectJAutoProxy 如果配置了 proxyTargetClass = true
// 则将代理对象放入 ThreadLocal,以方便后续获取,解决代理对象的方法中调用本来其他方法代理失效的问题。
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// 获取原始对象的信息
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
// 获取符合 AOP 配置切入点的拦截器链,同一个方法可以设置多个 AOP 切入点,多个切入点的顺序可以使用 @Ordered 注解指定,越小越优先
// 如何判断是否满足切入点的配置?底层是通过 Pointcut 接口的 AspectJExpressionPointcut 来进行条件的判断,先匹配类型,再匹配方法
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
if (chain.isEmpty()) {
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
// 原始方法 + 额外功能的整合
MethodInvocation invocation =
new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// 按照顺序逐个执行拦截器链中每个拦截器的逻辑,这里面是一个链式调用
retVal = invocation.proceed();
}
// 后面都是对返回值类型和返回值的处理
Class<?> returnType = method.getReturnType();
if (retVal != null && retVal == target &&
returnType != Object.class && returnType.isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
retVal = proxy;
}
else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
throw new AopInvocationException(
"Null return value from advice does not match primitive return type for: " + method);
}
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
targetSource.releaseTarget(target);
}
if (setProxyContext) {
AopContext.setCurrentProxy(oldProxy);
}
}
}
// ...
}
CGLib 动态代理的生效
使用 CGLib 动态代理创建的对象,当调用代理对象的代理的方法的时候,会进入 CglibAopProxy 的内部拦截器类 DynamicAdvisedInterceptor 的 intercept 方法。
class CglibAopProxy implements AopProxy, Serializable {
// ...
private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {
// ...
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
Object target = null;
TargetSource targetSource = this.advised.getTargetSource();
try {
if (this.advised.exposeProxy) {
// @EnableAspectJAutoProxy 如果配置了 proxyTargetClass = true
// 则将代理对象放入 ThreadLocal,以方便后续获取,解决代理对象的方法中调用本来其他方法代理失效的问题。
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// 获取原始对象的信息
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
// 获取符合 AOP 配置切入点的拦截器链,同一个方法可以设置多个 AOP 切入点,多个切入点的顺序可以使用 @Ordered 注解指定,越小越优先
// 如何判断是否满足切入点的配置?底层是通过 Pointcut 接口的 AspectJExpressionPointcut 来进行条件的判断,先匹配类型,再匹配方法
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Object retVal;
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = methodProxy.invoke(target, argsToUse);
}
else {
// 原始方法 + 额外功能的整合
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
// 按照顺序逐个执行拦截器链中每个拦截器的逻辑,这里面是一个链式调用
retVal = processReturnType(proxy, target, method, retVal);
return retVal;
} finally {
if (target != null && !targetSource.isStatic()) {
targetSource.releaseTarget(target);
}
if (setProxyContext) {
AopContext.setCurrentProxy(oldProxy);
}
}
}
}
}