CGLib和JDK动态代理的区别与选择
CGLib和JDK动态代理是Java中两种常见的实现动态代理的方式。在选择使用哪种方式时,我们需要了解它们的区别和适用场景。
1. CGLib和JDK动态代理的原理和概念:
- JDK动态代理是通过Java的反射机制来实现的。它要求被代理类实现一个接口,并且通过InvocationHandler接口来拦截方法调用并进行处理。
- CGLib动态代理则是通过继承被代理类并重写其方法来实现的。它不要求被代理类实现接口,可以直接对类进行代理。
2. CGLib和JDK动态代理的特点:
- JDK动态代理只能代理实现了接口的类,对于没有实现接口的类无法直接进行代理。而CGLib则可以对任意类进行代理,包括没有实现接口的类。
- JDK动态代理在生成代理类时需要消耗一定的时间,而CGLib则需要更多的时间来生成代理类。所以在性能要求较高的场景下,JDK动态代理可能更合适。
3. CGLib和JDK动态代理的选择:
- 如果被代理的类已经实现了接口,优先选择JDK动态代理。它的使用更简单,不需要额外的依赖。
- 如果被代理的类没有实现接口,或者需要对类的方法进行代理,那么只能选择CGLib动态代理。
下面是使用JDK动态代理和CGLib动态代理的示例代码:
JDK动态代理示例:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
interface UserService {
void save();
}
class UserServiceImpl implements UserService {
public void save() {
System.out.println("Save user");
}
}
class LogHandler implements InvocationHandler {
private Object target;
public LogHandler(Object target) {
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("Before method: " + method.getName());
Object result = method.invoke(target, args);
System.out.println("After method: " + method.getName());
return result;
}
}
public class Main {
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
LogHandler logHandler = new LogHandler(userService);
UserService proxy = (UserService) Proxy.newProxyInstance(
userService.getClass().getClassLoader(),
userService.getClass().getInterfaces(),
logHandler
);
proxy.save();
}
}
CGLib动态代理示例:
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
class UserService {
public void save() {
System.out.println("Save user");
}
}
class LogInterceptor implements MethodInterceptor {
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy)
throws Throwable {
System.out.println("Before method: " + method.getName());
Object result = proxy.invokeSuper(obj, args);
System.out.println("After method: " + method.getName());
return result;
}
}
public class Main {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(UserService.class);
enhancer.setCallback(new LogInterceptor());
UserService userService = (UserService) enhancer.create();
userService.save();
}
}
通过以上代码示例,我们可以清楚地看到两种动态代理方式的使用方法和效果。根据实际的需求和场景,选择合适的动态代理方式来实现我们的代理逻辑。