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动态代理(JDK和cglib)

  • 2017-07-04 21:10
  • 246KB
  • 下载

Java动态代理再理解

这是我理解的动态代理的原理图: 动态代理实例: public class TestProxy { public static void main(String[] args) { //被...

java反射机制与动态代理

  • 2012-03-12 12:34
  • 250KB
  • 下载

java 动态代理高级

从JDK1.3以后,java引入动态代理机制,即对目标对象的方法调用是通过代理对象来完成的,java的动态代理只能针对接口进行动态代理,即要实现动态代理的类必须实现接口,CGLIB提供了针对类的动态代...

Java事务处理全解析(六)—— 使用动态代理(Dynamic Proxy)完成事务

在本系列的上一篇文章中,我们讲到了使用Template模式进行事务管理,这固然是一种很好的方法,但是不那么完美的地方在于我们依然需要在service层中编写和事务处理相关的代码,即我们需要在servi...

java动态代理

内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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