返回
Java基础-探寻cglib动态代理的本质
见解分享
2024-01-20 17:11:53
cglib动态代理的本质
cglib动态代理与JDK动态代理相似,都采用了字节码技术,通过生成新的字节码实现对目标类的增强。cglib动态代理是通过修改目标类的字节码生成新的子类,从而实现动态代理。这种方式不需要实现接口,因此适用范围更广。
cglib动态代理与JDK动态代理的比较
特性 | cglib动态代理 | JDK动态代理 |
---|---|---|
目标类要求 | 不需要实现接口 | 必须实现接口 |
代理方式 | 生成新的子类 | 实现接口 |
适用范围 | 更广 | 仅限于实现了接口的类 |
性能 | 较低 | 较高 |
cglib动态代理的应用场景
cglib动态代理广泛应用于以下场景:
- 对没有实现接口的类进行动态代理
- 需要对目标类进行更细粒度的控制
- 需要提高代理的性能
实际应用案例
案例一:对没有实现接口的类进行动态代理
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class Main {
public static void main(String[] args) {
// 创建目标类对象
Target target = new Target();
// 创建Enhancer对象
Enhancer enhancer = new Enhancer();
// 设置目标类
enhancer.setSuperclass(Target.class);
// 设置方法拦截器
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
// 在方法调用前后执行自定义逻辑
System.out.println("方法调用前");
Object result = proxy.invokeSuper(obj, args);
System.out.println("方法调用后");
return result;
}
});
// 创建代理类对象
Target proxy = (Target) enhancer.create();
// 调用代理类的方法
proxy.sayHello();
}
}
class Target {
public void sayHello() {
System.out.println("Hello world!");
}
}
案例二:对目标类进行更细粒度的控制
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class Main {
public static void main(String[] args) {
// 创建目标类对象
Target target = new Target();
// 创建Enhancer对象
Enhancer enhancer = new Enhancer();
// 设置目标类
enhancer.setSuperclass(Target.class);
// 设置方法拦截器
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
// 根据方法名进行不同的处理
if ("sayHello".equals(method.getName())) {
// 对sayHello方法进行增强
System.out.println("方法调用前");
Object result = proxy.invokeSuper(obj, args);
System.out.println("方法调用后");
return result;
} else {
// 对其他方法不进行增强
return proxy.invokeSuper(obj, args);
}
}
});
// 创建代理类对象
Target proxy = (Target) enhancer.create();
// 调用代理类的方法
proxy.sayHello();
proxy.sayGoodbye();
}
}
class Target {
public void sayHello() {
System.out.println("Hello world!");
}
public void sayGoodbye() {
System.out.println("Goodbye world!");
}
}
案例三:提高代理的性能
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class Main {
public static void main(String[] args) {
// 创建目标类对象
Target target = new Target();
// 创建Enhancer对象
Enhancer enhancer = new Enhancer();
// 设置目标类
enhancer.setSuperclass(Target.class);
// 设置方法拦截器
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
// 缓存方法调用结果
Map<String, Object> cache = new HashMap<>();
String key = method.getName() + Arrays.toString(args);
if (cache.containsKey(key)) {
// 从缓存中获取结果
return cache.get(key);
} else {
// 调用目标类的方法并缓存结果
Object result = proxy.invokeSuper(obj, args);
cache.put(key, result);
return result;
}
}
});
// 创建代理类对象
Target proxy = (Target) enhancer.create();
// 调用代理类的方法
proxy.sayHello();
proxy.sayHello();
}
}
class Target {
public void sayHello() {
System.out.println("Hello world!");
}
}
总结
cglib动态代理是一种功能强大的动态代理技术,可以对目标类进行更细粒度的控制。cglib动态代理与JDK动态代理各有优缺点,在实际项目中应根据具体情况选择合适的动态代理技术。