首页 > 其他分享 >动态代理的几种方式

动态代理的几种方式

时间:2023-07-25 17:45:52浏览次数:28  
标签:对象 Object 代理 几种 动态 方法 public targetObject

JDK动态代理:是Java标准库提供的一种动态代理实现方式,基于接口生成代理对象。使用Proxy类和InvocationHandler接口来创建代理对象,被代理的类必须实现接口。

CGlib动态代理:使用CGLib库实现,通过生成目标类的子类来创建代理对象。不需要目标类实现接口,可以直接代理普通类。

区别:JDK代理只能对实现接口的类生成代理;CGlib是针对类实现代理,对指定的类生成一个子类,并覆盖其中的方法,这种通过继承类的实现方式,不能代理final修饰的类。

 

注意:类的私有方法、类的pulibc+final方法、以及final类,JDK和CGLib均无法进行动态代理,因为私有、final均不可被代理。

 

1. 接口类

public interface DDService {
    public void addUser(String id,String password);
}

2. 实现类

public class DDServiceImpl implements DDService{
    @Override
    public void addUser(String id, String password) {
        System.out.println("调用 addUser方法");
    }
}

3. JDK动态代理类

public class JDKProxy implements InvocationHandler {
    //需要代理的目标对象
    private Object targetObject;

    /**
     * 创建 JDK 动态代理类实例
     */
    public Object newProxy(Object targetObject) {
        // 将目标对象传入进行代理
        this.targetObject = targetObject;
        // JDK提供的用于创建代理对象的静态方法, 返回代理对象
        return Proxy.newProxyInstance(
                targetObject.getClass().getClassLoader(),   // 指定目标类的类加载
                targetObject.getClass().getInterfaces(),    // 代理需要实现的接口
                this    // 调用代理对象逻辑的拦截器,即InvocationHandler 实现类
        );
    }

    /**
     * 动态代理方法拦截器。每当代理对象的方法被调用时,都会进入该方法
     *
     * @param proxy  代理目标对象的代理对象,它是真实的代理对象。
     * @param method 被拦截的目标类的方法
     * @param args   执行目标类的方法的参数
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //进行逻辑处理的函数
        checkPopedom();
        //调用目标对象上对应的方法,并传入相应的参数。
        Object ret = method.invoke(targetObject, args);
        //返回目标方法的执行结果。
        return ret;
    }

    /**
     * 检查权限
     */
    private void checkPopedom() {
        System.out.println("检查权限");
    }
}

4. CGLib动态代理类

public class CGLibProxy implements MethodInterceptor {
    /**
     * 创建 CGLib 动态代理类实例
     */
    public Object createProxyObject(Object targetObject) {
        // 创建Enhancer对象,用于创建代理对象
        Enhancer enhancer = new Enhancer();
        // 设置目标类的类加载器
        enhancer.setClassLoader(targetObject.getClass().getClassLoader());
        // 设置代理目标类
        enhancer.setSuperclass(targetObject.getClass());
        // 设置方法拦截器
        enhancer.setCallback(this);
        // 创建代理对象
        return enhancer.create();
    }

    /**
     * 动态代理方法拦截器。每当代理对象的方法被调用时,都会进入该方法
     *
     * @param proxy       代理目标对象的代理对象,它是真实的代理对象。
     * @param method      被拦截的目标类的方法
     * @param args        执行目标类的方法的参数
     * @param methodProxy CGLib提供的用于调用目标方法的代理对象。通过这个MethodProxy对象,可以调用目标方法而不必使用Java的反射机制。
     */
    @Override
    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        //进行逻辑处理的函数
        if ("addUser".equals(method.getName())) {
            //检查权限
            checkPopedom();
        }
        //调用目标对象上对应的方法,并传入相应的参数。
        Object obj = methodProxy.invokeSuper(proxy, args);
        return obj;
    }

    private void checkPopedom() {
        System.out.println("检查权限:checkPopedom()!");
    }
}

5. Test类

public static void main(String[] args) {
    System.out.println("JDKProxy:======================");
    DDService userManagerJDK = (DDService) new JDKProxy().newProxy(new DDServiceImpl());
    userManagerJDK.addUser("tom", "root");

    System.out.println("CGLib:======================");
    DDService userManager = (DDService) new CGLibProxy().createProxyObject(new DDServiceImpl());
    userManager.addUser("tom", "root");
}

输出

JDKProxy:======================
检查权限
调用 addUser方法
CGLib:======================
检查权限:checkPopedom()!
调用 addUser方法

 

标签:对象,Object,代理,几种,动态,方法,public,targetObject
From: https://www.cnblogs.com/yifanSJ/p/17580439.html

相关文章

  • 2023长郡集训 动态规划笔记
    动态规划原理何为动态规划?动态规划(\(\text{Dynamicprogramming}\)),简称DP。DP并不是一种算法,与模拟、贪心一样,而是一种解决问题的方式。DP的基本思想为「将给定的问题拆分为一个个规模更小的子问题,直到子问题可以直接解决,返回/保存这个值,再根据方程一步步推出原本问题的答......
  • 平台关闭影响业务开展?IPIDEA为您提供稳定可靠的全球IP代理服务
    最近几天非常抱歉收到这样的消息:某些平台效仿911代理商,突然关闭服务,这使得大量用户的业务不能正常开展。对于用户来讲,遭遇这种突如其来的情况实在令人沮丧,我们建议您尽快与该平台的客服团队联系,了解具体情况。同时,如果您不想因为平台的原因影响到公司业务的进度,也可以寻找其他可靠......
  • ASEMI代理海矽美快恢复二极管SFP6002的特性和应用分析
    编辑-Z二极管SFP6002是一种常见的电子元件,也被称为快恢复二极管。它具有快速恢复时间和低反向恢复电流的特点,适用于高频电路和开关电源等应用。 SFP6002的主要特性包括:1.快速恢复时间:SFP6002具有快速的恢复时间,可以在电流反向变化时迅速恢复到正常工作状态。这使得它在高频......
  • Vue3.0 页面跳转的几种方式
     首先引入import{useRouter}from"vue-router";使用router接收useRouterconstrouter=useRouter(); 1. router.push我们最常用的router.push方法会将新的路由添加到历史记录中,同时会导航到该路由页面,当用户点击浏览器后退按钮时,则回到之前的URL。//保留......
  • 动态SQL
    什么是动态SQL:动态SQL就是指根据不同的条件生成不同的SQL语句利用动态SQL这一特性可以彻底摆脱这种痛苦。动态SQL元素和JSTL或基于类似XML的文本处理器相似。在MyBatis之前的版本中,有很多元素需要花时间了解。MyBatis3大大精简了元素种类,现在只需学习原来一半的元素......
  • HTTP代理爬虫在大数据分析中的崭新应用
    HTTP代理爬虫在大数据分析中的崭新应用作为一家专业的HTTP代理产品供应商,我们深知HTTP代理爬虫在大数据分析中的重要性和价值。在这个领域中,HTTP代理爬虫不仅帮助企业高效地获取数据,还可以为数据分析提供强有力的支持,让您的业务在大数据时代脱颖而出。HTTP代理爬虫是一种通过使用HT......
  • 代理IP的扩展和分布式部署策略​
    代理IP的扩展和分布式部署策略在如今信息爆炸的时代,网络抓取已经成为许多行业中必不可少的一环。而要进行网络抓取,使用代理IP是一种常见的方式。然而,在应对大规模数据爬取的需求时,我们需要考虑代理IP的扩展和分布式部署策略,以提高网络抓取的稳定性和效率。本文将向您介绍一些关键策......
  • 代理IP的来源和选择标准
    代理IP的来源和选择标准在今天的互联网时代,隐私保护和网络安全成为了我们越来越关注的问题。使用代理IP是一种常见的手段,可以隐藏真实的IP地址,保护个人隐私。然而,选择合适的代理IP供应商和标准变得至关重要。本文将为大家分享代理IP的来源和选择标准,帮助你保护网络隐私。首先,我们需......
  • 几种验证端口开启的方法
    TLDRmacOS下,验证服务器端口是否连通的方法[telnet](#telnet)[nc](#netcat(nc))[nmap](#nmap)tip:扫描端口时,需要注意不要违反网络安全规定,避免对他人的网络造成不必要的干扰和损害。背景网络相关的记忆,都就着饭吃到肚子里了......
  • 几种验证端口开启的方法
    TLDRmacOS下,验证服务器端口是否连通的方法[telnet](#telnet)[nc](#netcat(nc))[nmap](#nmap)tip:扫描端口时,需要注意不要违反网络安全规定,避免对他人的网络造成不必要的干扰和损害。背景网络相关的记忆,都就着饭吃到肚子里了今天需要验证服务器端口是否可以连通,......