动态代理
动态代理可以让我们在运行时动态生成代理类,解耦程度更高。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();
}
}
网友评论