我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Spring实现泛型注入的示例详解

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Spring实现泛型注入的示例详解

1.Spring泛型注入

创建一个抽象泛型类BaseDao,有参数化类型T

public abstract class BaseDao<T> {
    
  public abstract void eat();
}

每种动物有不同的行为,猫、狗

public class Cat {

}

public class Dog {

}

分别继承BaseDao实现不同的行为 

@Repository
public class CatDao extends BaseDao<Cat> {

  @Override
  public void eat() {
    System.out.println("cat eat....");
  }
}
@Repository
public class DogDao extends BaseDao<Dog> {

  @Override
  public void eat() {
    System.out.println("dog eat....");
  }
}

接着创建一个抽象业务类,也有参数化类型T。

注意:此处不能使用@Resource注入,会找到多个BaseDao类型的bean,无法确认注入哪一个bean会报错

需要使用@Autowired注入,它有根据泛型参数匹配的逻辑,会一个个去匹配

public abstract class BaseService<T> {

  @Autowired
  private BaseDao<T> baseDao;


  protected void eat() {
    baseDao.eat();
  }
}

子类继承BaseService指定参数化类型实现注入相应的BaseDao

@Service
public class CatService extends BaseService<Cat> {


}
@Service
public class DogService extends BaseService<Dog> {

}

代码目录

测试 

@Configuration
@ComponentScan(value = "com.monian.test.generic")
public class GenericConfig {

}
public class GenericTests {

  public static void main(String[] args) {
    AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
    applicationContext.register(GenericConfig.class);
    applicationContext.refresh();

    DogService dogService = applicationContext.getBean(DogService.class);
    CatService catService = applicationContext.getBean(CatService.class);
    dogService.eat();
    catService.eat();
  }

}

结果输出,成功注入相应的BaseDao

2. 关于java泛型有四种Type

GenericArrayType泛型数组类型

public class GenericArrayTypeTest {


  public static class TestClass<S> {

    // 泛型数组
    private List<String>[] lists;

    // 泛型数组
    private S[] ss;

    private String[] s;
  }

  public static void main(String[] args) {

    Class cl = TestClass.class;
    for (Field field : cl.getDeclaredFields()) {
      System.out.println("filed's name:" + field.getName());

      Type genericType = field.getGenericType();
      System.out.println("Is it genericArrayType:" + (genericType instanceof GenericArrayType));

      if (genericType instanceof GenericArrayType) {
        GenericArrayType genericArrayType = (GenericArrayType) genericType;
        System.out.println(genericArrayType.getTypeName());
        Type genericComponentType = genericArrayType.getGenericComponentType();
        System.out.println(genericComponentType);
      }
      System.out.println();
    }
  }
}

result:

filed's name:lists
Is it genericArrayType:true
java.util.List<java.lang.String>[]
java.util.List<java.lang.String>

filed's name:ss
Is it genericArrayType:true
S[]
S

filed's name:s
Is it genericArrayType:false

ParameterizedType参数化类型

public class ParameterizedTypeTest {

  public static abstract class Test<T> {

    public abstract void test(T t);

  }

  public static class TestClass<T extends Number> extends Test<Integer> {

    private List<T> tList;

    private List<? extends Number> list;

    private Map<String, Integer> map;

    @Override
    public void test(Integer o) {

    }
  }


  public static void main(String[] args) {
    TestClass<Integer> tt = new TestClass<>();
    Class cl = tt.getClass();

    Type genericSuperclass = cl.getGenericSuperclass();
    assert genericSuperclass instanceof ParameterizedType;
    ParameterizedType parameterizedType1 = (ParameterizedType) genericSuperclass;
    System.out.println(parameterizedType1.getActualTypeArguments()[0]);

    for (Field field : cl.getDeclaredFields()) {
      System.out.println("field's name:" + field.getName());
      Type genericType = field.getGenericType();
      System.out.println("Is it ParameterizedType:" + (genericType instanceof ParameterizedType));

      if (genericType instanceof ParameterizedType) {
        ParameterizedType parameterizedType = (ParameterizedType) genericType;
        for (Type type : parameterizedType.getActualTypeArguments()) {
          System.out.println("actualType:" + type);
          System.out.println(type.getTypeName());
        }
      }
      System.out.println();
    }
  }

}

result:

class java.lang.Integer
field's name:tList
Is it ParameterizedType:true
actualType:T
T

field's name:list
Is it ParameterizedType:true
actualType:? extends java.lang.Number
? extends java.lang.Number

field's name:map
Is it ParameterizedType:true
actualType:class java.lang.String
java.lang.String
actualType:class java.lang.Integer
java.lang.Integer

TypeVariable 类型变量

public class TypeVariableTest {

  public static class TestClass<S extends Number, T> {

    private Map<S, T> map;
  }


  public static void main(String[] args) throws Exception {

    Class cl = TestClass.class;
    Field field = cl.getDeclaredField("map");
    Type genericType = field.getGenericType();
    ParameterizedType parameterizedType = (ParameterizedType) genericType;
    for (Type type : parameterizedType.getActualTypeArguments()) {
      TypeVariable typeVariable = (TypeVariable) type;
      // 类型变量名
      System.out.println(typeVariable.getName());
      // 变量上边界
      Type[] bounds = typeVariable.getBounds();
      System.out.println(Arrays.toString(bounds));
    }
  }
}

result:

S
[class java.lang.Number]
T
[class java.lang.Object]

WildcardType 通配符类型 

public class WildcardTypeTest {

  public static class TestClass {

    private List<? extends Number> lists;

    private Set<?> sets;

    private Map<? extends Number, ? super String> map;
  }

  public static void main(String[] args) {
    Class cl = TestClass.class;

    for (Field field : cl.getDeclaredFields()) {
      System.out.println("filed's name:" + field.getName());
      Type genericType = field.getGenericType();
      ParameterizedType parameterizedType = (ParameterizedType) genericType;
      for (Type type : parameterizedType.getActualTypeArguments()) {
        // 通配符类型
        WildcardType wildcardType = (WildcardType) type;
        System.out.println(wildcardType.getTypeName());
        // 上边界
        System.out.println("上边界" + Arrays.toString(wildcardType.getUpperBounds()));
        // 下边界
        System.out.println("下边界" + Arrays.toString(wildcardType.getLowerBounds()));
      }
      System.out.println();
    }
  }
}

result:

filed's name:lists
? extends java.lang.Number
上边界[class java.lang.Number]
下边界[]

filed's name:sets
?
上边界[class java.lang.Object]
下边界[]

filed's name:map
? extends java.lang.Number
上边界[class java.lang.Number]
下边界[]
? super java.lang.String
上边界[class java.lang.Object]
下边界[class java.lang.String]

 注:spring对泛型的解析主要是在ResolvableType类,掌握上述的基本知识后可以去阅读下相关源码

到此这篇关于Spring实现泛型注入的示例详解的文章就介绍到这了,更多相关Spring泛型注入内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Spring实现泛型注入的示例详解

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Java中泛型的示例详解

泛型机制在项目中一直都在使用,不仅如此,很多源码中都用到了泛型机制。本文将通过一些示例带大家深入了解一下Java的泛型机制,需要的可以了解一下
2022-11-13

java 泛型的详解及实例

java 泛型的详解及实例Java在1.5版本中增加了泛型,在没有泛型之前,从集合中读取每一个对象都需要进行强转,如果一不小心插入了类型错误的对象,在运行时就会报错,给日常开发带来了很多不必要的麻烦,比如以下代码:public class
2023-05-31

Java 获取泛型的类型实例详解

Java 获取泛型的类型实例详解Java 泛型实际上有很多缺陷,比如不能直接获取泛型的类型,不能获取带泛型类等。以下方式是不正确的:①.获取带泛型的类的类型Class lstUClazz = List.class
2023-05-31

Kotlin泛型的型变之路演变示例详解

这篇文章主要为大家介绍了Kotlin泛型的型变之路演变示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2022-12-21

Spring Bean注册与注入实现方法详解

首先,要学习Spring中的Bean的注入方式,就要先了解什么是依赖注入。依赖注入是指:让调用类对某一接口的实现类的实现类的依赖关系由第三方注入,以此来消除调用类对某一接口实现类的依赖。Spring容器中支持的依赖注入方式主要有属性注入、构造函数注入、工厂方法注入
2022-11-13

spring 重复注解和aop拦截的实现示例

前言:  1:jdk1.8开始支持重复注解@Repeatable实现  2:aop拦截需要拦截当前注解和@Repeatable指向的包装注解才可以完全拦截到,因为:1.当在在方法上只有一个注解时,aop拦截认为是非包装类型注解。2.当方法上有多个重复注解时,a
2020-09-23

Java 泛型的上界和下界通配符示例详解

这篇文章主要为大家通过示例介绍了Java 泛型的上界和下界通配符,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-05-14

Three.jsGLTF模型加载实现示例详解

这篇文章主要为大家介绍了Three.jsGLTF模型加载实现示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-05-16

Spring Batch教程(六)spring boot实现batch功能注解示例:读文件写入mysql

Spring batch 系列文章 Spring Batch教程(一) 简单的介绍以及通过springbatch将xml文件转成txt文件 Spring Batch教程(二)示例:将txt文件转成xml文件以及读取xml文件内容存储到数据库
2023-08-20

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录