1.JDK动态代理
1.1.有一个接口
package com.example.untitled;
public interface TestService {
String test();
}
1.2.获取动态生成的字节码并存放到文件中
package com.example.untitled;
import sun.misc.ProxyGenerator;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class UntitledApplication {
public static void main(String[] args) throws IOException {
byte[] bytes = ProxyGenerator.generateProxyClass("$Proxy0", new Class[]{TestService.class});
File file = new File("TestServiceProxy.class");
FileOutputStream fos = new FileOutputStream(file);
fos.write(bytes);
fos.flush();
fos.close();
}
}
1.3.查看动态生成的字节码类
import com.example.untitled.TestService;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
public final class $Proxy0 extends Proxy implements TestService {
}
2.CGLIB动态代理
2.1.CGLIB代理接口情况
2.1.1.有一个接口
package com.example.untitled;
public interface TestService {
String test();
}
2.1.2.MethodInterceptor 代码
package com.example.untitled;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class MyMethodInterceptor implements MethodInterceptor {
public Object getInstance(Class claxx) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(claxx);
// 回调方法
enhancer.setCallback(this);
// 创建代理对象
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("MyMethodInterceptor.intercept");
return "cglib test";
}
}
2.1.3.获取动态生成的字节码类
package com.example.untitled;
import net.sf.cglib.core.DebuggingClassWriter;
import sun.misc.ProxyGenerator;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class UntitledApplication {
public static void main(String[] args) {
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "C:\\Users\\Administrator\\Desktop\\untitled");
MyMethodInterceptor interceptor = new MyMethodInterceptor();
TestService instance = (TestService) interceptor.getInstance(TestService.class);
String test = instance.test();
System.out.println("test = " + test);
}
}
2.1.4.查看动态生成的代理类
package com.example.untitled;
import java.lang.reflect.Method;
import net.sf.cglib.core.ReflectUtils;
import net.sf.cglib.core.Signature;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.Factory;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class TestService$$EnhancerByCGLIB$$7e0058f7 implements TestService, Factory {
// 删除了一些代码
}
2.2.CGLIB 代理类情况
2.2.1.有一个类
package com.example.untitled;
public class Demo {
public String test(){
return "demo test";
}
}
2.2.2.查看动态生成的代理类
package com.example.untitled;
import java.lang.reflect.Method;
import net.sf.cglib.core.ReflectUtils;
import net.sf.cglib.core.Signature;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.Factory;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class Demo$$EnhancerByCGLIB$$f99348cd extends Demo implements Factory {
// 删除了一些代码
}
3.总结
- JDK动态代理只支持代理接口,因为JDK动态代理生成的代理类默认实现了一个Proxy类,鉴于Java单继承多实现机制,顾只支持代理接口。
- CGLIB动态代理既支持代理接口也支持代理类,动态生成的代理类根据代理的对象情况,自动识别是接口还是类,生成对应的代理类。