天天看点

Spring5入门到实战------9、AOP基本概念、底层原理、JDK动态代理实现

1、基本概念

  • (1)面向切面编程(方面),利用 AOP 可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
  • (2)通俗描述:不通过修改源代码方式,在主干功能里面添加新功能
比如说、你完成了一个功能需求、后来产品经理在这个需求上增加一些新需求。你要么修改源代码(这个可能比较麻烦、耦合性也高)、这个时候就可以使用AOP切面编程、对原有的需求进行功能增强。横切进去、就可以在不修改原先代码的基础上、完成新的需求(也方便后期维护、万一产品经理说、这样又不好呢。修改起来也容易、直接将切面拿走。)
  • (3)使用登录例子说明 AOP
  • Spring5入门到实战------9、AOP基本概念、底层原理、JDK动态代理实现

2、底层原理

AOP 底层使用动态代理

有两种情况动态代理

  • 第一种 有接口情况,使用 JDK 动态代理

    创建接口实现类代理对象,增强类的方法

Spring5入门到实战------9、AOP基本概念、底层原理、JDK动态代理实现
  • 第二种 没有接口情况,使用 CGLIB 动态代理

    创建子类的代理对象,增强类的方法

  • Spring5入门到实战------9、AOP基本概念、底层原理、JDK动态代理实现

3、JDK动态代理实现

3.1 查看对应Proxy方法使用

1、使用 JDK 动态代理,使用 Proxy 类里面的方法创建代理对象

开胃小知识

Spring5入门到实战------9、AOP基本概念、底层原理、JDK动态代理实现
Spring5入门到实战------9、AOP基本概念、底层原理、JDK动态代理实现

3.2 方法详解

(1)调用 newProxyInstance 方法

Spring5入门到实战------9、AOP基本概念、底层原理、JDK动态代理实现

方法有三个参数:

第一参数,类加载器

第二参数,增强方法所在的类,这个类实现的接口,支持多个接口

第三参数,实现这个接口 InvocationHandler,创建代理对象,写增强的部分

3.3 JDK动态代理代码

3.3.1 创建接口,定义方法

PersonDao .java

/**
 * @author Lenovo
 * @version 1.0
 * @data 2022/10/19 22:37
 */
public interface PersonDao {
    public int add(int a,int b);

    public void update(int a);
}      

3.3.2 创建接口实现类,实现方法

PersonDaoImpl.java

/**
 * @author Lenovo
 * @version 1.0
 * @data 2022/10/19 22:39
 */
public class PersonDaoImpl implements PersonDao {
    @Override
    public int add(int a, int b) {
        System.out.println("执行了add方法");
        return a+b;
    }

    @Override
    public void update(int a) {
        System.out.println(a);
    }
}
      

3.3.3 使用 Proxy 类创建接口代理对象

/**
 * @author Lenovo
 * @version 1.0
 * @data 2022/10/19 22:40
 */
public class JdkProxy {
    public static void main(String[] args) {
        //创建接口实现类代理对象
        Class[] interfaces = {PersonDao.class};
//        Proxy.newProxyInstance(JdkProxy.class.getClassLoader(), interfaces,
//                new InvocationHandler() {
//                    @Override
//                    public Object invoke(Object proxy, Method method, Object[] args)
//                            throws
//                            Throwable {
//                        return null;
//                    }
//                });
        PersonDaoImpl personDao = new PersonDaoImpl();
        PersonDao dao = (PersonDao) Proxy.newProxyInstance(JdkProxy.class.getClassLoader(), interfaces, new PersonDaoProxy(personDao));
        int rs = dao.add(4, 5);
        System.out.println("result:" + rs);

    }
}

/**
 * 代理对象代码
 */
class PersonDaoProxy implements InvocationHandler {
    /**
     * 1 把创建的是谁的代理对象,把谁传递过来
     *  有参数构造传递
     */
    private Object obj;

    public PersonDaoProxy(Object obj) {
        this.obj = obj;
    }


    /**
     *  增强的逻辑
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //方法之前
        System.out.println("方法执行之前:" + method.getName() + ",传递的参数是:" + Arrays.toString(args));
        //被增强的方法执行
        Object rs = method.invoke(obj, args);
        //方法之后
        System.out.println("方法执行之后:" + obj);
        return rs;
    }
}      
Spring5入门到实战------9、AOP基本概念、底层原理、JDK动态代理实现

3.3.4 测试结果

4、后语