关注微信公众号【行走在代码行的寻路人】获取Java相关资料,分享项目经验及知识干货。
以下测试的源码地址:https://github.com/877148107/Spring-Annotation
-
@EnableTransactionManagement开启基于注解的事务功能
@ComponentScan({"com.spring.annotation.dao","com.spring.annotation.service"})
@EnableTransactionManagement
@Configuration
public class MyTxConfig {
@Bean
public DataSource dataSource() throws Exception{
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser("root");
dataSource.setPassword("123456");
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");
return dataSource;
}
@Bean
public JdbcTemplate jdbcTemplate() throws Exception{
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource());
return jdbcTemplate;
}
@Bean
public PlatformTransactionManager platformTransactionManager() throws Exception{
return new DataSourceTransactionManager(dataSource());
}
}
-
@EnableTransactionManagement原理:
-
@EnableTransactionManagement利用TransactionManagementConfigurationSelector给容器中导入两个组件:
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import(TransactionManagementConfigurationSelector.class) public @interface EnableTransactionManagement { /** * Indicate whether subclass-based (CGLIB) proxies are to be created ({@code true}) as * opposed to standard Java interface-based proxies ({@code false}). The default is * {@code false}. <strong>Applicable only if {@link #mode()} is set to * {@link AdviceMode#PROXY}</strong>. * <p>Note that setting this attribute to {@code true} will affect <em>all</em> * Spring-managed beans requiring proxying, not just those marked with * {@code @Transactional}. For example, other beans marked with Spring's * {@code @Async} annotation will be upgraded to subclass proxying at the same * time. This approach has no negative impact in practice unless one is explicitly * expecting one type of proxy vs another, e.g. in tests. */ boolean proxyTargetClass() default false; /** * Indicate how transactional advice should be applied. The default is * {@link AdviceMode#PROXY}. * @see AdviceMode */ AdviceMode mode() default AdviceMode.PROXY; /** * Indicate the ordering of the execution of the transaction advisor * when multiple advices are applied at a specific joinpoint. * The default is {@link Ordered#LOWEST_PRECEDENCE}. */ int order() default Ordered.LOWEST_PRECEDENCE; }
-
AutoProxyRegistrar
-
ProxyTransactionManagementConfiguration
-
-
AutoProxyRegistrar作用:
-
给容器中注册一个InfrastructureAdvisorAutoProxyCreator组件
-
InfrastructureAdvisorAutoProxyCreator也是一个后置处理器,利用后置处理机制在对象创建完成后,返回一个代理对象,代理对象执行方法利用拦截器链进行调用
-
-
ProxyTransactionManagementConfiguration作用:
-
给容器中注册事务增强器
-
事务增强器要用事务注解的信息,AnnotationTransactionAttributeSource解析事务注解
-
事务拦截器transactionInterceptor(),TransactionInterceptor保存了事务属性的信息,还有事务管理器,实际上它是一个方法拦截器MethodInterceptor
-
transactionInterceptor()在目标方法执行的时候:实际上就是执行拦截器链
-
先获取事务相关的属性
-
再获取PlatformTransactionManager,如果事先没有添加,那么会从容器中按照类型获取
-
执行目标方法。如果异常,获取到事务管理器,利用事务管理回滚操作; 如果正常,利用事务管理器,提交事务