细节知多少 - spring boot transaction解析之阶段一 带有@Transactional方法的service类生成代理类的阶段

本文深入探讨了Spring Boot Transaction的第一阶段,即带有@Transactional注解的服务类如何生成代理类。通过分析源码,揭示了在AOP机制下,如何判断是否需要生成事务代理类,并详细介绍了生成代理类的条件和过程。文章还提到了关键组件如BeanFactoryTransactionAttributeSourceAdvisor的作用,以及代理类的创建与方法匹配逻辑。
摘要由CSDN通过智能技术生成

细节知多少 - spring boot transaction解析之阶段一 带有@Transactional方法的service类生成代理类的阶段

date: 2019-06-04

原文:spring boot transaction解析之阶段一 带有@Transactional方法的service类生成代理类的阶段

概述

spring boot transaction我们平时用着非常简单,只需要在service方法上声明@Transactional就可以了。但是要知道,简单的背后是不简单,只是很多东西spring框架帮我们做好了。如果想进阶,想进步,想弄懂,想学习,需要接近它,了解它,弄懂它,最好的方法莫过于debug它的源码了。

笔者把spring boot transaction的整个过程分为两个阶段

  1. 带有@Transactional方法的service类生成代理类的阶段
  2. 访问service类的@Transactional方法实现事务的阶段

本文说下第一阶段,用过spring的人差不多都是知道,spring 事务的实现是通过aop的方式。所以本系列的前提是基于注解的aop实现解析你要知道些,这部分请参考:spring boot aop过程解析之阶段一 AnnotationAwareAspectJAutoProxyCreator加载和初始化, AnnotationAwareAspectJAutoProxyCreator是aop动态代理的起始点和入口处,所有的beanClass经过通过他的实例化前置方法和所有的bean Object经过他的初始化后置方法时都会判断是否生成代理类。笔者假定你了解了这部分。

本文用到的代码项目:springboot_mybatis

技术栈

spring boot 1.5.10
spring framework 4.3.14

用例代码

@RestController
@Slf4j
@RequestMapping("/user")
public class UserController {

	@Resource
	private IUserService userService;

	/**
	 * @param schoolName
	 * @param studentId
	 * @return
	 */
    @GetMapping("/updateSchoolName")
    public ResponseResult updateSchoolName(String schoolName, long studentId) {
        log.info("updateSchoolName param schoolName:{} studentId:{}", schoolName, studentId);
        userService.updateSchoolName(schoolName, studentId);
        return ResponseResult.ok();
    }
}

public interface IUserService {
	int insert(User user);
    int updateScore(long score, long id);
    void updateSchoolName(String schoolName, long studentId);
}

@Service
public class UserServiceImpl implements IUserService {
	@Resource
	private UserMapper userMapper;
    @Resource
    private StudentMapper studentMapper;

	@Override
    @Transactional(rollbackFor = Throwable.class)
	public int insert(User user) {
        int count = userMapper.insert(user);
		return count;
	}

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public int updateScore(long score, long id) {
        int count = userMapper.updateScore(iii, id);
        return count;
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public void updateSchoolName(String schoolName, long studentId) {
        User user = userMapper.fingByStudentId(studentId);
        studentMapper.updateSchoolName(schoolName, user.getStudentId());
    }
}

public interface StudentMapper {
    Student findById(@Param("id") long id);
	int updateSchoolName(@Param("schoolName") String schoolName, @Param("id") long id);
}

public interface UserMapper {
	int insert(User user);
	int updateScore(@Param("score") long score, @Param("id") long id);
}

以上代码模拟了实际开发中mvc层级调用关系,事务在service层。我们以此代码为例阐述spring事务相关知识点

带着问题学习

带着问题学习往往起到更好的效果

问题:

1. service类只要有方法加了@Transactional注解就会生成代理类吗,此处的方法有条件吗
2. spring boot 涉及transaction事务的xxxAutoConfiguration都有哪些
3. spring boot 默认生成代理的方式是cglib还是jdk
4. 什么样的方法可以生成代理方法

下面开始和笔者一起走入spring aop生成代理类的小溪,从本文开头处我们知道,生成代理类的入口是AnnotationAwareAspectJAutoProxyCreator(使用父类的方法)实例化前置方法和初始化后置方法(如果此处不太了解,请参考:spring boot aop过程解析之阶段一 AnnotationAwareAspectJAutoProxyCreator加载和初始化)。我们直接从此处展开

生成代理类条件判断

我们看下前后置方法的代码。同样,因为这里在spring boot aop过程解析之阶段一 AnnotationAwareAspectJAutoProxyCreator加载和初始化)已经阐述过。所以这里我们只关注和spring transaction有关的地方

public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
	······
	// shouldSkip方法是重点,判断是否应该为beanClass生成代理类
	if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) { // (1)
		this.advisedBeans.put(cacheKey, Boolean.FALSE);
		return null;
	}
	 

	// Create proxy here if we have a custom TargetSource
	if (beanName != null) {
		TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
		if (targetSource != null) {
			this.targetSourcedBeans.add(beanName);
			Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource); // (2)
			Object proxy = createProxy(beanClass, beanName, sp
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值