Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
sesemomo
spring-framework
提交
e1a382b6
S
spring-framework
项目概览
sesemomo
/
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,发现更多精彩内容 >>
提交
e1a382b6
编写于
11月 01, 2016
作者:
R
Rossen Stoyanchev
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Polish
上级
b07d40cc
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
80 addition
and
60 deletion
+80
-60
spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/InvocableHandlerMethod.java
...rk/web/reactive/result/method/InvocableHandlerMethod.java
+62
-53
spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/SyncInvocableHandlerMethod.java
...eb/reactive/result/method/SyncInvocableHandlerMethod.java
+17
-6
spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerAdapter.java
...esult/method/annotation/RequestMappingHandlerAdapter.java
+1
-1
未找到文件。
spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/InvocableHandlerMethod.java
浏览文件 @
e1a382b6
...
...
@@ -21,6 +21,7 @@ import java.lang.reflect.Method;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.List
;
import
java.util.Optional
;
import
java.util.stream.Collectors
;
import
java.util.stream.IntStream
;
import
java.util.stream.Stream
;
...
...
@@ -40,17 +41,17 @@ import org.springframework.web.reactive.HandlerResult;
import
org.springframework.web.server.ServerWebExchange
;
/**
*
Extension of HandlerMethod that can invoke the target method after resolving
*
its method arguments
.
*
A sub-class of {@link HandlerMethod} that can resolve method arguments from
*
a {@link ServerWebExchange} and use that to invoke the underlying method
.
*
* @author Rossen Stoyanchev
* @since 5.0
*/
public
class
InvocableHandlerMethod
extends
HandlerMethod
{
private
static
final
Mono
<
Object
[]>
NO
_ARGS
=
Mono
.
just
(
new
Object
[
0
]);
private
static
final
Mono
<
Object
[]>
EMPTY
_ARGS
=
Mono
.
just
(
new
Object
[
0
]);
private
static
final
Object
NO_VALUE
=
new
Object
();
private
static
final
Object
NO_
ARG_
VALUE
=
new
Object
();
private
List
<
HandlerMethodArgumentResolver
>
resolvers
=
new
ArrayList
<>();
...
...
@@ -68,8 +69,8 @@ public class InvocableHandlerMethod extends HandlerMethod {
/**
*
Set {@link HandlerMethodArgumentResolver}s to use to use for resolving
*
method argument values
.
*
Configure the argument resolvers to use to use for resolving method
*
argument values against a {@code ServerWebExchange}
.
*/
public
void
setArgumentResolvers
(
List
<
HandlerMethodArgumentResolver
>
resolvers
)
{
this
.
resolvers
.
clear
();
...
...
@@ -81,24 +82,18 @@ public class InvocableHandlerMethod extends HandlerMethod {
* (e.g. default request attribute name).
* <p>Default is a {@link DefaultParameterNameDiscoverer}.
*/
public
void
setParameterNameDiscoverer
(
ParameterNameDiscoverer
parameterNameDiscoverer
)
{
this
.
parameterNameDiscoverer
=
parameterNameDiscoverer
;
}
@Override
protected
Method
getBridgedMethod
()
{
return
super
.
getBridgedMethod
();
public
void
setParameterNameDiscoverer
(
ParameterNameDiscoverer
nameDiscoverer
)
{
this
.
parameterNameDiscoverer
=
nameDiscoverer
;
}
/**
* Invoke the method and return a Publisher for the return value.
* Invoke the method for the given exchange.
*
* @param exchange the current exchange
* @param bindingContext the binding context to use
* @param providedArgs optional list of argument values to check by type
* (via {@code instanceof}) for resolving method arguments.
* @return Publisher that produces a single HandlerResult or an error signal;
* never throws an exception
* @param providedArgs optional list of argument values to match by type
* @return Mono with a {@link HandlerResult}.
*/
public
Mono
<
HandlerResult
>
invoke
(
ServerWebExchange
exchange
,
BindingContext
bindingContext
,
Object
...
providedArgs
)
{
...
...
@@ -124,59 +119,73 @@ public class InvocableHandlerMethod extends HandlerMethod {
BindingContext
bindingContext
,
Object
...
providedArgs
)
{
if
(
ObjectUtils
.
isEmpty
(
getMethodParameters
()))
{
return
NO
_ARGS
;
return
EMPTY
_ARGS
;
}
try
{
List
<
Mono
<
Object
>>
m
onos
=
Stream
.
of
(
getMethodParameters
())
List
<
Mono
<
Object
>>
argM
onos
=
Stream
.
of
(
getMethodParameters
())
.
map
(
param
->
{
param
.
initParameterNameDiscovery
(
this
.
parameterNameDiscoverer
);
GenericTypeResolver
.
resolveParameterType
(
param
,
getBean
().
getClass
());
if
(!
ObjectUtils
.
isEmpty
(
providedArgs
))
{
for
(
Object
providedArg
:
providedArgs
)
{
if
(
param
.
getParameterType
().
isInstance
(
providedArg
))
{
return
Mono
.
just
(
providedArg
).
log
(
"reactor.resolved"
);
}
}
}
HandlerMethodArgumentResolver
resolver
=
this
.
resolvers
.
stream
()
.
filter
(
r
->
r
.
supportsParameter
(
param
))
.
findFirst
()
.
orElseThrow
(()
->
getArgError
(
"No resolver for "
,
param
,
null
));
try
{
return
resolver
.
resolveArgument
(
param
,
bindingContext
,
exchange
)
.
defaultIfEmpty
(
NO_VALUE
)
.
doOnError
(
cause
->
{
if
(
logger
.
isDebugEnabled
())
{
logger
.
debug
(
getDetailedErrorMessage
(
"Error resolving "
,
param
),
cause
);
}
})
.
log
(
"reactor.unresolved"
);
}
catch
(
Exception
ex
)
{
throw
getArgError
(
"Error resolving "
,
param
,
ex
);
}
return
findProvidedArg
(
param
,
providedArgs
)
.
map
(
Mono:
:
just
)
.
orElseGet
(()
->
{
HandlerMethodArgumentResolver
resolver
=
findResolver
(
param
);
return
resolveArg
(
resolver
,
param
,
bindingContext
,
exchange
);
});
})
.
collect
(
Collectors
.
toList
());
// Create Mono with array of resolved values...
return
Mono
.
when
(
monos
,
args
->
Stream
.
of
(
args
).
map
(
o
->
o
!=
NO
_VALUE
?
o
:
null
).
toArray
());
return
Mono
.
when
(
argMonos
,
argValues
->
Stream
.
of
(
argValues
).
map
(
o
->
o
!=
NO_ARG
_VALUE
?
o
:
null
).
toArray
());
}
catch
(
Throwable
ex
)
{
return
Mono
.
error
(
ex
);
}
}
private
IllegalStateException
getArgError
(
String
message
,
MethodParameter
param
,
Throwable
cause
)
{
return
new
IllegalStateException
(
getDetailedErrorMessage
(
message
,
param
),
cause
);
private
Optional
<
Object
>
findProvidedArg
(
MethodParameter
param
,
Object
...
providedArgs
)
{
if
(
ObjectUtils
.
isEmpty
(
providedArgs
))
{
return
Optional
.
empty
();
}
return
Arrays
.
stream
(
providedArgs
)
.
filter
(
arg
->
param
.
getParameterType
().
isInstance
(
arg
))
.
findFirst
();
}
private
HandlerMethodArgumentResolver
findResolver
(
MethodParameter
param
)
{
return
this
.
resolvers
.
stream
()
.
filter
(
r
->
r
.
supportsParameter
(
param
))
.
findFirst
()
.
orElseThrow
(()
->
getArgumentError
(
"No resolver for "
,
param
,
null
));
}
private
Mono
<
Object
>
resolveArg
(
HandlerMethodArgumentResolver
resolver
,
MethodParameter
param
,
BindingContext
bindingContext
,
ServerWebExchange
exchange
)
{
try
{
return
resolver
.
resolveArgument
(
param
,
bindingContext
,
exchange
)
.
defaultIfEmpty
(
NO_ARG_VALUE
)
.
doOnError
(
cause
->
{
if
(
logger
.
isDebugEnabled
())
{
logger
.
debug
(
getDetailedErrorMessage
(
"Error resolving "
,
param
),
cause
);
}
});
}
catch
(
Exception
ex
)
{
throw
getArgumentError
(
"Error resolving "
,
param
,
ex
);
}
}
private
IllegalStateException
getArgumentError
(
String
message
,
MethodParameter
param
,
Throwable
ex
)
{
return
new
IllegalStateException
(
getDetailedErrorMessage
(
message
,
param
),
ex
);
}
private
String
getDetailedErrorMessage
(
String
message
,
MethodParameter
param
)
{
StringBuilder
sb
=
new
StringBuilder
(
message
);
sb
.
append
(
"argument ["
).
append
(
param
.
getParameterIndex
()).
append
(
"] "
);
sb
.
append
(
"of type ["
).
append
(
param
.
getParameterType
().
getName
()).
append
(
"] "
);
sb
.
append
(
"on method ["
).
append
(
getBridgedMethod
().
toGenericString
()).
append
(
"]"
);
return
sb
.
toString
();
return
message
+
"argument ["
+
param
.
getParameterIndex
()
+
"] "
+
"of type ["
+
param
.
getParameterType
().
getName
()
+
"] "
+
"on method ["
+
getBridgedMethod
().
toGenericString
()
+
"]"
;
}
private
Object
doInvoke
(
Object
[]
args
)
throws
Exception
{
...
...
spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/SyncInvocableHandlerMethod.java
浏览文件 @
e1a382b6
...
...
@@ -16,7 +16,7 @@
package
org.springframework.web.reactive.result.method
;
import
java.lang.reflect.Method
;
import
java.util.
Collections
;
import
java.util.
ArrayList
;
import
java.util.List
;
import
org.springframework.util.Assert
;
...
...
@@ -25,9 +25,10 @@ import org.springframework.web.reactive.HandlerResult;
import
org.springframework.web.server.ServerWebExchange
;
/**
* An extension of {@code InvocableHandlerMethod} for use with
* {@link SyncHandlerMethodArgumentResolver}s which in turn enables synchronous
* handler method invocation via {@link #invokeForHandlerResult}.
* An extension of {@code InvocableHandlerMethod} for synchronous, non-blocking
* method invocation via {@link #invokeForHandlerResult}. By allowing only
* {@link SyncHandlerMethodArgumentResolver}s to be configured, the invocation
* is guaranteed to be non-blocking.
*
* @author Rossen Stoyanchev
* @since 5.0
...
...
@@ -45,8 +46,9 @@ public class SyncInvocableHandlerMethod extends InvocableHandlerMethod {
/**
* Overloaded variant of the same setter from the base class that ensures
* all resolvers are {@link SyncHandlerMethodArgumentResolver}.
* {@inheritDoc}
* <p>Resolvers must be of type {@link SyncHandlerMethodArgumentResolver}.
* @see #setSyncArgumentResolvers(List)
*/
@Override
public
void
setArgumentResolvers
(
List
<
HandlerMethodArgumentResolver
>
resolvers
)
{
...
...
@@ -56,6 +58,15 @@ public class SyncInvocableHandlerMethod extends InvocableHandlerMethod {
super
.
setArgumentResolvers
(
resolvers
);
}
/**
* Convenient alternative to {@link #setArgumentResolvers(List)} to configure
* synchronous argument resolvers.
*/
public
void
setSyncArgumentResolvers
(
List
<
SyncHandlerMethodArgumentResolver
>
resolvers
)
{
setArgumentResolvers
(
new
ArrayList
<>(
resolvers
));
}
/**
* Delegate to the base class {@link #invoke} and also wait for the result.
* Since all argument resolvers are synchronous this won't actually block.
...
...
spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerAdapter.java
浏览文件 @
e1a382b6
...
...
@@ -311,7 +311,7 @@ public class RequestMappingHandlerAdapter implements HandlerAdapter, BeanFactory
for
(
Method
method
:
methods
)
{
Object
bean
=
handlerMethod
.
getBean
();
SyncInvocableHandlerMethod
initBinderMethod
=
new
SyncInvocableHandlerMethod
(
bean
,
method
);
initBinderMethod
.
set
ArgumentResolvers
(
new
ArrayList
<>(
this
.
initBinderArgumentResolvers
));
initBinderMethod
.
set
SyncArgumentResolvers
(
getInitBinderArgumentResolvers
(
));
initBinderMethods
.
add
(
initBinderMethod
);
}
return
new
InitBinderBindingContext
(
getWebBindingInitializer
(),
initBinderMethods
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录