首页后端开发其他后端知识Spring泛型注入有几种,如何实现?

Spring泛型注入有几种,如何实现?

时间2024-03-24 17:20:05发布访客分类其他后端知识浏览488
导读:这篇文章主要为大家详细介绍了Spring泛型注入有几种,如何实现?的内容,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望对大家学习或工作能有帮助,接下来就跟随小编一起来学习吧。1.Spring泛型注入 创建一个抽...
这篇文章主要为大家详细介绍了Spring泛型注入有几种,如何实现?的内容,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望对大家学习或工作能有帮助,接下来就跟随小编一起来学习吧。

1.Spring泛型注入

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

public abstract class BaseDaoT>
 {
    
    
  public abstract void eat();

}

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

public class Cat {


}


public class Dog {


}
    

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

@Repository
public class CatDao extends BaseDaoCat>
 {


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

  }

}
    
@Repository
public class DogDao extends BaseDaoDog>
 {


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

  }

}
    

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

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

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

public abstract class BaseServiceT>
 {
    

  @Autowired
  private BaseDaoT>
     baseDao;



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

  }

}
    

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

@Service
public class CatService extends BaseServiceCat>
 {



}
    
@Service
public class DogService extends BaseServiceDog>
 {


}

代码目录

测试

@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 TestClassS>
 {
    

    // 泛型数组
    private ListString>
    [] 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.Listjava.lang.String> []
java.util.Listjava.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 TestT>
 {
    

    public abstract void test(T t);


  }
    

  public static class TestClassT extends Number>
     extends TestInteger>
 {
    

    private ListT>
     tList;
    

    private List? extends Number>
     list;
    

    private MapString, Integer>
     map;


    @Override
    public void test(Integer o) {


    }

  }



  public static void main(String[] args) {
    
    TestClassInteger>
     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 TestClassS extends Number, T>
 {
    

    private MapS, 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泛型注入有几种,如何实现?内容,欢迎关注网络资讯频道,小编将为大家输出更多高质量的实用文章!

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!


若转载请注明出处: Spring泛型注入有几种,如何实现?
本文地址: https://pptw.com/jishu/652205.html
JVM提供哪些引用方法,目的是什么? Java如何实现Dijkstra算法,代码是怎样

游客 回复需填写必要信息