詳解SpringMVC的攔截器鏈實現及攔截器鏈配置

1、攔截器鏈實現

隻需定義多個攔截器的 bean,然後在攔截器的配置類中將其逐一添加即可

第一個攔截器的定義:

@Component
public class ProjectInterceptor1 implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle111...");
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle111...");
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion111...");
    }
}

第二個攔截器的定義:

@Component
public class ProjectInterceptor2 implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle222...");
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle222...");
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion222...");
    }
}

攔截器配置類:

@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {
    @Autowired
    private ProjectInterceptor1 interceptor1;
    @Autowired
    private ProjectInterceptor2 interceptor2;
    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(interceptor1).addPathPatterns("/books", "/books/*");
        registry.addInterceptor(interceptor2).addPathPatterns("/books", "/books/*");
    }
}

2、攔截器鏈的執行順序

攔截器配置類中,首先被添加的攔截器在外層,之後添加的在內層,請求發出之後首先被外層的攔截器攔截,外層放行後進入內層,而離開攔截器時先離開內層的攔截器,再離開外層。

上例子中第一個攔截器在外層,第二個在內層,所以上例中攔截器的輸出順序為:

preHandle111…
preHandle222…
postHandle222…
postHandle111…
afterCompletion222…
afterCompletion111…

值得註意的是,afterCompletion 方法的一定會在 postHandle 之後執行,並且也是由內層向外層執行,所以 afterCompletion222 輸出在 postHandle111 之後,而在 afterCompletion111 之前。換言之,即便有再多的攔截器,最先執行的 afterCompletion 也一定在最後執行的 postHandle 之後才執行

此外,當攔截器的 preHandle 方法返回 false 時,其內層的攔截器以及它自身 postHandle 和 afterCompletion 都不會再執行,而所有外層攔截器的 postHandle 不再執行,但 afterCompletion 照常執行

這是因為 postHandle 執行在原始 Controller 方法執行之後,必須所有攔截器都放行時,才會執行原始方法,也就才會執行 postHandle 方法

上例中第二個攔截器 preHandle 返回 false 時的輸出順序:

preHandle111…
preHandle222…
afterCompletion111…

到此這篇關於詳解SpringMVC的攔截器鏈實現及攔截器鏈配置的文章就介紹到這瞭,更多相關SpringMVC攔截器鏈 內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: