JDK动态代理

本文主要讲解的是JDK动态代理的使用方法

JDK动态代理只能代理接口。

java.lang.reflect.Proxy为JDK的代理类,它为创建动态代理类和实例提供了一些静态方法,

并且它是所有用这些方法创建出来的动态代理类的父类。

以下是Proxy类源码注释中提供的创建动态代理类的两种方法:

<p>To create a proxy for some interface {@code Foo}:
* <pre>

第一种方法:
* InvocationHandler handler = new MyInvocationHandler(...);
* Class proxyClass = Proxy.getProxyClass(
* Foo.class.getClassLoader(), new Class[] { Foo.class });
* Foo f = (Foo) proxyClass.
* getConstructor(new Class[] { InvocationHandler.class }).
* newInstance(new Object[] { handler });
* </pre>
* or more simply:

第二种更简洁的方法:
* <pre>
* Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
* new Class[] { Foo.class },
* handler);
* </pre>

下面再介绍一下java.lang.reflect.InvocationHandler接口:

它是一个代理实例的调用处理器,每一个代理实例都有一个相关的调用处理器,

当一个方法在代理实例上被调用时,方法调用将会被编码并且转发到它的调用处理器的invoke方法上。

我们自己编写的调用处理器必须实现此接口,并且重写其中的invoke方法。

接下来我们来写一些代码来尝试一下JDK动态代理的流程:

第一步:

需要注意的是JDK动态代理的对象必须是interface类型的即接口。

所以我们先创建一个简单的接口:

public interface Fruit {
    void say();

}

再编写一个它的实现类:

public class Apple implements Fruit {

    @Override
    public void say() {
        // TODO Auto-generated method stub
        System.out.println("I am apple");
    }

}

接下来编写一个调用处理器:


public class CustomInvocationHandler implements InvocationHandler {


private Object object;
public CustomInvocationHandler(Object obj){
this.object = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("方法调用前");
Object result = method.invoke(object, args);
System.out.println("方法调用后");
return result;
}


}

 

最后编写一个main方法来测试:


public class JDKproxy {


public static void main(String[] args) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {

InvocationHandler handler = new CustomInvocationHandler(new Apple());
// 第一种方法:
// Class<?> proxyClass = Proxy.getProxyClass(
// Fruit.class.getClassLoader(), new Class[] { Fruit.class });
// Fruit f = (Fruit) proxyClass.
// getConstructor(new Class[] { InvocationHandler.class }).
// newInstance(new Object[] { handler });
// f.say();
// 第二种方法:
Fruit f = (Fruit) Proxy.newProxyInstance(Fruit.class.getClassLoader(),new Class[] { Fruit.class },handler);
f.say();
}


}

 

运行一下,看一下测试结果是:

方法调用前
I am apple
方法调用后

以上就是JDK动态代理的使用方法。

 

posted @ 2016-10-19 20:20  CLAYJJ  阅读(218)  评论(0编辑  收藏  举报