动态代理会在程序运行时,自动的为原对象生成一个代理对象。该代理对象的方法会有逻辑上的增强,其一方面会执行增强的逻辑,另一方面其实就是通过反射调用被代理类的方法,这个调用过程跟静态代理就很像了。
JDK动态代理Demo如下:
首先是原始类:
public interface Subject {
void request();
}
public class RealSubject implements Subject {
@Override
public void request() {
System.out.println("RealSubject: Handling request.");
}
}
然后是代理类:
public class ProxyHandler implements InvocationHandler {
private Object realSubject;
public ProxyHandler(Object realSubject) {
this.realSubject = realSubject;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 增强逻辑
System.out.println("ProxyHandler: Handing request.");
// 以反射方法间接调用原始对象的方法
Object result = method.invoke(realSubject, args);
return result;
}
}
这里通过实现了JDK的InvocationHandler接口中invoke方法,其实这个类就是JDK动态代理的代理类,后面生成的代理对象就是通过该代理类,来间接调用原始类的方法的。
最后就是生成代理对象
public class DynamicProxyDemo {
public static void main(String[] args) {
// 将生成的代理对象保存为Class文件
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
// 原始对象
RealSubject realSubject = new RealSubject();
// 代理类
ProxyHandler proxyHandler = new ProxyHandler(realSubject);
// 通过Proxy生成的代理对象
Subject proxySubject = (Subject) Proxy.newProxyInstance(
realSubject.getClass().getClassLoader(),
realSubject.getClass().getInterfaces(),
proxyHandler);
proxySubject.request();
}
}
代理对象的方法是如何被增强的呢,其实增加逻辑并不在代理对象中,而是在代理类这个中间者里,代理对象只不过是调用了这个中间者的invoke方法而已;代理对象的Class文件内容如下:
public final class $Proxy0 extends Proxy implements Subject {
private static Method m1;
private static Method m2;
private static Method m3;
private static Method m0;
public $Proxy0(InvocationHandler var1) throws {
super(var1);
}
public final boolean equals(Object var1) throws {
try {
return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final String toString() throws {
try {
return (String)super.h.invoke(this, m2, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
// 这个方法调用了代理类这个中间类的方法
public final void request() throws {
try {
super.h.invoke(this, m3, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final int hashCode() throws {
try {
return (Integer)super.h.invoke(this, m0, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
m2 = Class.forName("java.lang.Object").getMethod("toString");
m3 = Class.forName("com.example.study.proxy.jdk.Subject").getMethod("request");
m0 = Class.forName("java.lang.Object").getMethod("hashCode");
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
}
CGLIG原理与上述同理,但其原始类不需要实现接口,下面是CGLIB的Demo,其代理类这个中间者需实现MethodInterceptor接口,重写其intercept方法,其中包括增强逻辑和调用原始对象的方法。
首先是原始类
public class UserServiceImpl {
public void getUser() {
System.out.println("userServiceImpl的getUser方法");
}
}
其次是代理类
public class MyInterceptor implements MethodInterceptor {
private Object obj;
public MyInterceptor(Object object) {
this.obj = object;
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
// 增强逻辑
System.out.println("CGLIB-方法前后打印日志--------before");
// 调用原始对象的方法
Object invoke = methodProxy.invoke(obj, objects);
// 增强逻辑
System.out.println("CGLIB-方法前后打印日志--------after");
return invoke;
}
}
最后是生成代理对象
public class DynamicProxyDemo {
public static void main(String[] args) {
// 生成代理对象的Class文件
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "./cg");
UserServiceImpl userService = new UserServiceImpl();
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(userService.getClass());
enhancer.setCallback(new MyInterceptor(userService));
// 通过Enhancer生成代理对象
UserServiceImpl proxy = (UserServiceImpl)enhancer.create();
proxy.getUser();
}
}