1. 什么是过滤器
         过滤器,顾名思义就是起到过滤筛选作⽤的⼀种事物,只不过相较于现实⽣活中的过滤器,这⾥的过滤器过滤的对象是客户端访问的web资源,也可以理解为⼀种预处理⼿段,对资源进⾏拦截后,将其中我们认为的杂质(⽤户⾃⼰定义的)过滤,符合条件的放⾏,不符合的则拦截下来。
1.1 过滤器常见使⽤场景
 统⼀设置编码
 过滤敏感字符
 登录校验
 URL级别的访问权限控制
 数据压缩
1.2 springboot整合过滤器
bean注⼊⽅式
a) 编写Filter
 public class HeFilter implements Filter {
  @Override
  public void init(FilterConfig filterConfig) throws ServletException {
  }
  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {
   System.out.println("您已进⼊filter过滤器,您的请求正常,请继续遵规则...");
   chain.doFilter(request, response);
  }
  @Override
  public void destroy() {
  }
 }
b) 编写Filter配置类
 @Configuration
 public class ServletConfig {
     @Bean
     public FilterRegistrationBean heFilterRegistration() {
         FilterRegistrationBean registration = new FilterRegistrationBean(new HeFilter());
         registration.addUrlPatterns("/*");
         return registration;
     }
 }
注解⽅式
@Slf4j
 @Component
 // filterName就是当前类名称,还有⼀个urlPattens的参数,这个参数表⽰要过滤的URL上的后缀名,是多参数,可以⽤数组表⽰。
 @WebFilter(value = "/hello")或(filterName = "f1", urlPatterns = {"*.html","*.jsp","/hello"})
 public class HelloFilter2 implements Filter {
     @Override
     public void init(FilterConfig filterConfig) throws ServletException {
     }
     @Override
     public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
             FilterChain filterChain) throws IOException, ServletException {
         log.info("进⼊到过滤器2啦");
         filterChain.doFilter(servletRequest,servletResponse);
     }
     @Override
     public void destroy() {
     }
 }
在主启动类上加@ServletComponentScan("com.pandy.blog.filters")   指明filter所在位置的包。
 若有多个filter,默认根据filter类名的字母倒叙排列,且@WebFilter注解⽅式的过滤器优先级⾼于Bean注⼊⽅式配置的过滤器。
1.3 Filter过滤器详解
        a) Filter是依赖于Servlet的,需要有Servlet的依赖。
         b) init() 在容器初始化时执⾏,只执⾏⼀次。
         c) doFilter() ⽬标请求之前拦截执⾏,拦截之后需要放⾏才开始执⾏⽬标⽅法。 filterChain.doFilter(servletRequest,servletResponse);
         d) destroy() 在容器销毁时执⾏,只执⾏⼀次。
         e) Filter可以拦截所有请求。包括静态资源[css,js...]。
         f) 基于函数回调实现。
         g) 过滤器只能在容器初始化时被调⽤⼀次。
2. 什么是拦截器
         拦截器是springmvc提供的,类似于过滤器。主要⽤于拦截⽤户请求并作相应的处理。
2.1 拦截器常见使⽤场景
         a) ⽇志记录
         b) 权限校验
         c) 登录校验
         d) 性能检测[检测⽅法的执⾏时间]
         其实拦截器和过滤器很像,有些使⽤场景。⽆论选⽤谁都能实现。需要注意的使他们彼此的使⽤范围,触发机制。
2.2 springboot整合拦截器
         a) 编写⾃定义拦截器类实现HandlerInterceptor接⼝或继承其⼦类【推荐实现的⽅式,实现可以⾃动⽣成preHandle..】
 @Component
 public class InterceptorDemo implements HandlerInterceptor {
     @Override
     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
         System.out.println("拦截器preHandle在控制器⽅法执⾏前执⾏");
         //true:表⽰放⾏
         return true;
     }
     @Override
     public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
         System.out.println("拦截器postHandle在控制器⽅法执⾏后执⾏");
     }
     @Override
     public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
         System.out.println("拦截器afterCompletion在请求完成后执⾏");
     }
 }
         b) 基于springmvc编写配置类
 @Configuration
 // ⽼版本呢是继承WebMvcConfigurerAdapter不过新版本已经放弃了,推荐⽤下⾯的⽅式。
 public class InterceptorConfig implements WebMvcConfigurer { 
     @Autowired
     private InterceptorDemo interceptorDemo;
     @Override
     public void addInterceptors(InterceptorRegistry registry) {
         // ** 表⽰所有拦截路径
         registry.addInterceptor(interceptorDemo).addPathPatterns("/**");
         // 或下⾯这种写法【若编写⾃定义拦截器类没有加@Component注解】
         registry.addInterceptor(new InterceptorDemo()).addPathPatterns("/**");
     }
 }
2.3 拦截器详解
         a) 拦截器是依赖于SpringMVC的,需要有mvc的依赖。
         b) preHandle() 在⽬标请求完成之前执⾏。有返回值Boolean类型,true:表⽰放⾏
         c) postHandle() 在⽬标请求之完成后执⾏。
         d) afterCompletion() 在整个请求完成之后【modelAndView已被渲染执⾏】。
         e) 拦截器只能拦截action请求。不包括静态资源[css,js...]。
         f) 基于java反射机制实现。
         g) 在拦截器的⽣命周期中,可以多次被调⽤。
 关于拦截器的preHandle()⽅法的参数说明:
       public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler){
       }
       @param request        current HTTP request
       @param response       current HTTP response
       @param handler        chosen handler to execute, for type and/or instance evaluation   //选择要执⾏的处理程序,⽤于类型和/或实例计算
3. 拦截器与过滤器区别
  
1、过滤器和拦截器触发时机不⼀样,过滤器是在请求进⼊容器后,但请求进⼊servlet之前进⾏预处理的。请求结束返回也是,是在servlet
 处理完后,返回给前端之前。
 2、拦截器可以获取IOC容器中的各个bean,⽽过滤器就不⾏,因为拦截器是spring提供并管理的,spring的功能可以被拦截器使⽤,在拦截
 器⾥注⼊⼀个service,可以调⽤业务逻辑。⽽过滤器是JavaEE标准,只需依赖servlet api ,不需要依赖spring。
 3、过滤器的实现基于回调函数。⽽拦截器(代理模式)的实现基于反射
 4、Filter是依赖于Servlet容器,属于Servlet规范的⼀部分,⽽拦截器则是独⽴存在的,可以在任何情况下使⽤。
 5、Filter的执⾏由Servlet容器回调完成,⽽拦截器通常通过动态代理(反射)的⽅式来执⾏。
 6、Filter的⽣命周期由Servlet容器管理,⽽拦截器则可以通过IoC容器来管理,因此可以通过注⼊等⽅式来获取其他Bean的实例,因此使⽤
 会更⽅便。
 过滤器和拦截器⾮常相似,但是它们有很⼤的区别:
 最简单明了的区别就是==过滤器可以修改request,⽽拦截器不能==
 过滤器需要在servlet容器中实现,拦截器可以适⽤于javaEE,javaSE等各种环境
 拦截器可以==调⽤IOC容器中的各种依赖,⽽过滤器不能==
 ==过滤器只能在请求的前后使⽤,⽽拦截器可以详细到每个⽅法==
 ==当有过滤器和拦截器时的执⾏流程:==
  
4. aop与过滤器,拦截器的区别
过滤器,拦截器拦截的是URL。AOP拦截的是类的元数据(包、类、⽅法名、参数等)。
 过滤器并没有定义业务⽤于执⾏逻辑前、后等,仅仅是请求到达就执⾏。
 拦截器有三个⽅法,相对于过滤器更加细致,有被拦截逻辑执⾏前、后等。
 AOP针对具体的代码,能够实现更加复杂的业务逻辑。
 三者功能类似,但各有优势,从过滤器--》拦截器--》切⾯,拦截规则越来越细致。
 执⾏顺序依次是过滤器、拦截器、切⾯。
4.1 三者使⽤场景
在编写相对⽐较公⽤的代码时,优先考虑过滤器,然后是拦截器,最后是aop。
 ⽐如:
 权限校验,⼀般情况下,所有的请求都需要做登陆校验,此时就应该使⽤过滤器在最顶层做校验;⽇志记录,⼀般⽇志只会针对部分逻辑做
 ⽇志记录,⽽且牵扯到业务逻辑完成前后的⽇志记录,因此使⽤过滤器不能细致地划分模块,此时应该考虑拦截器,然⽽拦截器也是依据
 URL做规则匹配,因此相对来说不够细致,因此我们会考虑到使⽤AOP实现,AOP可以针对代码的⽅法级别做拦截,很适合⽇志功能。
  
