JDK动态代理(基于接口)
需要代理类对象实现了接口。
创建代理类: JDK 动态代理使用 Proxy.newProxyInstance
方法生成一个代理类,这个代理类会实现目标接口(一个或多个)。
public class ProxyUtil {
public static Object getProxy(Object o) {
return Proxy.newProxyInstance(ProxyUtil.class.getClassLoader(),o.getClass().getInterfaces(),new jdkProxy(o));
}
}
调用 invoke
方法: 代理类的方法调用会转发到 InvocationHandler
接口的 invoke
方法。该方法中包含了拦截逻辑,你可以在这里实现方法的增强(比如日志、事务等)。
具体实现。
public class jdkProxy implements InvocationHandler {
private final Object target; // 目标对象
public jdkProxy(Object target) {
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("进入jdk代理");
String res = (String)method.invoke(target, args);
System.out.println(res);
return res;
}
}
委托调用: 在 invoke
方法中,你可以通过 method.invoke()
来调用实际的目标对象方法。
JDK 动态代理要求目标类必须实现接口,代理类会自动实现这些接口。
CGLIB动态代理(基于继承)
CGLIB(Code Generation Library)通过字节码生成技术为目标类生成一个子类来实现代理。它不要求目标类实现接口,而是通过继承目标类,重写目标类的方法来实现代理。
不需要接口。
-
步骤:
-
生成代理类: CGLIB 动态代理通过继承目标类并重写其方法来创建代理对象。CGLIB 使用字节码技术(ASM)动态生成代理类。
-
拦截方法调用: 代理类中的方法会被重写,调用这些方法时,CGLIB 会将调用转发到
MethodInterceptor
接口的intercept
方法。
-
-
public class MyInterceptor implements MethodInterceptor { @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("进入cglib动态代理"); String o1 = (String)methodProxy.invokeSuper(o, objects); System.out.println(o1); return o1; } }
-
调用目标方法: 在
intercept
方法中,通过MethodProxy.invokeSuper()
方法调用目标类的原始方法。 -
这就得用Enhancer的方法。
public class test {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(Hello.class);
enhancer.setCallback(new MyInterceptor());
Hello o = (Hello)enhancer.create();
o.getHello();
}
}