1. 程式人生 > >過濾器、攔截器、AOP切面執行順序的比較

過濾器、攔截器、AOP切面執行順序的比較

過濾器:基於 Servlet,通過函式回撥方式實現,可以過濾請求和圖片檔案等,每個請求一個過濾器只能過濾一次。

 

攔截器:基於 java 的反射機制,代理模式實現,只能攔截請求,可以訪問上下文等物件,功能強大,一個請求可多次攔截。

 

攔截器是 Spring 中AOP的一種實現方法。另一種方法通過 Pointcut、Advice實現

 

下面具體測試三者執行順序:

 

第一步:新增過濾器

 

  1、web.xml 中新增 filter 及對映

 

<filter>

    <filter-name>GlobalFilter</filter-name>

    <filter-class>com.test.filter.GlobalFilter</filter-class>

    <async-supported>true</async-supported>

    <init-param>

        <param-name>encoding</param-name>

        <param-value>UTF-8</param-value>

    </init-param>

</filter>

<filter-mapping>

    <filter-name>GlobalFilter</filter-name>

    <url-pattern>/*</url-pattern>

</filter-mapping>

  2、新建過濾器

 

public class GlobalFilter extends OncePerRequestFilter {

    @Override

    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)throws ServletException, IOException{

        System.out.println("--------------------Filter過濾----------------------");

        filterChain.doFilter(request, response);

    }

}

第二步:新增攔截器

 

攔截器有兩種方式實現:註解和配置檔案,習慣採用配置檔案方式

 

  1、新增配置,裝配 bean

 

<mvc:interceptors>

    <mvc:interceptor>

        <mvc:mapping path="/**"/>

        <bean class="com.test.interceptor.GlobalInterceptor" />

    </mvc:interceptor>

</mvc:interceptors>

  2、新建攔截器

 

public class GlobalInterceptor implements HandlerInterceptor {

    @Override

    public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object o) throws Exception {

        System.out.println("--------------------Intercept攔截--------------------");

        return true;

    }

 

    @Override

    public void postHandle(HttpServletRequest req, HttpServletResponse res, Object o, ModelAndView modelAndView) throws Exception {

        System.out.println("--------------------Intercept攔截返回--------------------");

    }

 

    @Override

    public void afterCompletion(HttpServletRequest req, HttpServletResponse res, Object o, Exception e) throws Exception {

        System.out.println("--------------------Intercept檢視渲染回撥--------------------");

    }

}

第三步:新增 AOP 切面

 

同樣採用配置檔案的方法

 

  1、配置檔案中配置切面、切入點、通知,裝配 bean

 

<bean id="globalAspect" class="com.test.globalAspect"/>

<!--配置切面攔截方法 -->

<aop:config>

    <aop:aspect ref="globalAspect">

        <aop:pointcut id="globalPointcut" expression="within(com.test.controller.TestController)"/>

        <aop:before pointcut-ref="globalPointcut" method="before"/>

        <aop:after pointcut-ref="globalPointcut" method="after"/>

    </aop:aspect>

</aop:config>

  2、新建切面類

 

public class globalAspect {

    public void before() {

        System.out.println("------------------------AOP攔截----------------------");

    }

 

    public void after() {

        System.out.println("------------------------AOP攔截返回------------------");

    }

}

最後寫一個 Controller 方法來測試一下:

 

public class TestController {

    @RequestMapping(value = "/test", method = RequestMethod.GET)

    public void test(){

        System.out.println("-----------------測試方法執行--------------------");

    }

}

測試結果:

image.png