文章目录
前言
当一个方法上面上面加了多个AOP注解的时候,运行顺序是如何的呢?
一、问题的提出
我们想对某个加了@Transactional注解的方法再添加一个自定义注解,来进行日志的打印。此时一个问题就出现在脑海里了:到底是先运行@Transactional注解的逻辑还是先运行自定义注解的逻辑呢?自定义注解实现的逻辑会在事务里么?也就是如果抛出异常会使得事务回滚么?
二、思考的逻辑
1. advisor运行的顺序
基于我们以前的了解,最后bean会被封装成一个proxy,proxy里的target才是raw bean。在method进行invoke的时候,需要遍历proxy里的advisors。
此处我们以CglibAopProxy为例,JdkDynamicAopProxy逻辑类似。
class CglibAopProxy implements AopProxy, Serializable {
// 其他属性本文不会涉及,暂时忽略
/** The configuration used to configure this proxy. */
protected final AdvisedSupport advised;
}
可以看到CglibAopProxy里有个advised属性。
public class AdvisedSupport extends ProxyConfig implements Advised{
// 其余属性忽略
/**
* Canonical TargetSource when there's no target, and behavior is
* supplied by the advisors.
*/
public static final TargetSource EMPTY_TARGET_SOURCE = EmptyTargetSource.INSTANCE;
/** Package-protected to allow direct access for efficiency. */
TargetSource targetSource = EMPTY_TARGET_SOURCE;
/**
* List of Advisors. If an Advice is added, it will be wrapped
* in an Advisor before being added to this List.
*/
private List<Advisor> advisors = new ArrayList<>();
}
可以看到advised属性里的targetSource和advisors,分别代表目标方法和相应的advisor。
执行的时候是遍历advisors,把每个advisor里的advice拿出来,然后进行链式调用,具体使用方式类似filter。
那么advisors里的advisor顺序就变得尤为重要。
那么此处我们反推,在生成CglibAopProxy的时候,放入进去的advisors顺序是如何的?咱们去往回找代码。
2. advisor添加的顺序
相信大家看过我之前的博客,应该知道给raw bean变成aop proxy是在AbstractAutoProxyCreator里的wrapIfNecessary
在wrapIfNecessary中调用了createProxy方法
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对象上
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass<