概述
- 通过 Proxy::newProxyInstance 和 InvocationHandler 接口 来实现代理
- 要求 被代理的对象 至少实现一个 接口
- 代理的原理是在内存生成一个代理类的 Class 文件,可以将其保存下来,通过反编译查看
// 被代理的对象的接口
public interface IHello {
void say();
}
// 被代理的对象的类
public class Hello implements IHello{
public void say(){
System.out.println("hello world");
}
}
public class AOPProxy {
// ordinaryObj 为被代理的对象,返回的 Object 对象为代理对象
public static Object proxy(Object ordinaryObj) {
Class clazz = ordinaryObj.getClass();
// 使用 Proxy::newProxyInstance 来生成代理
// 第一个参数为被代理类的 ClassLoader
// 第二个参数为被代理类实现的接口
// 第三个参数为 InvocationHandler 接口,实现真正的处理逻辑
return Proxy.newProxyInstance(clazz.getClassLoader(),
clazz.getInterfaces(),
// proxy 为代理类,method 为代理的方法,args 为 method 使用的入参
(proxy, method, args) -> {
System.out.println("before invoke"); // 前置逻辑
Object result = method.invoke(ordinaryObj, args); // 通过反射调用方法,result 为方法的返回值
System.out.println("after invoke"); // 后置逻辑
return result;
});
}
public static void main(String[] args) {
// 代理的原理是在内存中生成一个代理类的 Class 文件
// 通过下面设置可以使代理类的 Class 文件保存在类目录下,名称为 $Proxy0.class
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true");
// 代理 Hello 类
IHello hello = (IHello) AOPProxy.proxy(new Hello());
// 结果:
// before invoke
// hello world
// after invoke
hello.say();
}
}
ps:上面使用的是 Java8 的 lambda 表达式来实现 InvocationHandler 接口,如果看不懂可以看下面的代码
// AOPProxy::proxy
public static Object proxy(Object ordinaryObj) {
Class clazz = ordinaryObj.getClass();
return Proxy.newProxyInstance(clazz.getClassLoader(),
clazz.getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before invoke");
Object result = method.invoke(ordinaryObj, args);
System.out.println("after invoke");
return result;
}
});
}