Spring AOP的实现原理

前言

在以前的项目中,很少去关注Spring AOP的实现原理,只是简单了解了一下什么是AOP具体怎么用,本篇将不介绍其使用方法,主要其实如何实现的(即实现原理是什么)。

AOP的原理

AOP 指的是面向切面编程,就是在不改变源码的基础上横向扩展一些功能,主要应用场景有事务管理、日志、缓存等等。其实现的关键在于AOP框架自动创建的AOP代理,如图所示↓↓
Spring AOP的实现原理_第1张图片

下面我们就以最经典的转账操作进行事务管理的操作进行演示。

Spring AOP的实现原理_第2张图片

第一步:

分析转账业务的整体流程:

  • 甲方扣钱
  • 乙方收钱
  • 结束

但为了确保整个过程中有意外发生,就需要在扣钱之前开启事务,在成功收钱之后提交事务,所以此时业务流程就变成了

  • 开启事务
  • 转账操作
  • 提交事务(失败则回滚事务)

第二步:

1. 让我们先创建一个dao,实现基本的扣钱和收钱的操作

public class MoneyDao {
    /**
     * 扣钱
     * @param name
     * @param money
     */
    public void subMoney(String name, BigDecimal money){
        System.out.println(name + "消费了" + money + "元");
    }

    /**
     * 收钱
     * @param name
     * @param money
     */
    public void addMoney(String name, BigDecimal money){
        System.out.println(name + "收到了" + money + "元");
    }

}

2.定义服务接口

public interface MoneyService {

    void transfer(String from, String to, BigDecimal money) ;

}

3.然后创建它的实体类去实现它

public class MoneyServiceImpl implements MoneyService {

    private MoneyDao moneyDao = new MoneyDao() ;
    
    //为方便模拟,创建了dao的get和set方法,实际操作中只需自动注入即可
    public MoneyDao getMoneyDao() {
        return moneyDao;
    }
    public void setMoneyDao(MoneyDao moneyDao) {
        this.moneyDao = moneyDao;
    }

    /**
     * 转账业务
     * @param from
     * @param to
     * @param money
     */
    public void transfer(String from, String to, BigDecimal money) {
        //转出
        moneyDao.subMoney(from,money);
        //转入
        moneyDao.addMoney(to,money);
    }
}

4.动态代理实现功能的嵌入(aop核心)

public class MyFactory {

    public static MoneyService getMoneyService(){

        final MoneyService service = new MoneyServiceImpl() ;
        MoneyDao moneyDao = new MoneyDao() ;
        ((MoneyServiceImpl) service).setMoneyDao(moneyDao);

        MoneyService moneyService = (MoneyService) Proxy.newProxyInstance(MyFactory.class.getClassLoader(), service.getClass().getInterfaces(), new InvocationHandler() {
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //模拟开启事务
                System.out.println("开启事务");
                Object invoke = null ;
                try{
                    invoke = method.invoke(service, args);
                    //模拟提交事务
                    System.out.println("提交事务");
                }finally {
                    //出现异常回滚事务
                    System.out.println("回滚事务");
                }        
                return invoke;
            }
        });
        return moneyService ;
    }
}

5.创建controller类模拟接收页面参数,并调用服务

public class UserController {

    public void transfer(String from, String to, BigDecimal money){
        //使用代理类生成service对象,并调用转账方法
        MoneyService service = MyFactory.getMoneyService();
        service.transfer(from,to,money);
    }
}

6.测试(模拟页面传参)

public class TestMain {

    public static void main(String[] args) {
        UserController userController = new UserController() ;
        userController.transfer("张三","李四",new BigDecimal(1000));
    }
}

运行结果:
Spring AOP的实现原理_第3张图片

你可能感兴趣的:(Java总结,java,spring,aop,动态代理)