JDK动态代理

Wesley13
• 阅读 537

一 ,什么是代理?

代理 : 本来是自己应该做的事, 却请了别人来做, 被请的人就是代理对象

举例 : 春节回家买票找人代买, 黄牛就是代理对象

二 ,什么是动态代理?

代理的对象是变动的, 在程序运行过程中产生的 . 而在程序运行过程中产生对象, 这个对象是不固定的, 那么可以通过反射来实现, 所以动态代理是基于反射实现的.

三 ,动态代理常见有JDK提供的动态代理,和Cglib提供的代理 , 这次介绍JDK提供的代理

1, 在Java中java.lang.reflect包下提供了一个Proxy类和InvocationHandler接口,通过使用这个类和接口就可以生成动态代理对象. JDK提供的代理只能针对接口做代理. Cglib提供的代理会更强大一些.

2, Proxy类中的方法创建动态代理类对象,该方法会返回代理类

Public static Object newProxyInstance(ClassLoader loader, Class<?>[] intergaces,InvocationHandler h )

最终会调用InvocationHandler的方法

3, InvocationHandler接口 , 定义动态代理要实现的具体业务逻辑

Object invoke(Objectproxy, Method method , Object[] args );

自定义类实现IncovationHandler接口, 复写invoke()方法, 具体代理的逻辑写在该方法中. invoke()方法执行后的返回值为代理对象 .

代码举例:

1,创建要代理的接口和实现类

    public interface UserDao {  
          
        void add();  
          
        void delete();  
          
    }  
    public class UserDaoImp implements UserDao{  
      
        public void add() {  
            System.out.println("执行了添加的方法");  
        }  
      
        public void delete() {  
            System.out.println("执行了删除的方法");  
        }  
          
    }  
    public interface WorkDao {  
          
        void work();  
          
        void study();  
          
    }  
    public class WorkDaoImp implements WorkDao {  
      
        public void work() {  
            System.out.println("工作");  
        }  
      
        public void study() {  
            System.out.println("学习");  
        }  
      
    }  

2,创建InvocationHandler接口的实现类,具体代理的业务逻辑在Invoke方法

    /** 
     * 自定义类实现IncovationHandler接口, 复写invoke()方法 
     */  
    public class MyInvocationHandler implements InvocationHandler {  
          
        private Object target; //目标对象  
          
        public MyInvocationHandler(Object target){  
            this.target = target;  
        }  
      
        /** 
         * 在代理实例上处理方法调用并返回结果 
         * proxy - 在其上调用方法的代理实例 
         * method - 对应于在代理实例上调用的接口方法的 Method 实例 
         * args - 包含传入代理实例上方法调用的参数值的对象数组,如果接口方法不使用参数,则为 null 
         */  
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {  
            System.out.println("权限校验");  
              
            //invoke 方法执行后的返回值为代理类对象  
            Object result = method.invoke(target, args);  
            System.out.println("日志分析");  
            return result;   //返回代理类对象  
        }  
      
    }  

3,测试类,Proxy类中的方法创建动态代理类对象,该方法会返回代理类

    public class ProxyTest {  
          
        /** 
         * 使用JDK动态代理,在原来的方法执行前后执行授权,日志记录 
         * @param args 
         */  
        public static void main(String[] args) {  
              
            UserDao userDao = new UserDaoImp();  
            //不使用代理的情况下调用方法  
            userDao.add();  
            userDao.delete();  
              
            //代理用户  
            MyInvocationHandler myInvocationHandler = new MyInvocationHandler(userDao);  
            //返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序  
            //返回对象只能是接口UserDao,不能是接口的实现类UserDaoImp,所以说JDK提供的代理只能针对接口做代理  
            UserDao newProxyInstance = (UserDao) Proxy.newProxyInstance(userDao.getClass().getClassLoader(),   
                    userDao.getClass().getInterfaces(),myInvocationHandler);  
              
            newProxyInstance.add();  
            newProxyInstance.delete();  
              
              
              
            System.out.println("--------------------------------");  
              
            WorkDao workDao = new WorkDaoImp();  
            //不使用代理的情况下调用方法  
            workDao.work();  
            workDao.study();  
              
            //代理工人  
            MyInvocationHandler myInvocationHandler2 = new MyInvocationHandler(workDao);  
            WorkDao newProxyInstance2 = (WorkDao) Proxy.newProxyInstance(workDao.getClass().getClassLoader(),   
                    workDao.getClass().getInterfaces(), myInvocationHandler2);  
              
            newProxyInstance2.work();  
            newProxyInstance2.study();  
              
        }  
          
    }  

4, 控制台输出 , 在方法执行前后执行了授权和添加日志的方法,具体方法中业务逻辑可以根据实际情况定义

执行了添加的方法
执行了删除的方法
权限校验
执行了添加的方法
日志分析
权限校验
执行了删除的方法
日志分析
--------------------------------
工作
学习
权限校验
工作
日志分析
权限校验
学习
日志分析
点赞
收藏
评论区
推荐文章
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Wesley13 Wesley13
3年前
java模式之一
代理模式的概念:对其他对象提供一种代理以控制对这个对象的访问代理模式的三种实现(1)静态代理静态代理在使用时,需要定义接口或者父类,被代理对象与代理对象一起实现相同的接口或者是继承相同父类.eg publicinterfacePammerDao{   voiddomain();}publicTargetimpl
Wesley13 Wesley13
3年前
java的动态代理
1\.什么是动态代理代理模式是为了提供额外或不同的操作,而插入的用来替代”实际”对象的对象,这些操作涉及到与”实际”对象的通信,因此代理通常充当中间人角色。Java的动态代理比代理的思想更前进了一步,它可以动态地创建并代理并动态地处理对所代理方法的调用。在动态代理上所做的所有调用都会被重定向到单一的调用处理器上,它的工作是揭示调用的类型并确定相
Wesley13 Wesley13
3年前
CGLIB介绍与原理(通过继承的动态代理)
一、什么是CGLIB?CGLIB是一个功能强大,高性能的代码生成包。它为没有实现接口的类提供代理,为JDK的动态代理提供了很好的补充。通常可以使用Java的动态代理创建代理,但当要代理的类没有实现接口或者为了更好的性能,CGLIB是一个好的选择。二、CGLIB原理CGLIB原理:动态生成一个要代理类的子类,子类重写要代理的类的所有不是final的
Easter79 Easter79
3年前
Spring的两种代理JDK和CGLIB的区别浅谈
一、原理区别:java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。而cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。1、如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP 2、如果目标对象实现了接口,可以
Wesley13 Wesley13
3年前
Java 动态代理机制分析及扩展,第 1 部分
引言Java动态代理机制的出现,使得Java开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类。代理类会负责将所有的方法调用分派到委托对象上反射执行,在分派执行的过程中,开发人员还可以按需调整委托类对象及其功能,这是一套非常灵活有弹性的代理框架。通过阅读本文,读者将会对Java动态代理机制有更加深入的理解
Easter79 Easter79
3年前
Spring的两种动态代理:Jdk和Cglib 的区别和实现
一、原理区别:java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。而cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。1、如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP 2、如果目标对象实现了接口,可以
Wesley13 Wesley13
3年前
JDK动态代理的简单实现
1\.先理一下动态代理实现的思路:    实现功能:自己定义一个类Proxy,通过Proxy的静态方法newProxyInstance(Class<Tintface,InvocationHandlerh)返回代理对象, intface:被代理类的接口对象, h:InvocationHandler的实例对象    1).声明一段动
Wesley13 Wesley13
3年前
Java动态代理机制解析
动态代理是指在运行时动态生成代理类。不需要我们像静态代理那个去手动写一个个的代理类。生成动态代理类有很多方式:Java动态代理,CGLIB,Javassist,ASM库等。这里主要说一下Java动态代理的实现。Java动态代理InvocationHandler接口Java动态代理中,每一个
Wesley13 Wesley13
3年前
Java中jdk代理和cglib代理
代理模式给某一个对象提供一个代理,并由代理对象控制对原对象的引用。在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。在Java中代理模式从实现方式上可以分为两个类别:静态代理和动态代理静态代理:也就是我们学习设计模式之代理模式时常见的事例,具体不在赘述,参见: