淺嘗Spring注解開發_宣告式事務及原理
淺嘗Spring注解開發,基于Spring 4.3.12
包含宣告式事務使用、基本原理分析
淺嘗Spring注解開發_自定義注冊組件、屬性賦值、自動裝配
淺嘗Spring注解開發_Bean生命周期及執行程序
淺嘗Spring注解開發_AOP原理及完整程序分析(原始碼)
淺嘗Spring注解開發_宣告式事務及原理
淺嘗Spring注解開發_簡單理解BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor、ApplicationListener
宣告式事務
環境搭建
-
添加依賴:資料源、資料庫驅動、Spring-jdbc模塊
-
業務類
UserDao
@Repository public class UserDao { @Autowired private JdbcTemplate jdbcTemplate; public void insert(){ String sql = "INSERT INTO `tbl_user`(username,age) VALUES(?,?)"; String username = UUID.randomUUID().toString().substring(0, 5); jdbcTemplate.update(sql, username,19); } }UserService
@Service public class UserService { @Autowired private UserDao userDao; public void insertUser(){ userDao.insert(); //otherDao.other();xxx System.out.println("插入完成..."); int i = 10/0; } } -
配置資料源、JdbcTemplate(Spring提供的簡化資料庫操作的工具)操作資料
@Configuration public class TxConfig { //資料源 @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; } //jdbcTemplate @Bean public JdbcTemplate jdbcTemplate() throws Exception{ //Spring對@Configuration類會特殊處理;給容器中加組件的方法,多次呼叫都只是從容器中找組件 JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource()); return jdbcTemplate; } }
開啟注解
-
給方法上標注 @Transactional 表示當前方法是一個事務方法
UserService
@Service public class UserService { @Autowired private UserDao userDao; @Transactional public void insertUser(){ userDao.insert(); //otherDao.other();xxx System.out.println("插入完成..."); int i = 10/0; } } -
@EnableTransactionManagement 開啟基于注解的事務管理功能
@EnableTransactionManagement @Configuration public class TxConfig { //... } -
配置事務管理器來控制事務
@EnableTransactionManagement @Configuration public class TxConfig { //資料源 @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; } //jdbcTemplate @Bean public JdbcTemplate jdbcTemplate() throws Exception{ //Spring對@Configuration類會特殊處理;給容器中加組件的方法,多次呼叫都只是從容器中找組件 JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource()); return jdbcTemplate; } //注冊事務管理器在容器中 @Bean public PlatformTransactionManager transactionManager() throws Exception{ return new DataSourceTransactionManager(dataSource()); } } -
測驗
- 出現例外時會回滾,不會插入資料庫
public class IOCTest_Tx { @Test public void test01(){ AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(TxConfig.class); UserService userService = applicationContext.getBean(UserService.class); userService.insertUser(); applicationContext.close(); } }
原理分析
與AOP相似,注冊,包裝,增強器,攔截器,執行目標方法
淺嘗Spring注解開發_AOP原理及完整程序分析(原始碼)
-
進入
@EnableTransactionManagement-
利用
TransactionManagementConfigurationSelector給容器中會匯入組件,判斷AdviceMode的值選擇匯入哪個組件-
如果是
PROXY匯入兩個組件(默認)AutoProxyRegistrar(自動代理注冊器)ProxyTransactionManagementConfiguration(代理事務管理配置)
-
如果是
ASPECTJ匯入TransactionManagementConfigUtils
-
-
-
分析
AutoProxyRegistrar- 用于給容器中注入Bean,呼叫
registerBeanDefinitions() - 呼叫
AopConfigUtils.registerAutoProxyCreatorIfNecessary()最終注冊InfrastructureAdvisorAutoProxyCreator(基礎架構自動代理創建者)組件,也是后置處理器型別,利用后置處理器機制在物件創建以后,包裝物件,回傳一個代理物件(增強器),代理物件執行方法利用攔截器鏈進行呼叫 - 這個類中同時注冊了一個
AnnotationAwareAspectJAutoProxyCreator(注解裝配模式的AspectJ切面自動代理創建器),這個就是在AOP一開始注冊的那個類,用于Bean實體化時的后置處理器
- 用于給容器中注入Bean,呼叫
-
分析
ProxyTransactionManagementConfiguration-
給容器中注冊事務增強器,如
BeanFactoryTransactionAttributeSourceAdvisor(BeanFactory事務屬性源增強器)-
事務增強器要用事務注解的資訊,
AnnotationTransactionAttributeSource決議事務注解 -
事務攔截器:
-
TransactionInterceptor(它是一個MethodInterceptor方法攔截器,和AOP中是相同的):保存了事務屬性資訊,事務管理器 -
在目標方法執行的時候執行攔截器鏈
-
事務攔截器
-
先獲取事務相關的屬性
-
再獲取
PlatformTransactionManager,如果事先沒有添加指定任何transactionmanger最侄訓從容器中按照型別獲取一個
PlatformTransactionManager -
執行目標方法
invokeWithinTransaction(){ invocation.proceedWithInvocation() }- 如果例外,獲取到事務管理器,利用事務管理回滾操作
txInfo.getTransactionManager().rollback() - 如果正常,利用事務管理器,提交事務
txInfo.getTransactionManager().commit()
- 如果例外,獲取到事務管理器,利用事務管理回滾操作
-
-
-
-
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/469678.html
標籤:其他
上一篇:C++實體2--職工管理系統
