# SpringAOP **Repository Path**: dsjwangqing/spring-aop ## Basic Information - **Project Name**: SpringAOP - **Description**: SpringAOP_Test - **Primary Language**: Java - **License**: GPL-3.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-08-25 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # SpringAOP #### 介绍 SpringAOP_Test #### 软件架构 软件架构说明 #### 安装教程 1. xxxx 2. xxxx 3. xxxx #### 使用说明 ### Spring Aop 注解增强 控制事务 ##### 1、maven依赖 ```xml org.springframework spring-context 5.2.5.RELEASE mysql mysql-connector-java 5.1.48 commons-dbutils commons-dbutils 1.7 com.mchange c3p0 0.9.5.5 org.projectlombok lombok 1.18.12 junit junit 4.13 test org.springframework spring-test 5.2.5.RELEASE org.aspectj aspectjweaver 1.9.2 ``` ##### 2、spring-config.xml ```xml ``` ##### 3、ConnectionUtil ```java /** * 保证一个线程只有一个Connection */ @Component("connectionUtil") public class ConnectionUtil { //本地线程变量 private ThreadLocal threadLocal=new ThreadLocal(); //定义数据源 @Autowired private DataSource dataSource; /** * 获取Connection对象 * @return * @throws SQLException */ public Connection getConnectin() throws SQLException { Connection connection=threadLocal.get(); if(connection==null){ connection=dataSource.getConnection(); threadLocal.set(connection); } return connection; } /** * 让当前线程和Connection解绑 */ public void removeConnection(){ threadLocal.remove(); } } ``` ##### 4、TransactionUtil ```java /** * 事务工具类 */ @Component("transactionUtil") public class TransactionUtil { @Autowired private ConnectionUtil connectionUtil; /** * 开始事务 * @throws SQLException */ public void beginTransaction() throws SQLException { connectionUtil.getConnectin().setAutoCommit(false); } /** * 提交事务 * @throws SQLException */ public void commitTransaction() throws SQLException { connectionUtil.getConnectin().commit(); } /** * 回滚事务 * @throws SQLException */ public void rollbackTransaction() throws SQLException { connectionUtil.getConnectin().rollback(); } /** * 释放连接 * @throws SQLException */ public void closeTransaction() throws SQLException { connectionUtil.getConnectin().close(); connectionUtil.removeConnection(); } } ``` ##### 5、AopUtil ```java /** * 增强类控制事务 */ @Component("AopUtil") @Aspect public class AopUtil { @Autowired private TransactionUtil transactionUtil; @Pointcut("execution(* cn.kgc.service.AccountService.transfer(..))") public void pt(){} @Around("pt()") public void around(ProceedingJoinPoint joinPoint) throws SQLException { try { System.out.println("前置通知,开启事务"); transactionUtil.beginTransaction(); joinPoint.proceed(); System.out.println("后置通知,提交事务"); transactionUtil.commitTransaction(); } catch (Throwable throwable) { System.out.println("异常增强,回滚事务"); transactionUtil.rollbackTransaction(); throwable.printStackTrace(); } finally { System.out.println("最终增强,释放资源"); transactionUtil.closeTransaction(); } } } ``` ##### 6、AccountService ```java /** * 账户持久成接口 */ public interface AccountService { /** * 根据账号查询账户 */ Account findAccountByNum(String accountNum) throws SQLException; /** * 更新账户 */ Integer modifyAccount(Account account) throws SQLException; /** * 转账 */ void transfer(String sourceNum,String desNum,Float money) throws SQLException; } ``` ##### 7、AccountServiceImpl ```java @Service("accountService") public class AccountServiceImpl implements AccountService { @Autowired private AccountDao accountDao; /** * 根据账号查询账户 * * @param accountNum */ public Account findAccountByNum(String accountNum) throws SQLException { return accountDao.getAccountByNum(accountNum); } /** * 更新账户 * * @param account */ public Integer modifyAccount(Account account) throws SQLException { return accountDao.updateAccount(account); } /** * 模拟转账,如果转出金额大于账户余额则设定报一个异常 */ public void transfer(String sourceNum, String desNum, Float money) throws SQLException { //根据账号查询两个账户 Account sourceAccount=accountDao.getAccountByNum(sourceNum); Account desAccount=accountDao.getAccountByNum(desNum); if (sourceAccount.getAccountMoney()< money){ System.out.println("转账失败,余额不足!"); int i = 1/0; } // 修改两个账户的余额 sourceAccount.setAccountMoney(sourceAccount.getAccountMoney()-money); desAccount.setAccountMoney(desAccount.getAccountMoney()+money); //将数据持久化到数据库中 accountDao.updateAccount(sourceAccount); accountDao.updateAccount(desAccount); } } ``` ##### 8、test ```java import static org.junit.Assert.*; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations ="classpath:spring-config.xml") public class AccountServiceTest { @Autowired private AccountService accountService; @Test public void transfer() { try { accountService.transfer("123456","456789",1000f); } catch (SQLException throwables) { throwables.printStackTrace(); } } } ``` ##### 9、database ```sql CREATE TABLE `account` ( `id` int(11) NOT NULL AUTO_INCREMENT, `accountNum` varchar(18) NOT NULL, `accountName` varchar(50) NOT NULL, `accountMoney` float NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; /*Data for the table `account` */ insert into `account`(`id`,`accountNum`,`accountName`,`accountMoney`) values (1,'123456','张三',800),(2,'456789','李四',2200); ``` #### 参与贡献 1. Fork 本仓库 2. 新建 Feat_xxx 分支 3. 提交代码 4. 新建 Pull Request #### 码云特技 1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md 2. 码云官方博客 [blog.gitee.com](https://blog.gitee.com) 3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解码云上的优秀开源项目 4. [GVP](https://gitee.com/gvp) 全称是码云最有价值开源项目,是码云综合评定出的优秀开源项目 5. 码云官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) 6. 码云封面人物是一档用来展示码云会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)