Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
爱吃血肠
spring-framework
提交
90309ab0
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,发现更多精彩内容 >>
提交
90309ab0
编写于
4月 16, 2014
作者:
J
Juergen Hoeller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
CglibAopProxy detects package-visible methods when defined in a different ClassLoader
Issue: SPR-11618
上级
7bc2168a
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
106 addition
and
52 deletion
+106
-52
spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java
...java/org/springframework/aop/framework/CglibAopProxy.java
+32
-23
spring-context/src/test/java/org/springframework/aop/framework/CglibProxyTests.java
...va/org/springframework/aop/framework/CglibProxyTests.java
+74
-29
未找到文件。
spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java
浏览文件 @
90309ab0
...
...
@@ -172,7 +172,7 @@ class CglibAopProxy implements AopProxy, Serializable {
}
// Validate the class, writing log messages as necessary.
validateClassIfNecessary
(
proxySuperClass
);
validateClassIfNecessary
(
proxySuperClass
,
classLoader
);
// Configure CGLIB Enhancer...
Enhancer
enhancer
=
createEnhancer
();
...
...
@@ -239,11 +239,11 @@ class CglibAopProxy implements AopProxy, Serializable {
* Checks to see whether the supplied {@code Class} has already been validated and
* validates it if not.
*/
private
void
validateClassIfNecessary
(
Class
<?>
proxySuperClass
)
{
if
(
logger
.
is
Warn
Enabled
())
{
private
void
validateClassIfNecessary
(
Class
<?>
proxySuperClass
,
ClassLoader
proxyClassLoader
)
{
if
(
logger
.
is
Info
Enabled
())
{
synchronized
(
validatedClasses
)
{
if
(!
validatedClasses
.
containsKey
(
proxySuperClass
))
{
doValidateClass
(
proxySuperClass
);
doValidateClass
(
proxySuperClass
,
proxyClassLoader
);
validatedClasses
.
put
(
proxySuperClass
,
Boolean
.
TRUE
);
}
}
...
...
@@ -251,19 +251,28 @@ class CglibAopProxy implements AopProxy, Serializable {
}
/**
* Checks for final methods on the
{@code Class} and writes warnings to the log
* for each one found.
* Checks for final methods on the
given {@code Class}, as well as package-visible
*
methods across ClassLoaders, and writes warnings to the log
for each one found.
*/
private
void
doValidateClass
(
Class
<?>
proxySuperClass
)
{
if
(
logger
.
isWarnEnabled
(
))
{
Method
[]
methods
=
proxySuperClass
.
getMethods
();
private
void
doValidateClass
(
Class
<?>
proxySuperClass
,
ClassLoader
proxyClassLoader
)
{
if
(
!
Object
.
class
.
equals
(
proxySuperClass
))
{
Method
[]
methods
=
proxySuperClass
.
get
Declared
Methods
();
for
(
Method
method
:
methods
)
{
if
(!
Object
.
class
.
equals
(
method
.
getDeclaringClass
())
&&
!
Modifier
.
isStatic
(
method
.
getModifiers
())
&&
Modifier
.
isFinal
(
method
.
getModifiers
()))
{
logger
.
warn
(
"Unable to proxy method ["
+
method
+
"] because it is final: "
+
"All calls to this method via a proxy will be routed directly to the proxy."
);
int
mod
=
method
.
getModifiers
();
if
(!
Modifier
.
isStatic
(
mod
))
{
if
(
Modifier
.
isFinal
(
mod
))
{
logger
.
info
(
"Unable to proxy method ["
+
method
+
"] because it is final: "
+
"All calls to this method via a proxy will NOT be routed to the target instance."
);
}
else
if
(!
Modifier
.
isPublic
(
mod
)
&&
!
Modifier
.
isProtected
(
mod
)
&&
!
Modifier
.
isPrivate
(
mod
)
&&
proxyClassLoader
!=
null
&&
proxySuperClass
.
getClassLoader
()
!=
proxyClassLoader
)
{
logger
.
info
(
"Unable to proxy method ["
+
method
+
"] because it is package-visible "
+
"across different ClassLoaders: All calls to this method via a proxy will "
+
"NOT be routed to the target instance."
);
}
}
}
doValidateClass
(
proxySuperClass
.
getSuperclass
(),
proxyClassLoader
);
}
}
...
...
@@ -604,7 +613,7 @@ class CglibAopProxy implements AopProxy, Serializable {
*/
private
static
class
DynamicAdvisedInterceptor
implements
MethodInterceptor
,
Serializable
{
private
AdvisedSupport
advised
;
private
final
AdvisedSupport
advised
;
public
DynamicAdvisedInterceptor
(
AdvisedSupport
advised
)
{
this
.
advised
=
advised
;
...
...
@@ -622,8 +631,8 @@ class CglibAopProxy implements AopProxy, Serializable {
oldProxy
=
AopContext
.
setCurrentProxy
(
proxy
);
setProxyContext
=
true
;
}
// May be null Get as late as possible to minimize the time we
// "own" the target, in case it comes from a pool.
// May be null
.
Get as late as possible to minimize the time we
// "own" the target, in case it comes from a pool.
..
target
=
getTarget
();
if
(
target
!=
null
)
{
targetClass
=
target
.
getClass
();
...
...
@@ -689,13 +698,13 @@ class CglibAopProxy implements AopProxy, Serializable {
private
final
MethodProxy
methodProxy
;
private
boolean
protected
Method
;
private
final
boolean
public
Method
;
public
CglibMethodInvocation
(
Object
proxy
,
Object
target
,
Method
method
,
Object
[]
arguments
,
Class
<?>
targetClass
,
List
<
Object
>
interceptorsAndDynamicMethodMatchers
,
MethodProxy
methodProxy
)
{
super
(
proxy
,
target
,
method
,
arguments
,
targetClass
,
interceptorsAndDynamicMethodMatchers
);
this
.
methodProxy
=
methodProxy
;
this
.
p
rotectedMethod
=
Modifier
.
isProtected
(
method
.
getModifiers
());
this
.
p
ublicMethod
=
Modifier
.
isPublic
(
method
.
getModifiers
());
}
/**
...
...
@@ -704,11 +713,11 @@ class CglibAopProxy implements AopProxy, Serializable {
*/
@Override
protected
Object
invokeJoinpoint
()
throws
Throwable
{
if
(
this
.
p
rotected
Method
)
{
return
super
.
invokeJoinpoint
(
);
if
(
this
.
p
ublic
Method
)
{
return
this
.
methodProxy
.
invoke
(
this
.
target
,
this
.
arguments
);
}
else
{
return
this
.
methodProxy
.
invoke
(
this
.
target
,
this
.
arguments
);
return
super
.
invokeJoinpoint
(
);
}
}
}
...
...
@@ -829,8 +838,8 @@ class CglibAopProxy implements AopProxy, Serializable {
// of the target type. If so we know it never needs to have return type
// massage and can use a dispatcher.
// If the proxy is being exposed, then must use the interceptor the
// correct one is already configured. If the target is not static
cannot
//
use a Dispatcher because the target can not then
be released.
// correct one is already configured. If the target is not static
, then
//
cannot use a dispatcher because the target cannot
be released.
if
(
exposeProxy
||
!
isStatic
)
{
return
INVOKE_TARGET
;
}
...
...
spring-context/src/test/java/org/springframework/aop/framework/CglibProxyTests.java
浏览文件 @
90309ab0
...
...
@@ -102,6 +102,7 @@ public final class CglibProxyTests extends AbstractAopProxyTests implements Seri
@Test
public
void
testProtectedMethodInvocation
()
{
ProtectedMethodTestBean
bean
=
new
ProtectedMethodTestBean
();
bean
.
value
=
"foo"
;
mockTargetSource
.
setTarget
(
bean
);
AdvisedSupport
as
=
new
AdvisedSupport
(
new
Class
<?>[]{});
...
...
@@ -109,8 +110,47 @@ public final class CglibProxyTests extends AbstractAopProxyTests implements Seri
as
.
addAdvice
(
new
NopInterceptor
());
AopProxy
aop
=
new
CglibAopProxy
(
as
);
Object
proxy
=
aop
.
getProxy
();
ProtectedMethodTestBean
proxy
=
(
ProtectedMethodTestBean
)
aop
.
getProxy
();
assertTrue
(
AopUtils
.
isCglibProxy
(
proxy
));
assertEquals
(
proxy
.
getClass
().
getClassLoader
(),
bean
.
getClass
().
getClassLoader
());
assertEquals
(
"foo"
,
proxy
.
getString
());
}
@Test
public
void
testPackageMethodInvocation
()
{
PackageMethodTestBean
bean
=
new
PackageMethodTestBean
();
bean
.
value
=
"foo"
;
mockTargetSource
.
setTarget
(
bean
);
AdvisedSupport
as
=
new
AdvisedSupport
(
new
Class
<?>[]{});
as
.
setTargetSource
(
mockTargetSource
);
as
.
addAdvice
(
new
NopInterceptor
());
AopProxy
aop
=
new
CglibAopProxy
(
as
);
PackageMethodTestBean
proxy
=
(
PackageMethodTestBean
)
aop
.
getProxy
();
assertTrue
(
AopUtils
.
isCglibProxy
(
proxy
));
assertEquals
(
proxy
.
getClass
().
getClassLoader
(),
bean
.
getClass
().
getClassLoader
());
assertEquals
(
"foo"
,
proxy
.
getString
());
}
@Test
public
void
testPackageMethodInvocationWithDifferentClassLoader
()
{
ClassLoader
child
=
new
ClassLoader
(
getClass
().
getClassLoader
())
{
};
PackageMethodTestBean
bean
=
new
PackageMethodTestBean
();
bean
.
value
=
"foo"
;
mockTargetSource
.
setTarget
(
bean
);
AdvisedSupport
as
=
new
AdvisedSupport
(
new
Class
<?>[]{});
as
.
setTargetSource
(
mockTargetSource
);
as
.
addAdvice
(
new
NopInterceptor
());
AopProxy
aop
=
new
CglibAopProxy
(
as
);
PackageMethodTestBean
proxy
=
(
PackageMethodTestBean
)
aop
.
getProxy
(
child
);
assertTrue
(
AopUtils
.
isCglibProxy
(
proxy
));
assertNotEquals
(
proxy
.
getClass
().
getClassLoader
(),
bean
.
getClass
().
getClassLoader
());
assertNull
(
proxy
.
getString
());
// we're stuck in the proxy instance
}
@Test
...
...
@@ -410,54 +450,59 @@ public final class CglibProxyTests extends AbstractAopProxyTests implements Seri
}
public
static
class
HasFinalMethod
{
public
static
class
NoArgCtorTestBean
{
private
boolean
called
=
false
;
public
final
void
foo
()
{
public
NoArgCtorTestBean
(
String
x
,
int
y
)
{
called
=
true
;
}
public
boolean
wasCalled
()
{
return
called
;
}
public
void
reset
()
{
called
=
false
;
}
}
}
class
Cglib
TestBean
{
public
static
class
ProtectedMethod
TestBean
{
private
String
nam
e
;
public
String
valu
e
;
public
CglibTestBean
()
{
setName
(
"Some Default"
);
protected
String
getString
()
{
return
this
.
value
;
}
}
public
void
setName
(
String
name
)
{
this
.
name
=
name
;
}
public
String
getName
()
{
return
this
.
name
;
public
static
class
PackageMethodTestBean
{
public
String
value
;
String
getString
()
{
return
this
.
value
;
}
}
}
class
NoArgCtorTestBean
{
private
boolean
called
=
false
;
class
CglibTestBean
{
public
NoArgCtorTestBean
(
String
x
,
int
y
)
{
called
=
true
;
}
private
String
name
;
public
boolean
wasCalled
()
{
return
called
;
public
CglibTestBean
()
{
setName
(
"Some Default"
)
;
}
public
void
reset
(
)
{
called
=
fals
e
;
public
void
setName
(
String
name
)
{
this
.
name
=
nam
e
;
}
}
class
ProtectedMethodTestBean
{
protected
String
getString
()
{
return
"foo"
;
public
String
getName
()
{
return
this
.
name
;
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录