Spring5学习笔记(8) — “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这个动态代理类所代理的接口类的抽象方法的真实实现

猜你喜欢

转载自blog.csdn.net/qq_47354826/article/details/120688257
今日推荐