上一篇说了通过JDK实现实现了动态代理,但是用JDK实现代理,要求所代理的类必须实现一个接口。如果我们类不实现接口,这就在无法使用JDK提供的Proxy来实现动态代理,这个时候我们应该怎么办呢?我们找到了一个能代理没有接口的类,就是CGLib类库。

1、什么是CGLib?

Byte Code Generation Library is high level API to generate and transform Java byte code. It is used by AOP, testing, data access frameworks to generate
dynamic proxy objects and intercept field access.

1)CGlib是一个强大的,高性能,高质量的Code生成类库。它可以在运行期扩展Java类与实现Java接口。

2)CGLib使用ASM(Java字节码操控框架),转换字节码并生成新的class。

3)Spring AOP和hibernate动用到了CGLib来实现动态代理。

2、下面我们来用CGLib实现动态代理

1)创建一个需要被代理的类:Hello

public class  Hello {

    public void say(String name) {

        System.out.println("Hello!"+name);
} }

2)创建CGLib代理类:CGLipProxy

public class CGLipProxy implements MethodInterceptor {

    private static CGLipProxy instance = new CGLipProxy();

    private CGLipProxy(){

    }

    public static CGLipProxy getInstance(){
return instance;
} public <T> T getProxy(Class<T> cls) {
return (T) Enhancer.create(cls, this);
} @Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
before();
Object result = methodProxy.invokeSuper(obj,args);
after();
return result;
} private void before() {
System.out.println("Before");
} private void after() {
System.out.println("After"); }
}

3、客户端的应用

public class Test {

    public static void main(String[] args){

        Hello helloProxy =CGLipProxy.getInstance().getProxy(HelloImpl.class);
helloProxy.say("Tom"); }
}

4、总结

以上我们通过代码实现了用CGLib来创建没有接口的类,但工作中我们应该怎么选择呢?是CGLib的性能更优呢还是JDK的Proxy呢?JDK动态代理是通过Proxy这个类反射生成的真实对象,每个代理类都必须要调用Proxy,而CGLIB采用字节码操控ASM直接生成class,显然当代理的类多了,Proxy就会遇到瓶颈,当然我们在工作中还要根据选择的JDK来决定究竟用哪一个?

05-28 14:06