• 拦截器、过滤器、AOP


    拦截器

    拦截器拦截的是URL,拦截器是MVC级别。拦截器是通过Java反射机制来拦截web请求,是“拒你想拒绝的”,它只拦截web请求,但不拦截静态资源

    拦截器有三个方法,相对于过滤器更加细致,有被拦截逻辑执行前、后等。Spring中拦截器有三个方法:preHandle,postHandle,afterCompletion。分别表示如下

     package org.springframework.web.servlet.handler;
     import javax.servlet.http.HttpServletRequest;
     import javax.servlet.http.HttpServletResponse;
     import org.springframework.web.servlet.HandlerInterceptor;
     import org.springframework.web.servlet.ModelAndView;
     ​
     public abstract class HandlerInterceptorAdapter implements HandlerInterceptor{
         // 在业务处理器处理请求之前被调用 , 被拦截的URL对应的方法执行前的自定义处理
         public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception{
             return true;
         }
         // 在业务处理器处理请求完成之后,生成视图之前执行 , 被拦截的URL对应的方法执行后的自定义处理
         public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
           throws Exception{
         }
         // 在DispatcherServlet完全处理完请求之后被调用,可用于清理资源  表示此时modelAndView已被渲染,执行拦截器的自定义处理。
         public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
           throws Exception{
         }
     }

    过滤器

    过滤器拦截的是URL,过滤器是servlet级别。 通俗说:去取你想取的

    Spring中自定义过滤器(Filter)一般只有一个方法,返回值是void,当请求到达web容器时,会探测当前请求地址是否配置有过滤器,有则调用该过滤器的方法(可能会有多个过滤器),然后才调用真实的业务逻辑,至此过滤器任务完成。过滤器并没有定义业务逻辑执行前、后等,仅仅是请求到达就执行。

    特别注意:过滤器方法的入参有request,response,FilterChain,其中FilterChain是过滤器链,使用比较简单,而request,response则关联到请求流程,因此可以对请求参数做过滤和修改,同时FilterChain过滤链执行完,并且完成业务流程后,会返回到过滤器,此时也可以对请求的返回数据做处理。

     

    package com.study.filter;
     ​
     import org.springframework.stereotype.Component;
     ​
     import javax.servlet.*;
     import java.io.IOException;
     ​
     @Component
     public class InterfaceRequestFilter implements Filter {
         @Override
         public void init(FilterConfig filterConfig) throws ServletException {
             System.out.println("过滤器初始化了........init... " + filterConfig);
         }
     ​
         @Override
         public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
             System.out.println("过滤前........doFilter "); //过滤器前的处理
             filterChain.doFilter(servletRequest, servletResponse);//继续执行后续方法
             System.out.println("过滤后.......doFilter"); //方法执行完成后
     ​
         }
     ​
         @Override
         public void destroy() {
             System.out.println("销毁了.....destroy");
         }
     }
     

     

     

    Spring AOP

    面向切面拦截的是类的元数据(包、类、方法名、参数等)

    相对于拦截器更加细致,而且非常灵活,拦截器只能针对URL做拦截,而AOP针对具体的代码,能够实现更加复杂的业务逻辑。具体类型参照其他博客。

     

     

    总结

    【Filter与Interceptor的区别】

    • filter基于filter接口中的doFilter回调函数,interceptor则基于Java本身的反射机制;

    • filter是依赖于servlet容器的,没有servlet容器就无法回调doFilter方法,而interceptor与servlet无关;

    • filter的过滤范围比interceptor大,filter除了过滤请求外通过通配符可以保护页面、图片、文件等,而interceptor只能过滤请求,只对action起作用,在action之前开始,在action完成后结束(如被拦截,不执行action);

    • 在action的生命周期中,拦截器可以被多次调用,而过滤器只能在容器初始化时被调用一次。

    【Interceptor 与spring AOP的区别】

    • spring Interceptor也是一种aop思想,我们这里面的spring AOP主要是讲aop应用,interceptor 的使用场合比aop小很多,顾名思义,它是拦截一些action请求,但是比aop使用起来简便;

    • 程序执行的顺序是先进过滤器,再进拦截器,最后进切面;

    • Interceptor可以阻止代码执行下去,当preHandle返回false,那么这个请求就到此结束,真正的被拦截了,但是aop不能,它只是单纯的切入添加操作;

     

     

     

    三者使用场景

    三者功能类似,但各有优势,从过滤器--》拦截器--》切面,拦截规则越来越细致,执行顺序依次是过滤器、拦截器、切面。一般情况下数据被过滤的时机越早对服务的性能影响越小,因此我们在编写相对比较公用的代码时,优先考虑过滤器,然后是拦截器,最后是aop。比如权限校验,一般情况下,所有的请求都需要做登陆校验,此时就应该使用过滤器在最顶层做校验;日志记录,一般日志只会针对部分逻辑做日志记录,而且牵扯到业务逻辑完成前后的日志记录,因此使用过滤器不能细致地划分模块,此时应该考虑拦截器,然而拦截器也是依据URL做规则匹配,因此相对来说不够细致,因此我们会考虑到使用AOP实现,AOP可以针对代码的方法级别做拦截,很适合日志功能。

    参考:https://www.jianshu.com/p/2d1fa2834d9c

  • 相关阅读:
    JAVA基础 (三)反射 深入解析反射机制
    JAVA基础 (二)反射 深入解析反射机制
    JAVA注解引发的思考
    深入理解jsonp解决跨域访问
    设计模式之简单工厂模式
    设计模式之接口隔离原则
    设计模式之迪米特法则
    设计模式之依赖倒置原则
    设计模式之里氏替换原则
    设计模式之开放封闭原则
  • 原文地址:https://www.cnblogs.com/it1042290135/p/16071990.html
Copyright © 2020-2023  润新知