zoukankan      html  css  js  c++  java
  • Spring AOP 原理之 JDK动态代理与CGLIB动态代理

    (一)JDK的动态代理

      原理: JDK动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。

      JDK的动态代理 必须是实现了接口的类

      1 接口

    public interface UserDao {
    
        public void saveUser();
    
    }

       2 实现类

    public class UserDaoImpl implements UserDao {
        
        @Override
        public void saveUser() {
            System.out.println("用户保存成功");
        }
    }

       3 测试类编写

    @Test
        void test1() { //JDK的动态代理,必须要有接口
            UserDao userDao = new UserDaoImpl();
            UserDao dao = (UserDao) Proxy.newProxyInstance(userDao.getClass().getClassLoader(), userDao.getClass().getInterfaces(), new InvocationHandler() {
                // 参数proxy:被代理的对象
                // 参数method:执行的方法,代理对象执行哪个方法,method就是哪个方法
                // 参数args:执行方法的参数
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    System.out.println("JDK代理前  do something!!!  (例如记录日志)");
                    Object result = method.invoke(userDao, args);
                    return result;
                }
            });
    
            dao.saveUser();
        }

      4 运行结果

      


    (二)CGLIB的动态代理

       可以是没有实现接口的类

      1 保存方法

    public class CglibDao {
    
        public void save(){
            System.out.println("保存成功!!!!!");
        }
    }

       2  测试类编写

        @Test
        void test2(){
            final CglibDao cglibDao = new CglibDao();
    
            //创建cglib的核心对象
            Enhancer enhance = new Enhancer();
    
            //设置父类
            enhance.setSuperclass(cglibDao.getClass());
    
            //设置回调
            enhance.setCallback(new MethodInterceptor() {
                /**
                 * 当你调用目标方法时,实质上是调用该方法
                 * intercept四个参数:
                 * proxy:代理对象
                 * method:目标方法
                 * args:目标方法的形参
                 * methodProxy:代理方法
                 */
                @Override
                public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
    
                    System.out.println("CGLIB代理前   dosomething!!!!!! (例如记录日志)");
    
                    Object result = method.invoke(cglibDao, args);
    
                    return result;
                }
            });
            CglibDao dao = (CglibDao) enhance.create();
            dao.save();
    
         }

       3 运行结果

      


        原来如此

  • 相关阅读:
    linux grep命令
    PHP 利用simplexml_load_file 读取XML对应的字段 然后存入mysql数据库
    php 设计模式之单类模式
    Mac C#开发工具Rider安利与环境配置教程
    模拟,贪心,枚举(二)
    模拟,贪心,枚举
    10.10 review
    review 10.9
    10.6 review
    9.28 review
  • 原文地址:https://www.cnblogs.com/misscai/p/13029912.html
Copyright © 2011-2022 走看看