Cglib简介
在 Java 中,CGLIB(Code Generation Library)是一个强大的、高性能的代码生成库,它可以在运行时扩展 Java 类与实现 Java 接口,常用于实现动态代理。与 Java 自带的动态代理不同,CGLIB 可以为没有实现接口的类创建代理,它通过生成目标类的子类来实现代理功能。
实现案例
1、配置maven依赖:
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2.2</version>
</dependency>
2、目标代理对象
// 目标类
public class TargetClass {
public void doSomething() {
System.out.println("目标类执行操作:做一些事情");
}
}
3、通过拦截器实现功能扩展
//配置一个拦截器
public class MyMethodInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("在调用方法前执行额外的操作");
//调用方法
Object result = methodProxy.invokeSuper(o,objects);
System.out.println("方法后执行的操作");
return result;
}
}
4、创建代理对象
public class CglibProxyExample {
public static <T> Object getProxy(T t){
// 创建 Enhancer 对象
Enhancer enhancer = new Enhancer();
// 设置要代理的目标类
enhancer.setSuperclass(TargetClass.class);
// 设置方法拦截器
enhancer.setCallback(new MyMethodInterceptor());
// 创建代理对象
TargetClass proxy = (TargetClass) enhancer.create();
// // 调用代理对象的方法
// proxy.doSomething();
return proxy;
}
}
5、测试类
public class Test {
public static void main(String[] args) {
TargetClass targetClass = (TargetClass) CglibProxyExample.getProxy(new TargetClass());
System.out.println(targetClass.getClass().getName());
targetClass.doSomething();
}
}
总结
优点:
- CGLIB 可以为没有实现任何接口的普通类创建代理,它通过生成目标类的子类来实现代理功能。这使得 CGLIB 的使用场景更加广泛,特别是在处理一些遗留代码或者第三方库中的类时,这些类可能没有实现接口,但又需要进行代理增强。
- 在创建代理对象的过程中,虽然 CGLIB 需要生成字节码并加载类,有一定的初始化开销,但一旦代理类生成并加载到 JVM 中,后续的方法调用性能通常比 Java 反射实现的动态代理要好。尤其是在方法调用频繁的场景下,CGLIB 的性能优势会更加明显。
缺点:
- 由于 CGLIB 是通过生成目标类的子类来实现代理的,因此目标类不能是
final
类,因为final
类不能被继承。同样,目标类中的final
方法也不能被代理,因为final
方法不能被重写。这在一定程度上限制了 CGLIB 的使用范围