Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
爱吃血肠
spring-framework
提交
25e29b85
S
spring-framework
项目概览
爱吃血肠
/
spring-framework
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
S
spring-framework
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
25e29b85
编写于
5月 14, 2013
作者:
J
Juergen Hoeller
提交者:
unknown
5月 14, 2013
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
GenericTypeResolver defensively calls Class.getGenericSuperclass() and consistently uses Class<?>
Issue: SPR-10559
上级
23737a45
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
85 addition
and
70 deletion
+85
-70
spring-context/src/main/java/org/springframework/context/event/GenericApplicationListenerAdapter.java
...work/context/event/GenericApplicationListenerAdapter.java
+3
-3
spring-core/src/main/java/org/springframework/core/GenericCollectionTypeResolver.java
...g/springframework/core/GenericCollectionTypeResolver.java
+9
-3
spring-core/src/main/java/org/springframework/core/GenericTypeResolver.java
...in/java/org/springframework/core/GenericTypeResolver.java
+45
-30
spring-core/src/main/java/org/springframework/core/ParameterizedTypeReference.java
.../org/springframework/core/ParameterizedTypeReference.java
+23
-31
spring-core/src/test/java/org/springframework/core/ParameterizedTypeReferenceTests.java
...springframework/core/ParameterizedTypeReferenceTests.java
+5
-3
未找到文件。
spring-context/src/main/java/org/springframework/context/event/GenericApplicationListenerAdapter.java
浏览文件 @
25e29b85
/*
* Copyright 2002-201
2
the original author or authors.
* Copyright 2002-201
3
the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
...
...
@@ -54,9 +54,9 @@ public class GenericApplicationListenerAdapter implements SmartApplicationListen
@Override
public
boolean
supportsEventType
(
Class
<?
extends
ApplicationEvent
>
eventType
)
{
Class
typeArg
=
GenericTypeResolver
.
resolveTypeArgument
(
this
.
delegate
.
getClass
(),
ApplicationListener
.
class
);
Class
<?>
typeArg
=
GenericTypeResolver
.
resolveTypeArgument
(
this
.
delegate
.
getClass
(),
ApplicationListener
.
class
);
if
(
typeArg
==
null
||
typeArg
.
equals
(
ApplicationEvent
.
class
))
{
Class
targetClass
=
AopUtils
.
getTargetClass
(
this
.
delegate
);
Class
<?>
targetClass
=
AopUtils
.
getTargetClass
(
this
.
delegate
);
if
(
targetClass
!=
this
.
delegate
.
getClass
())
{
typeArg
=
GenericTypeResolver
.
resolveTypeArgument
(
targetClass
,
ApplicationListener
.
class
);
}
...
...
spring-core/src/main/java/org/springframework/core/GenericCollectionTypeResolver.java
浏览文件 @
25e29b85
/*
* Copyright 2002-201
2
the original author or authors.
* Copyright 2002-201
3
the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
...
...
@@ -19,6 +19,7 @@ package org.springframework.core;
import
java.lang.reflect.Array
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.GenericArrayType
;
import
java.lang.reflect.MalformedParameterizedTypeException
;
import
java.lang.reflect.Method
;
import
java.lang.reflect.ParameterizedType
;
import
java.lang.reflect.Type
;
...
...
@@ -446,8 +447,13 @@ public abstract class GenericCollectionTypeResolver {
return
null
;
}
if
(
clazz
.
getSuperclass
()
!=
null
&&
isIntrospectionCandidate
(
clazz
.
getSuperclass
()))
{
return
extractType
(
clazz
.
getGenericSuperclass
(),
source
,
typeIndex
,
typeVariableMap
,
typeIndexesPerLevel
,
nestingLevel
,
currentLevel
);
try
{
return
extractType
(
clazz
.
getGenericSuperclass
(),
source
,
typeIndex
,
typeVariableMap
,
typeIndexesPerLevel
,
nestingLevel
,
currentLevel
);
}
catch
(
MalformedParameterizedTypeException
ex
)
{
// from getGenericSuperclass() - ignore and continue with interface introspection
}
}
Type
[]
ifcs
=
clazz
.
getGenericInterfaces
();
if
(
ifcs
!=
null
)
{
...
...
spring-core/src/main/java/org/springframework/core/GenericTypeResolver.java
浏览文件 @
25e29b85
...
...
@@ -18,6 +18,7 @@ package org.springframework.core;
import
java.lang.reflect.Array
;
import
java.lang.reflect.GenericArrayType
;
import
java.lang.reflect.MalformedParameterizedTypeException
;
import
java.lang.reflect.Method
;
import
java.lang.reflect.ParameterizedType
;
import
java.lang.reflect.Type
;
...
...
@@ -74,12 +75,12 @@ public abstract class GenericTypeResolver {
* @param clazz the class to resolve type variables against
* @return the corresponding generic parameter or return type
*/
public
static
Class
<?>
resolveParameterType
(
MethodParameter
methodParam
,
Class
clazz
)
{
public
static
Class
<?>
resolveParameterType
(
MethodParameter
methodParam
,
Class
<?>
clazz
)
{
Type
genericType
=
getTargetType
(
methodParam
);
Assert
.
notNull
(
clazz
,
"Class must not be null"
);
Map
<
TypeVariable
,
Type
>
typeVariableMap
=
getTypeVariableMap
(
clazz
);
Type
rawType
=
getRawType
(
genericType
,
typeVariableMap
);
Class
result
=
(
rawType
instanceof
Class
?
(
Class
)
rawType
:
methodParam
.
getParameterType
());
Class
<?>
result
=
(
rawType
instanceof
Class
?
(
Class
)
rawType
:
methodParam
.
getParameterType
());
methodParam
.
setParameterType
(
result
);
methodParam
.
typeVariableMap
=
typeVariableMap
;
return
result
;
...
...
@@ -227,7 +228,7 @@ public abstract class GenericTypeResolver {
* @param genericIfc the generic interface or superclass to resolve the type argument from
* @return the resolved type of the argument, or {@code null} if not resolvable
*/
public
static
Class
<?>
resolveTypeArgument
(
Class
clazz
,
Class
genericIfc
)
{
public
static
Class
<?>
resolveTypeArgument
(
Class
<?>
clazz
,
Class
<?>
genericIfc
)
{
Class
[]
typeArgs
=
resolveTypeArguments
(
clazz
,
genericIfc
);
if
(
typeArgs
==
null
)
{
return
null
;
...
...
@@ -248,11 +249,11 @@ public abstract class GenericTypeResolver {
* @return the resolved type of each argument, with the array size matching the
* number of actual type arguments, or {@code null} if not resolvable
*/
public
static
Class
[]
resolveTypeArguments
(
Class
clazz
,
Class
genericIfc
)
{
public
static
Class
[]
resolveTypeArguments
(
Class
<?>
clazz
,
Class
<?>
genericIfc
)
{
return
doResolveTypeArguments
(
clazz
,
clazz
,
genericIfc
);
}
private
static
Class
[]
doResolveTypeArguments
(
Class
ownerClass
,
Class
classToIntrospect
,
Class
genericIfc
)
{
private
static
Class
[]
doResolveTypeArguments
(
Class
<?>
ownerClass
,
Class
<?>
classToIntrospect
,
Class
<?>
genericIfc
)
{
while
(
classToIntrospect
!=
null
)
{
if
(
genericIfc
.
isInterface
())
{
Type
[]
ifcs
=
classToIntrospect
.
getGenericInterfaces
();
...
...
@@ -264,10 +265,15 @@ public abstract class GenericTypeResolver {
}
}
else
{
Class
[]
result
=
doResolveTypeArguments
(
ownerClass
,
classToIntrospect
.
getGenericSuperclass
(),
genericIfc
);
if
(
result
!=
null
)
{
return
result
;
try
{
Class
[]
result
=
doResolveTypeArguments
(
ownerClass
,
classToIntrospect
.
getGenericSuperclass
(),
genericIfc
);
if
(
result
!=
null
)
{
return
result
;
}
}
catch
(
MalformedParameterizedTypeException
ex
)
{
// from getGenericSuperclass() - return null to skip further superclass traversal
return
null
;
}
}
classToIntrospect
=
classToIntrospect
.
getSuperclass
();
...
...
@@ -275,7 +281,7 @@ public abstract class GenericTypeResolver {
return
null
;
}
private
static
Class
[]
doResolveTypeArguments
(
Class
ownerClass
,
Type
ifc
,
Class
genericIfc
)
{
private
static
Class
[]
doResolveTypeArguments
(
Class
<?>
ownerClass
,
Type
ifc
,
Class
<?>
genericIfc
)
{
if
(
ifc
instanceof
ParameterizedType
)
{
ParameterizedType
paramIfc
=
(
ParameterizedType
)
ifc
;
Type
rawType
=
paramIfc
.
getRawType
();
...
...
@@ -301,7 +307,7 @@ public abstract class GenericTypeResolver {
/**
* Extract a class instance from given Type.
*/
private
static
Class
extractClass
(
Class
ownerClass
,
Type
arg
)
{
private
static
Class
<?>
extractClass
(
Class
<?>
ownerClass
,
Type
arg
)
{
if
(
arg
instanceof
ParameterizedType
)
{
return
extractClass
(
ownerClass
,
((
ParameterizedType
)
arg
).
getRawType
());
}
...
...
@@ -368,7 +374,7 @@ public abstract class GenericTypeResolver {
* {@link Class concrete classes} for the specified {@link Class}. Searches
* all super types, enclosing types and interfaces.
*/
public
static
Map
<
TypeVariable
,
Type
>
getTypeVariableMap
(
Class
clazz
)
{
public
static
Map
<
TypeVariable
,
Type
>
getTypeVariableMap
(
Class
<?>
clazz
)
{
Map
<
TypeVariable
,
Type
>
typeVariableMap
=
typeVariableCache
.
get
(
clazz
);
if
(
typeVariableMap
==
null
)
{
...
...
@@ -377,28 +383,37 @@ public abstract class GenericTypeResolver {
// interfaces
extractTypeVariablesFromGenericInterfaces
(
clazz
.
getGenericInterfaces
(),
typeVariableMap
);
// super class
Type
genericType
=
clazz
.
getGenericSuperclass
();
Class
type
=
clazz
.
getSuperclass
();
while
(
type
!=
null
&&
!
Object
.
class
.
equals
(
type
))
{
if
(
genericType
instanceof
ParameterizedType
)
{
ParameterizedType
pt
=
(
ParameterizedType
)
genericType
;
populateTypeMapFromParameterizedType
(
pt
,
typeVariableMap
);
try
{
// super class
Class
<?>
type
=
clazz
;
while
(
type
.
getSuperclass
()
!=
null
&&
!
Object
.
class
.
equals
(
type
.
getSuperclass
()))
{
Type
genericType
=
type
.
getGenericSuperclass
();
if
(
genericType
instanceof
ParameterizedType
)
{
ParameterizedType
pt
=
(
ParameterizedType
)
genericType
;
populateTypeMapFromParameterizedType
(
pt
,
typeVariableMap
);
}
extractTypeVariablesFromGenericInterfaces
(
type
.
getSuperclass
().
getGenericInterfaces
(),
typeVariableMap
);
type
=
type
.
getSuperclass
();
}
extractTypeVariablesFromGenericInterfaces
(
type
.
getGenericInterfaces
(),
typeVariableMap
);
genericType
=
type
.
getGenericSuperclass
();
type
=
type
.
getSuperclass
();
}
catch
(
MalformedParameterizedTypeException
ex
)
{
// from getGenericSuperclass() - ignore and continue with member class check
}
// enclosing class
type
=
clazz
;
while
(
type
.
isMemberClass
())
{
genericType
=
type
.
getGenericSuperclass
();
if
(
genericType
instanceof
ParameterizedType
)
{
ParameterizedType
pt
=
(
ParameterizedType
)
genericType
;
populateTypeMapFromParameterizedType
(
pt
,
typeVariableMap
);
try
{
// enclosing class
Class
<?>
type
=
clazz
;
while
(
type
.
isMemberClass
())
{
Type
genericType
=
type
.
getGenericSuperclass
();
if
(
genericType
instanceof
ParameterizedType
)
{
ParameterizedType
pt
=
(
ParameterizedType
)
genericType
;
populateTypeMapFromParameterizedType
(
pt
,
typeVariableMap
);
}
type
=
type
.
getEnclosingClass
();
}
type
=
type
.
getEnclosingClass
();
}
catch
(
MalformedParameterizedTypeException
ex
)
{
// from getGenericSuperclass() - ignore and preserve previously accumulated type variables
}
typeVariableCache
.
put
(
clazz
,
typeVariableMap
);
...
...
spring-core/src/main/java/org/springframework/core/ParameterizedTypeReference.java
浏览文件 @
25e29b85
/*
* Copyright 2002-201
2
the original author or authors.
* Copyright 2002-201
3
the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
...
...
@@ -24,7 +24,7 @@ import org.springframework.util.Assert;
/**
* The purpose of this class is to enable capturing and passing a generic
* {@link Type}. In order to capture the generic type and retain it at runtime,
* you need to create a sub
-
class as follows:
* you need to create a subclass as follows:
*
* <pre class="code">
* ParameterizedTypeReference<List<String>> typeRef = new ParameterizedTypeReference<List<String>>() {};
...
...
@@ -37,54 +37,31 @@ import org.springframework.util.Assert;
* @author Arjen Poutsma
* @author Rossen Stoyanchev
* @since 3.2
*
* @see <a href="http://gafter.blogspot.nl/2006/12/super-type-tokens.html">Neal Gafter on Super Type Tokens</a>
*/
public
abstract
class
ParameterizedTypeReference
<
T
>
{
private
final
Type
type
;
protected
ParameterizedTypeReference
()
{
Class
<?>
parameterizedTypeReferenceSubClass
=
findParameterizedTypeReferenceSubClass
(
getClass
());
Type
type
=
parameterizedTypeReferenceSubClass
.
getGenericSuperclass
();
protected
ParameterizedTypeReference
()
{
Class
<?>
parameterizedTypeReferenceSubclass
=
findParameterizedTypeReferenceSubclass
(
getClass
());
Type
type
=
parameterizedTypeReferenceSubclass
.
getGenericSuperclass
();
Assert
.
isInstanceOf
(
ParameterizedType
.
class
,
type
);
ParameterizedType
parameterizedType
=
(
ParameterizedType
)
type
;
Assert
.
isTrue
(
parameterizedType
.
getActualTypeArguments
().
length
==
1
);
this
.
type
=
parameterizedType
.
getActualTypeArguments
()[
0
];
}
private
static
Class
<?>
findParameterizedTypeReferenceSubClass
(
Class
<?>
child
)
{
Class
<?>
parent
=
child
.
getSuperclass
();
if
(
Object
.
class
.
equals
(
parent
))
{
throw
new
IllegalStateException
(
"Expected ParameterizedTypeReference superclass"
);
}
else
if
(
ParameterizedTypeReference
.
class
.
equals
(
parent
))
{
return
child
;
}
else
{
return
findParameterizedTypeReferenceSubClass
(
parent
);
}
}
public
Type
getType
()
{
return
this
.
type
;
}
@Override
public
boolean
equals
(
Object
o
)
{
if
(
this
==
o
)
{
return
true
;
}
if
(
o
instanceof
ParameterizedTypeReference
)
{
ParameterizedTypeReference
<?>
other
=
(
ParameterizedTypeReference
<?>)
o
;
return
this
.
type
.
equals
(
other
.
type
);
}
return
false
;
public
boolean
equals
(
Object
obj
)
{
return
(
this
==
obj
||
(
obj
instanceof
ParameterizedTypeReference
&&
this
.
type
.
equals
(((
ParameterizedTypeReference
)
obj
).
type
)));
}
@Override
...
...
@@ -96,4 +73,19 @@ public abstract class ParameterizedTypeReference<T> {
public
String
toString
()
{
return
"ParameterizedTypeReference<"
+
this
.
type
+
">"
;
}
private
static
Class
<?>
findParameterizedTypeReferenceSubclass
(
Class
<?>
child
)
{
Class
<?>
parent
=
child
.
getSuperclass
();
if
(
Object
.
class
.
equals
(
parent
))
{
throw
new
IllegalStateException
(
"Expected ParameterizedTypeReference superclass"
);
}
else
if
(
ParameterizedTypeReference
.
class
.
equals
(
parent
))
{
return
child
;
}
else
{
return
findParameterizedTypeReferenceSubclass
(
parent
);
}
}
}
spring-core/src/test/java/org/springframework/core/ParameterizedTypeReferenceTest.java
→
spring-core/src/test/java/org/springframework/core/ParameterizedTypeReferenceTest
s
.java
浏览文件 @
25e29b85
/*
* Copyright 2002-201
2
the original author or authors.
* Copyright 2002-201
3
the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
...
...
@@ -20,16 +20,17 @@ import java.lang.reflect.Type;
import
java.util.List
;
import
java.util.Map
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
org.junit.Test
;
import
static
org
.
junit
.
Assert
.*;
/**
* Test fixture for {@link ParameterizedTypeReference}.
*
* @author Arjen Poutsma
* @author Rossen Stoyanchev
*/
public
class
ParameterizedTypeReferenceTest
{
public
class
ParameterizedTypeReferenceTest
s
{
@Test
public
void
map
()
throws
NoSuchMethodException
{
...
...
@@ -58,4 +59,5 @@ public class ParameterizedTypeReferenceTest {
public
static
List
<
String
>
listMethod
()
{
return
null
;
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录