Spring5学习笔记 — “Spring AOP底层原理(动态代理)”

Posted 一切因为是码农

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring5学习笔记 — “Spring AOP底层原理(动态代理)”相关的知识,希望对你有一定的参考价值。

Spring AOP底层原理(动态代理)


一、AOP 底层使用 “动态代理”

动态代理有两种情况

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


  • 第二种:无接口情况,使用CGLIB动态代理


动态代理即为创建(被增强类/实现类的)代理对象
通过类的代理对象增加原来类的功能


二、“JDK 动态代理”(代码实例)

1.使用 JDK 动态代理,调用 Proxy 类里的newProxyInstance方法创建代理对象

public static Object newProxyInstance(
	ClassLoader loader,
	Class<?>[] interfaces,
	InvocationHandler h
)

1)ClassLoader loader
类加载器
2)Class<?>[] interfaces
被增强方法所在的类,这个类实现的接口,支持多个接口
3)InvocationHandler h
实现这个接口 InvocationHandler,创建代理对象,写增强的部分


2.编写 JDK 动态代理代码

//1.编写一个接口,定义方法
public interface UserDao {
    public int add(int a,int b);
    public String update(String id);
}
//2.定义接口的实现类,这个类即为“被增强类”
public class UserDaoImpl implements UserDao{
	@Override
    public int add(int a,int b){
        System.out.println("add方法执行啦!");
        return a+b;
    }
    @Override
    public String update(String id){
        return id;
    }
}
//3.使用 Proxy 类创建接口代理对象
public class JDKproxy {
    public static void main(String[] args) {
        Class[] interfaces = {UserDao.class};
        
        //创建实现类的对象,将对象传入下面的第三个参数
        UserDaoImpl ud = new UserDaoImpl();
        
        //创建UserDao接口的代理对象( Proxy.newProxyInstance()方法返回Object类对象,使用要进行强转)
        UserDao dao=(UserDao) Proxy.newProxyInstance(JDKproxy.class.getClassLoader(),interfaces,new UserDaoProxy(ud));
        /** 
         Proxy.newProxyInstance()方法:
         第一参数,类加载器 
         第二参数,增强方法所在的类,这个类实现的接口,(支持多个接口)
         第三参数,实现这个接口 InvocationHandler,创建代理对象,写增强的部分  
         **/
       
        int result = dao.add(1, 3);
        System.out.println(result);
    }
}
//4.InvocationHandler接口的实现类,作为第三参数传入Proxy方法
class UserDaoProxy implements InvocationHandler{
    /*
    * 创建谁的对象,就把谁的对象传过来
    * 通过有参构造传对象
    */
    private Object obj;
    public UserDaoProxy(Object obj){
        this.obj=obj;
    }
    //方法中写增强的逻辑
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //方法之前执行
        System.out.println("方法之前执行......");

        //被增强的方法执行
        Object res=method.invoke(obj,args);

        //方法之后执行
        System.out.println("方法之后执行......");

        return res;
    }
}

代码执行结果:


重点理解:

动态代理就是要生成一个包装类对象,由于代理的对象是动态的,所以叫动态代理。

由于我们需要增强,这个增强是需要留给开发人员开发代码的,因此代理类不能直接包含被代理对象,而是一个InvocationHandler
InvocationHandler包含被代理对象,并负责分发请求给被代理对象,分发前后均可以做增强。从原理可以看出,JDK动态代理是“对象”的代理。

这个对象的invoke()方法就是Proxy这个动态代理类所代理的接口类的抽象方法的真实实现

以上是关于Spring5学习笔记 — “Spring AOP底层原理(动态代理)”的主要内容,如果未能解决你的问题,请参考以下文章

Spring5学习笔记 — “Spring AOP的概念相关术语”

Spring5学习笔记 — “Spring AOP底层原理(动态代理)”

Spring5学习笔记 — “Spring AOP底层原理(动态代理)”

spring5:AOP操作

惊人!Spring5 AOP 默认使用 CGLIB ?从现象到源码的深度分析

[Spring5]AOP底层原理