• 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 运行结果

      


        原来如此

  • 相关阅读:
    BZOJ_4320_ShangHai2006 Homework_分块
    BZOJ_3362_[Usaco2004 Feb]Navigation Nightmare 导航噩梦_并查集
    BZOJ_2788_[Poi2012]Festival_差分约束+tarjan+floyed
    BZOJ_2795_[Poi2012]A Horrible Poem_hash+暴力
    BZOJ_1598_[Usaco2008 Mar]牛跑步_A*
    [转载]java匿名对象
    [转载]static in Java
    Bat批处理文件入门
    在set中放入自定义类型
    [转载]C++STL概述
  • 原文地址:https://www.cnblogs.com/misscai/p/13029912.html
Copyright © 2020-2023  润新知