springMVC源码分析--AbstractHandlerMapping(二)
上一篇博客springMVC源码分析--HandlerMapping(一)中我们简单的介绍了HandlerMapping,接下来我们介绍一下它的抽象实现类AbstractHandlerMapping
HandlerMapping中定义了方法getHandler(HttpServletRequest request),AbstractHandlerMapping中的实现如下:
//获得一个HandlerExecutionChain
@Override
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
//从实现类中获得HanlderMethod
Object handler = getHandlerInternal(request);
if (handler == null) {
handler = getDefaultHandler();
}
if (handler == null) {
return null;
}
// Bean name or resolved handler?
if (handler instanceof String) {
String handlerName = (String) handler;
handler = getApplicationContext().getBean(handlerName);
}
//获得HandlerExecutionChain
HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);
if (CorsUtils.isCorsRequest(request)) {
CorsConfiguration globalConfig = this.corsConfigSource.getCorsConfiguration(request);
CorsConfiguration handlerConfig = getCorsConfiguration(handler, request);
CorsConfiguration config = (globalConfig != null ? globalConfig.combine(handlerConfig) : handlerConfig);
executionChain = getCorsHandlerExecutionChain(request, executionChain, config);
}
return executionChain;
}
在getHandler方法中又出现了两个方法getHandlerInternal(request),在子类中实现,目的就是获取要执行的Controller。
//模板方法,用于子类中实现,通过request去查找对应的执行方法HandlerMethod protected abstract Object getHandlerInternal(HttpServletRequest request) throws Exception;
getHandlerExecutionChain就是创建一个HandlerExecutionChain实例,参数值就是handler和request。
//
protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
//如果没有获得则创建一个
HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ?
(HandlerExecutionChain) handler : new HandlerExecutionChain(handler));
//获得IP地址及端口后的URL地址
String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);
//在HandlerExecutionChain中添加拦截器
for (HandlerInterceptor interceptor : this.adaptedInterceptors) {
if (interceptor instanceof MappedInterceptor) {
MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor;
//根据lookupPath来获取Interceptor
if (mappedInterceptor.matches(lookupPath, this.pathMatcher)) {
chain.addInterceptor(mappedInterceptor.getInterceptor());
}
}
else {
chain.addInterceptor(interceptor);
}
}
return chain;
}
AbstractHandlerMapping提供了设置不同HandlerMapping的执行顺序oder。
//设置不同HandlerMapping实现类的执行顺序
public final void setOrder(int order) {
this.order = order;
}
@Override
public final int getOrder() {
return this.order;
}
除了以上几个重要的方法外,AbstractHandlerMapping还提供了进行拦截器初始化的一些操作。
//初始化时调用,初始化一些基本信息,这里主要是初始化一些拦截器
@Override
protected void initApplicationContext() throws BeansException {
extendInterceptors(this.interceptors);//添加或修车intercept,现在并没有具体实现
detectMappedInterceptors(this.adaptedInterceptors);//将springMVC容器或者父容器中的所有MappedInterceptor类型的Bean添加到mappedInterceptors属性中
initInterceptors();
}
protected void extendInterceptors(List<Object> interceptors) {
}
//将springMVC容器或者父容器中的所有MappedInterceptor类型的Bean添加到mappedInterceptors属性中
protected void detectMappedInterceptors(List<HandlerInterceptor> mappedInterceptors) {
mappedInterceptors.addAll(
BeanFactoryUtils.beansOfTypeIncludingAncestors(
getApplicationContext(), MappedInterceptor.class, true, false).values());
}
//初始化Interceptor,将interceptors属性里所包含的对象按类型添加到mappedInterceptors或者adaptedInterceptors中。
protected void initInterceptors() {
if (!this.interceptors.isEmpty()) {
for (int i = 0; i < this.interceptors.size(); i++) {
Object interceptor = this.interceptors.get(i);
if (interceptor == null) {
throw new IllegalArgumentException("Entry number " + i + " in interceptors array is null");
}
this.adaptedInterceptors.add(adaptInterceptor(interceptor));
}
}
}
protected HandlerInterceptor adaptInterceptor(Object interceptor) {
if (interceptor instanceof HandlerInterceptor) {
return (HandlerInterceptor) interceptor;
}
else if (interceptor instanceof WebRequestInterceptor) {
return new WebRequestHandlerInterceptorAdapter((WebRequestInterceptor) interceptor);
}
else {
throw new IllegalArgumentException("Interceptor type not supported: " + interceptor.getClass().getName());
}
}
protected final HandlerInterceptor[] getAdaptedInterceptors() {
int count = this.adaptedInterceptors.size();
return (count > 0 ? this.adaptedInterceptors.toArray(new HandlerInterceptor[count]) : null);
}
protected final MappedInterceptor[] getMappedInterceptors() {
List<MappedInterceptor> mappedInterceptors = new ArrayList<MappedInterceptor>();
for (HandlerInterceptor interceptor : this.adaptedInterceptors) {
if (interceptor instanceof MappedInterceptor) {
mappedInterceptors.add((MappedInterceptor) interceptor);
}
}
int count = mappedInterceptors.size();
return (count > 0 ? mappedInterceptors.toArray(new MappedInterceptor[count]) : null);
}
总体来看AbstractHandlerMapping提供了抽象方法getHandlerInternal在子类中实现,根据获得的Handler及配置的拦截器Interceptor来生成HandlerExecutionChain。
完整的AbstractHandlerMapping源码如下:
public abstract class AbstractHandlerMapping extends WebApplicationObjectSupport
implements HandlerMapping, Ordered {
private int order = Integer.MAX_VALUE; // default: same as non-Ordered
private Object defaultHandler;
private UrlPathHelper urlPathHelper = new UrlPathHelper();
private PathMatcher pathMatcher = new AntPathMatcher();
private final List<Object> interceptors = new ArrayList<Object>();
private final List<HandlerInterceptor> adaptedInterceptors = new ArrayList<HandlerInterceptor>();
private CorsProcessor corsProcessor = new DefaultCorsProcessor();
private final UrlBasedCorsConfigurationSource corsConfigSource = new UrlBasedCorsConfigurationSource();
//设置不同HandlerMapping实现类的执行顺序
public final void setOrder(int order) {
this.order = order;
}
@Override
public final int getOrder() {
return this.order;
}
public void setDefaultHandler(Object defaultHandler) {
this.defaultHandler = defaultHandler;
}
public Object getDefaultHandler() {
return this.defaultHandler;
}
public void setAlwaysUseFullPath(boolean alwaysUseFullPath) {
this.urlPathHelper.setAlwaysUseFullPath(alwaysUseFullPath);
this.corsConfigSource.setAlwaysUseFullPath(alwaysUseFullPath);
}
public void setUrlDecode(boolean urlDecode) {
this.urlPathHelper.setUrlDecode(urlDecode);
this.corsConfigSource.setUrlDecode(urlDecode);
}
public void setRemoveSemicolonContent(boolean removeSemicolonContent) {
this.urlPathHelper.setRemoveSemicolonContent(removeSemicolonContent);
this.corsConfigSource.setRemoveSemicolonContent(removeSemicolonContent);
}
public void setUrlPathHelper(UrlPathHelper urlPathHelper) {
Assert.notNull(urlPathHelper, "UrlPathHelper must not be null");
this.urlPathHelper = urlPathHelper;
this.corsConfigSource.setUrlPathHelper(urlPathHelper);
}
public UrlPathHelper getUrlPathHelper() {
return urlPathHelper;
}
public void setPathMatcher(PathMatcher pathMatcher) {
Assert.notNull(pathMatcher, "PathMatcher must not be null");
this.pathMatcher = pathMatcher;
this.corsConfigSource.setPathMatcher(pathMatcher);
}
public PathMatcher getPathMatcher() {
return this.pathMatcher;
}
public void setInterceptors(Object[] interceptors) {
this.interceptors.addAll(Arrays.asList(interceptors));
}
public void setCorsProcessor(CorsProcessor corsProcessor) {
Assert.notNull(corsProcessor, "CorsProcessor must not be null");
this.corsProcessor = corsProcessor;
}
/**
* Return the configured {@link CorsProcessor}.
*/
public CorsProcessor getCorsProcessor() {
return this.corsProcessor;
}
public void setCorsConfigurations(Map<String, CorsConfiguration> corsConfigurations) {
this.corsConfigSource.setCorsConfigurations(corsConfigurations);
}
/**
* Get the CORS configuration.
*/
public Map<String, CorsConfiguration> getCorsConfigurations() {
return this.corsConfigSource.getCorsConfigurations();
}
//初始化时调用,初始化一些基本信息,这里主要是初始化一些拦截器
@Override
protected void initApplicationContext() throws BeansException {
extendInterceptors(this.interceptors);//添加或修车intercept,现在并没有具体实现
detectMappedInterceptors(this.adaptedInterceptors);//将springMVC容器或者父容器中的所有MappedInterceptor类型的Bean添加到mappedInterceptors属性中
initInterceptors();
}
protected void extendInterceptors(List<Object> interceptors) {
}
//将springMVC容器或者父容器中的所有MappedInterceptor类型的Bean添加到mappedInterceptors属性中
protected void detectMappedInterceptors(List<HandlerInterceptor> mappedInterceptors) {
mappedInterceptors.addAll(
BeanFactoryUtils.beansOfTypeIncludingAncestors(
getApplicationContext(), MappedInterceptor.class, true, false).values());
}
//初始化Interceptor,将interceptors属性里所包含的对象按类型添加到mappedInterceptors或者adaptedInterceptors中。
protected void initInterceptors() {
if (!this.interceptors.isEmpty()) {
for (int i = 0; i < this.interceptors.size(); i++) {
Object interceptor = this.interceptors.get(i);
if (interceptor == null) {
throw new IllegalArgumentException("Entry number " + i + " in interceptors array is null");
}
this.adaptedInterceptors.add(adaptInterceptor(interceptor));
}
}
}
protected HandlerInterceptor adaptInterceptor(Object interceptor) {
if (interceptor instanceof HandlerInterceptor) {
return (HandlerInterceptor) interceptor;
}
else if (interceptor instanceof WebRequestInterceptor) {
return new WebRequestHandlerInterceptorAdapter((WebRequestInterceptor) interceptor);
}
else {
throw new IllegalArgumentException("Interceptor type not supported: " + interceptor.getClass().getName());
}
}
protected final HandlerInterceptor[] getAdaptedInterceptors() {
int count = this.adaptedInterceptors.size();
return (count > 0 ? this.adaptedInterceptors.toArray(new HandlerInterceptor[count]) : null);
}
protected final MappedInterceptor[] getMappedInterceptors() {
List<MappedInterceptor> mappedInterceptors = new ArrayList<MappedInterceptor>();
for (HandlerInterceptor interceptor : this.adaptedInterceptors) {
if (interceptor instanceof MappedInterceptor) {
mappedInterceptors.add((MappedInterceptor) interceptor);
}
}
int count = mappedInterceptors.size();
return (count > 0 ? mappedInterceptors.toArray(new MappedInterceptor[count]) : null);
}
//获得一个HandlerExecutionChain
@Override
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
//从实现类中获得HanlderMethod
Object handler = getHandlerInternal(request);
if (handler == null) {
handler = getDefaultHandler();
}
if (handler == null) {
return null;
}
// Bean name or resolved handler?
if (handler instanceof String) {
String handlerName = (String) handler;
handler = getApplicationContext().getBean(handlerName);
}
//获得HandlerExecutionChain
HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);
if (CorsUtils.isCorsRequest(request)) {
CorsConfiguration globalConfig = this.corsConfigSource.getCorsConfiguration(request);
CorsConfiguration handlerConfig = getCorsConfiguration(handler, request);
CorsConfiguration config = (globalConfig != null ? globalConfig.combine(handlerConfig) : handlerConfig);
executionChain = getCorsHandlerExecutionChain(request, executionChain, config);
}
return executionChain;
}
//模板方法,用于子类中实现,通过request去查找对应的执行方法HandlerMethod
protected abstract Object getHandlerInternal(HttpServletRequest request) throws Exception;
//
protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
//如果没有获得则创建一个
HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ?
(HandlerExecutionChain) handler : new HandlerExecutionChain(handler));
//获得IP地址及端口后的URL地址
String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);
//在HandlerExecutionChain中添加拦截器
for (HandlerInterceptor interceptor : this.adaptedInterceptors) {
if (interceptor instanceof MappedInterceptor) {
MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor;
//根据lookupPath来获取Interceptor
if (mappedInterceptor.matches(lookupPath, this.pathMatcher)) {
chain.addInterceptor(mappedInterceptor.getInterceptor());
}
}
else {
chain.addInterceptor(interceptor);
}
}
return chain;
}
protected CorsConfiguration getCorsConfiguration(Object handler, HttpServletRequest request) {
if (handler instanceof HandlerExecutionChain) {
handler = ((HandlerExecutionChain) handler).getHandler();
}
if (handler instanceof CorsConfigurationSource) {
return ((CorsConfigurationSource) handler).getCorsConfiguration(request);
}
return null;
}
protected HandlerExecutionChain getCorsHandlerExecutionChain(HttpServletRequest request,
HandlerExecutionChain chain, CorsConfiguration config) {
if (CorsUtils.isPreFlightRequest(request)) {
HandlerInterceptor[] interceptors = chain.getInterceptors();
chain = new HandlerExecutionChain(new PreFlightHandler(config), interceptors);
}
else {
chain.addInterceptor(new CorsInterceptor(config));
}
return chain;
}
private class PreFlightHandler implements HttpRequestHandler {
private final CorsConfiguration config;
public PreFlightHandler(CorsConfiguration config) {
this.config = config;
}
@Override
public void handleRequest(HttpServletRequest request, HttpServletResponse response)
throws IOException {
corsProcessor.processRequest(this.config, request, response);
}
}
private class CorsInterceptor extends HandlerInterceptorAdapter {
private final CorsConfiguration config;
public CorsInterceptor(CorsConfiguration config) {
this.config = config;
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
return corsProcessor.processRequest(this.config, request, response);
}
}
}
springMVC源码分析--AbstractHandlerMapping(二)的更多相关文章
- springmvc 源码分析(二)-- DiapartcherServlet核心调用流程分析
测试环境搭建: 本次搭建是基于springboot来实现的,代码在码云的链接:https://gitee.com/yangxioahui/thymeleaf.git 项目结构代码如下: 一: cont ...
- springMVC源码分析--AbstractHandlerMethodMapping获取url和HandlerMethod对应关系(十)
在之前的博客springMVC源码分析--AbstractHandlerMapping(二)中我们介绍了AbstractHandlerMethodMapping的父类AbstractHandlerMa ...
- springMVC源码分析--AbstractUrlHandlerMapping(三)
上一篇博客springMVC源码分析--AbstractHandlerMapping(二)中我们介绍了AbstractHandlerMapping了,接下来我们介绍其子类AbstractUrlHand ...
- 框架-springmvc源码分析(二)
框架-springmvc源码分析(二) 参考: http://www.cnblogs.com/leftthen/p/5207787.html http://www.cnblogs.com/leftth ...
- springMVC源码分析--国际化实现Session和Cookie(二)
上一篇博客springMVC源码分析--国际化LocaleResolver(一)中我们介绍了springMVC提供的国际化的解决方案,接下来我们根据springMVC提供的解决方案来简单的实现一个多语 ...
- springMVC源码分析--HandlerMethodReturnValueHandlerComposite返回值解析器集合(二)
在上一篇博客springMVC源码分析--HandlerMethodReturnValueHandler返回值解析器(一)我们介绍了返回值解析器HandlerMethodReturnValueHand ...
- springMVC源码分析--SimpleServletHandlerAdapter(二)
上一篇博客springMVC源码分析--HandlerAdapter(一)中我们主要介绍了一下HandlerAdapter接口相关的内容,实现类及其在DispatcherServlet中执行的顺序,接 ...
- springMVC源码分析--异常处理机制HandlerExceptionResolver执行原理(二)
上一篇博客springMVC源码分析--异常处理机制HandlerExceptionResolver简单示例(一)中我们简单地实现了一个异常处理实例,接下来我们要介绍一下HandlerExceptio ...
- springMVC源码分析--HandlerInterceptor拦截器调用过程(二)
在上一篇博客springMVC源码分析--HandlerInterceptor拦截器(一)中我们介绍了HandlerInterceptor拦截器相关的内容,了解到了HandlerInterceptor ...
随机推荐
- jsonViewer json格式化工具
以前一直以来都觉得xml个可读性要比json的可读性好,后来使用了JSON Viewer这个小工具之后,发现自己错了.之前认为json的可读性差,完全是因为没有很好的查看工具.JSON Viewer这 ...
- 五,前端---关于JS的点滴
一:异常抛出 try,catch,throw 例如: function myFunction(){ try{ var x = document.getElementBy('demo').value; ...
- Hibernate 学习之Query查询(HQL查询)
package com.itcloud.test; import com.itcloud.pojo.Dept; import org.hibernate.Session; import org.hib ...
- [LeetCode] IPO 上市
Suppose LeetCode will start its IPO soon. In order to sell a good price of its shares to Venture Cap ...
- python字符串-内置方法用法分析
1.字母大小写相关(中文无效) 1.1 S.upper() -> string 返回一个字母全部大写的副本
- “百度杯”CTF比赛 十二月场_blog(kindeditor编辑器遍历,insert注入,文件包含)
题目在i春秋的ctf训练营中能找到 首先先是一个用户登录与注册界面,一般有注册界面的都是要先让你注册一波,然后找惊喜的 那我就顺着他的意思去注册一个号 注册了一个123用户登录进来看到有个文本编辑器, ...
- [Codeforces 961G]Partitions
Description 题库链接 给你 \(n\) 个不同的元素组成的集合 \(R\) ,每个元素有一个权值 \(w\) .对于一个子集集合 \(S\) ,它的价值为 \(W(S)=|S|\cdot\ ...
- [SDOI2017]数字表格
Description Doris刚刚学习了fibonacci数列.用f[i]表示数列的第i项,那么 f[0]=0 f[1]=1 f[n]=f[n-1]+f[n-2],n>=2 Doris用老师 ...
- [HNOI2009]有趣的数列
题目描述 我们称一个长度为2n的数列是有趣的,当且仅当该数列满足以下三个条件: (1)它是从1到2n共2n个整数的一个排列{ai}: (2)所有的奇数项满足a1<a3<...<a2n ...
- 计蒜客NOIP2017提高组模拟赛(三)day2-数三角形
传送门 这题有点坑啊 设A为两边颜色不同的角,B为两边颜色相同的角 那么考虑三种三角形:异色,同色,其他 对于任何一个异色三角形,一定会有三个颜色不同的角, 对于任何一个同色三角形,一定会有零个颜色不 ...