代理相当于中介,可以通过代理目标对象的方法,对方法进行增强(类似装饰者设计模式),可以在目标方法执行之前/之后添加一些业务逻辑(例如权限控制)。
ProxyTest.java(测试类):
package com.xxx.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyTest {
public static void main(String[] args) {
final Target target = new Target(); //目标对象。 匿名内部类InvocationHandler中使用的对象必须是final修饰的。
//获得动态的代理对象----在运行时,在内存中动态的为Target创建一个虚拟的代理对象
//动态创建代理对象proxyObj,根据参数确定到底是哪个目标对象的代理对象
TargetInterface proxyObj = (TargetInterface) Proxy.newProxyInstance(
target.getClass().getClassLoader(), //与目标对象相同的类加载器
target.getClass().getInterfaces(), // 目标对象实现的接口的字节码对象(数组) (创建的代理对象也会实现这些接口)
new InvocationHandler() {
//invoke 代表执行代理对象的方法
@Override
//method:代表目标对象的方法的字节码对象
//args:代表目标对象相应的方法的参数
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("执行目标方法前的逻辑"); // 可以进行权限控制。
//执行目标对象的方法
Object result = method.invoke(target, args);
System.out.println("执行目标方法后的逻辑"); // 代理的作用就是可以在目标函数之前/之后添加业务逻辑。
return result; // return method.invoke(target, args);
}
}
); // 动态创建代理对象proxyObj (其实就是目标对象的接口类型;代理和目标对象实现相同的接口)
proxyObj.method1(); // 代理对象通过调用接口中的方法,来调用目标对象中的方法。
String method2 = proxyObj.method2(); // 动态改变接口中的方法,并不用修改代理 (动态代理)
}
}
Target.java(目标对象类,必须要实现某些接口):
package com.xxx.proxy;
public class Target implements TargetInterface{
@Override
public void method1() {
System.out.println("method1 running...");
}
@Override
public String method2() {
System.out.println("method2 running...");
return "method2";
}
}
TargetInterface.java(目标对象类要实现的接口):
package com.xxx.proxy;
public interface TargetInterface {
public void method1();
public String method2();
}