Cglib代理-代码增强测试

导包

<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>3.3.0</version>
</dependency>

编写方法拦截器

  • 方法增强具体逻辑
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * 自定义 cglib 代理
 *
 * @author Ara
 * @since 2022/6/20
 */
public class MyCglibProxyMethodInterceptor<T> implements MethodInterceptor {

    /**
     * 目标对象
     */
    private final T target;

    /**
     * 构造方法
     */
    public MyCglibProxyMethodInterceptor(T target) {
        this.target = target;
    }

    /**
     * 获取代理对象
     */
    public T getProxyObject(){
        Enhancer enhancer = new Enhancer();
        //设置父类 因为cglib是针对指定的类生成一个子类用于其增强行为
        enhancer.setSuperclass(target.getClass());
        enhancer.setCallback(this);
        return (T) enhancer.create();
    }

    // TODO 执行增强部分
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("执行前 方法参数: " + Arrays.toString(objects));

        Object result = method.invoke(target, objects);

        System.out.println("执行后 返回值: " + result);

        return result;
    }
}

编写待增强测试类

  • 增强目标点
/**
 * 文章 Service
 *
 * @author Ara
 * @since 2022/6/20
 */
public class ArticleService {

    public String saveArticle(String article) {
        System.out.printf("保存文章[%s]...%n", article);
        return article;
    }

}

编写测试

  • 检验是否能够进行增强
public class MainTest {
    public static void main(String[] args) {
        ArticleService articleService = new ArticleService();
        //声明Cglib方法拦截增强实现类
        MyCglibProxyMethodInterceptor<ArticleService> cglibProxyMethodInterceptor = new MyCglibProxyMethodInterceptor<>(articleService);
        // 获取代理类
        ArticleService articleServiceProxy = cglibProxyMethodInterceptor.getProxyObject();

        //使用代理类调用方法
        articleServiceProxy.saveArticle("Java");
    }
}

验证结果

在这里插入图片描述

小总结

简单对比cglib与JDK动态代理:

  • 这里使用cglib进行代理时,不论其目标类是否实现了接口,都可以对其进行增强。
  • 但是单独使用JDK动态代理,就只能增强实现了接口的类重写的方法。

博主JDK动态代理的文章链接

以下是对cglib和JDK动态代理是否能够增强有无接口实现的类的对比代码,感兴趣的读者可以进行测试:

public class MainTest {
    public static void main(String[] args) {
        cglibProxyNoInterfaceTest();
    }

    /**
     * cglib代理(代理目标类未实现接口)
     */
    private static void cglibProxyNoInterfaceTest(){
        ArticleService articleService = new ArticleService();
        //声明Cglib方法拦截增强实现类
        MyCglibProxyMethodInterceptor<ArticleService> cglibProxyMethodInterceptor = new MyCglibProxyMethodInterceptor<>(articleService);
        // 获取代理类
        ArticleService articleServiceProxy = cglibProxyMethodInterceptor.getProxyObject();

        //使用代理类调用方法
        articleServiceProxy.saveArticle("Java");
    }

    /**
     * cglib代理(代理目标类实现了接口)
     */
    private static void cglibProxyHasInterfaceTest(){
        UserService userService = new UserServiceImpl();
        //声明Cglib方法拦截增强实现类
        MyCglibProxyMethodInterceptor<UserService> cglibProxyMethodInterceptor = new MyCglibProxyMethodInterceptor<>(userService);
        // 获取代理类
        UserService userServiceProxy = cglibProxyMethodInterceptor.getProxyObject();

        //使用代理类调用方法
        userServiceProxy.add("Ara");
    }

    /**
     * JDK动态代理(代理目标类实现了接口)
     */
    private static void jdkDynamicProxyHasInterfaceTest(){
        //原对象 (接口接收参数)
        UserService userService = new UserServiceImpl();

        //声明增强处理程序
        MyJdkProxyInvocationHandler<UserService> proxyInvocationHandler = new MyJdkProxyInvocationHandler<>(userService);
        //获取代理对象
        UserService proxyUserService = proxyInvocationHandler.getProxyObject();

        //使用代理对象来调用方法
        proxyUserService.add("Ara");
    }

    /**
     * JDK动态代理(代理目标类未实现接口)
     * 有误,使用JDK动态代理实现增强,必须要求代理目标实现了接口
     */
    private static void jdkDynamicProxyNoInterfaceTest(){
        ArticleService articleService = new ArticleService();

        //声明增强处理程序
        MyJdkProxyInvocationHandler<ArticleService> proxyInvocationHandler = new MyJdkProxyInvocationHandler<>(articleService);
        //获取代理对象
        ArticleService proxyArticleService = proxyInvocationHandler.getProxyObject();

        //使用代理对象来调用方法
        proxyArticleService.saveArticle("Java");
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值