Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
.-Smile-.
spring-framework
提交
dbec2121
S
spring-framework
项目概览
.-Smile-.
/
spring-framework
与 Fork 源项目一致
从无法访问的项目Fork
通知
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,发现更多精彩内容 >>
提交
dbec2121
编写于
10月 07, 2015
作者:
J
Juergen Hoeller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
EventListenerMethodProcessor does not validate target classes behind proxies anymore
Issue: SPR-13526 Issue: SPR-13538
上级
28c07a6d
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
41 addition
and
74 deletion
+41
-74
spring-context/src/main/java/org/springframework/context/event/EventListenerMethodProcessor.java
...framework/context/event/EventListenerMethodProcessor.java
+23
-57
spring-context/src/test/java/org/springframework/context/event/AnnotationDrivenEventListenerTests.java
...ork/context/event/AnnotationDrivenEventListenerTests.java
+18
-17
未找到文件。
spring-context/src/main/java/org/springframework/context/event/EventListenerMethodProcessor.java
浏览文件 @
dbec2121
...
...
@@ -28,9 +28,7 @@ import java.util.concurrent.ConcurrentHashMap;
import
org.apache.commons.logging.Log
;
import
org.apache.commons.logging.LogFactory
;
import
org.springframework.aop.SpringProxy
;
import
org.springframework.aop.scope.ScopedProxyUtils
;
import
org.springframework.aop.support.AopUtils
;
import
org.springframework.beans.BeansException
;
import
org.springframework.beans.factory.BeanInitializationException
;
import
org.springframework.beans.factory.SmartInitializingSingleton
;
...
...
@@ -48,6 +46,7 @@ import org.springframework.util.ReflectionUtils;
* instances.
*
* @author Stephane Nicoll
* @author Juergen Hoeller
* @since 4.2
*/
public
class
EventListenerMethodProcessor
implements
SmartInitializingSingleton
,
ApplicationContextAware
{
...
...
@@ -61,6 +60,7 @@ public class EventListenerMethodProcessor implements SmartInitializingSingleton,
private
final
Set
<
Class
<?>>
nonAnnotatedClasses
=
Collections
.
newSetFromMap
(
new
ConcurrentHashMap
<
Class
<?>,
Boolean
>(
64
));
@Override
public
void
setApplicationContext
(
ApplicationContext
applicationContext
)
throws
BeansException
{
Assert
.
isTrue
(
applicationContext
instanceof
ConfigurableApplicationContext
,
...
...
@@ -69,18 +69,6 @@ public class EventListenerMethodProcessor implements SmartInitializingSingleton,
}
/**
* Return the {@link EventListenerFactory} instances to use to handle {@link EventListener}
* annotated methods.
*/
protected
List
<
EventListenerFactory
>
getEventListenerFactories
()
{
Map
<
String
,
EventListenerFactory
>
beans
=
this
.
applicationContext
.
getBeansOfType
(
EventListenerFactory
.
class
);
List
<
EventListenerFactory
>
allFactories
=
new
ArrayList
<
EventListenerFactory
>(
beans
.
values
());
AnnotationAwareOrderComparator
.
sort
(
allFactories
);
return
allFactories
;
}
@Override
public
void
afterSingletonsInstantiated
()
{
List
<
EventListenerFactory
>
factories
=
getEventListenerFactories
();
...
...
@@ -91,16 +79,27 @@ public class EventListenerMethodProcessor implements SmartInitializingSingleton,
try
{
processBean
(
factories
,
beanName
,
type
);
}
catch
(
RuntimeException
e
)
{
catch
(
Throwable
ex
)
{
throw
new
BeanInitializationException
(
"Failed to process @EventListener "
+
"annotation on bean with name '"
+
beanName
+
"'"
,
e
);
"annotation on bean with name '"
+
beanName
+
"'"
,
e
x
);
}
}
}
}
protected
void
processBean
(
List
<
EventListenerFactory
>
factories
,
String
beanName
,
final
Class
<?>
type
)
{
Class
<?>
targetType
=
getTargetClass
(
beanName
,
type
);
/**
* Return the {@link EventListenerFactory} instances to use to handle {@link EventListener}
* annotated methods.
*/
protected
List
<
EventListenerFactory
>
getEventListenerFactories
()
{
Map
<
String
,
EventListenerFactory
>
beans
=
this
.
applicationContext
.
getBeansOfType
(
EventListenerFactory
.
class
);
List
<
EventListenerFactory
>
allFactories
=
new
ArrayList
<
EventListenerFactory
>(
beans
.
values
());
AnnotationAwareOrderComparator
.
sort
(
allFactories
);
return
allFactories
;
}
protected
void
processBean
(
List
<
EventListenerFactory
>
factories
,
String
beanName
,
final
Class
<?>
targetType
)
{
if
(!
this
.
nonAnnotatedClasses
.
contains
(
targetType
))
{
final
Set
<
Method
>
annotatedMethods
=
new
LinkedHashSet
<
Method
>(
1
);
Method
[]
methods
=
ReflectionUtils
.
getUniqueDeclaredMethods
(
targetType
);
...
...
@@ -111,13 +110,10 @@ public class EventListenerMethodProcessor implements SmartInitializingSingleton,
}
for
(
EventListenerFactory
factory
:
factories
)
{
if
(
factory
.
supportsMethod
(
method
))
{
if
(!
type
.
equals
(
targetType
))
{
method
=
getProxyMethod
(
type
,
method
);
}
ApplicationListener
<?>
applicationListener
=
factory
.
createApplicationListener
(
beanName
,
type
,
method
);
factory
.
createApplicationListener
(
beanName
,
t
argetT
ype
,
method
);
if
(
applicationListener
instanceof
ApplicationListenerMethodAdapter
)
{
((
ApplicationListenerMethodAdapter
)
applicationListener
)
((
ApplicationListenerMethodAdapter
)
applicationListener
)
.
init
(
this
.
applicationContext
,
this
.
evaluator
);
}
this
.
applicationContext
.
addApplicationListener
(
applicationListener
);
...
...
@@ -127,49 +123,19 @@ public class EventListenerMethodProcessor implements SmartInitializingSingleton,
}
}
if
(
annotatedMethods
.
isEmpty
())
{
this
.
nonAnnotatedClasses
.
add
(
type
);
this
.
nonAnnotatedClasses
.
add
(
t
argetT
ype
);
if
(
logger
.
isTraceEnabled
())
{
logger
.
trace
(
"No @EventListener annotations found on bean class: "
+
type
);
logger
.
trace
(
"No @EventListener annotations found on bean class: "
+
t
argetT
ype
);
}
}
else
{
// Non-empty set of methods
if
(
logger
.
isDebugEnabled
())
{
logger
.
debug
(
annotatedMethods
.
size
()
+
" @EventListener methods processed on bean '"
+
beanName
+
"': "
+
annotatedMethods
);
logger
.
debug
(
annotatedMethods
.
size
()
+
" @EventListener methods processed on bean '"
+
beanName
+
"': "
+
annotatedMethods
);
}
}
}
}
private
Class
<?>
getTargetClass
(
String
beanName
,
Class
<?>
type
)
{
if
(
SpringProxy
.
class
.
isAssignableFrom
(
type
))
{
Object
bean
=
this
.
applicationContext
.
getBean
(
beanName
);
return
AopUtils
.
getTargetClass
(
bean
);
}
else
{
return
type
;
}
}
private
Method
getProxyMethod
(
Class
<?>
proxyType
,
Method
method
)
{
try
{
// Found a @EventListener method on the target class for this JDK proxy ->
// is it also present on the proxy itself?
return
proxyType
.
getMethod
(
method
.
getName
(),
method
.
getParameterTypes
());
}
catch
(
SecurityException
ex
)
{
ReflectionUtils
.
handleReflectionException
(
ex
);
}
catch
(
NoSuchMethodException
ex
)
{
throw
new
IllegalStateException
(
String
.
format
(
"@EventListener method '%s' found on bean target class '%s', "
+
"but not found in any interface(s) for bean JDK proxy. Either "
+
"pull the method up to an interface or switch to subclass (CGLIB) "
+
"proxies by setting proxy-target-class/proxyTargetClass "
+
"attribute to 'true'"
,
method
.
getName
(),
method
.
getDeclaringClass
().
getSimpleName
()));
}
return
null
;
}
}
spring-context/src/test/java/org/springframework/context/event/AnnotationDrivenEventListenerTests.java
浏览文件 @
dbec2121
...
...
@@ -73,6 +73,7 @@ public class AnnotationDrivenEventListenerTests {
private
CountDownLatch
countDownLatch
;
// 1 call by default
@After
public
void
closeContext
()
{
if
(
this
.
context
!=
null
)
{
...
...
@@ -80,6 +81,7 @@ public class AnnotationDrivenEventListenerTests {
}
}
@Test
public
void
simpleEventJavaConfig
()
{
load
(
TestEventListener
.
class
);
...
...
@@ -241,13 +243,6 @@ public class AnnotationDrivenEventListenerTests {
this
.
eventCollector
.
assertTotalEventsCount
(
1
);
}
@Test
public
void
methodNotAvailableOnProxyIsDetected
()
throws
Exception
{
thrown
.
expect
(
BeanInitializationException
.
class
);
thrown
.
expectMessage
(
"handleIt2"
);
load
(
InvalidProxyTestBean
.
class
);
}
@Test
public
void
eventListenerWorksWithCglibProxy
()
throws
Exception
{
load
(
CglibProxyTestBean
.
class
);
...
...
@@ -409,6 +404,7 @@ public class AnnotationDrivenEventListenerTests {
assertThat
(
listener
.
order
,
contains
(
"first"
,
"second"
,
"third"
));
}
private
void
load
(
Class
<?>...
classes
)
{
List
<
Class
<?>>
allClasses
=
new
ArrayList
<>();
allClasses
.
add
(
BasicConfiguration
.
class
);
...
...
@@ -450,6 +446,7 @@ public class AnnotationDrivenEventListenerTests {
}
static
abstract
class
AbstractTestEventListener
extends
AbstractIdentifiable
{
@Autowired
...
...
@@ -458,9 +455,9 @@ public class AnnotationDrivenEventListenerTests {
protected
void
collectEvent
(
Object
content
)
{
this
.
eventCollector
.
addEvent
(
this
,
content
);
}
}
@Component
static
class
TestEventListener
extends
AbstractTestEventListener
{
...
...
@@ -473,15 +470,16 @@ public class AnnotationDrivenEventListenerTests {
public
void
handleString
(
String
content
)
{
collectEvent
(
content
);
}
}
@EventListener
@Target
(
ElementType
.
METHOD
)
@Retention
(
RetentionPolicy
.
RUNTIME
)
@interface
FooListener
{
}
@Component
static
class
MetaAnnotationListenerTestBean
extends
AbstractTestEventListener
{
...
...
@@ -491,6 +489,7 @@ public class AnnotationDrivenEventListenerTests {
}
}
@Component
static
class
ContextEventListener
extends
AbstractTestEventListener
{
...
...
@@ -501,6 +500,7 @@ public class AnnotationDrivenEventListenerTests {
}
@Component
static
class
InvalidMethodSignatureEventListener
{
...
...
@@ -509,6 +509,7 @@ public class AnnotationDrivenEventListenerTests {
}
}
@Component
static
class
ReplyEventListener
extends
AbstractTestEventListener
{
...
...
@@ -532,6 +533,7 @@ public class AnnotationDrivenEventListenerTests {
}
@Component
static
class
ExceptionEventListener
extends
AbstractTestEventListener
{
...
...
@@ -557,12 +559,14 @@ public class AnnotationDrivenEventListenerTests {
}
}
@Configuration
@Import
(
BasicConfiguration
.
class
)
@EnableAsync
(
proxyTargetClass
=
true
)
static
class
AsyncConfiguration
{
}
@Component
static
class
AsyncEventListener
extends
AbstractTestEventListener
{
...
...
@@ -578,6 +582,7 @@ public class AnnotationDrivenEventListenerTests {
}
}
interface
SimpleService
extends
Identifiable
{
@EventListener
...
...
@@ -585,6 +590,7 @@ public class AnnotationDrivenEventListenerTests {
}
@Component
@Scope
(
proxyMode
=
ScopedProxyMode
.
INTERFACES
)
static
class
ProxyTestBean
extends
AbstractIdentifiable
implements
SimpleService
{
...
...
@@ -598,14 +604,6 @@ public class AnnotationDrivenEventListenerTests {
}
}
@Component
@Scope
(
proxyMode
=
ScopedProxyMode
.
INTERFACES
)
static
class
InvalidProxyTestBean
extends
ProxyTestBean
{
@EventListener
// does not exist on any interface so it should fail
public
void
handleIt2
(
TestEvent
event
)
{
}
}
@Component
@Scope
(
proxyMode
=
ScopedProxyMode
.
TARGET_CLASS
)
...
...
@@ -617,6 +615,7 @@ public class AnnotationDrivenEventListenerTests {
}
}
@Component
static
class
GenericEventListener
extends
AbstractTestEventListener
{
...
...
@@ -626,6 +625,7 @@ public class AnnotationDrivenEventListenerTests {
}
}
@Component
static
class
ConditionalEventListener
extends
TestEventListener
{
...
...
@@ -648,6 +648,7 @@ public class AnnotationDrivenEventListenerTests {
}
@Component
static
class
OrderedTestListener
extends
TestEventListener
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录