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 {
@Override
public 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 WebApplicationObjectSupport
implements 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()
*/
@Override
protected 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 afterCompletion
if (mappedHandler != null)
{mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);}}
else {// Clean up any resources used by a multipart request.if (multipartRequestParsed) {cleanupMultipart(processedRequest);}}}}