动态代理
JVM 动态代理
JVM 动态代理(基于接口)
只能代理有接口的类,通过实现接口生成代理类。
Spring 默认使用 JDK 动态代理。
CGLib(Code Generation Library) 代理(基于子类继承)
通过继承目标类生成子类,没接口也能代理。
spring 默认使用 JVM动态代理,当目标类无接口,或启用
proxyTargetClass=true
时,Spring 使用 CGLib。
上代码
public interface HelloWorld {
void sayHello(String name);
}
public class HelloWorldImpl implements HelloWorld {
@Override
public void sayHello(String name) {
System.out.println("Hello " + name);
}
}
public class CustomInvocationHandler implements InvocationHandler {
private Object target;
public CustomInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("Before invocation");
Object retVal = method.invoke(target, args);
System.out.println("After invocation");
return retVal;
}
}
public class ProxyTest {
public static void main(String[] args) throws Exception {
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
CustomInvocationHandler handler = new CustomInvocationHandler(new HelloWorldImpl());
HelloWorld proxy = (HelloWorld) Proxy.newProxyInstance(
ProxyTest.class.getClassLoader(),
new Class[]{HelloWorld.class},
handler);
proxy.sayHello("Mikan");
}
}
// 获取计数
long num = nextUniqueNumber.getAndIncrement();
// 默认情况下,代理类的完全限定名为:com.sun.proxy.$Proxy0,com.sun.proxy.$Proxy1……依次递增
String proxyName = proxyPkg + proxyClassNamePrefix + num;
// 这里才是真正的生成代理类的字节码的地方
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
proxyName, interfaces);
public final class $Proxy0 extends Proxy implements HelloWorld {
Last updated
Was this helpful?