Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
爱吃血肠
spring-framework
提交
182da159
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,体验更适合开发者的 AI 搜索 >>
提交
182da159
编写于
10月 24, 2017
作者:
J
Juergen Hoeller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
BridgeMethodResolver properly resolves interface hierarchies
Issue: SPR-16103
上级
55b0c2f2
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
160 addition
and
91 deletion
+160
-91
spring-core/src/main/java/org/springframework/core/BridgeMethodResolver.java
...n/java/org/springframework/core/BridgeMethodResolver.java
+42
-32
spring-core/src/test/java/org/springframework/core/BridgeMethodResolverTests.java
...a/org/springframework/core/BridgeMethodResolverTests.java
+118
-59
未找到文件。
spring-core/src/main/java/org/springframework/core/BridgeMethodResolver.java
浏览文件 @
182da159
...
...
@@ -138,43 +138,13 @@ public abstract class BridgeMethodResolver {
return
(
method
!=
null
&&
isResolvedTypeMatch
(
method
,
candidateMethod
,
declaringClass
));
}
/**
* Searches for the generic {@link Method} declaration whose erased signature
* matches that of the supplied bridge method.
* @throws IllegalStateException if the generic declaration cannot be found
*/
@Nullable
private
static
Method
findGenericDeclaration
(
Method
bridgeMethod
)
{
// Search parent types for method that has same signature as bridge.
Class
<?>
superclass
=
bridgeMethod
.
getDeclaringClass
().
getSuperclass
();
while
(
superclass
!=
null
&&
Object
.
class
!=
superclass
)
{
Method
method
=
searchForMatch
(
superclass
,
bridgeMethod
);
if
(
method
!=
null
&&
!
method
.
isBridge
())
{
return
method
;
}
superclass
=
superclass
.
getSuperclass
();
}
// Search interfaces.
Class
<?>[]
interfaces
=
ClassUtils
.
getAllInterfacesForClass
(
bridgeMethod
.
getDeclaringClass
());
for
(
Class
<?>
ifc
:
interfaces
)
{
Method
method
=
searchForMatch
(
ifc
,
bridgeMethod
);
if
(
method
!=
null
&&
!
method
.
isBridge
())
{
return
method
;
}
}
return
null
;
}
/**
* Returns {@code true} if the {@link Type} signature of both the supplied
* {@link Method#getGenericParameterTypes() generic Method} and concrete {@link Method}
* are equal after resolving all types against the declaringType, otherwise
* returns {@code false}.
*/
private
static
boolean
isResolvedTypeMatch
(
Method
genericMethod
,
Method
candidateMethod
,
Class
<?>
declaringClass
)
{
private
static
boolean
isResolvedTypeMatch
(
Method
genericMethod
,
Method
candidateMethod
,
Class
<?>
declaringClass
)
{
Type
[]
genericParameters
=
genericMethod
.
getGenericParameterTypes
();
Class
<?>[]
candidateParameters
=
candidateMethod
.
getParameterTypes
();
if
(
genericParameters
.
length
!=
candidateParameters
.
length
)
{
...
...
@@ -197,6 +167,41 @@ public abstract class BridgeMethodResolver {
return
true
;
}
/**
* Searches for the generic {@link Method} declaration whose erased signature
* matches that of the supplied bridge method.
* @throws IllegalStateException if the generic declaration cannot be found
*/
@Nullable
private
static
Method
findGenericDeclaration
(
Method
bridgeMethod
)
{
// Search parent types for method that has same signature as bridge.
Class
<?>
superclass
=
bridgeMethod
.
getDeclaringClass
().
getSuperclass
();
while
(
superclass
!=
null
&&
Object
.
class
!=
superclass
)
{
Method
method
=
searchForMatch
(
superclass
,
bridgeMethod
);
if
(
method
!=
null
&&
!
method
.
isBridge
())
{
return
method
;
}
superclass
=
superclass
.
getSuperclass
();
}
Class
<?>[]
interfaces
=
ClassUtils
.
getAllInterfacesForClass
(
bridgeMethod
.
getDeclaringClass
());
return
searchInterfaces
(
interfaces
,
bridgeMethod
);
}
@Nullable
private
static
Method
searchInterfaces
(
Class
<?>[]
interfaces
,
Method
bridgeMethod
)
{
for
(
Class
<?>
ifc
:
interfaces
)
{
Method
method
=
searchForMatch
(
ifc
,
bridgeMethod
);
if
(
method
!=
null
&&
!
method
.
isBridge
())
{
return
method
;
}
else
{
return
searchInterfaces
(
ifc
.
getInterfaces
(),
bridgeMethod
);
}
}
return
null
;
}
/**
* If the supplied {@link Class} has a declared {@link Method} whose signature matches
* that of the supplied {@link Method}, then this matching {@link Method} is returned,
...
...
@@ -204,7 +209,12 @@ public abstract class BridgeMethodResolver {
*/
@Nullable
private
static
Method
searchForMatch
(
Class
<?>
type
,
Method
bridgeMethod
)
{
return
ReflectionUtils
.
findMethod
(
type
,
bridgeMethod
.
getName
(),
bridgeMethod
.
getParameterTypes
());
try
{
return
type
.
getDeclaredMethod
(
bridgeMethod
.
getName
(),
bridgeMethod
.
getParameterTypes
());
}
catch
(
NoSuchMethodException
ex
)
{
return
null
;
}
}
/**
...
...
spring-core/src/test/java/org/springframework/core/BridgeMethodResolverTests.java
浏览文件 @
182da159
...
...
@@ -303,8 +303,26 @@ public class BridgeMethodResolverTests {
assertEquals
(
"findBy"
,
bridgedMethod
.
getName
());
}
@Test
// SPR-16103
public
void
testClassHierarchy
()
throws
Exception
{
doTestHierarchyResolution
(
FooClass
.
class
);
}
@Test
// SPR-16103
public
void
testInterfaceHierarchy
()
throws
Exception
{
doTestHierarchyResolution
(
FooInterface
.
class
);
}
private
void
doTestHierarchyResolution
(
Class
<?>
clazz
)
throws
Exception
{
for
(
Method
method
:
clazz
.
getDeclaredMethods
()){
Method
bridged
=
BridgeMethodResolver
.
findBridgedMethod
(
method
);
Method
expected
=
clazz
.
getMethod
(
"test"
,
FooEntity
.
class
);
assertEquals
(
expected
,
bridged
);
}
}
public
static
interface
Foo
<
T
extends
Serializable
>
{
public
interface
Foo
<
T
extends
Serializable
>
{
void
someMethod
(
T
theArg
,
Object
otherArg
);
...
...
@@ -355,7 +373,7 @@ public class BridgeMethodResolverTests {
}
public
static
interface
Adder
<
T
>
{
public
interface
Adder
<
T
>
{
void
add
(
T
item
);
}
...
...
@@ -404,7 +422,7 @@ public class BridgeMethodResolverTests {
}
public
static
interface
Boo
<
E
,
T
extends
Serializable
>
{
public
interface
Boo
<
E
,
T
extends
Serializable
>
{
void
foo
(
E
e
);
...
...
@@ -426,17 +444,15 @@ public class BridgeMethodResolverTests {
}
public
static
interface
Settings
{
public
interface
Settings
{
}
public
static
interface
ConcreteSettings
extends
Settings
{
public
interface
ConcreteSettings
extends
Settings
{
}
public
static
interface
Dao
<
T
,
S
>
{
public
interface
Dao
<
T
,
S
>
{
T
load
();
...
...
@@ -444,15 +460,14 @@ public class BridgeMethodResolverTests {
}
public
static
interface
SettingsDao
<
T
extends
Settings
,
S
>
extends
Dao
<
T
,
S
>
{
public
interface
SettingsDao
<
T
extends
Settings
,
S
>
extends
Dao
<
T
,
S
>
{
@Override
T
load
();
}
public
static
interface
ConcreteSettingsDao
extends
SettingsDao
<
ConcreteSettings
,
String
>
{
public
interface
ConcreteSettingsDao
extends
SettingsDao
<
ConcreteSettings
,
String
>
{
@Override
String
loadFromParent
();
...
...
@@ -470,7 +485,7 @@ public class BridgeMethodResolverTests {
this
.
otherObject
=
otherObject
;
}
//@Transactional(readOnly = true)
//
@Transactional(readOnly = true)
@Override
public
S
loadFromParent
()
{
return
otherObject
;
...
...
@@ -485,7 +500,7 @@ public class BridgeMethodResolverTests {
super
(
object
,
"From Parent"
);
}
//@Transactional(readOnly = true)
//
@Transactional(readOnly = true)
@Override
public
ConcreteSettings
load
()
{
return
super
.
object
;
...
...
@@ -493,7 +508,7 @@ public class BridgeMethodResolverTests {
}
public
static
interface
Bounded
<
E
>
{
public
interface
Bounded
<
E
>
{
boolean
boundedOperation
(
E
e
);
}
...
...
@@ -517,7 +532,7 @@ public class BridgeMethodResolverTests {
}
public
static
interface
GenericParameter
<
T
>
{
public
interface
GenericParameter
<
T
>
{
T
getFor
(
Class
<
T
>
cls
);
}
...
...
@@ -656,7 +671,7 @@ public class BridgeMethodResolverTests {
}
public
static
interface
Event
{
public
interface
Event
{
int
getPriority
();
}
...
...
@@ -686,24 +701,19 @@ public class BridgeMethodResolverTests {
}
public
static
interface
UserInitiatedEvent
{
//public Session getInitiatorSession();
public
interface
UserInitiatedEvent
{
}
public
static
abstract
class
BaseUserInitiatedEvent
extends
GenericEvent
implements
UserInitiatedEvent
{
public
static
abstract
class
BaseUserInitiatedEvent
extends
GenericEvent
implements
UserInitiatedEvent
{
}
public
static
class
MessageEvent
extends
BaseUserInitiatedEvent
{
}
public
static
interface
Channel
<
E
extends
Event
>
{
public
interface
Channel
<
E
extends
Event
>
{
void
send
(
E
event
);
...
...
@@ -713,29 +723,27 @@ public class BridgeMethodResolverTests {
}
public
static
interface
Broadcaster
{
public
interface
Broadcaster
{
}
public
static
interface
EventBroadcaster
extends
Broadcaster
{
public
interface
EventBroadcaster
extends
Broadcaster
{
public
void
subscribe
();
void
subscribe
();
public
void
unsubscribe
();
void
unsubscribe
();
public
void
setChannel
(
Channel
<?>
channel
);
void
setChannel
(
Channel
<?>
channel
);
}
public
static
class
GenericBroadcasterImpl
implements
Broadcaster
{
}
@SuppressWarnings
({
"unused"
,
"unchecked"
})
public
static
abstract
class
GenericEventBroadcasterImpl
<
T
extends
Event
>
extends
GenericBroadcasterImpl
implements
EventBroadcaster
{
public
static
abstract
class
GenericEventBroadcasterImpl
<
T
extends
Event
>
extends
GenericBroadcasterImpl
implements
EventBroadcaster
{
private
Class
<
T
>[]
subscribingEvents
;
...
...
@@ -761,27 +769,24 @@ public class BridgeMethodResolverTests {
@Override
public
void
subscribe
()
{
}
@Override
public
void
unsubscribe
()
{
}
public
GenericEventBroadcasterImpl
(
Class
<?
extends
T
>...
events
)
{
}
}
public
static
interface
Receiver
<
E
extends
Event
>
{
public
interface
Receiver
<
E
extends
Event
>
{
void
receive
(
E
event
);
}
public
static
interface
MessageBroadcaster
extends
Receiver
<
MessageEvent
>
{
public
interface
MessageBroadcaster
extends
Receiver
<
MessageEvent
>
{
}
...
...
@@ -835,7 +840,7 @@ public class BridgeMethodResolverTests {
// SPR-2454 Test Classes
//-----------------------------
public
static
interface
SimpleGenericRepository
<
T
>
{
public
interface
SimpleGenericRepository
<
T
>
{
public
Class
<
T
>
getPersistentClass
();
...
...
@@ -851,7 +856,7 @@ public class BridgeMethodResolverTests {
}
public
static
interface
RepositoryRegistry
{
public
interface
RepositoryRegistry
{
<
T
>
SimpleGenericRepository
<
T
>
getFor
(
Class
<
T
>
entityType
);
}
...
...
@@ -883,7 +888,7 @@ public class BridgeMethodResolverTests {
}
public
static
interface
ConvenientGenericRepository
<
T
,
ID
extends
Serializable
>
public
interface
ConvenientGenericRepository
<
T
,
ID
extends
Serializable
>
extends
SimpleGenericRepository
<
T
>
{
T
findById
(
ID
id
,
boolean
lock
);
...
...
@@ -977,7 +982,7 @@ public class BridgeMethodResolverTests {
// SPR-2603 classes
//-------------------
public
static
interface
Homer
<
E
>
{
public
interface
Homer
<
E
>
{
void
foo
(
E
e
);
}
...
...
@@ -1002,18 +1007,17 @@ public class BridgeMethodResolverTests {
}
public
static
interface
GenericDao
<
T
>
{
public
interface
GenericDao
<
T
>
{
public
void
saveOrUpdate
(
T
t
);
void
saveOrUpdate
(
T
t
);
}
public
static
interface
ConvenienceGenericDao
<
T
>
extends
GenericDao
<
T
>
{
public
interface
ConvenienceGenericDao
<
T
>
extends
GenericDao
<
T
>
{
}
public
static
class
GenericSqlMapDao
<
T
extends
Serializable
>
implements
ConvenienceGenericDao
<
T
>
{
public
static
class
GenericSqlMapDao
<
T
extends
Serializable
>
implements
ConvenienceGenericDao
<
T
>
{
@Override
public
void
saveOrUpdate
(
T
t
)
{
...
...
@@ -1022,8 +1026,7 @@ public class BridgeMethodResolverTests {
}
public
static
class
GenericSqlMapIntegerDao
<
T
extends
Number
>
extends
GenericSqlMapDao
<
T
>
{
public
static
class
GenericSqlMapIntegerDao
<
T
extends
Number
>
extends
GenericSqlMapDao
<
T
>
{
@Override
public
void
saveOrUpdate
(
T
t
)
{
...
...
@@ -1039,12 +1042,12 @@ public class BridgeMethodResolverTests {
}
public
static
interface
UserDao
{
public
interface
UserDao
{
//@Transactional
//
@Transactional
void
save
(
User
user
);
//@Transactional
//
@Transactional
void
save
(
Permission
perm
);
}
...
...
@@ -1071,8 +1074,9 @@ public class BridgeMethodResolverTests {
}
public
static
interface
DaoInterface
<
T
,
P
>
{
T
get
(
P
id
);
public
interface
DaoInterface
<
T
,
P
>
{
T
get
(
P
id
);
}
...
...
@@ -1125,13 +1129,13 @@ public class BridgeMethodResolverTests {
}
public
static
interface
MegaReceiver
<
E
extends
MegaEvent
>
{
public
interface
MegaReceiver
<
E
extends
MegaEvent
>
{
void
receive
(
E
event
);
}
public
static
interface
MegaMessageProducer
extends
MegaReceiver
<
MegaMessageEvent
>
{
public
interface
MegaMessageProducer
extends
MegaReceiver
<
MegaMessageEvent
>
{
}
...
...
@@ -1169,7 +1173,7 @@ public class BridgeMethodResolverTests {
}
public
static
interface
IGenericInterface
<
D
extends
DomainObjectSuper
>
{
public
interface
IGenericInterface
<
D
extends
DomainObjectSuper
>
{
<
T
>
void
doSomething
(
final
D
domainObject
,
final
T
value
);
}
...
...
@@ -1234,7 +1238,7 @@ public class BridgeMethodResolverTests {
// SPR-3534 classes
//-------------------
public
static
interface
SearchProvider
<
RETURN_TYPE
,
CONDITIONS_TYPE
>
{
public
interface
SearchProvider
<
RETURN_TYPE
,
CONDITIONS_TYPE
>
{
Collection
<
RETURN_TYPE
>
findBy
(
CONDITIONS_TYPE
conditions
);
}
...
...
@@ -1244,7 +1248,7 @@ public class BridgeMethodResolverTests {
}
public
static
interface
IExternalMessageProvider
<
S
extends
ExternalMessage
,
T
extends
ExternalMessageSearchConditions
<?>>
public
interface
IExternalMessageProvider
<
S
extends
ExternalMessage
,
T
extends
ExternalMessageSearchConditions
<?>>
extends
SearchProvider
<
S
,
T
>
{
}
...
...
@@ -1287,4 +1291,59 @@ public class BridgeMethodResolverTests {
}
}
//-------------------
// SPR-16103 classes
//-------------------
public
static
abstract
class
BaseEntity
{
private
String
id
;
}
public
static
class
FooEntity
extends
BaseEntity
{
private
String
name
;
}
public
static
class
BaseClass
<
T
>
{
public
<
S
extends
T
>
S
test
(
S
T
)
{
return
null
;
}
}
public
static
class
EntityClass
<
T
extends
BaseEntity
>
extends
BaseClass
<
T
>
{
@Override
public
<
S
extends
T
>
S
test
(
S
T
)
{
return
null
;
}
}
public
static
class
FooClass
extends
EntityClass
<
FooEntity
>
{
@Override
public
<
S
extends
FooEntity
>
S
test
(
S
T
)
{
return
null
;
}
}
public
interface
BaseInterface
<
T
>
{
<
S
extends
T
>
S
test
(
S
T
);
}
public
interface
EntityInterface
<
T
extends
BaseEntity
>
extends
BaseInterface
<
T
>
{
@Override
<
S
extends
T
>
S
test
(
S
T
);
}
public
interface
FooInterface
extends
EntityInterface
<
FooEntity
>
{
@Override
<
S
extends
FooEntity
>
S
test
(
S
T
);
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录