使用cglib动态代理实现前置通知与后置通知

本文介绍了如何使用JDK和Cglib库实现动态代理,展示了前后置通知的两种方式,并提及了使用函数式接口进行有返回值的拦截。测试代码演示了在UserServiceImpl中应用动态代理进行操作控制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

动态代理类


/**
 * @author 李亚杰
 * @date 2024/4/7 10:57
 * @description MyProxyUtil
 */
public class MyProxyUtil {
    /**
     * JDK动态代理
     *
     * @param t   需要被代理的对象
     * @param <T>
     * @return
     */
    @SuppressWarnings("unchecked")
    public static <T> T getProxyByJDK(@NotNull T t) {
        return (T) Proxy.newProxyInstance(t.getClass().getClassLoader(),
                t.getClass().getInterfaces(),
                (proxy, method, args) -> method.invoke(t, args)
        );
    }

   /**
     *
     * @param t   动态代理类
     * @param before  前置通知方法
     * @param after   后置通知方法
     * @return
     * @param <T>
     */
    @SuppressWarnings("unchecked")
    public static <T> T getProxyByCglib(@NotNull T t, Runnable before, Runnable after) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(t.getClass());
        enhancer.setCallback((MethodInterceptor) (obj, method, args, proxy) -> {
            before.run();
            Object object = proxy.invokeSuper(obj, args);
            after.run();
            return object;
        });
        return (T) enhancer.create();
    }

}

测试方法

@Test
    public void test02(){
        UserServiceImpl userService = new UserServiceImpl();
        UserServiceImpl proxyByCglib = MyProxyUtil.getProxyByCglib(userService,
                ()-> System.out.println("前置通知"),
                () -> System.out.println("后置通知")
        );
        proxyByCglib.insert(new User());
    }

结果

也可以通过将函数式接口改为Function<T,R>的方式实现前置拦截。

代码如下

@SuppressWarnings("unchecked")
    public static <T> T getProxyByCglib(@NotNull T t, Function<Object[],Boolean> before, Runnable after) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(t.getClass());
        enhancer.setCallback((MethodInterceptor) (obj, method, args, proxy) -> {
            if (!before.apply(args)) {
                return null;
            }
            Object object = proxy.invokeSuper(obj, args);
            after.run();
            return object;
        });
        return (T) enhancer.create();
    }

测试代码

@Test
    public void test02() {
        UserServiceImpl userService = new UserServiceImpl();
        UserServiceImpl proxyByCglib = MyProxyUtil.getProxyByCglib(userService,
                (args) -> {
                    System.out.println("前置拦截");
                    User user = (User) args[0];
                    return user != null;
                },
                () -> System.out.println("后置通知")
        );
        proxyByCglib.insert(null);
        System.out.println("_________");
        proxyByCglib.insert(new User());
    }

测试结果

通过有返回值的函数实现了拦截效果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

财大彭于晏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值