spring aop应用及源码详解 一篇就够了

本文将对spring aop的实现、jdk动态代理、Aspectj实现原理、spring数据库事务底层原理一一分析

一、AOP常用概念:

1、pointcut 切入点 也就是方法 spring会通过设置的pointcut来match要拦截的方法

2、joinpoint 连接点 还是方法 在哪里aop 最终还是会通过joinpoint执行原方法

3、advice 通知|增强 我们知道的@before @after @around这些注解都是advice

4、advisor = advice+pointcut 我们设置的advice最终都会被spring封装成advisor

5、weaving 织入 这是一个动作 将增强方法织入到原方法上

6、aspect 点连成面

7、target 目标类 通过反射调用目标类的目标方法

二、AOP的实现

2.1、实现1 通过ProxyFactoryBean

概念太抽象 用具体例子来描述 我们先通过ProxyFactoryBean 一个最简单的示例来完成一个aop

public class MainTest {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
        IproxyMethod proxyMethod = (IproxyMethod) context.getBean("myProxyFactoryBean");
        proxyMethod.test();
    }
}

@Configuration
public class MyConfig {

    // 被代理对象
    @Bean
    public ProxyMethod proxyMethod() {
        return new ProxyMethod();
    }

    // Advice 方式
    @Bean
    public MyBeforeAdvice myBeforeAdvice(){
        return new MyBeforeAdvice();
    }

    // Interceptor方式 , 可以理解为环绕通知
    @Bean
    public MyIntercepter myIntercepter() {
        return new MyIntercepter();
    }


    /**
     * FactoryBean方式单个: ProxyFactoryBean
     * 缺点:
     * 1、只能指定单一的Bean的AOP,
     * 2、拦截器的粒度只控制到了类级别,类中所有的方法都进行了拦截
     *
     */
     @Bean
     public ProxyFactoryBean myProxyFactoryBean(){
         ProxyFactoryBean proxyFactoryBean=new ProxyFactoryBean();
         proxyFactoryBean.setInterceptorNames("myBeforeAdvice","myIntercepter");  // 根据指定的顺序执行
         proxyFactoryBean.setTarget(proxyMethod());
         return proxyFactoryBean;
     }
}

public class MyBeforeAdvice implements MethodBeforeAdvice {
    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println("target方法[" + method.getName() + "] 前置增强 ,参数" + Arrays.asList(args));
    }
}
public class MyIntercepter implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        System.out.println(getClass()+"方法执行前");
        Object ret=invocation.proceed();
        System.out.println(getClass()+"方法执行后");
        return ret;
    }
}

public interface IproxyMethod {
    public void test();
    public void test1();
}

public class ProxyMethod implements IproxyMethod{

    public void test(){
        System.out.println("test执行");
    }

    public void test1(){
        System.out.println("test1执行");
    }
}

上面例子中

  1. target即目标类是proxyMethod()

  1. advice 增强方法有两个:myBeforeAdvice()和myIntercepter() 查看源码 我们可以发现 Interceptor其实是继承了Advice 也就是说Interceptor其实就是特殊的advice

  1. pointcut 切点我们并没有看到指定 也就是说上面的代理类会为所有方法创建 也是弊端之一

  1. joinpoint :test()和test1()方法及joinpoint

该示例缺点明显

  1. 只能指定单一的bean对象

  1. 因为没有设置pointcut 所有类的所有方法都被代理

2.2、实现2 通过Advisor来设置

NameMatchMethodPointcutAdvisor为例 advisor = advice+pointcut 设置就完事了

@Configuration
public class AdviserConfig {

    // 被代理对象
    @Bean
    public IproxyMethod proxyMethod() {
        return new ProxyMethod();
    }

    // Advice 方式
    @Bean
    public MyBeforeAdvice myBeforeAdvice(){
        return new MyBeforeAdvice();
    }

    /**
     * Advisor 种类很多 不一一赘述
     */
    @Bean
    public NameMatchMethodPointcutAdvisor myAspectAdvisor() {
        NameMatchMethodPointcutAdvisor advisor=new NameMatchMethodPointcutAdvisor();//创建advisor 
        advisor.setAdvice(myBeforeAdvice());//设置advice增强方法
        advisor.setMappedNames("test");//切点方法 设置pointcut切入点 按方法名匹配的切入点
        return advisor;
    }


    /**
     * 此时设置的interceptor是一个advisor
     * 缺点:还是只能代理单一的bean
     * @return
     */
    @Bean
    public ProxyFactoryBean myProxyFactoryBean(){
        ProxyFactoryBean myService=new ProxyFactoryBean();
        myService.setInterceptorNames("myAspectAdvisor");
        myService.setTarget(proxyMethod());
        return myService;
    }

}

spring提供了很多的adivsor 可以通过不同的方式去设置pointcut

此时我们可以自己设置pointcut的了 但是还是只能针对单一的bean

2.3、实现3 通过beanPostProcessor来设置

@Configuration
public class BeanPostProcessorConfig {
    // 被代理对象
    @Bean
    public IproxyMethod proxyMethod() {
        return new ProxyMethod();
    }

    // Interceptor方式 , 可以理解为环绕通知
    @Bean
    public MyIntercepter myIntercepter() {
        return new MyIntercepter();
    }


    @Bean
    public BeanNameAutoProxyCreator autoProxyCreator() {
        BeanNameAutoProxyCreator beanNameAutoProxyCreator = new BeanNameAutoProxyCreator();
        //设置要创建代理的那些Bean的名字 以proxy开头的beanname
        beanNameAutoProxyCreator.setBeanNames("proxy*");
        //设置拦截链名字(这些拦截器是有先后顺序的)
        beanNameAutoProxyCreator.setInterceptorNames("myIntercepter");
        return beanNameAutoProxyCreator;
    }
}

此时我们可以设置多个bean 并且可以设置自定义的advice增强

2.4、实现4 通过xml来设置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       https://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/aop
       https://www.springframework.org/schema/aop/spring-aop.xsd">

    <!-- target 目标对象 -->
    <bean id="proxyMethod" class="com.lgj.spring.aop.earlyaop.ProxyMethod"></bean>
    <!-- 增强具体实现 -->
    <bean id="myInterceptor" class="com.lgj.spring.aop.xml.MyInterceptor"></bean>
    <aop:config>
        <!-- 设置pointcut 路径下所有方法 -->
        <aop:pointcut expression="execution(* com.lgj.spring.aop.earlyaop.*.*(..) )" id="pointcut1" />
        <!-- aspect 配置切面  指向的是自定义的增强 -->
        <aop:aspect id="logAdvice" ref="myInterceptor">
            <!-- 增强adivice  before就会封装成前置增强 -->
            <aop:before method="before" pointcut-ref="pointcut1" />
        </aop:aspect>
    </aop:config>
</beans>
public class XmlAopMain {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:springAop.xml");
        IproxyMethod iproxyMethod = applicationContext.getBean(IproxyMethod.class);
        iproxyMethod.test();
    }
}

public class MyInterceptor {
    public void before(){
        System.out.println("前置增强");
    }
}

2.5、实现5 通过@aspectj注解来设置

示例代码:

@Component
@Aspect
public class MyAspectj {
    
    //EXECUtion可以是个范围 制定方法 方法名参数等等
    @Pointcut("execution(* com.lgj.spring.aop.aspectj.service.*.*(..))")
    public void pointCutPoint() {
        
    }


    @Before("pointCutPoint()")
    public void before() {
        System.out.println("before");
    }

    @After("pointCutPoint()")
    public void after(){
        System.out.println("after");
    }
    @Around("pointCutPoint()")
    public Object around(ProceedingJoinPoint joinPoint){//joinPoint-》MethodInvocationProceedingJoinPoint
        System.out.println("around 前置执行");
        try {
            Object proceed = joinPoint.proceed(joinPoint.getArgs());
            System.out.println("around 后置执行");
            return proceed;
        } catch (Throwable e) {
            System.out.println("around 异常执行");
            return null;
        } finally {
            System.out.println("around finally执行");
        }
    }
}

@Configuration
@ComponentScan("com.lgj.spring.aop.aspectj")
@EnableAspectJAutoProxy(proxyTargetClass =false)
public class AspectConfig {

}

public class TestAspectMain {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        ApplicationContext ac = new AnnotationConfigApplicationContext(AspectConfig.class);
        MyService myService = ac.getBean(MyService.class);
        myService.test();
    }
}

public interface MyService {
    void test();
}

@Service
public class MyServiceImpl implements MyService {
    @Override
    public void test() {
        System.out.println("执行test");
    }
}

三、AOP的原理前置知识 动态代理

我们都知道spring实现动态代理的两种方式:jdk动态代理以及cglib

以jdk动态代理为例:增强类即JdkDynamicAopProxy

org.springframework.aop.framework.JdkDynamicAopProxy#getProxy(java.lang.ClassLoader)

public Object getProxy(@Nullable ClassLoader classLoader) {//获取代理类
   if (logger.isTraceEnabled()) {
      logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
   }
   Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
   findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
   return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);//返回代理类  增强方法传的this 所以直接查看该类的invoke即可
}

查看动态代理生成的类发现 就是调用其invoke方法:

查看其增强方法invoke方法:

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;

        try {
            //1、参数合法性校验
            if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
                // The target does not implement the equals(Object) method itself.
                return equals(args[0]);
            }
            else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
                // The target does not implement the hashCode() method itself.
                return hashCode();
            }
            else if (method.getDeclaringClass() == DecoratingProxy.class) {
                // There is only getDecoratedClass() declared -> dispatch to proxy config.
                return AopProxyUtils.ultimateTargetClass(this.advised);
            }
            else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
                    method.getDeclaringClass().isAssignableFrom(Advised.class)) {
                // Service invocations on ProxyConfig with the proxy config...
                return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
            }

            Object retVal;

            if (this.advised.exposeProxy) {
                // Make invocation available if necessary.
                oldProxy = AopContext.setCurrentProxy(proxy);
                setProxyContext = true;
            }

            // Get as late as possible to minimize the time we "own" the target,
            // in case it comes from a pool.
            target = targetSource.getTarget();//目标类
            Class<?> targetClass = (target != null ? target.getClass() : null);

            // 2、拿到advice链 后续会嵌套执行其invoke方法
            List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

            // Check whether we have any advice. If we don't, we can fallback on direct
            // reflective invocation of the target, and avoid creating a MethodInvocation.
            if (chain.isEmpty()) {
                // We can skip creating a MethodInvocation: just invoke the target directly
                // Note that the final invoker must be an InvokerInterceptor so we know it does
                // nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
                Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
                retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
            }
            else {
                //3、创建反射方法调用类 
                MethodInvocation invocation =
                        new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
                // 4、执行其proceed方法
                retVal = invocation.proceed();
            }

            // Massage return value if necessary.
            Class<?> returnType = method.getReturnType();
            if (retVal != null && retVal == target &&
                    returnType != Object.class && returnType.isInstance(proxy) &&
                    !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
                // Special case: it returned "this" and the return type of the method
                // is type-compatible. Note that we can't help if the target sets
                // a reference to itself in another returned object.
                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()) {
                // Must have come from TargetSource.
                targetSource.releaseTarget(target);
            }
            if (setProxyContext) {
                // Restore old proxy.
                AopContext.setCurrentProxy(oldProxy);
            }
        }
    }

重要的三个步骤:

1、参数合法性校验

2、拿到advice组成的chain链

3、通过ReflectiveMethodInvocation调用其proceed方法

重要方法:

  1. getInterceptorsAndDynamicInterceptionAdvice 进入代理类的代理方法之前,通过pointcut来匹配当前方式是否需要增强

  1. invocation.proceed执行interceptor的chain 继而反射执行目标方法

查看getInterceptorsAndDynamicInterceptionAdvice方法:

public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) {
    MethodCacheKey cacheKey = new MethodCacheKey(method);
    List<Object> cached = this.methodCache.get(cacheKey);
    if (cached == null) {
        cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
                this, method, targetClass);//通过工厂获取advice chain
        this.methodCache.put(cacheKey, cached);
    }
    return cached;
}

public List<Object> getInterceptorsAndDynamicInterceptionAdvice(//转换成interceptor list
            Advised config, Method method, @Nullable Class<?> targetClass) {

    // This is somewhat tricky... We have to process introductions first,
    // but we need to preserve order in the ultimate list.
    AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
    Advisor[] advisors = config.getAdvisors();//拿到所有advisor
    List<Object> interceptorList = new ArrayList<>(advisors.length);//装合适的adivice
    Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
    Boolean hasIntroductions = null;

    for (Advisor advisor : advisors) {//遍历advisor
        if (advisor instanceof PointcutAdvisor) {//aspectj的 advice相关注解包装类即进入
            // Add it conditionally.
            PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
            // 1、先进行类级别上的匹配  很多自定义的advisor之前已经过滤了 isPreFiltered为true
            if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
                MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
                boolean match;
                if (mm instanceof IntroductionAwareMethodMatcher) {//IntroductionAwareMethodMatcher类型 比如aspectj的pointcut:AspectJExpressionPointcut
                    if (hasIntroductions == null) {
                        hasIntroductions = hasMatchingIntroductions(advisors, actualClass);
                    }
                    match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);
                }
                else {
                    //2、在进行方法级别上的匹配 扩展点2
                    match = mm.matches(method, actualClass);
                }
                if (match) {//方法匹配成功了
                    //3、拿到advisor对应的Advice增强器集合 或者是通过适配器 适配成合适的interceptor
                    MethodInterceptor[] interceptors = registry.getInterceptors(advisor);//注册器获取interceptor  所有注册的advisor拿到interceptor
                    if (mm.isRuntime()) {
                        // Creating a new object instance in the getInterceptors() method
                        // isn't a problem as we normally cache created chains.
                        for (MethodInterceptor interceptor : interceptors) {
                            interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
                        }
                    }
                    else {
                        //4、装入集合中
                        interceptorList.addAll(Arrays.asList(interceptors));
                    }
                }
            }
        }
        else if (advisor instanceof IntroductionAdvisor) {//IntroductionAdvisor实现
            IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
            if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
                Interceptor[] interceptors = registry.getInterceptors(advisor);
                interceptorList.addAll(Arrays.asList(interceptors));
            }
        }
        else {//spring自己的
            Interceptor[] interceptors = registry.getInterceptors(advisor);
            interceptorList.addAll(Arrays.asList(interceptors));
        }
    }

    return interceptorList;
}

org.springframework.aop.framework.adapter.DefaultAdvisorAdapterRegistry#getInterceptors
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
    List<MethodInterceptor> interceptors = new ArrayList<>(3);
    Advice advice = advisor.getAdvice();
    //1、直接实现了MethodInterceptor的advice 直接添加进去
    if (advice instanceof MethodInterceptor) {
        interceptors.add((MethodInterceptor) advice);
    }
    //2、否则会通过适配器来 装饰成对应的interceptor
    for (AdvisorAdapter adapter : this.adapters) {//adapters初始化有三个
        if (adapter.supportsAdvice(advice)) {
            interceptors.add(adapter.getInterceptor(advisor));
        }
    }
    if (interceptors.isEmpty()) {
        throw new UnknownAdviceTypeException(advisor.getAdvice());
    }
    //3、返回对应的interceptors
    return interceptors.toArray(new MethodInterceptor[0]);
}

直接查看ReflectiveMethodInvocation.proceed方法

org.springframework.aop.framework.ReflectiveMethodInvocation#proceed

public Object proceed() throws Throwable {//jdk动态代理进入
   // We start with an index of -1 and increment early.
   /**
    * currentInterceptorIndex-当前下标 默认为-1  使用前+1 从0开始
    * 满足条件代表代表 chain执行完毕 执行目标方法  递归调用
    */
   if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
      return invokeJoinpoint();//执行目标方法  通过目标类和目标方法反射执行
   }

   Object interceptorOrInterceptionAdvice =
         this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);//从0开始 拿到
   if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
      // Evaluate dynamic method matcher here: static part will already have
      // been evaluated and found to match.
      InterceptorAndDynamicMethodMatcher dm =
            (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
      Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
      if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
         return dm.interceptor.invoke(this);//入参是this 执行interceptor的invoke方法
      }
      else {
         // Dynamic matching failed.
         // Skip this interceptor and invoke the next in the chain.
         return proceed();
      }
   }
   else {
      // It's an interceptor, so we just invoke it: The pointcut will have
      // been evaluated statically before this object was constructed.
      /**
       * 常见的interceptor
       * 可以是相关的Advisor 比如NameMatchMethodPointcutAdvisor 最后还是会拿到设置的advice包装成advisor
       * 可以是MethodInterceptor实现
       * 可以是advice 支持如下三种
       *    MethodBeforeAdviceAdapter
       *    AfterReturningAdviceAdapter
       *    ThrowsAdviceAdapter
       */
      return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);//执行davice的invoke方法
   }
}

分析proceed方法:

1、嵌套调用chain里面的advice对象的invoke增强方法

2、 直至完成chain的调用 反射执行目标类的目标方法

所以我们知道如果要实现springAOP 那我们必须要准备一个Advisor ,

其中Advisor包含 advice(重写invoke方法实现增强逻辑)和pointcut(重写match匹配目标方法和目标类) 、target目标类、joinpoint (目标方法)

我们自定义的advice 需要重写invoke方法 实现增强逻辑

四、@EnableAspectJAutoProxy实现原理

1、通过import注解最终注入了一个beanPostProcessor:AnnotationAwareAspectJAutoProxyCreator

2、AnnotationAwareAspectJAutoProxyCreator继承了AbstractAutoProxyCreator 重写了相关方法 最终在创建动态代理之前找到相关advisor

接下来看是怎么找到这个advisor 怎么封装的advice和pointcut的

先看AnnotationAwareAspectJAutoProxyCreator类图

其中的org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization方法就是动态代理的关键

AnnotationAwareAspectJAutoProxyCreator重写了shouldSkip方法

org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator#shouldSkip

@Override
    protected boolean shouldSkip(Class<?> beanClass, String beanName) {
        //1、找到候选的advisor集合
        List<Advisor> candidateAdvisors = findCandidateAdvisors();
        for (Advisor advisor : candidateAdvisors) {
            if (advisor instanceof AspectJPointcutAdvisor &&
                    ((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
                return true;//合法的就返回true
            }
        }
        return super.shouldSkip(beanClass, beanName);
    }

查看方法org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors

//这个方法会被调用两次 包括下面分析的方法都是会调用两次 
//第一次是AbstractAutoProxyCreator#postProcessBeforeInstantiation 会提前找到advisor缓存起来
//第二次是AbstractAutoProxyCreator#postProcessAfterInstantiation 拿到advisor直接用
protected List<Advisor> findCandidateAdvisors() {
    // 1、找实现了Advisor接口的Advisor 我们这边没有
    List<Advisor> advisors = super.findCandidateAdvisors();
    // Build Advisors for all AspectJ aspects in the bean factory.
    if (this.aspectJAdvisorsBuilder != null) {//在initBeanFactory中被创建
        //2、创建AspectJ的advisor
        advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
    }
    return advisors;
}
org.springframework.aop.aspectj.annotation.BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors
public List<Advisor> buildAspectJAdvisors() {
    List<String> aspectNames = this.aspectBeanNames;//查看缓存中是否有 第二次进来就有了

    if (aspectNames == null) {//第一次进来没有的情况下
        synchronized (this) {
            aspectNames = this.aspectBeanNames;
            if (aspectNames == null) {
                List<Advisor> advisors = new ArrayList<>();
                aspectNames = new ArrayList<>();
                //3、找到所有实现了Object的bean对象 也就是所有bean对象
                String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                        this.beanFactory, Object.class, true, false);
                for (String beanName : beanNames) {
                    if (!isEligibleBean(beanName)) {
                        continue;
                    }
                    Class<?> beanType = this.beanFactory.getType(beanName);
                    if (beanType == null) {
                        continue;
                    }
                    //4、找到标注了@Aspect注解的bean对象
                    if (this.advisorFactory.isAspect(beanType)) {
                        aspectNames.add(beanName);//添加到缓存中
                        AspectMetadata amd = new AspectMetadata(beanType, beanName);//包装aspectj的bean对象 
                        if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
                            MetadataAwareAspectInstanceFactory factory =
                                    new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
                            //5、通过advisor工厂创建advisor对象
                            List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
                            if (this.beanFactory.isSingleton(beanName)) {
                                this.advisorsCache.put(beanName, classAdvisors);
                            }
                            else {
                                this.aspectFactoryCache.put(beanName, factory);
                            }
                            advisors.addAll(classAdvisors);
                        }
                        else {
                            // Per target or per this.
                            if (this.beanFactory.isSingleton(beanName)) {
                                throw new IllegalArgumentException("Bean with name '" + beanName +
                                        "' is a singleton, but aspect instantiation model is not singleton");
                            }
                            MetadataAwareAspectInstanceFactory factory =
                                    new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
                            this.aspectFactoryCache.put(beanName, factory);
                            advisors.addAll(this.advisorFactory.getAdvisors(factory));
                        }
                    }
                }
                this.aspectBeanNames = aspectNames;//设置到缓存
                return advisors;
            }
        }
    }

    if (aspectNames.isEmpty()) {
        return Collections.emptyList();
    }
    List<Advisor> advisors = new ArrayList<>();
    for (String aspectName : aspectNames) {
        List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
        if (cachedAdvisors != null) {
            advisors.addAll(cachedAdvisors);
        }
        else {
            MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
            advisors.addAll(this.advisorFactory.getAdvisors(factory));
        }
    }
    return advisors;
}
org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory#getAdvisors
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
    Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();//@Aspect注解对应的类
    String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();//beanName
    validate(aspectClass);/验证class

    // We need to wrap the MetadataAwareAspectInstanceFactory with a decorator
    // so that it will only instantiate once.
    MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
            new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);

    List<Advisor> advisors = new ArrayList<>();
    //找到非PointCut注解的所有方法 比如@Before @After声明的注解之类的方法 遍历 生成advisor对象
    for (Method method : getAdvisorMethods(aspectClass)) {
        //创建包装成adivsor对象 找pointcut
        Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
        if (advisor != null) {
            advisors.add(advisor);
        }
    }

    // 延迟初始化 否
    if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
        Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
        advisors.add(0, instantiationAdvisor);
    }

    // Find introduction fields. 找到生命式的代理@DeclareParents注解
    for (Field field : aspectClass.getDeclaredFields()) {
        Advisor advisor = getDeclareParentsAdvisor(field);
        if (advisor != null) {
            advisors.add(advisor);
        }
    }

    return advisors;
}
//创建advisor对象并创建pointcut对象
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
        int declarationOrderInAspect, String aspectName) {

    validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());

    AspectJExpressionPointcut expressionPointcut = getPointcut(//拿到对应的pointcut
            candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
    if (expressionPointcut == null) {
        return null;
    }
    //封装成advisor对象
    return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
            this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}

org.springframework.aop.aspectj.annotation.InstantiationModelAwarePointcutAdvisorImpl#InstantiationModelAwarePointcutAdvisorImpl
public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,
            Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,
            MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {

    this.declaredPointcut = declaredPointcut;
    this.declaringClass = aspectJAdviceMethod.getDeclaringClass();
    this.methodName = aspectJAdviceMethod.getName();
    this.parameterTypes = aspectJAdviceMethod.getParameterTypes();
    this.aspectJAdviceMethod = aspectJAdviceMethod;
    this.aspectJAdvisorFactory = aspectJAdvisorFactory;
    this.aspectInstanceFactory = aspectInstanceFactory;
    this.declarationOrder = declarationOrder;
    this.aspectName = aspectName;

    if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {//延迟加载
        // Static part of the pointcut is a lazy type.
        Pointcut preInstantiationPointcut = Pointcuts.union(
                aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);

        // Make it dynamic: must mutate from pre-instantiation to post-instantiation state.
        // If it's not a dynamic pointcut, it may be optimized out
        // by the Spring AOP infrastructure after the first evaluation.
        this.pointcut = new PerTargetInstantiationModelPointcut(
                this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory);
        this.lazy = true;
    }
    else {//单例
        // A singleton aspect.
        this.pointcut = this.declaredPointcut;//设置pointcut
        this.lazy = false;
        this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);//实例化advice
    }
}

private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) {//实例化advice对象
    Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut,
            this.aspectInstanceFactory, this.declarationOrder, this.aspectName);//通过工厂方法获取advise
    return (advice != null ? advice : EMPTY_ADVICE);
}

private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) {
    Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut,
            this.aspectInstanceFactory, this.declarationOrder, this.aspectName);//通过工厂方法获取advise
    return (advice != null ? advice : EMPTY_ADVICE);
}

public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
            MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {

    Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
    validate(candidateAspectClass);
    //1、判断该方法的注解是否属于aspect定义的这些注解
    AspectJAnnotation<?> aspectJAnnotation =
            AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);//aspectj相关advise注解
    if (aspectJAnnotation == null) {//不是即返回
        return null;
    }

    // If we get here, we know we have an AspectJ method.
    // Check that it's an AspectJ-annotated class 类不是Aspect注解声明的类
    if (!isAspect(candidateAspectClass)) {
        throw new AopConfigException("Advice must be declared inside an aspect type: " +
                "Offending method '" + candidateAdviceMethod + "' in class [" +
                candidateAspectClass.getName() + "]");
    }

    if (logger.isDebugEnabled()) {
        logger.debug("Found AspectJ method: " + candidateAdviceMethod);
    }

    AbstractAspectJAdvice springAdvice;
    //根据不同的注解创建adivce 重写了不同的invoke方法 被advisor chain调用
    switch (aspectJAnnotation.getAnnotationType()) {
        case AtPointcut://pointcut注解
            if (logger.isDebugEnabled()) {
                logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
            }
            return null;
        case AtAround://around注解
            springAdvice = new AspectJAroundAdvice(
                    candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
            break;
        case AtBefore://before注解
            springAdvice = new AspectJMethodBeforeAdvice(
                    candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
            break;
        case AtAfter://after注解
            springAdvice = new AspectJAfterAdvice(
                    candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
            break;
        case AtAfterReturning://afterReturn
            springAdvice = new AspectJAfterReturningAdvice(
                    candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
            AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
            if (StringUtils.hasText(afterReturningAnnotation.returning())) {
                springAdvice.setReturningName(afterReturningAnnotation.returning());
            }
            break;
        case AtAfterThrowing:
            springAdvice = new AspectJAfterThrowingAdvice(
                    candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
            AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
            if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
                springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
            }
            break;
        default:
            throw new UnsupportedOperationException(
                    "Unsupported advice type on method: " + candidateAdviceMethod);
    }

    // Now to configure the advice...
    springAdvice.setAspectName(aspectName);
    springAdvice.setDeclarationOrder(declarationOrder);
    String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
    if (argNames != null) {
        springAdvice.setArgumentNamesFromStringArray(argNames);
    }
    springAdvice.calculateArgumentBindings();

    return springAdvice;
}

最终我们创建的advisor是InstantiationModelAwarePointcutAdvisorImpl

上面我们看到了pointcut是声明成AspectJExpressionPointcut

advice对象:我们看到不同的注解创建了不同advice对象

查看org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary源码:

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;
    }
    //1、shouldSkip创建好了advisor对象 缓存起来
    if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }

    // 2、拿到或者创建advice
    Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
    if (specificInterceptors != DO_NOT_PROXY) {
        this.advisedBeans.put(cacheKey, Boolean.TRUE);
        //3、创建动态代理
        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;
}

创建动态三个步骤

  1. shouldSkip创建好了advisor对象 缓存起来 前面已经分析到了

  1. getAdvicesAndAdvisorsForBean拿到或者创建advice 下面重点分析

3、创建动态代理

org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean

protected Object[] getAdvicesAndAdvisorsForBean(
            Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {

    List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);//找到合法的advisors对象
    if (advisors.isEmpty()) {
        return DO_NOT_PROXY;
    }
    return advisors.toArray();
}

protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
    //1、findCandidateAdvisors方法在before方法中执行过并缓存起来 advisor即InstantiationModelAwarePointcutAdvisorImpl
    List<Advisor> candidateAdvisors = findCandidateAdvisors();//找到候选的advisor 也就是用户自定义的advisor 并create这个bean
    //2、通过pointcut去判断这个advisor是否匹配
    List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);//判断是否匹配
    extendAdvisors(eligibleAdvisors);//扩展的advisor
    if (!eligibleAdvisors.isEmpty()) {
        //3、对advisor进行排序
        eligibleAdvisors = sortAdvisors(eligibleAdvisors);//对advisor进行排序
    }
    return eligibleAdvisors;
}

这个findAdvisorsThatCanApply 会先对类级别注解进行匹配 然后再对方法级别进行匹配

总结起来@Aspectj原理:

1、通过import注解注入一个beanPostProcessor:AnnotationAwareAspectJAutoProxyCreator且该类实现了动态代理的核心类AbstractAutoProxyCreator,重写其相关方法 来发现和创建advisor

2、创建advisor的同时 创建pointcut(AspectJExpressionPointcut)以及advice

Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class标注了这些注解的方法最后都封装成一个advice增强器 最终通过反射调用相关方法执行

3、通过切点表达式来match匹配需要代理的方法

五、spring事务@EnableTransactionManagement实现原理

以数据库事务为例:

public class TransactionMainTest {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(TransactionConfig.class);
        ITransService transService = (ITransService) context.getBean(ITransService.class);
        transService.pay();
    }
}

@EnableTransactionManagement
@ComponentScan("com.lgj.spring.aop.transaction")
public class TransactionConfig {
    @Bean
    public DataSource dataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        dataSource.setUrl("jdbc:mysql://localhost:3306/test?serverTimezone=UTC&characterEncoding=UTF-8&allowMultiQueries=true&allowPublicKeyRetrieval=true&useSSL=false");
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        return dataSource;
    }

    @Bean
    public JdbcTemplate jdbcTemplate(DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }

    @Bean
    public PlatformTransactionManager transactionManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}

@Transactional(rollbackFor=Exception.class)
public interface ITransService {
    void pay();
}

@Service
public class TransServiceImpl implements ITransService{
    @Autowired
    JdbcTemplate jdbcTemplate;
    @Override
    public void pay() {
        jdbcTemplate.execute("insert into test(column1) values('testlgj')");
        int i =5/0;//异常 sql回滚
    }
}

从示例代码可知 sql insert语句因异常回滚 spring事务也是借助aop完成此操作

数据库开启事务 即设置连接为手动提交,try catch捕获异常 根据异常结果判断是否提交事务:

connection.setAutoCommit(false);

从上面aop的例子中 我们知道 spring要想实现aop

必须实现自己的advisor、advice(interceptor)、以及joinpoint

1、EnableTransactionManagement注解引入TransactionManagementConfigurationSelector

2、import能帮我们注入bean

查看org.springframework.transaction.annotation.TransactionManagementConfigurationSelector#selectImports

protected String[] selectImports(AdviceMode adviceMode) {
        switch (adviceMode) {
            case PROXY:
                return new String[] {AutoProxyRegistrar.class.getName(),//注入了一个事务的beanpostprocessor
                        ProxyTransactionManagementConfiguration.class.getName()};//注入了一个配置类 引入了一个advisor
            case ASPECTJ:
                return new String[] {determineTransactionAspectClass()};
            default:
                return null;
        }
    }

其中AutoProxyRegistrar实现了ImportBeanDefinitionRegistrar 帮助我们注入一个beanDefinition对象:

1、InfrastructureAdvisorAutoProxyCreator 该类也是一个BeanPostProcessor 通过bpp创建代理类并校验advisor的合法性

ProxyTransactionManagementConfiguration类 帮我们注入了以下几个东西:

2、advisor:BeanFactoryTransactionAttributeSourceAdvisor 内置了一个poincut:TransactionAttributeSourcePointcut 也就是利用TransactionAttributeSource 来扫描事务注解

3、Advice:TransactionInterceptor 实现事务增强逻辑 放最后说

4、TransactionAttributeSource:扫描事务注解

这四个类一个个分析:

InfrastructureAdvisorAutoProxyCreator 具体的事情都是父类在干 它没干什么事 只是对advisor的合法性做了一个校验 校验了advisor的角色

public class InfrastructureAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator {

    @Nullable
    private ConfigurableListableBeanFactory beanFactory;


    @Override
    protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {//子类实现
        super.initBeanFactory(beanFactory);
        this.beanFactory = beanFactory;//初始化一个beanFactory
    }

    @Override
    protected boolean isEligibleAdvisorBean(String beanName) {//合法advisor的bean 方法重写
        return (this.beanFactory != null && this.beanFactory.containsBeanDefinition(beanName) &&//beanFactory不为空 true  beanfactory包含该bd
                this.beanFactory.getBeanDefinition(beanName).getRole() == BeanDefinition.ROLE_INFRASTRUCTURE);//该bd的角色要对得上
    }

}

BeanFactoryTransactionAttributeSourceAdvisor 内置pointcut:TransactionAttributeSourcePointcut

public class BeanFactoryTransactionAttributeSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor {

    @Nullable
    private TransactionAttributeSource transactionAttributeSource;//AnnotationTransactionAttributeSource

    private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() {//内置pointcut
        @Override
        @Nullable
        protected TransactionAttributeSource getTransactionAttributeSource() {
            return transactionAttributeSource;//设置完属性 真真用到pointcut时 会创建TransactionAttributeSourcePointcut
        }
    };

    
    public void setTransactionAttributeSource(TransactionAttributeSource transactionAttributeSource) {
        this.transactionAttributeSource = transactionAttributeSource;
    }
    ...
}

TransactionAttributeSourcePointcut

  1. 设置了类过滤器

  1. 重写了类matchs方法

  1. 重写了方法matchs方法

protected TransactionAttributeSourcePointcut() {
    setClassFilter(new TransactionAttributeSourceClassFilter());//创建并设置类过滤器
}

public boolean matches(Method method, Class<?> targetClass) {//重写matches方法  方法的过滤器
    TransactionAttributeSource tas = getTransactionAttributeSource();//拿到AnnotationTransactionAttributeSource对象
    return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);// AnnotationTransactionAttributeSource对象父类AbstractFallbackTransactionAttributeSource有getTransactionAttribute方法
}

private class TransactionAttributeSourceClassFilter implements ClassFilter {//类过滤器

    @Override
    public boolean matches(Class<?> clazz) {
        // TransactionalProxy它是SpringProxy的子类。 如果是被TransactionProxyFactoryBean生产出来的Bean,就会自动实现此接口,那么就不会被这里再次代理了
        // PlatformTransactionManager:spring抽象的事务管理器
        // PersistenceExceptionTranslator对RuntimeException转换成DataAccessException的转换接口
        if (TransactionalProxy.class.isAssignableFrom(clazz) ||
                TransactionManager.class.isAssignableFrom(clazz) ||
                PersistenceExceptionTranslator.class.isAssignableFrom(clazz)) {
            return false;
        }
        TransactionAttributeSource tas = getTransactionAttributeSource();//getTransactionAttributeSource被重写 直接返回TransactionAttributeSource
        return (tas == null || tas.isCandidateClass(clazz));//子类AnnotationTransactionAttributeSource重写
    }
}

AnnotationTransactionAttributeSource

1、 创建了annotationParsers对象用来解析事务注解

2、重写了isCandidateClass方法 通过parser解析器来解析类上是否有事务注解 比如@Transactional

3、重写了findTransactionAttribute方法 分别可以查找类和方法上的事务注解

//我们也可以设置ejb和 jta的事务注解  通常还是用的spring的  
public AnnotationTransactionAttributeSource(boolean publicMethodsOnly) {
    this.publicMethodsOnly = publicMethodsOnly;
    if (jta12Present || ejb3Present) {
        this.annotationParsers = new LinkedHashSet<>(4);
        this.annotationParsers.add(new SpringTransactionAnnotationParser());//创建spring的注解解析器
        if (jta12Present) {
            this.annotationParsers.add(new JtaTransactionAnnotationParser());
        }
        if (ejb3Present) {
            this.annotationParsers.add(new Ejb3TransactionAnnotationParser());
        }
    }
    else {
        this.annotationParsers = Collections.singleton(new SpringTransactionAnnotationParser());//创建spring的注解解析器
    }
}

public boolean isCandidateClass(Class<?> targetClass) {
    for (TransactionAnnotationParser parser : this.annotationParsers) {
        if (parser.isCandidateClass(targetClass)) {//通过parser解析器 来判断是否是候选类  判断类是否有事务注解 比如org.springframework.transaction.annotation.Transactional
            return true;
        }
    }
    return false;
}

protected TransactionAttribute findTransactionAttribute(Class<?> clazz) {//查找类上事务的注解
    return determineTransactionAttribute(clazz);
}

protected TransactionAttribute findTransactionAttribute(Method method) {//查找方法上事务的注解
    return determineTransactionAttribute(method);//确定事务的注解
}

protected TransactionAttribute determineTransactionAttribute(AnnotatedElement element) {
    for (TransactionAnnotationParser parser : this.annotationParsers) {//通过annotationParser找到事务注解
        TransactionAttribute attr = parser.parseTransactionAnnotation(element);//解析Transactional注解
        if (attr != null) {
            return attr;
        }
    }
    return null;
}

AnnotationTransactionAttributeSource的父类AbstractFallbackTransactionAttributeSource

  1. 重写getTransactionAttribute方法: 拿到事务属性 adivice增强中会用到

1.1、先从实现类的方法上找事务注解

1.2、实现类的方法上没有 就从接口的方法上找

1.3、还没有 就再从实现类上找事务注解 如果还没有就从接口类上找事务注解

public TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass) {//拿到事务属性
    if (method.getDeclaringClass() == Object.class) {//是否是Object对象 必须是
        return null;
    }

    // First, see if we have a cached value.
    Object cacheKey = getCacheKey(method, targetClass);
    TransactionAttribute cached = this.attributeCache.get(cacheKey);
    if (cached != null) {
        // Value will either be canonical value indicating there is no transaction attribute,
        // or an actual transaction attribute.
        if (cached == NULL_TRANSACTION_ATTRIBUTE) {
            return null;
        }
        else {
            return cached;
        }
    }
    else {//缓存为空
        // We need to work it out.
        TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass);//拿到transaction注解属性
        // Put it in the cache.
        if (txAttr == null) {
            this.attributeCache.put(cacheKey, NULL_TRANSACTION_ATTRIBUTE);//放入缓存
        }
        else {
            String methodIdentification = ClassUtils.getQualifiedMethodName(method, targetClass);
            if (txAttr instanceof DefaultTransactionAttribute) {
                ((DefaultTransactionAttribute) txAttr).setDescriptor(methodIdentification);
            }
            if (logger.isTraceEnabled()) {
                logger.trace("Adding transactional method '" + methodIdentification + "' with attribute: " + txAttr);
            }
            this.attributeCache.put(cacheKey, txAttr);
        }
        return txAttr;
    }
}

protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
    // Don't allow no-public methods as required.  判断我们的事务方法上的修饰符是不是public的
    if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
        return null;
    }

    // The method may be on an interface, but we need attributes from the target class.
    // If the target class is null, the method will be unchanged. 获取最合适的方法  method可能是接口方法  specificMethod就是实现类的方法
    Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);

    // First try is the method in the target class. 第一步,我们先去目标class的方法上去找我们的事务注解  先去方法上找
    TransactionAttribute txAttr = findTransactionAttribute(specificMethod);//通过parser解析器找到相关事务注解 解析注解对应的属性信息
    if (txAttr != null) {
        return txAttr;
    }

    // Second try is the transaction attribute on the target class. //第二步:去我们targetClass类的实现类上找事务注解 方法上没有声明 就去类上找
    //如果实现类上没有 则会去接口类上找
    txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());
    if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
        return txAttr;
    }

    if (specificMethod != method) {
        // Fallback is to look at the original method.
        txAttr = findTransactionAttribute(method);
        if (txAttr != null) {
            return txAttr;
        }
        // Last fallback is the class of the original method.
        txAttr = findTransactionAttribute(method.getDeclaringClass());
        if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
            return txAttr;
        }
    }

    return null;
}

如何将他们串联起来

  1. 我们的InfrastructureAdvisorAutoProxyCreator继承了AbstractAutoProxyCreator 在spring 实例化bean的时候会调用其postProcessAfterInitialization方法

  1. 在找到合法的advisor方法findEligibleAdvisors

2.1、找到事务注入的advisor:BeanFactoryTransactionAttributeSourceAdvisor

2.2、事务注入的beanPostProcessor:InfrastructureAdvisorAutoProxyCreator会校验其合法性

2.3、事务注入的pointcut:TransactionAttributeSourcePointcut提前过滤合格的advisor

这样合格的 advisor就给我们找到了

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary
    org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean
        org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findEligibleAdvisors
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
    //1、findCandidateAdvisors方法在before方法中执行过并缓存起来 aspectj的advisor即InstantiationModelAwarePointcutAdvisorImpl  spring事务的即BeanFactoryTransactionAttributeSourceAdvisor
    List<Advisor> candidateAdvisors = findCandidateAdvisors();//找到候选的advisor 也就是用户自定义的advisor 并create这个bean
    //2、通过pointcut去判断这个advisor是否匹配
    List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);//判断是否匹配
    extendAdvisors(eligibleAdvisors);//扩展的advisor
    if (!eligibleAdvisors.isEmpty()) {
        //3、对advisor进行排序
        eligibleAdvisors = sortAdvisors(eligibleAdvisors);//对advisor进行排序
    }
    return eligibleAdvisors;
}

public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
    if (candidateAdvisors.isEmpty()) {
        return candidateAdvisors;
    }
    List<Advisor> eligibleAdvisors = new ArrayList<>();
    for (Advisor candidate : candidateAdvisors) {
        if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {//IntroductionAdvisor的advisor
            eligibleAdvisors.add(candidate);
        }
    }
    boolean hasIntroductions = !eligibleAdvisors.isEmpty();
    for (Advisor candidate : candidateAdvisors) {
        if (candidate instanceof IntroductionAdvisor) {//引入的advisor
            // already processed 已经处理过了
            continue;
        }
        if (canApply(candidate, clazz, hasIntroductions)) {//是否可以匹配  以事务为例 就判断类或者方法上是否有@Transactional注解 合格的就加进来
            eligibleAdvisors.add(candidate);//合格的就加进来
        }
    }
    return eligibleAdvisors;
}

public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
    if (advisor instanceof IntroductionAdvisor) {//引入类型的advisor
        return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
    }
    else if (advisor instanceof PointcutAdvisor) {//aop的advisor cglib对应的advisor
        PointcutAdvisor pca = (PointcutAdvisor) advisor;
        return canApply(pca.getPointcut(), targetClass, hasIntroductions);//是否匹配  通过match去匹配 //事务的AnnotationTransactionAttributeSource 重写了 match方法
    }
    else {
        // It doesn't have a pointcut so we assume it applies.
        return true;
    }
}

public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
    Assert.notNull(pc, "Pointcut must not be null");
    // 1、进行类级别过滤 就是通过pointcut解析类是否符合规范 事务的pointcut重写了该方法
    if (!pc.getClassFilter().matches(targetClass)) {
        return false;
    }
    // 2、拿到方法的matcher
    MethodMatcher methodMatcher = pc.getMethodMatcher();//TransactionAttributeSourcePointcut
    if (methodMatcher == MethodMatcher.TRUE) {
        // No need to iterate the methods if we're matching any method anyway...
        return true;
    }

    IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
    if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
        introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
    }

    Set<Class<?>> classes = new LinkedHashSet<>();
    if (!Proxy.isProxyClass(targetClass)) {
        classes.add(ClassUtils.getUserClass(targetClass));
    }
    classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));

    for (Class<?> clazz : classes) {
        Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);//找到所有方法
        for (Method method : methods) {
            //3、进行方法级别过滤
            if (introductionAwareMethodMatcher != null ?
                    introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
                    methodMatcher.matches(method, targetClass)) {//进行方法级别过滤  事务的pointcut重写了该方法
                return true;
            }
        }
    }

    return false;
}

protected List<Advisor> findCandidateAdvisors() {//该方法会被aspectj重写
    Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
    return this.advisorRetrievalHelper.findAdvisorBeans();//找到advisor的bean
}
//找到advisor 然后创建创建bean
public List<Advisor> findAdvisorBeans() {
    // Determine list of advisor bean names, if not cached already.
    String[] advisorNames = this.cachedAdvisorBeanNames;
    if (advisorNames == null) {
        // Do not initialize FactoryBeans here: We need to leave all regular beans
        // uninitialized to let the auto-proxy creator apply to them! 能拿到事务的advisor BeanFactoryTransactionAttributeSourceAdvisor
        advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                this.beanFactory, Advisor.class, true, false);
        this.cachedAdvisorBeanNames = advisorNames;
    }
    if (advisorNames.length == 0) {
        return new ArrayList<>();
    }
    //ioc容器中找到了我们配置的BeanFactoryTransactionAttributeSourceAdvisor
    List<Advisor> advisors = new ArrayList<>();
    for (String name : advisorNames) {
        if (isEligibleBean(name)) {//事务的bpp:InfrastructureAdvisorAutoProxyCreator重写了相关方法 
            if (this.beanFactory.isCurrentlyInCreation(name)) {//是不是正在创建中的bean
                if (logger.isTraceEnabled()) {
                    logger.trace("Skipping currently created advisor '" + name + "'");
                }
            }
            else {//不是
                try {
                    advisors.add(this.beanFactory.getBean(name, Advisor.class));//getBean 创建bean 添加到advisors中
                }
                catch (BeanCreationException ex) {
                    Throwable rootCause = ex.getMostSpecificCause();
                    if (rootCause instanceof BeanCurrentlyInCreationException) {
                        BeanCreationException bce = (BeanCreationException) rootCause;
                        String bceBeanName = bce.getBeanName();
                        if (bceBeanName != null && this.beanFactory.isCurrentlyInCreation(bceBeanName)) {
                            if (logger.isTraceEnabled()) {
                                logger.trace("Skipping advisor '" + name +
                                        "' with dependency on currently created bean: " + ex.getMessage());
                            }
                            // Ignore: indicates a reference back to the bean we're trying to advise.
                            // We want to find advisors other than the currently created bean itself.
                            continue;
                        }
                    }
                    throw ex;
                }
            }
        }
    }
    return advisors;
}

  1. 再看事务的增强逻辑:TransactionInterceptor

伪代码如下 当然spring实现的比这个更复杂

//1、拿到数据库链接
 Connection conn = getConnection 
try{
    //2、开启事务
    conn.setAutoCommit(false);
    //3、执行业务逻辑
    method.invoke();  
}catch{
    //4、异常回滚事务
    conn.rollBack();
}
//5、正常情况提交事务
conn.commit();

分析其源码:

org.springframework.transaction.interceptor.TransactionInterceptor#invoke

public Object invoke(MethodInvocation invocation) throws Throwable {
    // Work out the target class: may be {@code null}.
    // The TransactionAttributeSource should be passed the target class
    // as well as the method, which may be from an interface.
    Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);

    // Adapt to TransactionAspectSupport's invokeWithinTransaction...
    return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);//事务增强逻辑
}

//以非回调事务为例
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
            final InvocationCallback invocation) throws Throwable {

    // If the transaction attribute is null, the method is non-transactional.
    TransactionAttributeSource tas = getTransactionAttributeSource();//拿到AnnotationTransactionAttributeSource 也就是事务注解配置的相关属性源
    final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);//拿到事务属性 RuleBasedTransactionAttribute
    final TransactionManager tm = determineTransactionManager(txAttr);//找到事务管理器 创建事务用

    if (this.reactiveAdapterRegistry != null && tm instanceof ReactiveTransactionManager) {//响应式事务管理器
        ...代码省略...
    }

    PlatformTransactionManager ptm = asPlatformTransactionManager(tm);//强制类型转换为平台事务管理器
    final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);//从txAttr的discriptor中拿到方法名

    if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {//非回调事务管理器
        // Standard transaction demarcation with getTransaction and commit/rollback calls. 
        // 1、根据事务的传播级别看情况创建事务 开启事务
        TransactionInfo txInfo = createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);

        Object retVal;
        try {
            // This is an around advice: Invoke the next interceptor in the chain.
            // This will normally result in a target object being invoked.
            retVal = invocation.proceedWithInvocation();//反射执行目标方法
        }
        catch (Throwable ex) {
            // target invocation exception 
            // 2、异常情况回滚事务
            completeTransactionAfterThrowing(txInfo, ex);
            throw ex;
        }
        finally {
            //清理一些线程变量
            cleanupTransactionInfo(txInfo);
        }

        if (retVal != null && vavrPresent && VavrDelegate.isVavrTry(retVal)) {
            // Set rollback-only in case of Vavr failure matching our rollback rules...
            TransactionStatus status = txInfo.getTransactionStatus();
            if (status != null && txAttr != null) {
                retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
            }
        }
        //3、正常情况提交事务
        commitTransactionAfterReturning(txInfo);
        return retVal;
    }

    else {//回调事务管理器
        ...省略代码...
    }
}

关键代码:

  1. createTransactionIfNecessary:根据事务的传播级别看情况创建事务

  1. completeTransactionAfterThrowing 异常情况下回滚事务

  1. commitTransactionAfterReturning 正常情况下提交事务

挨个分析:

org.springframework.transaction.interceptor.TransactionAspectSupport#createTransactionIfNecessary

protected TransactionInfo createTransactionIfNecessary(@Nullable PlatformTransactionManager tm,
            @Nullable TransactionAttribute txAttr, final String joinpointIdentification) {

    // If no name specified, apply method identification as transaction name.
    if (txAttr != null && txAttr.getName() == null) {//创建代理事务属性
        txAttr = new DelegatingTransactionAttribute(txAttr) {
            @Override
            public String getName() {
                return joinpointIdentification;
            }
        };
    }

    TransactionStatus status = null;
    if (txAttr != null) {
        if (tm != null) {
            //1、拿到事务
            status = tm.getTransaction(txAttr);//拿到事务
        }
        else {
            if (logger.isDebugEnabled()) {
                logger.debug("Skipping transactional joinpoint [" + joinpointIdentification +
                        "] because no transaction manager has been configured");
            }
        }
    }
    //2、准备事务信息
    return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);//准备事务
}

org.springframework.transaction.support.AbstractPlatformTransactionManager#getTransaction
public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition)
            throws TransactionException {

    // Use defaults if no transaction definition given.
    TransactionDefinition def = (definition != null ? definition : TransactionDefinition.withDefaults());
    //1、获取事务 如果该线程之前已经开启过事务则事务信息保存于线程变量中 能判断出来线程之前是否有开启过事务
    Object transaction = doGetTransaction();//获取事务  重要属性connectionHolder保存该线程的连接 用来判断是否开启过事务
    boolean debugEnabled = logger.isDebugEnabled();
    //2、是否存在事务 通过ConnectionHolder 也就是线程变量中存储的事务信息
    if (isExistingTransaction(transaction)) {//是否存在事务 connectionHolder不为空
        // Existing transaction found -> check propagation behavior to find out how to behave.
        //3、处理已经存在的事务
        return handleExistingTransaction(def, transaction, debugEnabled);//存在事务了 处理已经存在的事务
    }
    //4、处理新开启的事务
    // Check definition settings for new transaction.
    if (def.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {//判断事务是否超时
        throw new InvalidTimeoutException("Invalid transaction timeout", def.getTimeout());
    }

    /**
     * 不同事务的传播级别 的不同处理方式
     * 1、MANDATORY- 外部不存在事务 抛出异常
     * 2、REQUIRED、REQUIRES_NEW、NESTED  外层即开启新事务
     */
    //5、不同事务传播级别下分别处理
    // No existing transaction found -> check propagation behavior to find out how to proceed.
    if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
        throw new IllegalTransactionStateException(
                "No existing transaction found for transaction marked with propagation 'mandatory'");
    }
    else if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
            def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
            def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
        SuspendedResourcesHolder suspendedResources = suspend(null);//挂起一个为null的事务
        if (debugEnabled) {
            logger.debug("Creating new transaction with name [" + def.getName() + "]: " + def);
        }
        try {
            //6、开启新事务
            return startTransaction(def, transaction, debugEnabled, suspendedResources);//开启事务
        }
        catch (RuntimeException | Error ex) {
            resume(null, suspendedResources);
            throw ex;
        }
    }
    //7、不开启事务的情况
    else {
        // Create "empty" transaction: no actual transaction, but potentially synchronization.
        if (def.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()) {
            logger.warn("Custom isolation level specified but no actual transaction initiated; " +
                    "isolation level will effectively be ignored: " + def);
        }
        boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
        return prepareTransactionStatus(def, null, true, newSynchronization, debugEnabled, null);
    }
}

protected Object doGetTransaction() {//数据源事务管理器创建
    DataSourceTransactionObject txObject = new DataSourceTransactionObject();//创建事务
    txObject.setSavepointAllowed(isNestedTransactionAllowed());
    ConnectionHolder conHolder =
            (ConnectionHolder) TransactionSynchronizationManager.getResource(obtainDataSource());//从事务同步管理器中 通过key-datasource数据源 来获取  第一次进来肯定没有  存在threadlocal修饰的全局变量resources中
    txObject.setConnectionHolder(conHolder, false);//设置connectionHolder 重要属性保存 外层设置的newConnectionHolder永远为false
    return txObject;
}

private TransactionStatus handleExistingTransaction(//处理已经存在的事务
            TransactionDefinition definition, Object transaction, boolean debugEnabled)
            throws TransactionException {
    //1、PROPAGATION_NEVER传播级别 内层事务会抛出异常
    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {//never级别 抛出异常
        throw new IllegalTransactionStateException(
                "Existing transaction found for transaction marked with propagation 'never'");
    }
    //2、NOT_SUPPORTED级别 挂起外层事务 不开启新事务
    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {//NOT_SUPPORTED级别
        if (debugEnabled) {
            logger.debug("Suspending current transaction");
        }
        Object suspendedResources = suspend(transaction);//挂起 清空transaction中的connectionHolder和 线程变量resource中暂存变量
        boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);//true 新同步器
        return prepareTransactionStatus(//事务清空 newTransaction为false
                definition, null, false, newSynchronization, debugEnabled, suspendedResources);
    }
    //3、PROPAGATION_REQUIRES_NEW级别 挂起外层事务  开启新事务
    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {
        if (debugEnabled) {
            logger.debug("Suspending current transaction, creating new transaction with name [" +
                    definition.getName() + "]");
        }
        SuspendedResourcesHolder suspendedResources = suspend(transaction);//挂起事务
        try {
            //开启新事务
            return startTransaction(definition, transaction, debugEnabled, suspendedResources);
        }
        catch (RuntimeException | Error beginEx) {
            resumeAfterBeginException(transaction, suspendedResources, beginEx);
            throw beginEx;
        }
    }
    //4、PROPAGATION_NESTED
    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
        if (!isNestedTransactionAllowed()) {
            throw new NestedTransactionNotSupportedException(
                    "Transaction manager does not allow nested transactions by default - " +
                    "specify 'nestedTransactionAllowed' property with value 'true'");
        }
        if (debugEnabled) {
            logger.debug("Creating nested transaction with name [" + definition.getName() + "]");
        }
        //4.1、如果使用了回滚点默认为true 使用外部事务 创建回滚点
        if (useSavepointForNestedTransaction()) {
            // Create savepoint within existing Spring-managed transaction,
            // through the SavepointManager API implemented by TransactionStatus.
            // Usually uses JDBC 3.0 savepoints. Never activates Spring synchronization.
            DefaultTransactionStatus status =
                    prepareTransactionStatus(definition, transaction, false, false, debugEnabled, null);
            status.createAndHoldSavepoint();
            return status;
        }
        //4.2、否则开启新事务 外部事务使用内部事务
        else {
            // Nested transaction through nested begin and commit/rollback calls.
            // Usually only for JTA: Spring synchronization might get activated here
            // in case of a pre-existing JTA transaction.
            return startTransaction(definition, transaction, debugEnabled, null);
        }
    }

    // Assumably PROPAGATION_SUPPORTS or PROPAGATION_REQUIRED.
    if (debugEnabled) {
        logger.debug("Participating in existing transaction");
    }
    if (isValidateExistingTransaction()) {//默认false
        if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) {
            Integer currentIsolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();
            if (currentIsolationLevel == null || currentIsolationLevel != definition.getIsolationLevel()) {
                Constants isoConstants = DefaultTransactionDefinition.constants;
                throw new IllegalTransactionStateException("Participating transaction with definition [" +
                        definition + "] specifies isolation level which is incompatible with existing transaction: " +
                        (currentIsolationLevel != null ?
                                isoConstants.toCode(currentIsolationLevel, DefaultTransactionDefinition.PREFIX_ISOLATION) :
                                "(unknown)"));
            }
        }
        if (!definition.isReadOnly()) {
            if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
                throw new IllegalTransactionStateException("Participating transaction with definition [" +
                        definition + "] is not marked as read-only but existing transaction is");
            }
        }
    }
    //5、其他情况融合到外部事务
    boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
    return prepareTransactionStatus(definition, transaction, false, newSynchronization, debugEnabled, null);
}

回滚事务:

protected void completeTransactionAfterThrowing(@Nullable TransactionInfo txInfo, Throwable ex) {
    if (txInfo != null && txInfo.getTransactionStatus() != null) {
        if (logger.isTraceEnabled()) {
            logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() +
                    "] after exception: " + ex);
        }
        //1、rollbackOn 根据异常类型判断是否要回滚事务
        if (txInfo.transactionAttribute != null && txInfo.transactionAttribute.rollbackOn(ex)) {
            try {
                //2、符合异常类型的回滚事务
                txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());
            }
            catch (TransactionSystemException ex2) {
                logger.error("Application exception overridden by rollback exception", ex);
                ex2.initApplicationException(ex);
                throw ex2;
            }
            catch (RuntimeException | Error ex2) {
                logger.error("Application exception overridden by rollback exception", ex);
                throw ex2;
            }
        }
        //3、不符合异常类型的 提交事务
        else {
            // We don't roll back on this exception.
            // Will still roll back if TransactionStatus.isRollbackOnly() is true.
            try {
                txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
            }
            catch (TransactionSystemException ex2) {
                logger.error("Application exception overridden by commit exception", ex);
                ex2.initApplicationException(ex);
                throw ex2;
            }
            catch (RuntimeException | Error ex2) {
                logger.error("Application exception overridden by commit exception", ex);
                throw ex2;
            }
        }
    }
}

public boolean rollbackOn(Throwable ex) {
    if (logger.isTraceEnabled()) {
        logger.trace("Applying rules to determine whether transaction should rollback on " + ex);
    }

    RollbackRuleAttribute winner = null;
    int deepest = Integer.MAX_VALUE;

    if (this.rollbackRules != null) {
        //遍历rollback类型
        for (RollbackRuleAttribute rule : this.rollbackRules) {
            //看异常名是否匹配 不匹配就往异常父类找 依次往上找 最大深度Integer.MAX_VALUE
            int depth = rule.getDepth(ex);
            if (depth >= 0 && depth < deepest) {
                deepest = depth;
                winner = rule;
            }
        }
    }

    if (logger.isTraceEnabled()) {
        logger.trace("Winning rollback rule is: " + winner);
    }

    // User superclass behavior (rollback on unchecked) if no rule matches.
    if (winner == null) {
        logger.trace("No relevant rollback rule found: applying default rules");
        return super.rollbackOn(ex);
    }

    return !(winner instanceof NoRollbackRuleAttribute);
}

提交事务:

protected void commitTransactionAfterReturning(@Nullable TransactionInfo txInfo) {
    if (txInfo != null && txInfo.getTransactionStatus() != null) {
        if (logger.isTraceEnabled()) {
            logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() + "]");
        }
        //提交事务
        txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
    }
}

事务传播级别详述:

事务传播行为类型

外部不存在事务

外部存在事务

使用方式

REQUIRED(默认)

开启新的事务

融合到外部事务中

@Transactional(propagation = Propagation.REQUIRED)

适用增删改查

SUPPORTS

不开启新的事务

融合到外部事务中

@Transactional(propagation = Propagation.SUPPORTS)

适用查询

REQUIRES_NEW

开启新的事务

不用外部事务,创建新的事务

@Transactional(propagation = Propagation.REQUIRES_NEW)

适用内部事务和外部事务不存在业务关联情况,如日志

NOT_SUPPORTED

不开启新的事务

不用外部事务

@Transactional(propagation = Propagation.NOT_SUPPORTED)

不常用

NEVER

不开启新的事务

抛出异常

@Transactional(propagation = Propagation.NEVER )

不常用

MANDATORY

抛出异常

融合到外部事务中

@Transactional(propagation = Propagation.MANDATORY)

不常用

NESTED

开启新的事务

融合到外部事务中,SavePoint机制

@Transactional(propagation = Propagation.NESTED)

不常用

关于几个隔离级别的特殊情况

场景1、

外层开启事务(REQUIRED)

内层事务是REQUIRES_NEW 会挂起外层事务 开启内层新事务

1.1、如果内层报错 不try catch内层 内层事务回滚 外层事务回滚

1.2、如果内层报错 且 try catch内层 内层事务回滚 外层事务提交

1.3、如果内层不报错 外层报错 内层事务提交 外层事务回滚

public class TransServiceImpl implements ITransService{
    @Autowired
    JdbcTemplate jdbcTemplate;
    @Autowired
    ITransService transServiceImpl1;
    @Transactional(rollbackFor=Exception.class,propagation = Propagation.REQUIRED)
    @Override
    public void insert() {
        jdbcTemplate.execute("insert into test(column1) values('aaaa')");
        transServiceImpl1.insert();
        int i =5/0;//异常 sql回滚
    }
}

@Service
public class TransServiceImpl1 implements ITransService{
    @Autowired
    JdbcTemplate jdbcTemplate;
    @Override
    @Transactional(rollbackFor=Exception.class,propagation = Propagation.REQUIRES_NEW)
    public void insert() {
        jdbcTemplate.execute("insert into test(column1) values('bbbb')");
//        int i =5/0;//异常 sql回滚
    }
}

场景2、

外层开启事务(REQUIRED)

内层事务是NESTED 融合外部事务

1、内层报错且没有try catch 内层回滚 外层回滚

2、内层报错且try catch 内层回滚 外层提交

3、内层不报错 外层报错 内层回滚 外层回滚

@Service
public class TransServiceImpl implements ITransService{
    @Autowired
    JdbcTemplate jdbcTemplate;
    @Autowired
    ITransService transServiceImpl1;

    @Transactional(rollbackFor=Exception.class,propagation = Propagation.REQUIRED)
    @Override
    public void insert1() {
        jdbcTemplate.execute("insert into test(column1) values('aaaa')");
        transServiceImpl1.insert1();
        int i =5/0;//异常 sql回滚
    }
}

@Service
public class TransServiceImpl1 implements ITransService{
    @Autowired
    JdbcTemplate jdbcTemplate;

    @Override
    @Transactional(rollbackFor=Exception.class,propagation = Propagation.NESTED)
    public void insert1() {
        jdbcTemplate.execute("insert into test(column1) values('bbbb')");
//        int i =5/0;//异常 sql回滚
    }
}

场景3、

外层开启事务(REQUIRED)

内层事务是REQUIRED 融合外部事务

1、内层报错且没有try catch 内层回滚 外层回滚

2、内层报错且try catch 内层回滚 外层回滚并报错:

3、内层不报错 外层报错 内层回滚 外层回滚

@Service
public class TransServiceImpl implements ITransService{
    @Autowired
    JdbcTemplate jdbcTemplate;
    @Autowired
    ITransService transServiceImpl1;

    @Transactional(rollbackFor=Exception.class,propagation = Propagation.REQUIRED)
    @Override
    public void insert2() {
        jdbcTemplate.execute("insert into test(column1) values('aaaa')");
        try {
            transServiceImpl1.insert2();
        } catch (Exception e) {
        }
//        int i =5/0;//异常 sql回滚
    }
}

@Service
public class TransServiceImpl1 implements ITransService{
    @Autowired
    JdbcTemplate jdbcTemplate;

    @Override
    @Transactional(rollbackFor=Exception.class,propagation = Propagation.REQUIRED)
    public void insert2() {
        jdbcTemplate.execute("insert into test(column1) values('bbbb')");
        int i =5/0;//异常 sql回滚
    }
}

事务的源码很复杂 本文仅分析了主干信息 并未分析细枝末节信息 但这些信息有些也很重要。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值