Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
爱吃血肠
spring-framework
提交
8d0ab1d2
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,发现更多精彩内容 >>
提交
8d0ab1d2
编写于
5月 08, 2011
作者:
R
Rossen Stoyanchev
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Refine HandlerMethod registration to allow detection by handler instance as well as by bean name
上级
d0c31ad8
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
80 addition
and
60 deletion
+80
-60
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodMapping.java
...ork/web/servlet/handler/AbstractHandlerMethodMapping.java
+44
-25
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java
...t/mvc/method/annotation/RequestMappingHandlerMapping.java
+16
-18
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/handler/HandlerMethodMappingTests.java
...mework/web/servlet/handler/HandlerMethodMappingTests.java
+18
-16
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ServletHandlerMethodTests.java
...vlet/mvc/method/annotation/ServletHandlerMethodTests.java
+1
-1
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/UriTemplateServletHandlerMethodTests.java
...thod/annotation/UriTemplateServletHandlerMethodTests.java
+1
-0
未找到文件。
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodMapping.java
浏览文件 @
8d0ab1d2
...
...
@@ -96,6 +96,14 @@ public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMap
return
urlPathHelper
;
}
/**
* Return the map with all {@link HandlerMethod}s. The key of the map is the generic type
* <strong>{@code <T>}</strong> containing request mapping conditions.
*/
public
Map
<
T
,
HandlerMethod
>
getHandlerMethods
()
{
return
Collections
.
unmodifiableMap
(
handlerMethods
);
}
/**
* Calls the initialization of the superclass and detects handlers.
*/
...
...
@@ -115,35 +123,36 @@ public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMap
logger
.
debug
(
"Looking for request mappings in application context: "
+
getApplicationContext
());
}
for
(
String
beanName
:
getApplicationContext
().
getBeanNamesForType
(
Object
.
class
))
{
if
(
isHandler
(
beanName
)){
if
(
isHandler
(
getApplicationContext
().
getType
(
beanName
)
)){
detectHandlerMethods
(
beanName
);
}
}
}
/**
* Determines if the given
bean is a handler that should be introspected for
handler methods.
* @param bean
Name the name of the bean
to check
* @return true if th
e bean is a handler and may
contain handler methods, false otherwise.
* Determines if the given
type could contain
handler methods.
* @param bean
Type the type
to check
* @return true if th
is a type that could
contain handler methods, false otherwise.
*/
protected
abstract
boolean
isHandler
(
String
beanNam
e
);
protected
abstract
boolean
isHandler
(
Class
<?>
beanTyp
e
);
/**
* Detect and register handler methods for the specified handler.
* @param handler the bean name of a handler or a handler instance
*/
private
void
detectHandlerMethods
(
final
String
beanName
)
{
Class
<?>
handlerType
=
getApplicationContext
().
getType
(
beanName
);
protected
void
detectHandlerMethods
(
final
Object
handler
)
{
final
Class
<?>
handlerType
=
(
handler
instanceof
String
)
?
getApplicationContext
().
getType
((
String
)
handler
)
:
handler
.
getClass
();
Set
<
Method
>
methods
=
HandlerMethodSelector
.
selectMethods
(
handlerType
,
new
MethodFilter
()
{
public
boolean
matches
(
Method
method
)
{
return
getMappingForMethod
(
beanName
,
method
)
!=
null
;
return
getMappingForMethod
(
method
,
handlerType
)
!=
null
;
}
});
for
(
Method
method
:
methods
)
{
HandlerMethod
handlerMethod
=
new
HandlerMethod
(
beanName
,
getApplicationContext
(),
method
);
T
mapping
=
getMappingForMethod
(
beanName
,
method
);
Set
<
String
>
paths
=
getMappingPaths
(
mapping
);
registerHandlerMethod
(
paths
,
mapping
,
handlerMethod
);
T
mapping
=
getMappingForMethod
(
method
,
handlerType
);
registerHandlerMethod
(
handler
,
method
,
mapping
);
}
}
...
...
@@ -151,40 +160,50 @@ public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMap
* Provides a request mapping for the given bean method. A method for which no request mapping can be determined
* is not considered a handler method.
*
* @param beanName the name of the bean the method belongs to
* @param method the method to create a mapping for
* @param handlerType the actual handler type (possibly a subtype of {@code method.getDeclaringClass()})
* @return the mapping, or {@code null} if the method is not mapped
*/
protected
abstract
T
getMappingForMethod
(
String
beanName
,
Method
method
);
protected
abstract
T
getMappingForMethod
(
Method
method
,
Class
<?>
handlerType
);
/**
* Registers a {@link HandlerMethod} with the given mapping.
*
* @param
paths URL paths mapped to this method
* @param m
apping the mapping for the method
* @param
handlerMethod the handler method to register
* @param
handler the bean name of the handler or the actual handler instance
* @param m
ethod the method to register
* @param
mapping the mapping conditions associated with the handler method
* @throws IllegalStateException if another method was already register under the same mapping
*/
protected
void
registerHandlerMethod
(
Set
<
String
>
paths
,
T
mapping
,
HandlerMethod
handlerMethod
)
{
Assert
.
notNull
(
mapping
,
"'mapping' must not be null"
);
Assert
.
notNull
(
handlerMethod
,
"'handlerMethod' must not be null"
);
HandlerMethod
mappedHandlerMethod
=
handlerMethods
.
get
(
mapping
);
if
(
mappedHandlerMethod
!=
null
&&
!
mappedHandlerMethod
.
equals
(
handlerMethod
))
{
protected
void
registerHandlerMethod
(
Object
handler
,
Method
method
,
T
mapping
)
{
HandlerMethod
handlerMethod
;
if
(
handler
instanceof
String
)
{
String
beanName
=
(
String
)
handler
;
handlerMethod
=
new
HandlerMethod
(
beanName
,
getApplicationContext
(),
method
);
}
else
{
handlerMethod
=
new
HandlerMethod
(
handler
,
method
);
}
HandlerMethod
oldHandlerMethod
=
handlerMethods
.
get
(
mapping
);
if
(
oldHandlerMethod
!=
null
&&
!
oldHandlerMethod
.
equals
(
handlerMethod
))
{
throw
new
IllegalStateException
(
"Ambiguous mapping found. Cannot map '"
+
handlerMethod
.
getBean
()
+
"' bean method \n"
+
handlerMethod
+
"\nto "
+
mapping
+
": There is already '"
+
mappedHandlerMethod
.
getBean
()
+
"' bean method\n"
+
mappe
dHandlerMethod
+
" mapped."
);
+
oldHandlerMethod
.
getBean
()
+
"' bean method\n"
+
ol
dHandlerMethod
+
" mapped."
);
}
handlerMethods
.
put
(
mapping
,
handlerMethod
);
if
(
logger
.
isInfoEnabled
())
{
logger
.
info
(
"Mapped \""
+
mapping
+
"\" onto "
+
handlerMethod
);
}
Set
<
String
>
paths
=
getMappingPaths
(
mapping
);
for
(
String
path
:
paths
)
{
urlMap
.
add
(
path
,
mapping
);
}
}
/**
* Get the URL paths
for
the given mapping.
* Get the URL paths
associated with
the given mapping.
*/
protected
abstract
Set
<
String
>
getMappingPaths
(
T
mapping
);
...
...
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java
浏览文件 @
8d0ab1d2
...
...
@@ -46,12 +46,12 @@ import org.springframework.web.servlet.handler.MappedInterceptors;
import
org.springframework.web.servlet.mvc.method.condition.RequestConditionFactory
;
/**
* An {@link AbstractHandlerMethodMapping} variant that uses {@link RequestMappingInfo}s for the registration and
* An {@link AbstractHandlerMethodMapping} variant that uses {@link RequestMappingInfo}s for the registration and
* the lookup of {@link HandlerMethod}s.
*
*
* @author Arjen Poutsma
* @author Rossen Stoyanchev
* @since 3.1
* @since 3.1
.0
*/
public
class
RequestMappingHandlerMapping
extends
AbstractHandlerMethodMapping
<
RequestMappingInfo
>
{
...
...
@@ -87,32 +87,30 @@ public class RequestMappingHandlerMapping extends AbstractHandlerMethodMapping<R
/**
* {@inheritDoc}
* The handler determination is made based on the presence of a type-level {@link Controller} or
* a type-level {@link RequestMapping} annotation.
* The handler determination in this method is made based on the presence of a type-level {@link Controller} annotation.
*/
@Override
protected
boolean
isHandler
(
String
beanName
)
{
return
((
getApplicationContext
().
findAnnotationOnBean
(
beanName
,
RequestMapping
.
class
)
!=
null
)
||
(
getApplicationContext
().
findAnnotationOnBean
(
beanName
,
Controller
.
class
)
!=
null
));
protected
boolean
isHandler
(
Class
<?>
beanType
)
{
return
AnnotationUtils
.
findAnnotation
(
beanType
,
Controller
.
class
)
!=
null
;
}
/**
* Provides a {@link RequestMappingInfo} for the given method.
* <p>Only {@link RequestMapping @RequestMapping}-annotated methods are considered.
* Type-level {@link RequestMapping @RequestMapping} annotations are also detected and their
* Provides a {@link RequestMappingInfo} for the given method.
* <p>Only {@link RequestMapping @RequestMapping}-annotated methods are considered.
* Type-level {@link RequestMapping @RequestMapping} annotations are also detected and their
* attributes combined with method-level {@link RequestMapping @RequestMapping} attributes.
*
* @param beanName the name of the bean the method belongs to
* @param method the method to create a mapping for
* @param handlerType the actual handler type, possibly a sub-type of {@code method.getDeclaringClass()}
* @return the mapping, or {@code null}
* @see RequestMappingInfo#combine(RequestMappingInfo, PathMatcher)
*/
@Override
protected
RequestMappingInfo
getMappingForMethod
(
String
beanName
,
Method
method
)
{
protected
RequestMappingInfo
getMappingForMethod
(
Method
method
,
Class
<?>
handlerType
)
{
RequestMapping
annotation
=
AnnotationUtils
.
findAnnotation
(
method
,
RequestMapping
.
class
);
if
(
annotation
!=
null
)
{
RequestMappingInfo
methodMapping
=
createFromRequestMapping
(
annotation
);
RequestMapping
typeAnnot
=
getApplicationContext
().
findAnnotationOnBean
(
beanNam
e
,
RequestMapping
.
class
);
RequestMapping
typeAnnot
=
AnnotationUtils
.
findAnnotation
(
handlerTyp
e
,
RequestMapping
.
class
);
if
(
typeAnnot
!=
null
)
{
RequestMappingInfo
typeMapping
=
createFromRequestMapping
(
typeAnnot
);
return
typeMapping
.
combine
(
methodMapping
,
pathMatcher
);
...
...
@@ -206,12 +204,12 @@ public class RequestMappingHandlerMapping extends AbstractHandlerMethodMapping<R
}
/**
* A comparator for {@link RequestMappingInfo}s. Effective comparison can only be done in the context of a
* specific request. For example not all {@link RequestMappingInfo} patterns may apply to the current request.
* A comparator for {@link RequestMappingInfo}s. Effective comparison can only be done in the context of a
* specific request. For example not all {@link RequestMappingInfo} patterns may apply to the current request.
* Therefore an HttpServletRequest is required as input.
*
* <p>Furthermore, the following assumptions are made about the input RequestMappings:
* <ul><li>Each RequestMappingInfo has been fully matched to the request <li>The RequestMappingInfo contains
* <p>Furthermore, the following assumptions are made about the input RequestMappings:
* <ul><li>Each RequestMappingInfo has been fully matched to the request <li>The RequestMappingInfo contains
* matched patterns only <li>Patterns are ordered with the best matching pattern at the top </ul>
*
* @see RequestMappingHandlerMapping#getMatchingMapping(RequestMappingInfo, String, HttpServletRequest)
...
...
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/handler/HandlerMethodMappingTests.java
浏览文件 @
8d0ab1d2
...
...
@@ -41,46 +41,48 @@ public class HandlerMethodMappingTests {
private
AbstractHandlerMethodMapping
<
String
>
mapping
;
private
HandlerMethod
handlerMethod1
;
private
MyHandler
handler
;
private
HandlerMethod
handlerMethod2
;
private
Method
method1
;
private
Method
method2
;
@Before
public
void
setUp
()
throws
Exception
{
mapping
=
new
MyHandlerMethodMapping
();
MyHandler
handler
=
new
MyHandler
();
handlerMethod1
=
new
HandlerMethod
(
handler
,
"handlerMethod1"
);
handlerMethod2
=
new
HandlerMethod
(
handler
,
"handlerMethod2"
);
handler
=
new
MyHandler
();
method1
=
handler
.
getClass
().
getMethod
(
"handlerMethod1"
);
method2
=
handler
.
getClass
().
getMethod
(
"handlerMethod2"
);
}
@Test
(
expected
=
IllegalStateException
.
class
)
public
void
registerDuplicates
()
{
mapping
.
registerHandlerMethod
(
new
HashSet
<
String
>(),
"foo"
,
handlerMethod1
);
mapping
.
registerHandlerMethod
(
new
HashSet
<
String
>(),
"foo"
,
handlerMethod2
);
mapping
.
registerHandlerMethod
(
handler
,
method1
,
"foo"
);
mapping
.
registerHandlerMethod
(
handler
,
method2
,
"foo"
);
}
@Test
public
void
directMatch
()
throws
Exception
{
String
key
=
"foo"
;
mapping
.
registerHandlerMethod
(
new
HashSet
<
String
>(),
key
,
handlerMethod1
);
mapping
.
registerHandlerMethod
(
handler
,
method1
,
key
);
HandlerMethod
result
=
mapping
.
getHandlerInternal
(
new
MockHttpServletRequest
(
"GET"
,
key
));
assertEquals
(
handlerMethod1
,
result
);
assertEquals
(
method1
,
result
.
getMethod
()
);
}
@Test
public
void
patternMatch
()
throws
Exception
{
mapping
.
registerHandlerMethod
(
new
HashSet
<
String
>(),
"/fo*"
,
handlerMethod1
);
mapping
.
registerHandlerMethod
(
new
HashSet
<
String
>(),
"/f*"
,
handlerMethod1
);
mapping
.
registerHandlerMethod
(
handler
,
method1
,
"/fo*"
);
mapping
.
registerHandlerMethod
(
handler
,
method1
,
"/f*"
);
HandlerMethod
result
=
mapping
.
getHandlerInternal
(
new
MockHttpServletRequest
(
"GET"
,
"/foo"
));
assertEquals
(
handlerMethod1
,
result
);
assertEquals
(
method1
,
result
.
getMethod
()
);
}
@Test
(
expected
=
IllegalStateException
.
class
)
public
void
ambiguousMatch
()
throws
Exception
{
mapping
.
registerHandlerMethod
(
new
HashSet
<
String
>(),
"/f?o"
,
handlerMethod1
);
mapping
.
registerHandlerMethod
(
new
HashSet
<
String
>(),
"/fo?"
,
handlerMethod2
);
mapping
.
registerHandlerMethod
(
handler
,
method1
,
"/f?o"
);
mapping
.
registerHandlerMethod
(
handler
,
method2
,
"/fo?"
);
mapping
.
getHandlerInternal
(
new
MockHttpServletRequest
(
"GET"
,
"/foo"
));
}
...
...
@@ -95,7 +97,7 @@ public class HandlerMethodMappingTests {
}
@Override
protected
String
getMappingForMethod
(
String
beanName
,
Method
method
)
{
protected
String
getMappingForMethod
(
Method
method
,
Class
<?>
handlerType
)
{
String
methodName
=
method
.
getName
();
return
methodName
.
startsWith
(
"handler"
)
?
methodName
:
null
;
}
...
...
@@ -106,7 +108,7 @@ public class HandlerMethodMappingTests {
}
@Override
protected
boolean
isHandler
(
String
beanNam
e
)
{
protected
boolean
isHandler
(
Class
<?>
beanTyp
e
)
{
return
true
;
}
...
...
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ServletHandlerMethodTests.java
浏览文件 @
8d0ab1d2
...
...
@@ -1531,6 +1531,7 @@ public class ServletHandlerMethodTests {
@RequestMapping
(
"/myPage"
)
@SessionAttributes
({
"object1"
,
"object2"
})
@Controller
public
interface
MySessionAttributesControllerIfc
{
@RequestMapping
(
method
=
RequestMethod
.
GET
)
...
...
@@ -1540,7 +1541,6 @@ public class ServletHandlerMethodTests {
String
post
(
@ModelAttribute
(
"object1"
)
Object
object1
);
}
@Controller
public
static
class
MySessionAttributesControllerImpl
implements
MySessionAttributesControllerIfc
{
public
String
get
(
Model
model
)
{
...
...
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/UriTemplateServletHandlerMethodTests.java
浏览文件 @
8d0ab1d2
...
...
@@ -542,6 +542,7 @@ public class UriTemplateServletHandlerMethodTests {
}
@Controller
@RequestMapping
(
"/*/menu/**"
)
public
static
class
MenuTreeController
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录