共计 2820 个字符,预计需要花费 8 分钟才能阅读完成。
Java 动态代理可以通过以下几种方式实现:
- 使用
java.lang.reflect.Proxy
类:Proxy
类提供了一个静态方法newProxyInstance()
,可以通过传入目标对象的类加载器、目标对象实现的接口和InvocationHandler
接口的实现类来创建代理对象。InvocationHandler
接口的实现类负责处理代理对象的方法调用。代理对象在调用方法时,会把方法调用转发给InvocationHandler
的invoke()
方法,从而实现代理功能。
public interface Subject {void doSomething();
}
public class RealSubject implements Subject {public void doSomething() {System.out.println("RealSubject doSomething");
}
}
public class MyInvocationHandler implements InvocationHandler {private Subject target;
public MyInvocationHandler(Subject target) {this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("Before method invoke");
Object result = method.invoke(target, args);
System.out.println("After method invoke");
return result;
}
}
public class Main {public static void main(String[] args) {Subject realSubject = new RealSubject();
Subject proxySubject = (Subject) Proxy.newProxyInstance(realSubject.getClass().getClassLoader(),
realSubject.getClass().getInterfaces(),
new MyInvocationHandler(realSubject));
proxySubject.doSomething();}
}
- 使用
CGLib
库:CGLib
是一个基于ASM
框架的字节码生成库,它可以在运行时动态生成目标对象的子类,并覆盖其中的方法以实现代理功能。
public interface Subject {void doSomething();
}
public class RealSubject implements Subject {public void doSomething() {System.out.println("RealSubject doSomething");
}
}
public class MyMethodInterceptor implements MethodInterceptor {public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {System.out.println("Before method invoke");
Object result = proxy.invokeSuper(obj, args);
System.out.println("After method invoke");
return result;
}
}
public class Main {public static void main(String[] args) {Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(RealSubject.class);
enhancer.setCallback(new MyMethodInterceptor());
Subject proxySubject = (Subject) enhancer.create();
proxySubject.doSomething();}
}
需要注意的是,使用 CGLib
实现动态代理时,目标对象不能是 final
类或者包含 final
方法,因为 CGLib
是通过生成目标对象的子类来实现代理的。
- 使用
ByteBuddy
库:ByteBuddy
是一个轻量级的字节码操作库,它可以在运行时动态生成目标对象的子类,并覆盖其中的方法以实现代理功能。
public interface Subject {void doSomething();
}
public class RealSubject implements Subject {public void doSomething() {System.out.println("RealSubject doSomething");
}
}
public class MyInterceptor implements MethodInterceptor {public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {System.out.println("Before method invoke");
Object result = proxy.invokeSuper(obj, args);
System.out.println("After method invoke");
return result;
}
}
public class Main {public static void main(String[] args) throws Exception {Class<? extends Subject> proxyClass = new ByteBuddy()
.subclass(Subject.class)
.method(any()).intercept(MethodDelegation.to(MyInterceptor.class))
.make()
.load(RealSubject.class.getClassLoader())
.getLoaded();
Subject proxySubject = proxyClass.getDeclaredConstructor().newInstance();
proxySubject.doSomething();}
}
需要注意的是,使用 ByteBuddy
实现动态代理时,需要引入 net.bytebuddy:byte-buddy
和net.bytebuddy:byte-buddy-agent
两个依赖。
丸趣 TV 网 – 提供最优质的资源集合!
正文完