解析动态代理jdk的Proxy与spring的CGlib
什么是动态代理
动态代理是一种代理模式,它的作用是通过创建一个代理类来代替原始类进行引用,可以使用 Java API 来生成动态代理类,这个过程不需要预先定义代理类的代码。
JDK动态代理
JDK动态代理是Java提供的一种代理方式,需要有接口来实现代理。在运行时,它会为一个或多个接口动态生成一个实现类,该类实现了这些接口的所有方法,并将方法调用转移到一个指定的调用处理程序上。
JDK动态代理示例:
public interface IUserDao {
void save();
}
public class UserDaoImpl implements IUserDao {
@Override
public void save() {
System.out.println("save user");
}
}
public class ProxyFactory implements InvocationHandler {
private Object target;
public ProxyFactory(Object target) {
this.target = target;
}
public Object getProxy() {
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before");
Object result = method.invoke(target, args);
System.out.println("after");
return result;
}
}
public class JDKDynamicProxyTest {
public static void main(String[] args) {
IUserDao userDao = new UserDaoImpl();
ProxyFactory proxyFactory = new ProxyFactory(userDao);
IUserDao proxy = (IUserDao) proxyFactory.getProxy();
proxy.save();
}
}
CGLib动态代理
CGLib(Code Generation Library)动态代理也是创建代理的一种方式,它是一个强大的、高性能的代码生成包,它能够在运行时动态生成字节码,从而创建一个动态代理对象。
CGLib动态代理示例:
public class User {
private int id;
public User(int id) {
this.id = id;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public void save() {
System.out.println("save user");
}
}
public class CGLibProxy implements MethodInterceptor {
private Object target;
public CGLibProxy(Object target) {
this.target = target;
}
public Object getProxy() {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(target.getClass());
enhancer.setCallback(this);
return enhancer.create();
}
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("before");
Object result = proxy.invokeSuper(obj, args);
System.out.println("after");
return result;
}
}
public class CGLibDynamicProxyTest {
public static void main(String[] args) {
CGLibProxy cgLibProxy = new CGLibProxy(new User(1));
User proxy = (User) cgLibProxy.getProxy();
proxy.save();
}
}
JDK动态代理与CGLib动态代理的区别
-
接口:JDK动态代理可以为接口动态创建代理类,而CGLib动态代理不需要接口,可以针对类创建代理。
-
代理对象:JDK动态代理只能代理实现了接口的类,而CGLib动态代理可以代理任意类。
-
性能:CGLib动态代理更加强大和高效,但是在创建代理对象的时候比JDK动态代理更耗费时间和空间。
-
调用方式:JDK动态代理是通过反射调用方法,而CGLib动态代理是通过内存调用方法。
综上所述,JDK动态代理和CGLib动态代理在实现方式上存在一些差异,应根据不同的场景来选择合适的代理方式。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:解析动态代理jdk的Proxy与spring的CGlib(包括区别介绍) - Python技术站