马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
在Java中,动态代理是一种在运行时动态创建代理类及其对象的技能。与静态代理不同,动态代理的代理类并不是在编译时创建的,而是在运行时根据需要动态生成。这种技能提供了更高的灵活性和可扩展性,因为它允许开发者在运行时根据需要添加或修改代理的举动。
动态代理的实现方式
在Java中,动态代理主要有两种实现方式:基于JDK的动态代理和基于CGLib的动态代理。
1. 基于JDK的动态代理
JDK动态代理主要依赖于`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口。`Proxy`类提供了创建动态代理类和实例的静态方法,而`InvocationHandler`接口则需要用户实现,以定义代理对象的举动。
JDK动态代理主要适用于实现了接口的类。
示例代码
- import java.lang.reflect.InvocationHandler;
- import java.lang.reflect.Method;
- import java.lang.reflect.Proxy;
- // 定义一个接口
- interface Subject {
- void doSomething();
- }
- // 实现接口的类
- class RealSubject implements Subject {
- @Override
- public void doSomething() {
- System.out.println("RealSubject.doSomething()");
- }
- }
- // 实现InvocationHandler接口
- class DynamicProxyHandler implements InvocationHandler {
- private Object target; // 真实对象
- public DynamicProxyHandler(Object target) {
- this.target = target;
- }
- @Override
- 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;
- }
- // 获取动态代理的实例
- @SuppressWarnings("unchecked")
- public static <T> T getProxyInstance(T target, Class<T> interfaceType) {
- return (T) Proxy.newProxyInstance(
- interfaceType.getClassLoader(), // 类加载器
- new Class<?>[]{interfaceType}, // 代理类需要实现的接口列表
- new DynamicProxyHandler(target) // 调用处理器
- );
- }
- }
- public class DynamicProxyExample {
- public static void main(String[] args) {
- // 创建真实对象
- RealSubject realSubject = new RealSubject();
- // 获取动态代理对象
- Subject proxySubject = DynamicProxyHandler.getProxyInstance(realSubject, Subject.class);
- // 通过代理对象调用方法
- proxySubject.doSomething();
- }
- }
复制代码
当运行上面的代码时,输出将是:
- Before method: doSomething
- RealSubject.doSomething()
- After method: doSomething
复制代码
在这个例子中,`DynamicProxyHandler`类实现了`InvocationHandler`接口,并在其`invoke`方法中定义了代理的举动。`getProxyInstance`静态方法用于获取动态代理的实例。留意,这个方法的返回范例是泛型,这允许我们创建任何实现了特定接口的代理对象。
2. 基于CGLib的动态代理
CGLib(Code Generation Library)是一个强大的、高性能的、高质量的Code生成类库,它可以在运行时扩展Java类和实现接口。CGLib通过继承的方式动态地创建目标类的子类,从而实现对目标类方法的拦截。
由于CGLib是通过继承的方式实现动态代理的,因此它不仅可以代理实现了接口的类,还可以代理没有实现任何接口的类。但是,由于Java的单继承限制,CGLib动态代理不能代理final类或者final方法。
示例代码
要使用CGLib,你起首需要将CGLib的jar包添加到你的项目中。以下是一个简单的CGLib动态代理的示例:
- import net.sf.cglib.proxy.Enhancer;
- import net.sf.cglib.proxy.MethodInterceptor;
- import net.sf.cglib.proxy.MethodProxy;
- // 定义一个没有实现接口的类
- class RealSubject {
- public void doSomething() {
- System.out.println("RealSubject.doSomething()");
- }
- }
- // 实现MethodInterceptor接口
- class CglibProxyInterceptor implements MethodInterceptor {
- @Override
- 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 CglibDynamicProxyExample {
- public static void main(String[] args) {
- // 创建真实对象
- RealSubject realSubject = new RealSubject();
-
- // 使用CGLib创建动态代理对象
- Enhancer enhancer = Enhancer.create(); // 创建Enhancer实例
- enhancer.setSuperclass(RealSubject.class); // 设置代理类的父类为RealSubject类
- enhancer.setCallback(new CglibProxyInterceptor()); // 设置回调,即我们要实现的逻辑
- RealSubject proxy = (RealSubject) enhancer.create(); // 创建代理对象并返回
-
- // 通过代理对象调用方法
- proxy.doSomething();
- }
- }
复制代码
当运行上面的代码时,输出结果将是:
- Before method: doSomething
- RealSubject.doSomething()
- After method: doSomething
复制代码
在这个例子中,我们使用CGLib库中的`Enhancer`类来创建动态代理。我们起首通过`setSuperclass`方法设置代理类的父类为`RealSubject`。然后通过`setCallback`方法设置回调,即我们实现的逻辑。在这个例子中,我们实现了`CglibProxyInterceptor`来定义代理对象的举动。这个类实现了`MethodInterceptor`接口,它有两个主要的方法:`intercept`和`getProxy』。`intercept`方法负责在目标方法的调用前后添加额外的逻辑。在这个例子中,我们在目标方法执行前后打印出日志信息。末了我们通过调用`create`方法来创建代理对象。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |