互联网架构-Spring5.0源码深度解析:SpringBean声明事务底层实现原理
025:SpringBean声明事务底层实现原理
1 Spring声明事务底层源码分析预览
课程内容:
1、回顾SpringAop底层调用链关系
2、构建Spring整合JDBC环境模式事务操作
3、@Transactional事务注解底层源码
4、@EnableTransactionManagement源码分析
1.事务保证数据一致性 一般在Service层方法上加上@Transactional(调用Dao层)
2.环绕通知+手动事务可以实现声明事务
2 SpringAop切面编程底层原理回顾
SpringAop中所有的通知最终是如何执行的?
调用链关系,采用递归+责任链设计模式实现。
AbstractAutoProxyCreator 使用该类创建目标对象代理类
MethodInterceptor子类下有很多自定义通知(前置、后置、环绕、异常等),还有一个子类TransactionInterceptor 事务拦截
SpringAop底层原理分析
- 首先启动SpringAop时,会使用@EnableAspectJAutoProxy注解
- 将@Import(AspectJAutoProxyRegistrar.class)注入SpringIOC容器中
- AspectJAutoProxyRegistrar中会注册对象
BeanId:org.springframework.aop.config.internalAutoProxyCreator
BeanClass :AnnotationAwareAspectJAutoProxyCreator - AnnotationAwareAspectJAutoProxyCreator最为核心:使用后置通知在bean的对象初始化的时候,实现对代理对象的增强。
AnnotationAwareAspectJAutoProxyCreator祖宗:AbstractAutoProxyCreator 祖宗:BeanPostProcessor - 被代理对象在初始化的时候,AbstractAutoProxyCreator 经过这样的一个类拦截。判断该被代理对象是否有被有实现过接口,如果有实现过接口就使用jdk动态代理,如果没有实现接口则使用cglib动态代理。
- 当我们调用目标方法的时候,会执行JdkDynamicAopProxy的invoke方法,再使用递归算法循环遍历执行MethodInterceptor(每个通知)的invoke方法。
3 基于Spring注解方式构建整合JDBC环境01
Maven依赖
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<!-- mysql 依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.46</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
</dependencies>
配置类
@Configuration
@ComponentScan("com.mayikt")
public class MyConfig {
// 注入到IOC容器中 beanid=dataSource,class=DataSource类的完整路径地址
// 配置数据源
@Bean
public DataSource dataSource(){
MysqlDataSource mysqlDataSource = new MysqlDataSource();
mysqlDataSource.setUser("root");
mysqlDataSource.setPassword("root");
mysqlDataSource.setURL("jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8&useSSL=false");
mysqlDataSource.setDatabaseName("test");
return mysqlDataSource;
}
// 注入jdbcTemplate
@Bean
public JdbcTemplate jdbcTemplate(){
return new JdbcTemplate(dataSource());
}
}
Service层
public interface OrderService {
public void addOrder();
}
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private OrderDao orderDao;
@Override
@Transactional
public void addOrder() {
orderDao.addOrder();
int i = 1 / 0;
}
}
Dao层
@Repository
public class OrderDao {
@Autowired
private JdbcTemplate jdbcTemplate;
public void addOrder() {
jdbcTemplate.update("insert into order_info values(null,'mayikt','zhangsan','1111')");
}
}
测试类
public class JdbcTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
OrderService orderService = annotationConfigApplicationContext.getBean("orderServiceImpl", OrderService.class);
orderService.addOrder();
}
}
4 基于Spring注解方式构建整合JDBC环境04
关闭事务运行结果:
开启事务运行结果:
使用事务之后,为什么有把Aop开启呢?
事务本身就是基于AOP实现的。
5 Spring声明事务底层源码分析01
Spring事务底层源码分析
- @EnableTransactionManagement 开启事务
- @Import(TransactionManagementConfigurationSelector.class)
- 默认使用PROXY:选择器new String[] {AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()}
- AutoProxyRegistrar会将InfrastructureAdvisorAutoProxyCreator注册到ioc容器中
Beanid: internalAutoProxyCreator
Value: InfrastructureAdvisorAutoProxyCreator - ProxyTransactionManagementConfiguration 将tansactionInterceptor对象注册到ioc容器
Beanid: TransactionInterceptor
Value: tansactionInterceptor
6 Spring声明事务底层源码分析02
重点分析:InfrastructureAdvisorAutoProxyCreator、tansactionInterceptor
6. 由类关系图可知,InfrastructureAdvisorAutoProxyCreator类祖宗是后置处理器,Bean对象在初始化之后都会判断是否需要创建代理类(根据是否有加上@Transactional)
7. 当调用目标方法的时候,进入代理类的invoke方法,执行到TransactionInterceptor中的invoke方法,里面封装手动事务相关处理逻辑。
7 Spring声明事务失效之谜原因
Spring的事务为什么会失效?
如果service 没有将异常抛出的时候,事务可能会失效,底层invokeWithinTransaction方法中没有捕获到异常进行回滚事务操作。
本文地址:https://blog.csdn.net/u012425860/article/details/110943619