Spring反射内置工具类ReflectionUtils用法及说明

 更新时间:2026年06月03日 15:10:33   作者:bingbingYang_88  
这段文章主要介绍了Java反射机制及其在获取sentinel熔断规则map和操作类属性方法中的应用,通过JDK和Spring的ReflectionUtils展示了如何优雅地处理反射操作,提升代码的可阅读性和维护性

前言

最近在搞通过sentinel熔断后,触发数据库代理ShardingSphere 代理直连DB的时候,这里需要通过反射获取sentinel熔断的规则map。

原先是通过jdk反射机制,发现一堆异常处理,特别的不友好,代码整洁度和可阅读性也不是很好,后面发现spring给我们提供了一个ReflectionUtils。

简直不要太香了。

反射

什么是反射

java反射机制在运行状态中,对于任何一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性。

这种动态的获取信息以及动态的调用对象的方法的功能我们称之为java的反射机制

eg:

类的class声明(class对象),变量(field),方法(method)等等信息,利用反射技术可以对一个类进行解剖,动态获取信息进行处理。

反射的实现

获取class对象的三种实现

Object ——> getClass();

 Demo demo = new Demo();
        Class<? extends Demo> clazz = demo.getClass();

任何数据对象(包括数据基本类型)都有一个静态的class属性

Class<Demo> clazz = Demo.class;

通过Class类的静态方法:forName(String className)(常用)

Class clazz = Class.forName("com.demo.Demo");

例子 获取类中hashMap的值

获取com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager 实体类中hashMap的数据,从以下JDK和spring的封装类中,我们能明显的感受到易用行。

通过JDK实现

 public void getRule()  {
        Class three = null;
        Object obj = null;
        Method getCircuitBreakers = null;
        try {
            three = Class.forName("com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager");
            obj = three.newInstance();
            Field[] declaredFields = three.getDeclaredFields();
            Field circuitBreakers1 = three.getDeclaredField("circuitBreakers");
            circuitBreakers1.setAccessible(true);
            HashMap<String, List<CircuitBreaker>> map = new HashMap<>();
            map = (HashMap<String, List<CircuitBreaker>>)circuitBreakers1.get(three);

            Method[] declaredMethods = three.getDeclaredMethods();
            Method getCircuitBreakers1 = three.getDeclaredMethod("getCircuitBreakers", String.class);

            getCircuitBreakers1.setAccessible(true);
            List<AbstractCircuitBreaker> invoke = (List<AbstractCircuitBreaker>) getCircuitBreakers1.invoke(obj, "http-api:/listFeedMessages");
            System.out.println("invoke--------"+JSONObject.toJSONString(invoke.get(0)));
            System.out.println(invoke.get(0).currentState().toString()+System.currentTimeMillis());
        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        }
    }

通过org.springframework.util.ReflectionUtils

 public void getRuleByUtil() {
        try {
            Class clazz=Class.forName("com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager");
            Field circuitBreakers = ReflectionUtils.findField(clazz, "circuitBreakers");
            ReflectionUtils.makeAccessible(circuitBreakers);
            HashMap<String, List<CircuitBreaker>> map= (HashMap<String, List<CircuitBreaker>>) ReflectionUtils.getField(circuitBreakers,clazz);
            System.out.println(map);
        }catch (ClassNotFoundException e){
            throw new RuntimeException(e);
        }
    }

对属性的操作

public static Field findField(Class<?> clazz, String name) 在类中查找指定属性

public void getRuleByUtil() {
        try {
            Class clazz=Class.forName("com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager");
            Field circuitBreakers = ReflectionUtils.findField(clazz, "circuitBreakers");
        }catch (ClassNotFoundException e){
            throw new RuntimeException(e);
        }
    }

public static Field findField(Class<?> clazz, @Nullable String name, @Nullable Class<?> type) 更精确的在类中查找指定属性,可以在指定属性的类型

public void getRuleByUtil() {
        try {
            Class clazz=Class.forName("com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager");
            Field circuitBreakers = ReflectionUtils.findField(clazz, "circuitBreakers",Map.class);
        }catch (ClassNotFoundException e){
            throw new RuntimeException(e);
        }
    }

public static Object getField(Field field, @Nullable Object target) 获取对象的值

public void getRuleByUtil() {
        try {
            Class clazz=Class.forName("com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager");
            Field circuitBreakers = ReflectionUtils.findField(clazz, "circuitBreakers");
            ReflectionUtils.makeAccessible(circuitBreakers);
            HashMap<String, List<CircuitBreaker>> map= (HashMap<String, List<CircuitBreaker>>) ReflectionUtils.getField(circuitBreakers,clazz);
            System.out.println(map);
        }catch (ClassNotFoundException e){
            throw new RuntimeException(e);
        }
    }

void setField(Field field, Object target, Object value),可以设置 target 对象的 field 属性值,值为 value。

public void getRuleByUtil() {
        try {
            Class clazz=Class.forName("com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager");
            Field circuitBreakers = ReflectionUtils.findField(clazz, "circuitBreakers");
            ReflectionUtils.makeAccessible(circuitBreakers);
            HashMap<String, List<CircuitBreaker>> map= (HashMap<String, List<CircuitBreaker>>) ReflectionUtils.setField(circuitBreakers,clazz,Lists.newArrayList());
            System.out.println(map);
        }catch (ClassNotFoundException e){
            throw new RuntimeException(e);
        }
    }

void makeAccessible(Field field),取消java的权限控制检查,方便private私有访问权限的操作。

对方法的操作

  • Method findMethod(Class clazz, String name),在类中查找指定名字方法
  • Method findMethod(Class clazz, String name, Class… paramTypes),有的时候同一个类可能会有多个方法名相同,形参数不同的重载方法,可以使用这个方法更精确的在类中找到指定方法;
  • Method[] getAllDeclaredMethods(Class leafClass),获得类中所有方法,包括继承而来的。

执行方法:

  • Object invokeMethod(Method method, Object target),执行无参数的方法;
  • Object invokeMethod(Method method, Object target, Object… args),执行有参数的方法
  • void makeAccessible(Method method),如果是私有方法,可以取消 Java 权限检查,以便后续执行该私有方法

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 为什么Java是程序员受欢迎的语言这几个原因你该清楚

    为什么Java是程序员受欢迎的语言这几个原因你该清楚

    Java一直稳居程序员很受欢迎的编程语言的榜首,是企业中使用最广泛的编程语言。这篇文章主要介绍了为什么Java是程序员受欢迎的语言这几个原因你该清楚,需要的朋友可以参考下
    2020-07-07
  • Java数据结构之红黑树的原理及实现

    Java数据结构之红黑树的原理及实现

    红黑树是一种特殊的二叉查找树,每个结点都要储存位表示结点的颜色,或红或黑。本文将通过示例为大家详细讲讲红黑树的原理及Java实现,感兴趣的可以了解一下
    2022-09-09
  • Java程序执行Cmd指令所遇问题记录及解决方案

    Java程序执行Cmd指令所遇问题记录及解决方案

    这篇文章主要介绍了Java程序执行Cmd指令所遇问题记录,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-09-09
  • 一文盘点Java创建实例对象的方式

    一文盘点Java创建实例对象的方式

    Java对象是通过加载、链接、初始化三大步骤来完成对象的创建及初始化,那么接下来就说一下Java创建实例对象的方式有哪几种,文中并通过代码示例讲解的非常详细,需要的朋友可以参考下
    2025-02-02
  • IDEA 单元测试创建方法详解(2020.03版本亲测)

    IDEA 单元测试创建方法详解(2020.03版本亲测)

    这篇文章主要介绍了IDEA 单元测试创建方法详解(2020.03版本亲测),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-10-10
  • mybatis-puls中的resultMap数据映射

    mybatis-puls中的resultMap数据映射

    这篇文章主要介绍了mybatis-puls中的resultMap数据映射,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • 解决Java中的强制类型转换和二进制表示问题

    解决Java中的强制类型转换和二进制表示问题

    这篇文章主要介绍了解决Java中的强制类型转换和二进制表示问题,需要的朋友可以参考下
    2019-05-05
  • 深入了解Java I/O 之File类

    深入了解Java I/O 之File类

    这篇文章主要介绍了Java I/O深入学习之File和RandomAccessFile, I/O系统即输入/输出系统,对于一门程序语言来说,创建一个好的输入/输出系统并非易事。需要的朋友可以参考下
    2021-08-08
  • springboot使用单元测试实战

    springboot使用单元测试实战

    这篇文章主要介绍了springboot使用单元测试实战,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-09-09
  • 使用spring的restTemplate注意点

    使用spring的restTemplate注意点

    这篇文章主要介绍了使用spring的restTemplate注意点,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-10-10

最新评论