Spring 中优雅的获取泛型信息的方法

简介

Spring 源码是个大宝库,我们能遇到的大部分工具在源码里都能找到,所以笔者开源的 mica 完全基于 Spring 进行基础增强,不重复造轮子。今天我要分享的是在 Spring 中优雅的获取泛型。

获取泛型

自己解析

我们之前的处理方式,代码来源 vjtools(江南白衣)。

/**
 * 通过反射, 获得Class定义中声明的父类的泛型参数的类型.
 *
 * 注意泛型必须定义在父类处. 这是唯一可以通过反射从泛型获得Class实例的地方.
 *
 * 如无法找到, 返回Object.class.
 *
 * 如public UserDao extends HibernateDao<User,Long>
 *
 * @param clazz clazz The class to introspect
 * @param index the Index of the generic declaration, start from 0.
 * @return the index generic declaration, or Object.class if cannot be determined
 */
public static Class getClassGenericType(final Class clazz, final int index) {

  Type genType = clazz.getGenericSuperclass();

  if (!(genType instanceof ParameterizedType)) {
    logger.warn(clazz.getSimpleName() + "'s superclass not ParameterizedType");
    return Object.class;
  }

  Type[] params = ((ParameterizedType) genType).getActualTypeArguments();

  if ((index >= params.length) || (index < 0)) {
    logger.warn("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: "
        + params.length);
    return Object.class;
  }
  if (!(params[index] instanceof Class)) {
    logger.warn(clazz.getSimpleName() + " not set the actual class on superclass generic parameter");
    return Object.class;
  }

  return (Class) params[index];
}

ResolvableType 工具

从 Spring 4.0 开始 Spring 中添加了 ResolvableType 工具,这个类可以更加方便的用来回去泛型信息。
首先我们来看看官方示例:

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
}

详细说明

构造获取 Field 的泛型信息

ResolvableType.forField(Field)

构造获取 Method 的泛型信息

ResolvableType.forMethodParameter(Method, int)

构造获取方法返回参数的泛型信息

ResolvableType.forMethodReturnType(Method)

构造获取构造参数的泛型信息

ResolvableType.forConstructorParameter(Constructor, int)

构造获取类的泛型信息

ResolvableType.forClass(Class)

构造获取类型的泛型信息

ResolvableType.forType(Type)

构造获取实例的泛型信息

ResolvableType.forInstance(Object)

更多使用 Api 请查看,ResolvableType java doc: https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/core/ResolvableType.html

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • spring中通过ApplicationContext getBean获取注入对象的方法实例

    用SpringContextUtil实现ApplicationContextAware package util; import java.util.Locale; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; pub

  • Springboot项目打war包docker包找不到resource下静态资源的解决方案

    前一段时间遇到一个问题,是关于读取项目中文件资源的问题.我是一个maven工程 我把一张照片放到resource下面,然后在本地读取的时候可以读取到,但是一旦打成WAR包以后就总是包找不到文件资源错误.我的war包是springboot打的war包,是内嵌的tomcat所以不解压,然后系统去找路径的时候会发现是个WAR包,而图片在WAR包内,所以找不到. 为了解决这个问题,我走了好多弯路,一直在路径上花费时间. 一开始使用修改配置文件的方式: # 配置静态资源访问前缀 spring.mvc.st

  • 详解spring-boot下如何满足多生产环境中个性化定制功能

    在项目的开发中,我们很难做到开发一套标准的流程来解决所有客户的需求.比如,我们当前的计量项目,分别运行于赤峰市和河北省.虽然两个区域处理的业务相同,但是对细节的实现要求却不同.前面也学习过计量检定软件,其为了解决各个定制者使用的功能需求,最后采取的方案是:将基础项目复制多份,进而满足不同的客户需求.优点当然是有的,但比起缺点来,优点便不值一提.缺点很明显,总结为一句话就是:项目变得难以维护.所以,当前让我们看到的就是,几个开发人员,每天处于解决问题当中.本文将给出一种方案,来有效的规避上述问题.

  • Springboot-dubbo-fescar 阿里分布式事务的实现方法

    大家可以自行百度下阿里分布式事务,在这里我就不啰嗦了.下面是阿里分布式事务开源框架的一些资料,本文是springboot+dubbo+fescar的集成. 快速开始 https://github.com/alibaba/fescar/wiki/Quick-Start GIT地址 https://github.com/alibaba/fescar 1.sql CREATE TABLE `undo_log` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `br

  • activemq整合springboot使用方法(个人微信小程序用)

    主题 ActiveMQ Spring Boot 小程序开发 1.引入依赖 <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.3.RELEASE</version> <relativePath /> <!-- lookup

  • spring boot定时任务接收邮件并且存储附件的方法讲解

    在spring boot中写定时任务很简单,两个注解就可以实现.在启动类中加@EnableScheduling ,然后在你需要定时的方法上加上@Scheduled(cron="0 10 8 * * ?"):括号内为cron表达式.如下图: 接收邮件及其判断是否有附件,并且存储附件. public class TimerTaskServiceImpl implements TimerTaskService { @Autowired private ParseTxtServiceImpl

  • Spring通过ApplicationContext主动获取bean的方法讲解

    问题1: 有个异步线程Runnable里面需要用到dao,无法通过AutoWired和compoment注解传递进来. 于是希望通过Spring context主动去获取bean. 问题2: getBean(name)获取失败. 解决: 默认的dao的name=类名(首字母小写) 例如: 接口名称:TemplateDao 则getName("templateDao")即可 通用的SpringContextUtil获取Bean 1.实现ApplicationContextAware接口

  • spring @Transactional 无效的解决方案

    关于@Transactional注解 一般都认为要注意以下三点 1 .在需要事务管理的地方加@Transactional 注解.@Transactional 注解可以被应用于接口定义和接口方法.类定义和类的 public 方法上 . 2 . @Transactional 注解只能应用到 public 可见度的方法上 . 如果你在 protected.private 或者 package-visible 的方法上使用 @Transactional 注解,它也不会报错, 但是这个被注解的方法将不会展

  • Spring自带的校验框架Validation的使用实例

    1.首先来一个项目结构图以及所需jar包 可以看到,没有添加除了日志和jstl相关的jar包外,没有其他spring以外的第三方jar包(即使用的是spring自带的校验框架). 2.从前台页面开始,首先是接收用户信息的表单loginForm.jsp <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@

  • 详解Spring框架下向异步线程传递HttpServletRequest参数的坑

    在spring的注解 @RequestMapping 之下可以直接获取 HttpServletRequest 来获得诸如request header等重要的请求信息: @Slf4j @RestController @RequestMapping("/test") public class TestController { private static final String HEADER = "app-version"; @RequestMapping(value

随机推荐