Java动态代理实例(JDK/CGLIB)

动态代理是 Java 中一种强大的技术,它允许在运行时创建代理类和对象。在 Java 中,主要有两种动态代理的实现方式:JDK 动态代理和 CGLIB 动态代理。下面分别介绍这两种方式的实例。

JDK 动态代理

JDK 动态代理是通过 java.lang.reflect 包中的 Proxy 类和 InvocationHandler 接口实现的。首先,我们需要定义一个实现了 InvocationHandler 接口的代理类,然后通过 Proxy.newProxyInstance 方法创建代理对象。

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

// 定义接口
interface Hello {
    void sayHello();
}

// 实现 InvocationHandler 接口的代理类
class MyInvocationHandler implements InvocationHandler {
    private Object target;

    public MyInvocationHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("Before method invocation");
        Object result = method.invoke(target, args);
        System.out.println("After method invocation");
        return result;
    }
}

// 测试
public class JDKDynamicProxyExample {
    public static void main(String[] args) {
        // 创建被代理的对象
        Hello realSubject = new HelloImpl();

        // 创建代理对象
        Hello proxy = (Hello) Proxy.newProxyInstance(
                Hello.class.getClassLoader(),
                new Class[]{Hello.class},
                new MyInvocationHandler(realSubject)
        );

        // 调用代理对象的方法
        proxy.sayHello();
    }
}

// 被代理的实际类
class HelloImpl implements Hello {
    @Override
    public void sayHello() {
        System.out.println("Hello, world!");
    }
}

在上面的例子中,MyInvocationHandler 是实现了 InvocationHandler 接口的代理类,通过它的 invoke 方法,在方法调用前后加入了额外的逻辑。Proxy.newProxyInstance 方法创建了代理对象,该对象实现了 Hello 接口。

CGLIB 动态代理

CGLIB(Code Generation Library)是一个代码生成库,它可以在运行时动态生成字节码,实现对类的增强。CGLIB 动态代理不要求目标对象实现接口,相比于 JDK 动态代理更加灵活。

import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import net.sf.cglib.proxy.Enhancer;

// 被代理的类
class Hello {
    public void sayHello() {
        System.out.println("Hello, world!");
    }
}

// 实现 MethodInterceptor 接口的代理类
class MyMethodInterceptor implements MethodInterceptor {
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("Before method invocation");
        Object result = proxy.invokeSuper(obj, args);
        System.out.println("After method invocation");
        return result;
    }
}

// 测试
public class CGLIBDynamicProxyExample {
    public static void main(String[] args) {
        // 创建 Enhancer 对象
        Enhancer enhancer = new Enhancer();
        // 设置被代理的类
        enhancer.setSuperclass(Hello.class);
        // 设置回调函数
        enhancer.setCallback(new MyMethodInterceptor());

        // 创建代理对象
        Hello proxy = (Hello) enhancer.create();

        // 调用代理对象的方法
        proxy.sayHello();
    }
}

在这个例子中,MyMethodInterceptor 实现了 CGLIB 的 MethodInterceptor 接口,通过它的 intercept 方法,在方法调用前后加入了额外的逻辑。Enhancer 类用于生成代理对象,通过设置被代理的类、回调函数等参数,最后调用 create 方法生成代理对象。

总体而言,JDK 动态代理适用于接口代理,而 CGLIB 动态代理适用于类代理。选择使用哪种方式取决于具体的需求和场景。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值