收藏私塾在线
 

欢迎您来到私塾在线网!   

请登录! 

免费注册 


zhang的笔记
状态: 离线
人气:3918153
访问用户量:4234
笔记经验:
总积分:261656
级别:VIP5
搜索本笔记
ta的交流分类
ta的交流主题贴(325)
ta的所有交流贴(824)
ta的全部笔记
全部笔记(137)
未分类笔记(0)
Java Web(8)
并发实践(1)
课程问题(0)
Java(22)
架构(1)
缓存(5)
JavaEE(0)
JVM(7)
跟我学spring3(52)
Spring Sec……(3)
Spring 3.x……(4)
Spring Sec……(3)
跟开涛学Spring……(14)
深入剖析Spring……(10)
性能调优(6)
前端(1)
Tomcat源码解读(0)
spring sec……(0)
存档
2014-01(3)
2013-12(8)
2012-10(4)
2012-09(2)
2012-08(15)
2012-07(9)
2012-06(0)
2012-05(7)
2012-04(1)
2012-03(3)
2012-02(43)
2011-11(16)
2011-10(26)

2013-12-23 07:46:37
Spring4新特性——更好的Java泛型操作API
浏览(14164)|评论(0)   交流分类:Java|笔记分类: 跟我学spring3

Spring4新特性——泛型限定式依赖注入

Spring4新特性——核心容器的其他改进

Spring4新特性——Web开发的增强

Spring4新特性——集成Bean Validation 1.1(JSR-349)到SpringMVC 

Spring4新特性——Groovy Bean定义DSL

Spring4新特性——更好的Java泛型操作API 

 

随着泛型用的越来越多,获取泛型实际类型信息的需求也会出现,如果用原生API,需要很多步操作才能获取到泛型,比如:

ParameterizedType parameterizedType = 
    (ParameterizedType) ABService.class.getGenericInterfaces()[0];
Type genericType = parameterizedType.getActualTypeArguments()[1];

 

Spring提供的ResolvableType API,提供了更加简单易用的泛型操作支持,如:

ResolvableType resolvableType1 = ResolvableType.forClass(ABService.class);
resolvableType1.as(Service.class).getGeneric(1).resolve()

对于获取更复杂的泛型操作ResolvableType更加简单。

 

假设我们的API是:

public interface Service<N, M> {
}

@org.springframework.stereotype.Service
public class ABService implements Service<A, B> {
}

@org.springframework.stereotype.Service
public class CDService implements Service<C, D> {
}

如上泛型类非常简单。 

 

1、得到类型的泛型信息

ResolvableType resolvableType1 = ResolvableType.forClass(ABService.class);

通过如上API,可以得到类型的ResolvableType,如果类型被Spring AOP进行了CGLIB代理,请使用ClassUtils.getUserClass(ABService.class)得到原始类型。

 

可以通过如下得到泛型参数的第1个位置(从0开始)的类型信息

resolvableType1.getInterfaces()[0].getGeneric(1).resolve()

因为我们泛型信息放在 Service<A, B> 上,所以需要resolvableType1.getInterfaces()[0]得到;

 

通过getGeneric(泛型参数索引)得到某个位置的泛型;

resolve()把实际泛型参数解析出来

 

2、得到字段级别的泛型信息

假设我们的字段如下:

   @Autowired
    private Service<A, B> abService;
    @Autowired
    private Service<C, D> cdService;

    private List<List<String>> list;

    private Map<String, Map<String, Integer>> map;

    private List<String>[] array;

 

通过如下API可以得到字段级别的ResolvableType

ResolvableType resolvableType2 =
                ResolvableType.forField(ReflectionUtils.findField(GenricInjectTest.class, "cdService"));

 

然后通过如下API得到Service<C, D>的第0个位置上的泛型实参类型,即C

resolvableType2.getGeneric(0).resolve()

 

比如 List<List<String>> list;是一种嵌套的泛型用例,我们可以通过如下操作获取String类型:

ResolvableType resolvableType3 =
                ResolvableType.forField(ReflectionUtils.findField(GenricInjectTest.class, "list"));
resolvableType3.getGeneric(0).getGeneric(0).resolve();

 

更简单的写法

resolvableType3.getGeneric(0, 0).resolve(); //List<List<String>> 即String 

 

比如Map<String, Map<String, Integer>> map;我们想得到Integer,可以使用:

ResolvableType resolvableType4 =
                ResolvableType.forField(ReflectionUtils.findField(GenricInjectTest.class, "map"));
resolvableType4.getGeneric(1).getGeneric(1).resolve();

更简单的写法  

resolvableType4.getGeneric(1, 1).resolve()

 

3、得到方法返回值的泛型信息