过滤器、拦截器、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

猜你喜欢

转载自blog.csdn.net/belalds/article/details/83376483
今日推荐