相比起Java SDK动态代理只能够对接口进行代理,同时返回的代理对象也只能转换到某个接口类型,Cglib动态代理能够做到直接代理类。
Cglib动态代理demo代码:
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CGLibDemo {
static class Service {
public void sayHello() {
System.out.println("say hello~~~~~");
}
}
static class SimpleInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("before--" + method.getName());
Object result = methodProxy.invokeSuper(o, objects);
System.out.println("after--" + method.getName());
return result;
}
}
private static <T> T getProxy(Class<T> tClass) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(tClass);
enhancer.setCallback(new SimpleInterceptor());
return (T) enhancer.create();
}
public static void main(String[] args) {
Service service = getProxy(Service.class);
service.sayHello();
}
}
运行结果如下:
从以上demo代码中可以发现,这里要被代理的对象不是接口,然后会通过cglib的Enhancer类的setSuperclass()方法设置被代理的类,setCallback()方法设置被代理类的被public修饰符修饰且非final方法被调用时的处理类,这个处理类就是我们自己定义的实现了MethodInterceptor接口的类,最后通过create()方法生成了该类的代理对象。
总结
与Java SDK动态代理做个对比,可以发现Cglib动态代理也是动态生成类。不过Cglib动态代理生成的类的父类是被代理的类,而Java SDK动态代理的父类统一都是Proxy。