zoukankan      html  css  js  c++  java
  • AOP的底层实现:JDK动态代理与Cglib动态代理

    转载自 https://www.cnblogs.com/ltfxy/p/9872870.html

    SpringAOP底层的实现原理:

    •    JDK动态代理:只能对实现了接口的类产生代理。(实现接口默认JDK动态代理,底层自动切换)
    •    Cglib动态代理(类似Javassist第三方的代理技术):对没有实现接口的类产生代理对象。生成子类对象。
    复制代码
    public class JdkProxy implements InvocationHandler {
      
        //设置需要代理增强的对象,传进代理类的构造s
        private UserDao userDao;
        
        public JdkProxy(UserDao userDao){
            this.userDao =  userDao;
        }
        
        //产生UserDao的代理方法
        //lang.reflect.Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 
        public UserDao createProxy(){
            UserDao proxy = (UserDao)Proxy.newProxyInstance(userDao.getClass().getClassLoader(), userDao.getClass().getInterfaces(), this);    
            return proxy;
        }
        
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            //判断方法名是不是add,如果是,进行增强
            if("add".equals(method.getName())){
                //增强:进行权限校验
                System.out.println("权限校验=======");
                return method.invoke(userDao, args);
            }
            return method.invoke(userDao, args);
        }
    }
    复制代码

    测试:

    复制代码
    package com.spring4.demo1;
    
    import org.junit.Test;
    
    public class SpringDemo1 {
    
        @Test
        // JDK动态代理
        public void demo1() {
            // 创建需要被代理的对象
            UserDao dao = new UserDaoImpl();
            // 创建代理
            UserDao proxy = new JdkProxy(dao).createProxy();
            proxy.add();
            proxy.delete();
            proxy.update();
            proxy.find();
        }
    }
    复制代码

    Cglib动态代理

    Cglib:第三方开源代码生产类库,动态添加类的属性和方法

    由于是第三方,需要引入jar包:Spring开发6个包,包含了Cglib

    复制代码
    package com.spring4.demo2;
    
    import java.lang.reflect.Method;
    
    import org.springframework.cglib.proxy.Callback;
    import org.springframework.cglib.proxy.Enhancer;
    import org.springframework.cglib.proxy.MethodInterceptor;
    import org.springframework.cglib.proxy.MethodProxy;
    
    /**
     *  Cglib动态代理,增强没有实现接口的对象
     *
     */
    public class CglibProxy implements MethodInterceptor {
        //设置要被增强的对象
        public CustomerDao customerDao;
        public CglibProxy(CustomerDao customerDao){
            this.customerDao = customerDao;
        }
        
        //设置CustomerDao的代理方法
        public CustomerDao createProxy(){
            //1 创建Cglib核心对象
            Enhancer enhancer = new Enhancer();
            //2 设置父类
            enhancer.setSuperclass(customerDao.getClass());
            //3 设置回调(类似InvocationHandler)
            enhancer.setCallback(this);
            //4 创建代理对象
            CustomerDao proxy =(CustomerDao)enhancer.create();
            return proxy;
        }
    
        @Override
        //进行增强
        public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
            //判断方法是否为add
            //如果增强的方法存在,调用proxy代理,执行增强
            //如果增强的方法不存在,通过代理对象找到父类并执行,不进行增强
            if("add".equals(method.getName())){
                System.out.println("权限校验=========");
                return methodProxy.invokeSuper(proxy, args);
            }
            return methodProxy.invokeSuper(proxy, args);
        }
        
    }
    复制代码

    测试:

    复制代码
    package com.spring4.demo2;
    
    import org.junit.Test;
    
    public class SpringDemo1 {
    
        @Test
        // Cglib
        public void demo1() {
         //创建要被增强的对象
            CustomerDao customerDao = new CustomerDao();
            CustomerDao proxy = new CglibProxy(customerDao).createProxy();
            proxy.add();
            proxy.delete();
            proxy.update();
            proxy.find();
        }
    }
  • 相关阅读:
    JVM基础(一)—— 运行时内存结构
    SQL if 和 case when查询示例
    SQL分组聚合查询
    My music
    DataX增量同步到ADB ADS时报错
    shell find的用法
    pycharm安装
    在两个库中查找出差异明细
    docker下安装centos
    升级RDS8.0遇到的问题
  • 原文地址:https://www.cnblogs.com/zengcongcong/p/10360013.html
Copyright © 2011-2022 走看看