# 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/)