zoukankan      html  css  js  c++  java
  • Spring学习笔记(六)AOP(JDK动态代理之底层原理)

    ------------恢复内容开始------------
    终于开始正题了

    AOP的底层原理

    底层动态代理的情况

    • 第一种使用接口,使用JDK动态代理,创建接口实现类代理对象,增强类的方法
    interface UserDao{
      public void login();
    }
    
    class UserDaoImpl implements UserDao{
      public void login(){
        //登录实现过程
      }
    }
    
    • 第二种没有接口情况,使用 CGLIB 动态代理
    class User{
      public void add(){
        ...
      }
    }
    
    //子类
    class Person extends User{
      public void add(){
        super.add();
        //增强逻辑
      }
    }
    

    JDK动态代理

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

    java.lang.reflect.Proxy

    • 调用 newProxyInstance 方法
    public static Object newProxyInstance(
    ClassLoader loader, 
    类<?>[] interfaces,
    InvocationHandler h) throws IllegalArgumentExceptio
    

    第一个参数:类加载器来定义代理类

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

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

    代码(JDK动态代理)

    1.创建接口,定义方法。

    //接口UserDao
    public interface UserDao {
        public int add(int a1,int a2);
        public String update(String id);
    }
    

    2.创建接口实现类,实现方法。

    //实现类
    public class UserDaoImpl implements UserDao{
        @Override
        public int add(int a1, int a2) {
            System.out.println("add方法执行...");
            return a1 + a2;
        }
    
        @Override
        public String update(String id) {
            System.out.println("update方法执行...");
            return id;
        }
    }
    

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

    public class JDKProxy {
    
        public static void main(String[] args) {
    
            /*
                三个参数:  类加载器、类实现的接口、InvocationHandler
            */
            // 2 第二个参数
            Class[] instances = {UserDao.class};
            UserDaoImpl userDao = new UserDaoImpl();
            // 1 调用Proxy的newProxyInstance方法创建动态代理
            UserDao dao = (UserDao) Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), instances, new UserDaoProxy(userDao));
            int res = dao.add(1, 2);
            System.out.println("res : "+res);
        }
    
    }
    //第三个参数 
    class UserDaoProxy implements InvocationHandler{
    
        // 创建谁的代理对象,就把谁传过来
        // 使用有参数构造的方法进行传递
        // 这里应该传递UserDaoImpl,为了更通用,传递Object
        
        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("方法执行之前..."+method.getName()+" 方法的参数:"+ Arrays.toString(args));
    
            // 方法执行
            Object result = method.invoke(obj, args);
    
            // 方法执行之后的增强
            System.out.println("方法执行之后..."+obj);
            return result;
        }
    }
    //输出结果
    方法执行之前...add 方法的参数:[1, 2]
    
    add方法执行...
    
    方法执行之后...add
    
    res : 3
    
    Process finished with exit code 0
    
  • 相关阅读:
    CSS学习笔记
    metadata的深入
    [极客大挑战 2019]BabySQL
    [极客大挑战 2019]LoveSQL
    [强网杯 2019]随便注
    [SUCTF 2019]CheckIn 1
    [ZJCTF 2019]NiZhuanSiWei 1
    [BJDCTF2020]Easy MD5
    [极客大挑战 2019]BuyFlag
    [ACTF2020 新生赛]BackupFile
  • 原文地址:https://www.cnblogs.com/Emuaer/p/15094773.html
Copyright © 2011-2022 走看看