Spring泛型注入
默念x 人气:01.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类,掌握上述的基本知识后可以去阅读下相关源码
加载全部内容