spring boot JAP事物分析

目的分析jap在开启事物后是如何运行的

我们的目的方法
@RestController
public class TestController {

    @Autowired
    UserNewService userNewService;


    @RequestMapping("/save/user")//--->①
    public String save() {
        UserNew userNew = new UserNew();
        userNew.setAge(12);
        userNew.setName("java");
        userNewService.saveUser(userNew);//--->②
        return "ok";
    }
}



@Service
public class UserNewServiceImpl implements UserNewService {

    @Autowired
    private UserNewRepository userNewRepository;

    //           tx          抛异常    保存情况
    //  save     REQUIRED      no          no
    //  save2    REQUIRES_NEW  yes         no

    //  save     REQUIRED      yes         no
    //  save2    REQUIRES_NEW  no          no


    @Transactional(
            value = "mysqlTransactionManager",
            rollbackFor = {Exception.class, RuntimeException.class},
            propagation = Propagation.REQUIRED,
            isolation = Isolation.DEFAULT
    )
    @Override
    public void saveUser(UserNew userNew) {
        //org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor.CrudMethodMetadataPopulatingMethodInterceptor.invoke()
        //ReflectiveMethodInvocation.proceed()
        //TransactionInterceptor.invoke()
        //org.springframework.transaction.interceptor.TransactionAspectSupport
        userNewRepository.save(userNew);//--->③

        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //UserNew user = new UserNew();
        //user.setName("22222");
        //user.setAge(222);
        //saveUser2(user);
        throw new RuntimeException("异常发生了");//--->④

    }

    @Transactional(
            value = "mysqlTransactionManager",
            rollbackFor = {Exception.class, RuntimeException.class},
            propagation = Propagation.REQUIRES_NEW,
            isolation = Isolation.DEFAULT
    )
    @Override
    public void saveUser2(UserNew user) {
        userNewRepository.save(user);
    }
}


逻辑分析

1: RequestMappingHandlerAdapter来处理requestmapping对应的请求
RequestMappingHandlerAdapter.invokeHandlerMethod() 
-->ServletInvocableHandlerMethod.invokeAndHandle()
-->InvocationHandlerMethod.invokeForRequest()
-->InvocableHandlerMethod.doInvoke()
执行TestController save 方法的业务代码 , 当执行到Userservice.save方法的时候
CglibAopProxy.intercept()
class ReflectiveMethodInvocation{
    @Override
    @Nullable
    public Object proceed() throws Throwable {
        //	We start with an index of -1 and increment early.
        if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
            return invokeJoinpoint();
        }

        Object interceptorOrInterceptionAdvice =
                this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
        if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
            // Evaluate dynamic method matcher here: static part will already have
            // been evaluated and found to match.
            InterceptorAndDynamicMethodMatcher dm =
                    (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
            if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
                return dm.interceptor.invoke(this);
            }
            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.
            //强转为interceptorOrInterceptionAdvice 调用invoke-->交个事物的拦截器处理 
            //就是交给了TransactionInterceptor, 该类在事物处理中扮演重要角色
            return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
        }
    }
}



class TransactionInterceptor{
  public Object invoke(final 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);
    }  
}

//TransactionAspectSupport是事物处理核心功能
class TransactionAspectSupport{
    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();
		//获取事物的注解属性包括quolifier, rollbackon 
		final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
		//根据quolifiter来判断使用哪个事物管理器
		final PlatformTransactionManager tm = determineTransactionManager(txAttr);
		//join point 连接点
		final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);

		if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
			// Standard transaction demarcation with getTransaction and commit/rollback calls.
			//创建TransactionInfo对象,将事物和当前的线程进行绑定
			TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
			Object retVal = null;
			try {
				// This is an around advice: Invoke the next interceptor in the chain.
				// This will normally result in a target object being invoked.
				//调用ReflectiveMethodInvocation的proceedWithInvocation方法
				retVal = invocation.proceedWithInvocation();
			}
			catch (Throwable ex) {
				// target invocation exception
				//如果有抛异常,进行rollback 
				completeTransactionAfterThrowing(txInfo, ex);
				throw ex;
			}
			finally {
				cleanupTransactionInfo(txInfo);
			}
			//提交事物
			commitTransactionAfterReturning(txInfo);
			return retVal;
		}

		else {
			...
		}
	}
}

TransactionInterceptor 分析

在ReflectiveMethodInvocation 里面, 在执行代码的业务代码的时候可能有很多的xxintercepter,  ReflectiveMethodInvocation根据类型
来判断使用哪个拦截器 , 那么TransactionInterceptor 是用来拦截事物业务代码的处理的拦截器

那么TransactionInterceptor是怎么定义的呢?

可以理解为ProxyTransactionManagementConfiguration定义了一个aop的切面    
@Configuration
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {

	@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
	    //声明一个advisor
		BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
		advisor.setTransactionAttributeSource(transactionAttributeSource());
		advisor.setAdvice(transactionInterceptor());
		if (this.enableTx != null) {
			advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
		}
		return advisor;
	}

	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public TransactionAttributeSource transactionAttributeSource() {
		return new AnnotationTransactionAttributeSource();
	}

	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public TransactionInterceptor transactionInterceptor() {
	    //声明一个TransactionInterceptor
		TransactionInterceptor interceptor = new TransactionInterceptor();
		//设置事物的属性源 : 定义拦截器拦截什么内容, 追踪代码
		interceptor.setTransactionAttributeSource(transactionAttributeSource());
		if (this.txManager != null) {
			interceptor.setTransactionManager(this.txManager);
		}
		return interceptor;
	}

}

class AnnotationTransactionAttributeSource{
    public AnnotationTransactionAttributeSource(boolean publicMethodsOnly) {
        this.publicMethodsOnly = publicMethodsOnly;
        this.annotationParsers = new LinkedHashSet<>(2);
        //SpringTransactionAnnotationParser 扫描@org.springframework.transaction.annotation.Transactional
        this.annotationParsers.add(new SpringTransactionAnnotationParser());
        if (jta12Present) {
            //JtaTransactionAnnotationParser 扫描:@javax.transaction.Transactional
            this.annotationParsers.add(new JtaTransactionAnnotationParser());
        }
        if (ejb3Present) {
            //ejb ignore
            this.annotationParsers.add(new Ejb3TransactionAnnotationParser());
        }
    }
}

总结

个人的见解
springboot 启动的时候通过自动配置类ProxyTransactionManagementConfiguration
创建了事物的拦截器来扫描系统项目里面的@Transactinal所有的注解的方法 作为事物的切入点
最终返回一个BeanFactoryTransactionAttributeSourceAdvisor 就是advisor 通知
执行业务代码的时候通过拦截器TransactionInterceptor 来处理事物的编制业务

这不就是AOP吗~~~ 

从TransactionAspectSupport的业务代码就可清楚的看到 当业务代码抛出异常的时候,然后进行回滚,如果没有异常,提交事物;

spring boot jap 的事物的实现就是一个基于注解的aop是实现的;