Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
爱吃血肠
spring-framework
提交
6a1fe0b1
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,发现更多精彩内容 >>
提交
6a1fe0b1
编写于
1月 07, 2018
作者:
J
Juergen Hoeller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
FunctionReference's method field is volatile
Issue: SPR-16255
上级
0a06bce3
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
28 addition
and
20 deletion
+28
-20
spring-expression/src/main/java/org/springframework/expression/spel/ast/FunctionReference.java
...pringframework/expression/spel/ast/FunctionReference.java
+28
-20
未找到文件。
spring-expression/src/main/java/org/springframework/expression/spel/ast/FunctionReference.java
浏览文件 @
6a1fe0b1
/*
* Copyright 2002-201
7
the original author or authors.
* Copyright 2002-201
8
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.
...
...
@@ -47,6 +47,7 @@ import org.springframework.util.ReflectionUtils;
* (right now), so the names must be unique.
*
* @author Andy Clement
* @author Juergen Hoeller
* @since 3.0
*/
public
class
FunctionReference
extends
SpelNodeImpl
{
...
...
@@ -56,9 +57,7 @@ public class FunctionReference extends SpelNodeImpl {
// Captures the most recently used method for the function invocation *if* the method
// can safely be used for compilation (i.e. no argument conversion is going on)
@Nullable
private
Method
method
;
private
boolean
argumentConversionOccurred
;
private
volatile
Method
method
;
public
FunctionReference
(
String
functionName
,
int
pos
,
SpelNodeImpl
...
arguments
)
{
...
...
@@ -90,14 +89,13 @@ public class FunctionReference extends SpelNodeImpl {
}
/**
* Execute a function represented as a
java.lang.reflect.Method
.
* Execute a function represented as a
{@code java.lang.reflect.Method}
.
* @param state the expression evaluation state
* @param method the method to invoke
* @return the return value of the invoked Java method
* @throws EvaluationException if there is any problem invoking the method
*/
private
TypedValue
executeFunctionJLRMethod
(
ExpressionState
state
,
Method
method
)
throws
EvaluationException
{
this
.
method
=
null
;
Object
[]
functionArgs
=
getArguments
(
state
);
if
(!
method
.
isVarArgs
()
&&
method
.
getParameterCount
()
!=
functionArgs
.
length
)
{
...
...
@@ -112,25 +110,33 @@ public class FunctionReference extends SpelNodeImpl {
// Convert arguments if necessary and remap them for varargs if required
TypeConverter
converter
=
state
.
getEvaluationContext
().
getTypeConverter
();
argumentConversionOccurred
=
ReflectionHelper
.
convertAllArguments
(
converter
,
functionArgs
,
method
);
boolean
argumentConversionOccurred
=
ReflectionHelper
.
convertAllArguments
(
converter
,
functionArgs
,
method
);
if
(
method
.
isVarArgs
())
{
functionArgs
=
ReflectionHelper
.
setupArgumentsForVarargsInvocation
(
method
.
getParameterTypes
(),
functionArgs
);
}
boolean
compilable
=
false
;
try
{
ReflectionUtils
.
makeAccessible
(
method
);
Object
result
=
method
.
invoke
(
method
.
getClass
(),
functionArgs
);
if
(!
argumentConversionOccurred
)
{
this
.
method
=
method
;
this
.
exitTypeDescriptor
=
CodeFlow
.
toDescriptor
(
method
.
getReturnType
());
}
compilable
=
!
argumentConversionOccurred
;
return
new
TypedValue
(
result
,
new
TypeDescriptor
(
new
MethodParameter
(
method
,
-
1
)).
narrow
(
result
));
}
catch
(
Exception
ex
)
{
throw
new
SpelEvaluationException
(
getStartPosition
(),
ex
,
SpelMessage
.
EXCEPTION_DURING_FUNCTION_CALL
,
this
.
name
,
ex
.
getMessage
());
}
finally
{
if
(
compilable
)
{
this
.
exitTypeDescriptor
=
CodeFlow
.
toDescriptor
(
method
.
getReturnType
());
this
.
method
=
method
;
}
else
{
this
.
exitTypeDescriptor
=
null
;
this
.
method
=
null
;
}
}
}
@Override
...
...
@@ -162,12 +168,13 @@ public class FunctionReference extends SpelNodeImpl {
@Override
public
boolean
isCompilable
()
{
if
(
this
.
method
==
null
||
this
.
argumentConversionOccurred
)
{
Method
method
=
this
.
method
;
if
(
method
==
null
)
{
return
false
;
}
int
methodModifiers
=
this
.
method
.
getModifiers
();
int
methodModifiers
=
method
.
getModifiers
();
if
(!
Modifier
.
isStatic
(
methodModifiers
)
||
!
Modifier
.
isPublic
(
methodModifiers
)
||
!
Modifier
.
isPublic
(
this
.
method
.
getDeclaringClass
().
getModifiers
()))
{
!
Modifier
.
isPublic
(
method
.
getDeclaringClass
().
getModifiers
()))
{
return
false
;
}
for
(
SpelNodeImpl
child
:
this
.
children
)
{
...
...
@@ -179,12 +186,13 @@ public class FunctionReference extends SpelNodeImpl {
}
@Override
public
void
generateCode
(
MethodVisitor
mv
,
CodeFlow
cf
)
{
Assert
.
state
(
this
.
method
!=
null
,
"No method handle"
);
String
classDesc
=
this
.
method
.
getDeclaringClass
().
getName
().
replace
(
'.'
,
'/'
);
generateCodeForArguments
(
mv
,
cf
,
this
.
method
,
this
.
children
);
mv
.
visitMethodInsn
(
INVOKESTATIC
,
classDesc
,
this
.
method
.
getName
(),
CodeFlow
.
createSignatureDescriptor
(
this
.
method
),
false
);
public
void
generateCode
(
MethodVisitor
mv
,
CodeFlow
cf
)
{
Method
method
=
this
.
method
;
Assert
.
state
(
method
!=
null
,
"No method handle"
);
String
classDesc
=
method
.
getDeclaringClass
().
getName
().
replace
(
'.'
,
'/'
);
generateCodeForArguments
(
mv
,
cf
,
method
,
this
.
children
);
mv
.
visitMethodInsn
(
INVOKESTATIC
,
classDesc
,
method
.
getName
(),
CodeFlow
.
createSignatureDescriptor
(
method
),
false
);
cf
.
pushDescriptor
(
this
.
exitTypeDescriptor
);
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录