Spring之Aop学习
程序员文章站
2022-05-24 23:44:03
...
AOP相关概念
AOP概述
什么是AOP
AOP:即面向切面编程
简单的说就是把我们程序重复的代码抽取出来,在需要执行的时候,使用动态代理技术,在不修改源码的基础上,对我们已有的方法进行增强。
AOP的作用以及优势
- 作用:在程序运行期间,不修改源码对已有方法进行增强。
- 优势:
* 减少重复代码
* 提高开发效率
* 维护方便
AOP的实现方式
使用动态代理即使
AOP的具体应用
案例中的问题
/**
* 账户的业务层实现类
*/
public class AccountServiceImpl implements IAccountService{
private IAccountDao accountDao;
public void setAccountDao(IAccountDao accountDao) {
this.accountDao = accountDao;
}
@Override
public List<Account> findAllAccount() {
return accountDao.findAllAccount();
}
@Override
public Account findAccountById(Integer accountId) {
return accountDao.findAccountById(accountId);
}
@Override
public void saveAccount(Account account) {
accountDao.saveAccount(account);
}
@Override
public void updateAccount(Account account) {
accountDao.updateAccount(account);
}
@Override
public void deleteAccount(Integer acccountId) {
accountDao.deleteAccount(acccountId);
}
}
问题就是:
事务是自动控制的,也就是connection对象是setAutoCommit(true)
此方式控制事务,如果我们每次都执行一条sql语句,没有问题,如果要执行多条语句,一旦多条语句之间抛出异常,那么就会出现问题
问题演示:
在业务层多加入一个方法。
/*
* 业务实现接口
* */
public interface IAccountService {
/**
* 删除
* @param sourceName
* @param targetName
* @param money
*/
void transfer(String sourceName, String targetName, Float money);
}
public class AccountServiceImpl implements IAccountService {
public void transfer(String sourceName, String targetName, Float money) {
//1、根据名称查询两个账户的信息
Account source = iAccountDao.findAccountByName(sourceName);
Account target = iAccountDao.findAccountByName(targetName);
//2、转出账户减钱,转入账户加钱
source.setMoney(source.getMoney() - money);
target.setMoney(target.getMoney() + money);
//3、跟新两个账户
iAccountDao.updateAccount(source);
//模拟异常
int i = 1/0;
iAccountDao.updateAccount(target);
}
}
持久层实现如下
/*
* 持久层接口定义
* */
public interface IAccountDao {
/**
* 删除
* @param acccountId
*/
void deleteAccount(Integer acccountId);
}
public class AccountDaoImpl implements IAccountDao {
public Account findAccountByName(String acccountName) {
try {
List<Account> accounts = runner.query("SELECT * FROM account where name = ?",
new BeanListHandler<Account>(Account.class), acccountName);
if (accounts == null || accounts.size() == 0){
return null;
}
if (accounts.size() > 1){
throw new RuntimeException("只允许有一个返回值");
}
return accounts.get(0);
}catch (SQLException e){
throw new RuntimeException(e);
}
}
}
测试类如下:
@Test
public void testTransfer() {
// //3、执行方法
accountService.transfer("aaa", "bbb", 500f);
}
测试发现数据异常,不符合事务的一致性。