java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Spring反射内置工具类ReflectionUtils

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

作者: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私有访问权限的操作。

对方法的操作

执行方法:

总结

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

您可能感兴趣的文章:
阅读全文