springMVC (七) mvc:interceptors
来源:互联网 发布:黄金交易软件手机版 编辑:程序博客网 时间:2024/06/11 00:36
HandlerInterceptor接口只有三个方法
public interface HandlerInterceptor {/**handler方法调用前调用//Intercept the execution of a handler. Called after HandlerMapping determined * an appropriate handler object, but before HandlerAdapter invokes the handler.*/boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;/** * Intercept the execution of a handler. Called after HandlerAdapter actually * invoked the handler, but before the DispatcherServlet renders the view.*/void postHandle( HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception;} /** * Callback after completion of request processing, that is, after rendering * the view. Will be called on any outcome of handler execution, thus allows * for proper resource cleanup.*/void afterCompletion( HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception;
我们在使用时候一般集成它的一个虚类HandlerInterceptorAdapter
springMVC处理mvc:interceptors的类是
class InterceptorsBeanDefinitionParser implements BeanDefinitionParser {@Overridepublic BeanDefinition parse(Element element, ParserContext parserContext) {CompositeComponentDefinition compDefinition = new CompositeComponentDefinition(element.getTagName(), parserContext.extractSource(element));parserContext.pushContainingComponent(compDefinition);RuntimeBeanReference pathMatcherRef = null;if (element.hasAttribute("path-matcher")) {pathMatcherRef = new RuntimeBeanReference(element.getAttribute("path-matcher"));}List<Element> interceptors = DomUtils.getChildElementsByTagName(element, "bean", "ref", "interceptor");for (Element interceptor : interceptors) {RootBeanDefinition mappedInterceptorDef = new RootBeanDefinition(MappedInterceptor.class);mappedInterceptorDef.setSource(parserContext.extractSource(interceptor));mappedInterceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);ManagedList<String> includePatterns = null;ManagedList<String> excludePatterns = null;Object interceptorBean;if ("interceptor".equals(interceptor.getLocalName())) {includePatterns = getIncludePatterns(interceptor, "mapping");excludePatterns = getIncludePatterns(interceptor, "exclude-mapping");Element beanElem = DomUtils.getChildElementsByTagName(interceptor, "bean", "ref").get(0);interceptorBean = parserContext.getDelegate().parsePropertySubElement(beanElem, null);}else {interceptorBean = parserContext.getDelegate().parsePropertySubElement(interceptor, null);}mappedInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, includePatterns);mappedInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(1, excludePatterns);mappedInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(2, interceptorBean);if (pathMatcherRef != null) {mappedInterceptorDef.getPropertyValues().add("pathMatcher", pathMatcherRef);}String beanName = parserContext.getReaderContext().registerWithGeneratedName(mappedInterceptorDef);parserContext.registerComponent(new BeanComponentDefinition(mappedInterceptorDef, beanName));}parserContext.popAndRegisterContainingComponent();return null;}private ManagedList<String> getIncludePatterns(Element interceptor, String elementName) {List<Element> paths = DomUtils.getChildElementsByTagName(interceptor, elementName);ManagedList<String> patterns = new ManagedList<String>(paths.size());for (Element path : paths) {patterns.add(path.getAttribute("path"));}return patterns;}}
xml中每一个interceptor最后都变成了一个MappedInterceptor,然后将这些注册到spring容器中
我们知道每个请求都会由一个合适handlerMapping找到HandlerExecutionChain,这个过程为:DispatcherServlet中方法
/** * Return the HandlerExecutionChain for this request. * <p>Tries all handler mappings in order. * @param request current HTTP request * @return the HandlerExecutionChain, or {@code null} if no handler could be found */protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {for (HandlerMapping hm : this.handlerMappings) {if (logger.isTraceEnabled()) {logger.trace("Testing handler map [" + hm + "] in DispatcherServlet with name '" + getServletName() + "'");}HandlerExecutionChain handler = hm.getHandler(request);//if (handler != null) {return handler;}}return null;}
public abstract class AbstractHandlerMapping extends WebApplicationObjectSupportimplements HandlerMapping, Ordered {/** * Look up a handler for the given request, falling back to the default * handler if no specific one is found. * @param request current HTTP request * @return the corresponding handler instance, or the default handler * @see #getHandlerInternal */ @Override public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception { Object handler = getHandlerInternal(request); //由具体子类实现找到对应handler 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); } return getHandlerExecutionChain(handler, request);//这个方法中有对interceptor的处理 } protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) { HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ? (HandlerExecutionChain) handler : new HandlerExecutionChain(handler)); chain.addInterceptors(getAdaptedInterceptors()); String lookupPath = this.urlPathHelper.getLookupPathForRequest(request); //筛选过滤合适的interceptor加入HandlerExecutionChain 中 for (MappedInterceptor mappedInterceptor : this.mappedInterceptors) { if (mappedInterceptor.matches(lookupPath, this.pathMatcher)) { chain.addInterceptor(mappedInterceptor.getInterceptor()); } } return chain; }}
那么上面的this.mappedInterceptors 是如何得到我们配置的数据了,还是在这个类中
/** * Initializes the interceptors. * @see #extendInterceptors(java.util.List) * @see #initInterceptors() */@Overrideprotected void initApplicationContext() throws BeansException {extendInterceptors(this.interceptors);detectMappedInterceptors(this.mappedInterceptors);initInterceptors();}//这个方法就是从容器中拿到所有的MappedInterceptor,然后加入到本类的变量中 protected void detectMappedInterceptors(List<MappedInterceptor> mappedInterceptors) { mappedInterceptors.addAll( BeanFactoryUtils.beansOfTypeIncludingAncestors( getApplicationContext(), MappedInterceptor.class, true, false).values()); }
至此HandlerExecutionChain已经找到,看看doDispatch后面处理过程
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {HttpServletRequest processedRequest = request;HandlerExecutionChain mappedHandler = null;boolean multipartRequestParsed = false;WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);try {ModelAndView mv = null;Exception dispatchException = null;try {processedRequest = checkMultipart(request);multipartRequestParsed = (processedRequest != request);// Determine handler for the current request.mappedHandler = getHandler(processedRequest);if (mappedHandler == null || mappedHandler.getHandler() == null) {noHandlerFound(processedRequest, response);return;}// Determine handler adapter for the current request.HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());// Process last-modified header, if supported by the handler.String method = request.getMethod();boolean isGet = "GET".equals(method);if (isGet || "HEAD".equals(method)) {long lastModified = ha.getLastModified(request, mappedHandler.getHandler());if (logger.isDebugEnabled()) {logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);}if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {return;}} //重点1 此方法内部 调用拦截器preHandle方法if (!mappedHandler.applyPreHandle(processedRequest, response)) {return;}//实际handler方法处理// Actually invoke the handler.mv = ha.handle(processedRequest, response, mappedHandler.getHandler());if (asyncManager.isConcurrentHandlingStarted()) {return;}applyDefaultViewName(request, mv);//重点2 此方法 调用拦截器的postHandle方法 并且顺序与preHandle相反 mappedHandler.applyPostHandle(processedRequest, response, mv);}catch (Exception ex) {dispatchException = ex;}//重点3 对异常处理 渲染view 调用拦截器afterCompletion方法 processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);}catch (Exception ex) {//就算异常也会调用拦截器afterCompletion triggerAfterCompletion(processedRequest, response, mappedHandler, ex);}catch (Error err) {//就算错误也会调用拦截器afterCompletion triggerAfterCompletionWithError(processedRequest, response, mappedHandler, err);}finally {if (asyncManager.isConcurrentHandlingStarted()) {// Instead of postHandle and afterCompletionif (mappedHandler != null) {mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);}}else {// Clean up any resources used by a multipart request.if (multipartRequestParsed) {cleanupMultipart(processedRequest);}}}}
0 0
- springMVC (七) mvc:interceptors
- springMVC-interceptors
- mvc:interceptors
- mvc:interceptors
- springMVC之mvc:interceptors拦截器的用法
- SpringMVC源码总结(十一)mvc:interceptors拦截器介绍
- springMVC之mvc:interceptors拦截器的用法
- springMVC之mvc:interceptors拦截器的用法
- SpringMVC源码总结(十一)mvc:interceptors拦截器介绍
- SpringMVC源码总结(十一)mvc:interceptors拦截器介绍
- SpringMVC源码总结(十一)mvc:interceptors拦截器介绍
- springMVC之mvc:interceptors拦截器的用法
- Spring参考手册 mvc:interceptors
- Spring3参考手册 mvc:interceptors
- Spring参考手册 mvc:interceptors
- spring-mvc interceptors
- 使用mvc:interceptors标签来声明需要加入到SpringMVC拦截器链中的拦截器
- flume七:Flume Interceptors介绍
- php的错误级别
- linux--定时任务--crontab
- Python中几个以“__”开头的方法介绍总结
- C#实现FTP基本功能源代码
- ural 1018 Binary Apple Tree(树形DP)
- springMVC (七) mvc:interceptors
- Android drawable文件使用(一)layer-list
- FTP命令全集
- DList双向链表
- Android性能优化
- 增加yum支持EPEL源
- intellij idea 注册服务器
- hibernate的方言
- 使用windows 窗体应用程序编写简单的阅读器