java 动态代理

2019-10-15  本文已影响0人  许多城

动态代理
动态代理可以让我们在运行时动态生成代理类,解耦程度更高。Java 动态代理的实现主要借助于 java.lang.reflect 包中的 Proxy 类与 InvocationHandler 接口,所有对动态代理对象的方法调用都会转发到 InvocationHandler 中的 invoke() 方法中实现。一般我们称实现了 InvocationHandler 接口的类为调用处理器。

我们可以通过 Proxy 的静态工厂方法 newProxyInstance 创建动态代理类实例。

方法如下:

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

loader:类加载器
interfaces:类实现的全部接口
h:调用处理器
示例如下:
public class DynamicProxy implements InvocationHandler {

private Object target = null;

DynamicProxy(Object target) {
    this.target = target;
}

/**
 * 代理方法逻辑
 *
 * @param proxy  代理对象
 * @param method 调度方法
 * @param args   调度方法参数
 */
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    System.out.println("代理前");
    method.invoke(target, args);
    System.out.println("代理后");
    return null;
}

}

public class DyProxyTest {
public static void main(String[] args) {
Shopping client = new Client();
DynamicProxy dyProxy = new DynamicProxy(client);
Shopping shop = (Shopping) Proxy.newProxyInstance(Shopping.class.getClassLoader(), new Class[]{Shopping.class}, dyProxy);
shop.buy();
}
}

输出结果:

代理前
我想买这件商品
代理后

当然我们也可以将 Proxy.newProxyInstance 方法放到调用处理器中,使客户端编程更为简单。

示例如下:

public class DynamicProxy implements InvocationHandler {
private Object target = null;

DynamicProxy() {
}

DynamicProxy(Object target) {
    this.target = target;
}

public Object bind(Object target) {
    this.target = target;
    return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}

/**
 * 代理方法逻辑
 *
 * @param proxy  代理对象
 * @param method 调度方法
 * @param args   调度方法参数
 */
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    System.out.println("代理前");
    method.invoke(target, args);
    System.out.println("代理后");
    return null;
}

}

public class DyProxyTest {
public static void main(String[] args) {
Shopping client = new Client();
DynamicProxy dyProxy = new DynamicProxy();
Shopping shop = (Shopping) dyProxy.bind(client);
shop.buy();
}
}

上一篇下一篇

猜你喜欢

热点阅读