java动态代理机制

一、在java动态代理机制中涉及的角色

1、委托类和委托对象:也可以称为业务类、真正类和业务对象、真正对象,比如;UserServiceImpl.java

2、程序处理类、目标类(或代理类):实现InvocationHandler接口的类,实现invoke()方法,比如:LogHandler.java

处理程序对象、目标对象(或代理对象):invocation handler,由程序处理类、目标类(或代理类)创建的对象,比如:new LogHandler(),它是invoke()方法的实际调用者;

3、动态代理类:proxy classess,由Proxy.getProxyClass(loader, interfaces)获取的类,所有动态代理类的基类都是Proxy类

动态代理对象:proxy instance,由Proxy.newProxyInstance()获取的实例对象,该动态代理对象与代理对象不同,它的类型与委托对象类型相同,而代理对象的类型是InvocationHandler类型。

动态代理对象将会调用委托类的业务方法,比如:saveUser(),触发调用代理对象invoke()方法,其内部再调用委托类的业务方法.

注:此处强行区分代理对象和动态代理对象,因为它们的职责不同,也为了更好的理解动态代理的逻辑、机制。

二、java的动态代理机制中的核心接口和类

java的动态代理机制中的核心接口和类,分别是 InvocationHandler(Interface)、 Proxy(Class)。首先我们先来看看java的API帮助文档是怎么样对这个接口和类进行描述的:

1、InvocationHandler:

/**
 * InvocationHandler is the interface implemented by
 * the invocation handler of a proxy instance.
 *
 * Each proxy instance has an associated invocation handler.
 *
 * When a method is invoked on a proxy instance, the method
 * invocation is encoded and dispatched to the  invoke
 * method of its invocation handler.
 *
 */

InvocationHandler是一个接口,它会被动态代理对象的调用处理程序类(代理类)实现。

即每一个代理类都必须要实现InvocationHandler这个接口,并且每个动态代理对象都会关联到这个代理类的对象:handler,当我们通过动态代理对象调用一个方法的时候,这个方法的调用就会被转发为由InvocationHandler这个接口的 invoke 方法来进行调用。我们来看看InvocationHandler这个接口的唯一一个方法 invoke 方法:

Object invoke(Object proxy, Method method, Object[] args) throws Throwable  


/**
*
*proxy:动态代理对象,即由Proxy.newProxyInstance()创建的对象
*
*method:委托对象的方法的Method对象,即真正方法的Method对象
*
*args:调用委托对象(真实对象)方法时传递的参数
*/

2、Proxy类:

/**
 * Proxy provides static methods for creating dynamic proxy
 * classes and instances, and it is also the superclass of all
 * dynamic proxy classes created by those methods.
 */

Proxy类的作用就是提供静态的方法创建动态代理类和动态代理对象,方法分别为:

public static Class<?> getProxyClass(ClassLoader loader,Class<?>... interfaces)
        throws IllegalArgumentException

public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,  InvocationHandler h)
    throws IllegalArgumentException  

/**
*
*loader:一个ClassLoader对象,定义动态代理类使用的类加载器
*
*interfaces:一个Interface对象的数组,定义动态代理类所要实现的接口列表
*
*h:一个InvocationHandler对象,表示动态代理对象在调用方法的时候,所关联的代理对象,也就是实现了InvokeHandler接口的实现类对象
*/

3、补充:
动态代理机制中,ClassLoader类作为类的加载器,也是核心的一部分。

三、动态代理实例

按照下面的一个小故事作为需求,通过动态代理实现:

有一个人,他叫王守财,做生意遇到了麻烦事,他想把对方弄死(有点暴力),但是他需要周密的部署和工具,所以他找了当地黑社会的头头,外号大B哥,大B哥说,这个好办,应下了此事。大B哥作为老大,具体动手都是由手下的马仔,大B哥只是负责组织,在幕后掌控一切。

依据上面的故事情景,对应动态代理的角色,如下:

委托对象:王守财
目标对象、代理对象:大B哥
动态代理对象:任意一个马仔

1、定义委托对象的接口和类:

public interface Person {
    public void killSomeOne(String userName);
}

public class Wangshoucai implements Person{

    @Override
    public void killSomeOne(String userName) {
        System.out.println(userName+",我要干掉你。。。");
    }
}

2、定义代理类,实现InvokeHandler接口:

public class DaB implements InvocationHandler{

    private Person realPerson;
    public DaB(Person realPerson){
        this.realPerson = realPerson;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {

        System.out.println("大B哥幕后准备枪支、刀具和交通工具,奔赴杀场。。。");

        method.invoke(realPerson, args);

        System.out.println("大B哥带领王守财逃离现场,并收取报酬。");

        return null;

    }

}

3、客户端,通过获取动态代理对象,调用委托对象的方法:

public class DynamicProxyTest {

    public static void main(String[] args) {
        //创建委托对象,王守财
        Person realPerson = new Wangshoucai();

        //创建代理对象、程序处理对象,幕后大B哥
        InvocationHandler handler = new DaB(realPerson);

        //创建动态代理对象,台前的小混混,马仔A,马仔A明面上代表王守财办事,实质服从大B哥的安排
        Person maZaiA = (Person)Proxy.newProxyInstance(
                realPerson.getClass().getClassLoader(), 
                realPerson.getClass().getInterfaces(), 
                handler);
        //马仔A去执行
        maZaiA.killSomeOne("坤哥");
    }

}

4、控制台输出:

大B哥幕后准备枪支、刀具和交通工具,奔赴杀场。。。
坤哥,我要干掉你。。。
大B哥带领王守财逃离现场,并收取报酬。

注意:如果把动态代理对象的类名打出来,com.sun.proxy.$Proxy0,它既不是Person也不是InvokeHandler类,而是一个动态代理类,由此也可以看出,DaB这个类是代理类,但不是动态代理类,由其生成的对象也不是动态代理对象,而是代理对象。

以上就是动态代理机制基本内容,希望可以帮助理解动态代理到底是怎么回事。

参考:http://blog.csdn.net/jenny8080/article/details/54576047

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值