java动态代理

  学习下java的动态代理。

  在java的动态代理机制中,有两个重要的类或接口,一个是 InvocationHandler(Interface)、另一个则是 Proxy(Class),这一个类和接口是实现我们动态代理所必须用到的。首先我们先来看看java的API帮助文档是怎么样对这两个类进行描述的:

  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是代理实例的调用处理程序实现的接口。每个代理实例都有一个关联的调用处理程序。当一个方法是在代理实例调用,方法调用被指派给调用处理程序的invoke方法。

其有唯一方法:

  

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

作用: 处理代理实例的方法调用并返回结果

  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.

   代理提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类。

其有一方法:

static Object    newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
Returns an instance of a proxy class for the specified interfaces that dispatches method invocations to the specified invocation handler.

作用:返回一个代理类指定的接口方法调用指派到指定的调用处理程序的实例。

  下面我们编码测试下:

1.我们定义一个接口Foo

public interface Foo {

    public void sayHello();

    public void sayGoodbye(String name);

}

在接口中定义了2个接口方法,sayHello和带参的sayGoodbye。

2.定义一个Foo接口的实现类FooImpl

public class FooImpl implements Foo {

    @Override
    public void sayHello() {
        System.out.println("Hello World");
    }

    @Override
    public void sayGoodbye(String name) {
        System.out.println(name+" ,goodbye!");

    }
}

3.定义一个InvocationHandler的实现类MyInvocationHandler

public class MyInvocationHandler implements InvocationHandler {

    // 这个就是我们要代理的真实对象
    private Object myObject;

    //为真实对象赋值
    public MyInvocationHandler(Object myObject) {
        this.myObject = myObject;
    }

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

        //在代理真实对象前我们可以添加一些自己的操作
        System.out.println("调用方法前的操作");

        //  真实对象调用方法 
        method.invoke(myObject,args);

        //在代理真实对象后我们可以添加一些自己的操作
        System.out.println("调用方法后的操作");
        return null;
    }
}

4.验证

public class Client {

    public static void main(String[] args) {

        //    我们要代理的真实对象
        FooImpl fooImpl = new FooImpl();

        InvocationHandler handler = new MyInvocationHandler(fooImpl);

        //获得代理对象
        Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
                new Class<?>[]{Foo.class},
                handler);

        System.out.println(f.getClass().getName());
        f.sayHello();
        f.sayGoodbye("boKeYuan");

    }
}

控制台输出为:

sun.proxy.$Proxy0
调用方法前的操作
Hello World
调用方法后的操作
调用方法前的操作
boKeYuan ,goodbye!
调用方法后的操作

  我们发现,代理对象的类名为$Proxy0,由jvm自动生成。当通过代理对象来调用方法的时候,其实是委托由其关联到的 handler 对象的invoke方法来调用,并不是自己来真实调用,而是通过代理的方式来调用的。在invoke方法中,我们可以对类的功能进行扩展。

  

  参考文献

  http://docs.oracle.com/javase/8/docs/api/?cm_mc_uid=68572479042314694146274&cm_mc_sid_50200000=1469666414

java的动态代理机制详解,http://www.importnew.com/20732.html

原文地址:https://www.cnblogs.com/parkdifferent/p/5848894.html