动态代理

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?