精华内容
下载资源
问答
  • Java两种动态代理JDK动态代理和CGLIB动态代理

    万次阅读 多人点赞 2018-08-07 15:33:35
    JDK动态代理 cglib动态代理 测试 代理模式 代理模式是23种设计模式的一种,他是指一个对象A通过持有另一个对象B,可以具有B同样的行为的模式。为了对外开放协议,B往往实现了一个接口,A也会去实现接口。但是B是...

    目录

    代理模式

    JDK动态代理

    cglib动态代理

    测试


    代理模式

    代理模式是23种设计模式的一种,他是指一个对象A通过持有另一个对象B,可以具有B同样的行为的模式。为了对外开放协议,B往往实现了一个接口,A也会去实现接口。但是B是“真正”实现类,A则比较“虚”,他借用了B的方法去实现接口的方法。A虽然是“伪军”,但它可以增强B,在调用B的方法前后都做些其他的事情。Spring AOP就是使用了动态代理完成了代码的动态“织入”。

    使用代理好处还不止这些,一个工程如果依赖另一个工程给的接口,但是另一个工程的接口不稳定,经常变更协议,就可以使用一个代理,接口变更时,只需要修改代理,不需要一一修改业务代码。从这个意义上说,所有调外界的接口,我们都可以这么做,不让外界的代码对我们的代码有侵入,这叫防御式编程。代理其他的应用可能还有很多。

    上述例子中,类A写死持有B,就是B的静态代理。如果A代理的对象是不确定的,就是动态代理。动态代理目前有两种常见的实现,jdk动态代理和cglib动态代理。

    JDK动态代理

    jdk动态代理是jre提供给我们的类库,可以直接使用,不依赖第三方。先看下jdk动态代理的使用代码,再理解原理。

    首先有个“明星”接口类,有唱、跳两个功能:

    package proxy;
    
    public interface Star
    {
        String sing(String name);
        
        String dance(String name);
    }
    

    再有个明星实现类“刘德华”:

    package proxy;
    
    public class LiuDeHua implements Star
    {   
        @Override
        public String sing(String name)
        {
             System.out.println("给我一杯忘情水");
    
            return "唱完" ;
        }
        
        @Override
        public String dance(String name)
        {
            System.out.println("开心的马骝");
    
            return "跳完" ;
        }
    }
    

    明星演出前需要有人收钱,由于要准备演出,自己不做这个工作,一般交给一个经纪人。便于理解,它的名字以Proxy结尾,但他不是代理类,原因是它没有实现我们的明星接口,无法对外服务,它仅仅是一个wrapper。

    package proxy;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class StarProxy implements InvocationHandler
    {
        // 目标类,也就是被代理对象
        private Object target;
        
        public void setTarget(Object target)
        {
            this.target = target;
        }
        
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
        {
            // 这里可以做增强
            System.out.println("收钱");
            
            Object result = method.invoke(target, args);
            
            return result;
        }
        
        // 生成代理类
        public Object CreatProxyedObj()
        {
            return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
        }  
       
    }
    

    上述例子中,方法CreatProxyedObj返回的对象才是我们的代理类,它需要三个参数,前两个参数的意思是在同一个classloader下通过接口创建出一个对象,该对象需要一个属性,也就是第三个参数,它是一个InvocationHandler。需要注意的是这个CreatProxyedObj方法不一定非得在我们的StarProxy类中,往往放在一个工厂类中。上述代理的代码使用过程一般如下:

    1、new一个目标对象

    2、new一个InvocationHandler,将目标对象set进去

    3、通过CreatProxyedObj创建代理对象,强转为目标对象的接口类型即可使用,实际上生成的代理对象实现了目标接口。

            Star ldh = new LiuDeHua();
    
            StarProxy proxy = new StarProxy();
    
            proxy.setTarget(ldh); 
      
            Object obj = proxy.CreatProxyedObj();
            
            Star star = (Star)obj;

    Proxy(jdk类库提供)根据B的接口生成一个实现类,我们成为C,它就是动态代理类(该类型是 $Proxy+数字 的“新的类型”)。生成过程是:由于拿到了接口,便可以获知接口的所有信息(主要是方法的定义),也就能声明一个新的类型去实现该接口的所有方法,这些方法显然都是“虚”的,它调用另一个对象的方法。当然这个被调用的对象不能是对象B,如果是对象B,我们就没法增强了,等于饶了一圈又回来了。

    所以它调用的是B的包装类,这个包装类需要我们来实现,但是jdk给出了约束,它必须实现InvocationHandler,上述例子中就是StarProxy, 这个接口里面有个方法,它是所有Target的所有方法的调用入口(invoke),调用之前我们可以加自己的代码增强。

    看下我们的实现,我们在InvocationHandler里调用了对象B(target)的方法,调用之前增强了B的方法。

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
        {
            // 这里增强
            System.out.println("收钱");
            
            Object result = method.invoke(target, args);
            
            return result;
        }

    所以可以这么认为C代理了InvocationHandler,InvocationHandler代理了我们的类B,两级代理。

    整个JDK动态代理的秘密也就这些,简单一句话,动态代理就是要生成一个包装类对象,由于代理的对象是动态的,所以叫动态代理。由于我们需要增强,这个增强是需要留给开发人员开发代码的,因此代理类不能直接包含被代理对象,而是一个InvocationHandler,该InvocationHandler包含被代理对象,并负责分发请求给被代理对象,分发前后均可以做增强。从原理可以看出,JDK动态代理是“对象”的代理。

    下面看下动态代理类到底如何调用的InvocationHandler的,为什么InvocationHandler的一个invoke方法能为分发target的所有方法。C中的部分代码示例如下,通过反编译生成后的代码查看,摘自链接地址。Proxy创造的C是自己(Proxy)的子类,且实现了B的接口,一般都是这么修饰的:

    public final class XXX extends Proxy implements XXX
    

    一个方法代码如下:

    
      public final String SayHello(String paramString)
      {
        try
        {
          return (String)this.h.invoke(this, m4, new Object[] { paramString });
        }
        catch (Error|RuntimeException localError)
        {
          throw localError;
        }
        catch (Throwable localThrowable)
        {
          throw new UndeclaredThrowableException(localThrowable);
        }
    

    可以看到,C中的方法全部通过调用h实现,其中h就是InvocationHandler,是我们在生成C时传递的第三个参数。这里还有个关键就是SayHello方法(业务方法)跟调用invoke方法时传递的参数m4一定要是一一对应的,但是这些对我们来说都是透明的,由Proxy在newProxyInstance时保证的。留心看到C在invoke时把自己this传递了过去,InvocationHandler的invoke的第一个方法也就是我们的动态代理实例类,业务上有需要就可以使用它。(所以千万不要在invoke方法里把请求分发给第一个参数,否则很明显就死循环了)

    C类中有B中所有方法的成员变量

      private static Method m1;
      private static Method m3;
      private static Method m4;
      private static Method m2;
      private static Method m0;
    

    这些变量在static静态代码块初始化,这些变量是在调用invocationhander时必要的入参,也让我们依稀看到Proxy在生成C时留下的痕迹。

    static
      {
        try
        {
          m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") });
          m3 = Class.forName("jiankunking.Subject").getMethod("SayGoodBye", new Class[0]);
          m4 = Class.forName("jiankunking.Subject").getMethod("SayHello", new Class[] { Class.forName("java.lang.String") });
          m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
          m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
          return;
        }
        catch (NoSuchMethodException localNoSuchMethodException)
        {
          throw new NoSuchMethodError(localNoSuchMethodException.getMessage());
        }
        catch (ClassNotFoundException localClassNotFoundException)
        {
          throw new NoClassDefFoundError(localClassNotFoundException.getMessage());
        }
      }
    

    从以上分析来看,要想彻底理解一个东西,再多的理论不如看源码,底层的原理非常重要。

    jdk动态代理类图如下

    cglib动态代理

    我们了解到,“代理”的目的是构造一个和被代理的对象有同样行为的对象,一个对象的行为是在类中定义的,对象只是类的实例。所以构造代理,不一定非得通过持有、包装对象这一种方式。

    通过“继承”可以继承父类所有的公开方法,然后可以重写这些方法,在重写时对这些方法增强,这就是cglib的思想。根据里氏代换原则(LSP),父类需要出现的地方,子类可以出现,所以cglib实现的代理也是可以被正常使用的。

    先看下代码

    package proxy;
    
    import java.lang.reflect.Method;
    
    import net.sf.cglib.proxy.Enhancer;
    import net.sf.cglib.proxy.MethodInterceptor;
    import net.sf.cglib.proxy.MethodProxy;
    
    public class CglibProxy implements MethodInterceptor
    {
        // 根据一个类型产生代理类,此方法不要求一定放在MethodInterceptor中
        public Object CreatProxyedObj(Class<?> clazz)
        {
            Enhancer enhancer = new Enhancer();
            
            enhancer.setSuperclass(clazz);
            
            enhancer.setCallback(this);
            
            return enhancer.create();
        }
        
        @Override
        public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable
        {
            // 这里增强
            System.out.println("收钱");
            
            return arg3.invokeSuper(arg0, arg2);
        } 
    }
    

    从代码可以看出,它和jdk动态代理有所不同,对外表现上看CreatProxyedObj,它只需要一个类型clazz就可以产生一个代理对象, 所以说是“类的代理”,且创造的对象通过打印类型发现也是一个新的类型。不同于jdk动态代理,jdk动态代理要求对象必须实现接口(三个参数的第二个参数),cglib对此没有要求。

    cglib的原理是这样,它生成一个继承B的类型C(代理类),这个代理类持有一个MethodInterceptor,我们setCallback时传入的。 C重写所有B中的方法(方法名一致),然后在C中,构建名叫“CGLIB”+“$父类方法名$”的方法(下面叫cglib方法,所有非private的方法都会被构建),方法体里只有一句话super.方法名(),可以简单的认为保持了对父类方法的一个引用,方便调用。

    这样的话,C中就有了重写方法、cglib方法、父类方法(不可见),还有一个统一的拦截方法(增强方法intercept)。其中重写方法和cglib方法肯定是有映射关系的。

    C的重写方法是外界调用的入口(LSP原则),它调用MethodInterceptor的intercept方法,调用时会传递四个参数,第一个参数传递的是this,代表代理类本身,第二个参数标示拦截的方法,第三个参数是入参,第四个参数是cglib方法,intercept方法完成增强后,我们调用cglib方法间接调用父类方法完成整个方法链的调用。

    这里有个疑问就是intercept的四个参数,为什么我们使用的是arg3而不是arg1?

        @Override
        public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable
        {
            System.out.println("收钱");
            
            return arg3.invokeSuper(arg0, arg2);
        }

     因为如果我们通过反射 arg1.invoke(arg0, ...)这种方式是无法调用到父类的方法的,子类有方法重写,隐藏了父类的方法,父类的方法已经不可见,如果硬调arg1.invoke(arg0, ...)很明显会死循环。

    所以调用的是cglib开头的方法,但是,我们使用arg3也不是简单的invoke,而是用的invokeSuper方法,这是因为cglib采用了fastclass机制,不仅巧妙的避开了调不到父类方法的问题,还加速了方法的调用。

    fastclass基本原理是,给每个方法编号,通过编号找到方法执行避免了通过反射调用。

    对比JDK动态代理,cglib依然需要一个第三者分发请求,只不过jdk动态代理分发给了目标对象,cglib最终分发给了自己,通过给method编号完成调用。cglib是继承的极致发挥,本身还是很简单的,只是fastclass需要另行理解。

    参考

    https://blog.csdn.net/jiankunking/article/details/52143504

    http://www.php.cn/java-article-407212.html

    https://www.cnblogs.com/chinajava/p/5880887.html

    https://rejoy.iteye.com/blog/1627405

    测试

       public static void main(String[] args)
        {
            int times = 1000000;
            
            Star ldh = new LiuDeHua();
            StarProxy proxy = new StarProxy();
            proxy.setTarget(ldh);
            
            long time1 = System.currentTimeMillis();
            Star star = (Star)proxy.CreatProxyedObj();
            long time2 = System.currentTimeMillis();
            System.out.println("jdk创建时间:" + (time2 - time1));
            
            CglibProxy proxy2 = new CglibProxy();
            long time5 = System.currentTimeMillis();
            Star star2 = (Star)proxy2.CreatProxyedObj(LiuDeHua.class);
            long time6 = System.currentTimeMillis();
            System.out.println("cglib创建时间:" + (time6 - time5));
            
            long time3 = System.currentTimeMillis();
            for (int i = 1; i <= times; i++)
            {
                star.sing("ss");
                
                star.dance("ss");
            }
            long time4 = System.currentTimeMillis();
            System.out.println("jdk执行时间" + (time4 - time3));
            
            long time7 = System.currentTimeMillis();
            for (int i = 1; i <= times; i++)
            {
                star2.sing("ss");
                
                star2.dance("ss");
            }
            
            long time8 = System.currentTimeMillis();
            
            System.out.println("cglib执行时间" + (time8 - time7));   
        }

    经测试,jdk创建对象的速度远大于cglib,这是由于cglib创建对象时需要操作字节码。cglib执行速度略大于jdk,所以比较适合单例模式。另外由于CGLIB的大部分类是直接对Java字节码进行操作,这样生成的类会在Java的永久堆中。如果动态代理操作过多,容易造成永久堆满,触发OutOfMemory异常。spring默认使用jdk动态代理,如果类没有接口,则使用cglib。

    展开全文
  • java动态代理对象实例的创建

    千次阅读 2016-02-02 11:58:00
  • Java动态代理简单实例:老板与秘书

    千次阅读 2017-02-26 22:38:41
    Java动态代理Java中比较晦涩难懂的一个部分,虽然看了一些别人的博客之后觉得自己懂一点了,但是事非经过不知难,自己写的时候发现了一些之前没在意的点。 本文用尽可能简单的例子来说明Java动态代理的机制。 例子...

    Java动态代理是Java中比较晦涩难懂的一个部分,虽然看了一些别人的博客之后觉得自己大体明白了,但是事非经过不知难,自己写的时候却产生了诸多疑问。

    本文用尽可能简单的例子来说明Java动态代理的机制。

    例子共四个部分:

    1. ReadFile接口(批改文件)

    2. Boss类,委托类,能够批改文件

    3. Secretary类,没有实现ReadFile接口,用Secretary可创建代理类,“代理”Boss批改文件(创建出来的代理类对象就是main函数中的secretary1)

    4. Main类


    1. ReadFile接口

    public interface ReadFile {
        public void read();
    }

    2. Boss类,实现了ReadFile接口,可以批改文件

    public class Boss implements ReadFile {
    
        @Override
        public void read() {
            System.out.println("I'm reading files.");
        }
    
    }

    3. Secretary类,不是代理类,但利用这个类能创建出代理类

    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    
    public class Secretary implements InvocationHandler {
    
        private Object object;
        
        public Secretary(Object object) {
            this.object = object;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
            System.out.println("I'm secretary.");
            Object result = method.invoke(object, args);
    
            return result;
        }
    
    }

    Secretary类中有一个变量object用来存boss对象,因为接下来Secretary要代理Boss做的事,因此先要把boss对象先保存起来。

    Secretary类如果想代理Boss做的事,即调用Boss类的方法,必须实现InvocationHandler,重载invoke方法,然后在invoke函数中调用Boss类的方法。

    我们看到invoke函数中有一句method.invoke(object, args),代理类就是用这种方式调用委托类的方法。


    4. Main类

    import java.lang.reflect.Proxy;
    
    public class Main {
    
        public static void main(String[] args) {
            ReadFile boss = new Boss();
    
            InvocationHandler handler = new Secretary(boss);
    
            ReadFile secretary = (ReadFile) Proxy.newProxyInstance(
                    boss.getClass().getClassLoader(),
                    boss.getClass().getInterfaces(),
                    handler);
            
            secretary.read();
        }
    }
    整个函数的执行流程如下:

    先是创建了一个boss对象,

    然后创建一个handler对象,

    然后利用handler构造出一个能调用boss方法的对象secretary,这个secretary就是代理类对象

    执行最后一句时,代理类的public Object invoke(...)方法被调用,代理类在此处调用委托类的方法,method.invoke()先打印I'm secretary,再调用boss对象的方法read()。



    secretary每调用一次read()时都会执行public Object invoke(...),显而易见传入的第二个参数method即read(),第三个参数args即传入read()的参数(这里没有)。


    实现了InvocationHandler的Secretary类并不能直接调用委托类的方法,handler对象只是一个handler,只有当handler对象用newProxyInstance方法包裹成secretary对象后,才具有调用boss方法的能力。

    既然说secretary是由handler包裹而成的,那secretary是什么类型的呢?

            System.out.println(secretary.getClass().getName());

    类型是$Proxy0




    如果文章中存在问题请及时指正。


    展开全文
  • Java动态代理Proxy&InvocationHandler 实例

    千次阅读 2020-04-22 10:19:35
    也就是说,这种情况下,代理类并不是在Java代码中定义的,而是在运行时根据我们在Java代码中的“指示”动态生成的。相比于静态代理动态代理的优势在于可以很方便的对代理类的函数进行统一的处理,而不用修改每个...

    代理类在程序运行时创建的代理方式被成为 动态代理。 也就是说,这种情况下,代理类并不是在Java代码中定义的,而是在运行时根据我们在Java代码中的“指示”动态生成的。相比于静态代理, 动态代理的优势在于可以很方便的对代理类的函数进行统一的处理,而不用修改每个代理类的函数. 

    话不多说, show you code . ...

     

    1.定义代理的接口类.

    public interface People {
        public String work();
    
    }

    2.定义接口的实现类.

    import java.time.LocalDate;
    
    public class Teacher implements People {
        @Override
        public String work() {
            System.out.println("上课=>"+ LocalDate.now() );
            return "上课";
        }
    }
    

    3.定义代理的实现类

    这里最重要的是构造函数和 invoke方法.

    构造函数: 设置要被代理的对象.

    invoke: 根据请求的方法&参数 . 构造代理实现

     

    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    
    public class WorkHandler implements InvocationHandler {
        //代理类中的真实对象
        private Object obj;
    
        public WorkHandler() {
            // TODO Auto-generated constructor stub
        }
        //构造函数,给我们的真实对象赋值
        public WorkHandler(Object obj) {
            this.obj = obj;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
            System.out.println("WorkHandler#invoke    "+proxy.getClass().getName());
            System.out.println("WorkHandler#invoke    "+this.obj.getClass().getName());
    
            //在真实的对象执行之前我们可以添加自己的操作
            System.out.println("before invoke。。。");
            Object invoke = method.invoke(obj, args);
            //在真实的对象执行之后我们可以添加自己的操作
            System.out.println("after invoke。。。");
            return invoke;
        }
    
    
    }
    

     

    4.定义运行方法

    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Proxy;
    
    public class Client {
    
        public static void main(String[] args) {
            //要代理的真实对象
            People people = new Teacher();
            //代理对象的调用处理程序,我们将要代理的真实对象传入代理对象的调用处理的构造函数中,最终代理对象的调用处理程序会调用真实对象的方法
            InvocationHandler handler = new WorkHandler(people);
            /**
             * 通过Proxy类的newProxyInstance方法创建代理对象,我们来看下方法中的参数
             * 第一个参数:people.getClass().getClassLoader(),使用handler对象的classloader对象来加载我们的代理对象
             * 第二个参数:people.getClass().getInterfaces(),这里为代理类提供的接口是真实对象实现的接口,这样代理对象就能像真实对象一样调用接口中的所有方法
             * 第三个参数:handler,我们将代理对象关联到上面的InvocationHandler对象上
             */
            People proxy = (People) Proxy.newProxyInstance(handler.getClass().getClassLoader(), people.getClass().getInterfaces(), handler);
    
            System.out.println(proxy.work());
    
            System.out.println("Client#manin "+proxy.getClass());
    
        }
    
    }
    

    5. 输出结果

    WorkHandler#invoke    com.sun.proxy.$Proxy0
    WorkHandler#invoke    org.apache.hadoop.reflect.Teacher
    before invoke。。。
    老师教书育人...
    after invoke。。。
    教书
    Client#manin class com.sun.proxy.$Proxy0
    

     

     

     

    展开全文
  • 本文介绍了java方法模拟动态代理,开始时老是因为把代理类的对象传入invoke方法使用陷入死循环。具体死循环的原因会再整理下再发一篇。
  • Java进阶-Java动态代理】03 创建动态类的实例对象及调用其方法创建动态类的实例对象由上一篇文章中分析,动态代理类只有一个构造方法 com.sun.proxy.$Proxy4(java.lang.reflect.InvocationHandler) 因此,我们...
  • Java动态代理类实现日志简单实例

    千次阅读 2016-07-01 07:17:41
    开心一笑上课呢,同桌撕了一片纸...提出问题Java动态代理类实现简单的日志解决问题假如你已经有一定的java基础 假如你已经知道什么是动态代理。1.假如下面是真实的业务类及其实现类package com.hwy.test;/** * Create
  • 上篇介绍了一下静态代理Java中的代理模式——静态代理以及分析静态代理的缺点 也分析了一下静态代理的缺点: 1、由于静态代理中的代理类是针对某一个类去做代理的,那么假设一个系统中有100个Service,则需要...
  • 1 什么是代理 代理模式的定义:对其他对象提供一种代理以控制对这个对象的访问。举个例子,如A对象有若干个方法,这时A对象对B对象进行委托授权,B对象便成了A对象的代理方,因此B对象便可对A对象进行访问并调用A...
  • 轻松学,Java 中的代理模式及动态代理

    万次阅读 多人点赞 2017-06-29 22:08:55
    前几天我写了《秒懂,Java 注解 (Annotation)你可以这样学》,因为注解其实算反射技术中的一部分,然后我想了一下,反射技术中还有个常见的概念就是动态代理,于是索性再写一篇关于动态代理的博文好了。...
  • 动态代理就是应用两个类来实现的
  • Java反射机制和动态代理实例

    千次阅读 2016-12-09 09:19:21
    反射机制是Java语言的一个重要特性,允许用户动态获取类的信息和动态调用对象的方法。 通过给定类的名字,通过反射机制就可以获取类的所有信息。 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的...
  • Java反射和动态代理详解和实例

    千次阅读 2014-09-09 14:26:14
    这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。  反射就是把Java类中的各种成分映射成相应的Java类。 Java反射机制主要提供了以下功能:  1、在运行时判断任意一个对
  • Java JDK 动态代理(AOP)使用及实现原理分析

    万次阅读 多人点赞 2019-05-08 21:28:06
    二、Java 动态代理类 三、JDK的动态代理怎么使用? 四、动态代理怎么实现的? 五、结论 一、什么是代理代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问。代理类负责为...
  • package com.mari.proxy...import java.lang.reflect.Constructor; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.ArrayList; imp
  • Java代理对象实例

    千次阅读 2018-05-05 13:57:02
    Java代理对象,可以通过代理来操作一个正真的实例对象,通过代理模式来重写那些我们需要增强的原对象的方法,下面是一个关于代理的简单实例:1.定义一个接口类public interface MyBusiness { public void ...
  • Java动态代理

    千次阅读 2017-09-26 10:43:00
    代理模式: 代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问。代理类负责为委托类预处理...动态代理代理类是在运行时生成的,也就是说Java编译完之后并没有实际的class文件,而
  • Java 动态代理-Jdk动态代理

    千次阅读 2019-08-27 16:24:41
    javajava.lang.reflect 包下提供了一个Proxy 和 InvocationHandler 接口来支持生产Jdk 动态代理类(不常用)或***动态代理对象***. 在普通的企业开发中, 通常是不会涉及到动态代理开发的, 但是若是开发框架或做底层...
  • 实例理解JDK动态代理和Cglib动态代理及其区别 深入理解设计模式之代理模式 代理代理化妆品生产理解JDK动态代理 代理代理汽车制造理解Cglib动态代理
  • 在上一篇博文中我们已经进行了反射机制的习题练习,这里我们在做一个考察比较全面的练习,如下: ...我们传入的实参字符串为:classMethod "java.lang.String.length()"就可以通过反射执行String类中的lengt
  • java动态代理Proxy.newProxyInstance

    万次阅读 多人点赞 2018-07-30 22:28:53
    利用Java的反射技术(Java Reflection),在运行时创建一个实现某些给定接口的新类(也称“动态代理类”)及其实例(对象),代理的是接口(Interfaces),不是类(Class),也不是抽象类。在运行时才知道具体的实现,...
  • 四、动态代理的JDK实现原理 4.1核心类/接口 4.2 代理类$Proxy0解析 4.3 动态代理的经典使用五、手写代码模拟JDK动态代理六、参考资料项目源码已经上传,欢迎点击下载~先将自己总结的Java动态代理UML图放在前面,...
  • java动态代理

    千次阅读 多人点赞 2019-04-30 15:47:21
    java动态代理实现与原理详细分析 原文地址 关于Java中的动态代理,我们首先需要了解的是一种常用的设计模式--代理模式,而对于代理,根据创建代理类的时间点,又可以分为静态代理动态代理。 一、代理模式 代理...
  • Java动态代理模式(Proxy)实例

    千次阅读 2012-10-22 20:43:49
    所谓代理,是指具有与代理元(被代理的对象)具有相同的接口的类,客户端必须通过代理与被代理的目标类交互,而代理一般在交互的过程中(交互前后),进行某些特别的处理。Proxy模式是很常见的模式,在我们生活中...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 207,522
精华内容 83,008
关键字:

动态代理java实例

java 订阅