前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring 的这个工具类操作对象类型真是方便

Spring 的这个工具类操作对象类型真是方便

作者头像
码农小胖哥
发布2021-01-04 10:19:16
1.1K0
发布2021-01-04 10:19:16
举报

1. 前言

今天在看Spring Security源码的时候无意间注意到两行代码;

ResolvableType type = ResolvableType.forClassWithGenerics(OAuth2UserService.class, OAuth2UserRequest.class, OAuth2User.class);

ApplicationContext context = getContext();

String[] names= context.getBeanNamesForType(type);

if (names.length == 1) {
 OAuth2UserService<OAuth2UserRequest, OAuth2User> bean =  (OAuth2UserService<OAuth2UserRequest, OAuth2User>) context.getBean(names[0]);
}

ResolvableType居然可以这样获取一个带泛型的类型,于是就研究了一番。

2. ResolvableType

通常我们想获取一个类型的信息都要通过 Java 反射从对应的Class类型中来获取信息,API 非常地底层,操作也十分繁琐。ResolvableType的出现简化了这一过程,文章的开头就是ResolvableType通过其静态方法来描述了一个带泛型的类型OAuth2UserService<OAuth2UserRequest, OAuth2User>,然后就可以从Spring IoC中获取对应的Spring Bean。那么它还有其它那些功能呢?

ResolvableType不能被直接实例化,不过它提供了很多的静态方法。

forClass

Class对象中获取类型的信息,它有一个重载方法可以从基类和实现类中获取组合的类型信息,例如:

//  java.lang.String
ResolvableType resolvableType1 = ResolvableType.forClass(String.class);
//  java.util.Map<?, ?>
ResolvableType resolvableType2 = ResolvableType.forClass(Map.class, HashMap.class);

forClassWithGenerics

Class对象中获取类型的信息,并且携带泛型,文章开头的例子就是。

forConstructorParameter

获取构造函数中特定参数的元信息,例如

User user = new User(“张三”);
 Constructor<?> constructor = user.getClass().getConstructors()[0]
// java.lang.String
ResolvableType.forConstructorParameter(constructor,0)

forField

从成员属性中获取成员属性的类型信息。例如:

    private HashMap<String, List<Object>> map;

    public void test() throws NoSuchFieldException {

        Field field = getClass().getDeclaredField("map");
        // java.util.HashMap<java.lang.String, java.util.List<java.lang.Object>>
        ResolvableType resolvableType = ResolvableType.forField(field);
    }

forMethodParameter

获取方法的参数类型信息。

User user = new User(“张三”);
// setName(String)
Method method = user.getClass().getMethods()[0];
// java.lang.String
ResolvableType.forMethodParameter(method,0)

forMethodReturnType

获取方法返回值的类型信息。

forArrayComponent

获取特定类型组成的数组形式。例如

ResolvableType resolvableType = ResolvableType.forClass(String.class);
// java.lang.String []
ResolvableType arrayComponent = ResolvableType.forArrayComponent(resolvableType);

forInstance

甚至还可以从对象实例中获取该对象的类型信息。

实例方法

那么问题来了,这到底有什么用呢?

当你需要利用反射获取 类实例、成员变量、方法的信息时就可以使用该操作类。它提供了获取基类、接口、Class对象、泛型类型等解析功能。例如我们可以从一个成员变量中可以获取:

 private HashMap<Integer, List<String>> myMap;

   public void example() {
       ResolvableType t = ResolvableType.forField(getClass().getDeclaredField("myMap"));
       t.getSuperType(); // AbstractMap<Integer, List<String>>
       t.asMap(); // Map<Integer, List<String>>
       t.getGeneric(0).resolve(); // Integer
       t.getGeneric(1).resolve(); // List
       t.getGeneric(1); // List<String>
       t.resolveGeneric(1, 0); // String
   }

感觉可以替代一些常见的反射操作,而且易用性更强。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-12-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码农小胖哥 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 前言
  • 2. ResolvableType
    • forClass
      • forClassWithGenerics
        • forConstructorParameter
          • forField
            • forMethodParameter
              • forMethodReturnType
                • forArrayComponent
                  • forInstance
                    • 实例方法
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档