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