欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring之Aop学习

程序员文章站 2022-05-24 23:44:03
...

AOP相关概念

AOP概述

什么是AOP

AOP:即面向切面编程
Spring之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);
    }

测试发现数据异常,不符合事务的一致性。

问题的解决