Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
爱吃血肠
spring-framework
提交
98808347
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,发现更多精彩内容 >>
提交
98808347
编写于
9月 06, 2012
作者:
P
Phillip Webb
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Remove trailing whitespace
上级
27c83710
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
66 addition
and
66 deletion
+66
-66
spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectiveMethodResolver.java
...ork/expression/spel/support/ReflectiveMethodResolver.java
+2
-2
spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java
...k/expression/spel/support/ReflectivePropertyAccessor.java
+21
-21
spring-expression/src/test/java/org/springframework/expression/spel/MethodInvocationTests.java
...pringframework/expression/spel/MethodInvocationTests.java
+35
-35
spring-expression/src/test/java/org/springframework/expression/spel/PropertyAccessTests.java
.../springframework/expression/spel/PropertyAccessTests.java
+8
-8
未找到文件。
spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectiveMethodResolver.java
浏览文件 @
98808347
...
...
@@ -53,7 +53,7 @@ public class ReflectiveMethodResolver implements MethodResolver {
private
Map
<
Class
<?>,
MethodFilter
>
filters
=
null
;
// Using distance will ensure a more accurate match is discovered,
// Using distance will ensure a more accurate match is discovered,
// more closely following the Java rules.
private
boolean
useDistance
=
false
;
...
...
@@ -66,7 +66,7 @@ public class ReflectiveMethodResolver implements MethodResolver {
* This constructors allows the ReflectiveMethodResolver to be configured such that it will
* use a distance computation to check which is the better of two close matches (when there
* are multiple matches). Using the distance computation is intended to ensure matches
* are more closely representative of what a Java compiler would do when taking into
* are more closely representative of what a Java compiler would do when taking into
* account boxing/unboxing and whether the method candidates are declared to handle a
* supertype of the type (of the argument) being passed in.
* @param useDistance true if distance computation should be used when calculating matches
...
...
spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java
浏览文件 @
98808347
...
...
@@ -37,8 +37,8 @@ import org.springframework.util.StringUtils;
/**
* Simple PropertyAccessor that uses reflection to access properties for reading and writing. A property can be accessed
* if it is accessible as a field on the object or through a getter (if being read) or a setter (if being written).
*
* if it is accessible as a field on the object or through a getter (if being read) or a setter (if being written).
*
* @author Andy Clement
* @author Juergen Hoeller
* @since 3.0
...
...
@@ -48,7 +48,7 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
protected
final
Map
<
CacheKey
,
InvokerPair
>
readerCache
=
new
ConcurrentHashMap
<
CacheKey
,
InvokerPair
>();
protected
final
Map
<
CacheKey
,
Member
>
writerCache
=
new
ConcurrentHashMap
<
CacheKey
,
Member
>();
protected
final
Map
<
CacheKey
,
TypeDescriptor
>
typeDescriptorCache
=
new
ConcurrentHashMap
<
CacheKey
,
TypeDescriptor
>();
...
...
@@ -85,7 +85,7 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
Field
field
=
findField
(
name
,
type
,
target
instanceof
Class
);
if
(
field
!=
null
)
{
TypeDescriptor
typeDescriptor
=
new
TypeDescriptor
(
field
);
this
.
readerCache
.
put
(
cacheKey
,
new
InvokerPair
(
field
,
typeDescriptor
));
this
.
readerCache
.
put
(
cacheKey
,
new
InvokerPair
(
field
,
typeDescriptor
));
this
.
typeDescriptorCache
.
put
(
cacheKey
,
typeDescriptor
);
return
true
;
}
...
...
@@ -252,7 +252,7 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
throw
new
AccessException
(
"Neither setter nor field found for property '"
+
name
+
"'"
);
}
private
TypeDescriptor
getTypeDescriptor
(
EvaluationContext
context
,
Object
target
,
String
name
)
{
if
(
target
==
null
)
{
return
null
;
...
...
@@ -340,22 +340,22 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
}
return
null
;
}
/**
* Captures the member (method/field) to call reflectively to access a property value and the type descriptor for the
* value returned by the reflective call.
*/
private
static
class
InvokerPair
{
final
Member
member
;
final
TypeDescriptor
typeDescriptor
;
public
InvokerPair
(
Member
member
,
TypeDescriptor
typeDescriptor
)
{
this
.
member
=
member
;
this
.
typeDescriptor
=
typeDescriptor
;
}
}
}
private
static
class
CacheKey
{
...
...
@@ -387,9 +387,9 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
}
}
/**
/**
* Attempt to create an optimized property accessor tailored for a property of a particular name on
* a particular class. The general ReflectivePropertyAccessor will always work but is not optimal
* a particular class. The general ReflectivePropertyAccessor will always work but is not optimal
* due to the need to lookup which reflective member (method/field) to use each time read() is called.
* This method will just return the ReflectivePropertyAccessor instance if it is unable to build
* something more optimal.
...
...
@@ -438,10 +438,10 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
}
return
this
;
}
/**
* An optimized form of a PropertyAccessor that will use reflection but only knows how to access a particular property
* on a particular class. This is unlike the general ReflectivePropertyResolver which manages a cache of methods/fields that
* An optimized form of a PropertyAccessor that will use reflection but only knows how to access a particular property
* on a particular class. This is unlike the general ReflectivePropertyResolver which manages a cache of methods/fields that
* may be invoked to access different properties on different classes. This optimal accessor exists because looking up
* the appropriate reflective object by class/name on each read is not cheap.
*/
...
...
@@ -449,13 +449,13 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
private
final
Member
member
;
private
final
TypeDescriptor
typeDescriptor
;
private
final
boolean
needsToBeMadeAccessible
;
OptimalPropertyAccessor
(
InvokerPair
target
)
{
this
.
member
=
target
.
member
;
this
.
member
=
target
.
member
;
this
.
typeDescriptor
=
target
.
typeDescriptor
;
if
(
this
.
member
instanceof
Field
)
{
Field
field
=
(
Field
)
member
;
needsToBeMadeAccessible
=
(!
Modifier
.
isPublic
(
field
.
getModifiers
())
||
!
Modifier
.
isPublic
(
field
.
getDeclaringClass
().
getModifiers
()))
needsToBeMadeAccessible
=
(!
Modifier
.
isPublic
(
field
.
getModifiers
())
||
!
Modifier
.
isPublic
(
field
.
getDeclaringClass
().
getModifiers
()))
&&
!
field
.
isAccessible
();
}
else
{
...
...
@@ -468,7 +468,7 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
public
Class
[]
getSpecificTargetClasses
()
{
throw
new
UnsupportedOperationException
(
"Should not be called on an OptimalPropertyAccessor"
);
}
public
boolean
canRead
(
EvaluationContext
context
,
Object
target
,
String
name
)
throws
AccessException
{
if
(
target
==
null
)
{
return
false
;
...
...
@@ -504,7 +504,7 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
catch
(
Exception
ex
)
{
throw
new
AccessException
(
"Unable to access property '"
+
name
+
"' through getter"
,
ex
);
}
}
}
if
(
member
instanceof
Field
)
{
try
{
if
(
needsToBeMadeAccessible
)
{
...
...
@@ -523,7 +523,7 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
public
boolean
canWrite
(
EvaluationContext
context
,
Object
target
,
String
name
)
throws
AccessException
{
throw
new
UnsupportedOperationException
(
"Should not be called on an OptimalPropertyAccessor"
);
}
public
void
write
(
EvaluationContext
context
,
Object
target
,
String
name
,
Object
newValue
)
throws
AccessException
{
throw
new
UnsupportedOperationException
(
"Should not be called on an OptimalPropertyAccessor"
);
...
...
spring-expression/src/test/java/org/springframework/expression/spel/MethodInvocationTests.java
浏览文件 @
98808347
...
...
@@ -40,7 +40,7 @@ import org.springframework.expression.spel.testresources.PlaceOfBirth;
/**
* Tests invocation of methods.
*
*
* @author Andy Clement
*/
public
class
MethodInvocationTests
extends
ExpressionTestCase
{
...
...
@@ -89,7 +89,7 @@ public class MethodInvocationTests extends ExpressionTestCase {
evaluate
(
"new String('hello 2.0 to you').startsWith(7.0d)"
,
false
,
Boolean
.
class
);
evaluate
(
"new String('7.0 foobar').startsWith(7.0d)"
,
true
,
Boolean
.
class
);
}
@Test
public
void
testMethodThrowingException_SPR6760
()
{
// Test method on inventor: throwException()
...
...
@@ -97,7 +97,7 @@ public class MethodInvocationTests extends ExpressionTestCase {
// On 2 it will throw a RuntimeException
// On 3 it will exit normally
// In each case it increments the Inventor field 'counter' when invoked
SpelExpressionParser
parser
=
new
SpelExpressionParser
();
Expression
expr
=
parser
.
parseExpression
(
"throwException(#bar)"
);
...
...
@@ -115,18 +115,18 @@ public class MethodInvocationTests extends ExpressionTestCase {
o
=
expr
.
getValue
(
eContext
);
Assert
.
assertEquals
(
"London"
,
o
);
// That confirms the logic to mark the cached reference stale and retry is working
// Now let's cause the method to exit via exception and ensure it doesn't cause
// a retry.
// First, switch back to throwException(int)
eContext
.
setVariable
(
"bar"
,
3
);
o
=
expr
.
getValue
(
eContext
);
Assert
.
assertEquals
(
3
,
o
);
Assert
.
assertEquals
(
2
,
parser
.
parseExpression
(
"counter"
).
getValue
(
eContext
));
// Now cause it to throw an exception:
eContext
.
setVariable
(
"bar"
,
1
);
try
{
...
...
@@ -157,7 +157,7 @@ public class MethodInvocationTests extends ExpressionTestCase {
// If counter is 5 then the method got called twice!
Assert
.
assertEquals
(
4
,
parser
.
parseExpression
(
"counter"
).
getValue
(
eContext
));
}
/**
* Check on first usage (when the cachedExecutor in MethodReference is null) that the exception is not wrapped.
*/
...
...
@@ -168,10 +168,10 @@ public class MethodInvocationTests extends ExpressionTestCase {
// On 2 it will throw a RuntimeException
// On 3 it will exit normally
// In each case it increments the Inventor field 'counter' when invoked
SpelExpressionParser
parser
=
new
SpelExpressionParser
();
Expression
expr
=
parser
.
parseExpression
(
"throwException(#bar)"
);
eContext
.
setVariable
(
"bar"
,
2
);
try
{
expr
.
getValue
(
eContext
);
...
...
@@ -184,7 +184,7 @@ public class MethodInvocationTests extends ExpressionTestCase {
// normal
}
}
@Test
public
void
testMethodThrowingException_SPR6941_2
()
{
// Test method on inventor: throwException()
...
...
@@ -192,10 +192,10 @@ public class MethodInvocationTests extends ExpressionTestCase {
// On 2 it will throw a RuntimeException
// On 3 it will exit normally
// In each case it increments the Inventor field 'counter' when invoked
SpelExpressionParser
parser
=
new
SpelExpressionParser
();
Expression
expr
=
parser
.
parseExpression
(
"throwException(#bar)"
);
eContext
.
setVariable
(
"bar"
,
4
);
try
{
expr
.
getValue
(
eContext
);
...
...
@@ -207,7 +207,7 @@ public class MethodInvocationTests extends ExpressionTestCase {
}
Assert
.
fail
(
"Should not be a SpelEvaluationException"
);
}
@Test
public
void
testMethodFiltering_SPR6764
()
{
SpelExpressionParser
parser
=
new
SpelExpressionParser
();
...
...
@@ -215,13 +215,13 @@ public class MethodInvocationTests extends ExpressionTestCase {
context
.
setRootObject
(
new
TestObject
());
LocalFilter
filter
=
new
LocalFilter
();
context
.
registerMethodFilter
(
TestObject
.
class
,
filter
);
// Filter will be called but not do anything, so first doit() will be invoked
SpelExpression
expr
=
(
SpelExpression
)
parser
.
parseExpression
(
"doit(1)"
);
String
result
=
expr
.
getValue
(
context
,
String
.
class
);
Assert
.
assertEquals
(
"1"
,
result
);
Assert
.
assertTrue
(
filter
.
filterCalled
);
// Filter will now remove non @Anno annotated methods
filter
.
removeIfNotAnnotated
=
true
;
filter
.
filterCalled
=
false
;
...
...
@@ -229,7 +229,7 @@ public class MethodInvocationTests extends ExpressionTestCase {
result
=
expr
.
getValue
(
context
,
String
.
class
);
Assert
.
assertEquals
(
"double 1.0"
,
result
);
Assert
.
assertTrue
(
filter
.
filterCalled
);
// check not called for other types
filter
.
filterCalled
=
false
;
context
.
setRootObject
(
new
String
(
"abc"
));
...
...
@@ -237,7 +237,7 @@ public class MethodInvocationTests extends ExpressionTestCase {
result
=
expr
.
getValue
(
context
,
String
.
class
);
Assert
.
assertEquals
(
"a"
,
result
);
Assert
.
assertFalse
(
filter
.
filterCalled
);
// check de-registration works
filter
.
filterCalled
=
false
;
context
.
registerMethodFilter
(
TestObject
.
class
,
null
);
//clear filter
...
...
@@ -247,14 +247,14 @@ public class MethodInvocationTests extends ExpressionTestCase {
Assert
.
assertEquals
(
"1"
,
result
);
Assert
.
assertFalse
(
filter
.
filterCalled
);
}
// Simple filter
static
class
LocalFilter
implements
MethodFilter
{
public
boolean
removeIfNotAnnotated
=
false
;
public
boolean
filterCalled
=
false
;
private
boolean
isAnnotated
(
Method
m
)
{
Annotation
[]
annos
=
m
.
getAnnotations
();
if
(
annos
==
null
)
{
...
...
@@ -282,53 +282,53 @@ public class MethodInvocationTests extends ExpressionTestCase {
}
return
methods
;
}
}
@Retention
(
RetentionPolicy
.
RUNTIME
)
@interface
Anno
{}
class
TestObject
{
public
int
doit
(
int
i
)
{
return
i
;
}
@Anno
public
String
doit
(
double
d
)
{
return
"double "
+
d
;
}
}
@Test
public
void
testAddingMethodResolvers
()
{
StandardEvaluationContext
ctx
=
new
StandardEvaluationContext
();
// reflective method accessor is the only one by default
List
<
MethodResolver
>
methodResolvers
=
ctx
.
getMethodResolvers
();
Assert
.
assertEquals
(
1
,
methodResolvers
.
size
());
MethodResolver
dummy
=
new
DummyMethodResolver
();
ctx
.
addMethodResolver
(
dummy
);
Assert
.
assertEquals
(
2
,
ctx
.
getMethodResolvers
().
size
());
List
<
MethodResolver
>
copy
=
new
ArrayList
<
MethodResolver
>();
copy
.
addAll
(
ctx
.
getMethodResolvers
());
Assert
.
assertTrue
(
ctx
.
removeMethodResolver
(
dummy
));
Assert
.
assertFalse
(
ctx
.
removeMethodResolver
(
dummy
));
Assert
.
assertEquals
(
1
,
ctx
.
getMethodResolvers
().
size
());
ctx
.
setMethodResolvers
(
copy
);
Assert
.
assertEquals
(
2
,
ctx
.
getMethodResolvers
().
size
());
}
static
class
DummyMethodResolver
implements
MethodResolver
{
public
MethodExecutor
resolve
(
EvaluationContext
context
,
Object
targetObject
,
String
name
,
List
<
TypeDescriptor
>
argumentTypes
)
throws
AccessException
{
throw
new
UnsupportedOperationException
(
"Auto-generated method stub"
);
}
}
...
...
@@ -355,7 +355,7 @@ public class MethodInvocationTests extends ExpressionTestCase {
evaluate
(
"aVarargsMethod2(2,'a',3.0d)"
,
4
,
Integer
.
class
);
// evaluate("aVarargsMethod2(8,new String[]{'a','b','c'})", 11, Integer.class);
}
@Test
public
void
testInvocationOnNullContextObject
()
{
evaluateAndCheckError
(
"null.toString()"
,
SpelMessage
.
METHOD_CALL_ON_NULL_OBJECT_NOT_ALLOWED
);
...
...
spring-expression/src/test/java/org/springframework/expression/spel/PropertyAccessTests.java
浏览文件 @
98808347
...
...
@@ -37,7 +37,7 @@ import org.springframework.expression.spel.support.StandardEvaluationContext;
/**
* Tests accessing of properties.
*
*
* @author Andy Clement
*/
public
class
PropertyAccessTests
extends
ExpressionTestCase
{
...
...
@@ -65,9 +65,9 @@ public class PropertyAccessTests extends ExpressionTestCase {
// name is ok but foobar does not exist:
evaluateAndCheckError
(
"name.foobar"
,
SpelMessage
.
PROPERTY_OR_FIELD_NOT_READABLE
,
5
);
}
/**
* The standard reflection resolver cannot find properties on null objects but some
* The standard reflection resolver cannot find properties on null objects but some
* supplied resolver might be able to - so null shouldn't crash the reflection resolver.
*/
@Test
...
...
@@ -132,25 +132,25 @@ public class PropertyAccessTests extends ExpressionTestCase {
// System.out.println(e.getMessage());
}
}
@Test
public
void
testAddingRemovingAccessors
()
{
StandardEvaluationContext
ctx
=
new
StandardEvaluationContext
();
// reflective property accessor is the only one by default
List
<
PropertyAccessor
>
propertyAccessors
=
ctx
.
getPropertyAccessors
();
Assert
.
assertEquals
(
1
,
propertyAccessors
.
size
());
StringyPropertyAccessor
spa
=
new
StringyPropertyAccessor
();
ctx
.
addPropertyAccessor
(
spa
);
Assert
.
assertEquals
(
2
,
ctx
.
getPropertyAccessors
().
size
());
List
<
PropertyAccessor
>
copy
=
new
ArrayList
<
PropertyAccessor
>();
copy
.
addAll
(
ctx
.
getPropertyAccessors
());
Assert
.
assertTrue
(
ctx
.
removePropertyAccessor
(
spa
));
Assert
.
assertFalse
(
ctx
.
removePropertyAccessor
(
spa
));
Assert
.
assertEquals
(
1
,
ctx
.
getPropertyAccessors
().
size
());
ctx
.
setPropertyAccessors
(
copy
);
Assert
.
assertEquals
(
2
,
ctx
.
getPropertyAccessors
().
size
());
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录