Java动态代理

原创 2016年08月31日 15:53:04

代理

有时候我们不希望直接访问对象A,而是希望通过访问中介对象B,由B来访问A,这种方式就是我们所说的代理。这里的类A即为委托类(被代理类),B为代理类。那么使用代理的好处是什么呢?

  1. 隐藏委托类的实现
  2. 实现解耦,在不改变委托类的情况下,对代理类进行修改,实现额外的处理。
    代理分为静态代理和动态代理。

静态代理

所谓静态代理就是程序运行之前代码中存在代理类,静态代理中代理类和委托类也常常继承同一父类或实现同一接口。

public interface Behaviour {
    void method();
}
//委托类
public class Principal implements Behaviour{
    public void method() {
        System.out.println("principle.method");
    }
}
//代理类
public class Agent implements Behaviour {
    private Principal principal;
    public Agent(Principal principal){
       this.principal = principal;
    }
    public void method() {
        principal.method();
    }
}

代理类持有委托类对象的引用,通过调用委托类对象的方法实现代理。使使用者和委托类之间解耦,但是缺点是我们要提前写好代理类。

动态代理

程序运行过程中创建代理类,这种方式叫动态代理。代码中不需要专门去写一个代理类。

动态代理的实现方式
  1. 新建行为接口和委托类
  2. 新建一个类实现InvocationHandler接口,这是负责连接代理类和委托类的中间类必须实现的接口
  3. 通过Proxy类产生代理类对象。
    先来新建行为接口和委托类
public interface Behaviour {
    void method();
}
//委托类
public class Principal implements Behaviour{
    public void method() {
        System.out.println("principle.method");
    }
}

再来写一个类实现InvocationHandler接口,

public class MyInvocation implements InvocationHandler {
    private Object principal;

    public MyInvocation(Object principal) {
        this.principal = principal;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = method.invoke(principal,args);
        return result;
    }
}

这里解释一下InvocationHandler接口里的public Object invoke(Object proxy, Method method, Object[] args) throws Throwable方法各个参数代表的意思,proxy是后面要生成的代理类对象,method表示代理对象被调用的函数。args表示代理对象被调用的函数的参数。
从上面代码我们看到,中介类持有委托类对象引用,在invoke方法中调用了委托类对象的相应方法。实际上,中介类与委托类构成了静态代理关系,在这个关系中,中介类是代理类,委托类就是委托类;代理类与中介类也构成一个静态代理关系,在这个关系中,中介类是委托类,代理类是代理类。也就是说,动态代理关系由两组静态代理关系组成,这就是动态代理的原理。

通过Proxy类产生代理类对象
public class Example {
    public static void main(String args[]) {
        Principal principal = new Principal();//构造一个委托类对象
        MyInvocation myInvocation = new MyInvocation(principal);//构造中介类,并把委托类对象传入
        Behaviour behaviour = (Behaviour) Proxy.newProxyInstance(Behaviour.class.getClassLoader(),
                new Class[]{Behaviour.class},myInvocation);//动态生成代理类对象
        behaviour.method();
    }

}

这里通过Proxy.newProxyInstance(Behaviour.class.getClassLoader(),
new Class[]{Behaviour.class},myInvocation);//动态生成代理类对象
,这个方法的三个参数,第一个参数是定义代理类的Classloader,第二个参数是委托类实现的接口列表,第三个参数是我们实现的invocaition接口实例。
当我们调用代理类的方法时,behaviour.method();,实际会调用MyInvocation里的public Object invoke(Object proxy, Method method, Object[] args)方法,而这个方法里又会调用委托类的相应方法,所以额外的处理逻辑一般都在这个方法里实现。

版权声明:本文为博主原创文章,未经博主允许不得转载。

Java动态代理(主要是对六个参数的理解)

import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflec...
  • nrsc272420199
  • nrsc272420199
  • 2017年08月04日 00:33
  • 110

彻底理解Java动态代理

代理设计模式 定义:为其他对象提供一种代理以控制对这个对象的访问。 代理模式的结构如下图所示。 动态代理使用 java动态代理机制以巧妙的方式实现了代理模式的设计理念。 ...
  • qq_29945661
  • qq_29945661
  • 2016年11月21日 22:06
  • 807

JAVA动态代理用法与实现过程

jdk动态代理实现已即原理
  • qq1004642027
  • qq1004642027
  • 2016年08月02日 11:33
  • 2079

Java动态代理示例代码

Proxy 提供用于创建动态代理类和实例的静态方法。简洁方法:Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),     ...
  • anerou
  • anerou
  • 2007年06月20日 11:35
  • 3733

详解java动态代理机制以及使用场景(一)

说起java动态代理,在我刚开始学java时对这项技术也是十分困惑,明明可以直接调通的对象方法为什么还要使用动态代理?随着学习的不断深入和工作经验的积累,慢慢的体会并理解了java动态代理机制。昨天再...
  • u011784767
  • u011784767
  • 2017年10月19日 10:29
  • 1003

好记性不如烂笔头48-java拦截器-JDK自带动态代理和CGLIB效率比较(3)

Java中自带的动态代理的类必须要实现一个接口,而且据说使用反射的效率也并不是很高。于是CGLIB就诞生了。 使用CGLib实现动态代理,完全不受代理类必须实现接口的限制,而且CGLib底层采用AS...
  • ffm83
  • ffm83
  • 2015年02月11日 10:04
  • 1153

JAVA的Proxy动态代理在自动化测试中的应用

转载地址:http://www.cnblogs.com/zhangfei/p/5180197.html JAVA的动态代理,在MYBATIS中应用的很广,其核心就是写一个interface,但...
  • wanglha
  • wanglha
  • 2016年03月01日 10:51
  • 275

Java动态代理、cglib动态代理

说动态代理,需要先清楚静态代理。所谓静态代理就是程序员提前实现好的代理类,编译后class文件是已经存在的。 实现原理,利用Java代理模式,由一个代理类持有委托类的实例,并实现委托类一样的接口,来...
  • catoop
  • catoop
  • 2016年02月24日 14:17
  • 2834

Java动态代理与静态代理的定义与区别??

JAVA的静态代理与动态代理比较 一、概念 代理模式是常用的Java 设计模式,它的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后...
  • whb123andy
  • whb123andy
  • 2014年02月26日 13:38
  • 586

Java 动态代理和CGlib

JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理,cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继...
  • jinsong1213
  • jinsong1213
  • 2015年04月08日 11:26
  • 290
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Java动态代理
举报原因:
原因补充:

(最多只允许输入30个字)