拦截器、过滤器、监听器的区别和使用

拦截器与过滤器的区别 : 
    1. 拦截器是基于java的反射机制的。而过滤器是基于函数回调,Spring框架支持,可Spring中的数据源、事务管理等。
    2. 使用范围不一样:拦截器不依赖与servlet容器,过滤器依赖与servlet容器。 
    3. 拦截器只能对action请求起做用,针对类,拦截器能够屡次被调用。java

             而过滤器则能够对几乎全部的请求起做用,在容器启动是初始化调用init方法,之后每一个请求都调用doFilter()。做用范围包含拦截器。
    4. 拦截器能够访问action上下文、值栈里的对象(即方法中的对象),而过滤器不能访问。 
    5. 拦截器能够在方法先后,异常前请求后各调用一次后等调用,程序员

            而过滤器只能在请求前和。web

    6.深度不一样:Filter在Servlet先后做用,Interceptor在方法的先后做用,异常抛出先后,具备更大的弹性。因此优先使用拦截器。spring

    7.filter配置在web.xml中    interceptor配置在spring配置文件中 服务器

拦截器是AOP的一种实现策略,可实现依赖注入。app

 

所以它的完整加载顺序就是 :ServletContext -> context-param -> listener-> filter -> servlet框架

 

开发一个监听器,实现  ServletContextListener 接口webapp

不过有一点须要注意的是: spring容器的加载要在servlet以后,所以在有些过滤器当中须要提早用到spring bean的时候,就须要改为 Listener 的方式函数

org.springframework.web.context.ContextLoaderListener工具

ContextLoaderListener的做用就是启动Web容器时,自动装配ApplicationContext的配置信息。由于它实现了ServletContextListener这个接口,在web.xml配置这个监听器,启动容器时,就会默认执行它实现的方法。

容器监听器ServletContextListener 是 ServletContext 的监听者,若是 ServletContext 发生变化,如服务器启动时 ServletContext 被建立,服务器关闭时 ServletContext 将要被销毁。

要求每次访问action都无需加载新的xml文件,利用框架的监听器实现只在服务器启动时加载一次xml配置,用于提升性能。

监听器内如何引用对象:

一、直接加载“bean.xml”文件,bean被实例化了两次,不可取。

二、从servletcontext中获取。解析:(前一步在contextLoaderListener,后两步在contextLoader中)

 

1
2
3
4
5
6
7
8
9
10
11
/**
      * Initialize the root web application context.
      */
     public  void  contextInitialized(ServletContextEvent event) {
         this .contextLoader = createContextLoader();
//获取spring配置文件,建立webapplicationcontext
     this .contextLoader.initWebApplicationContext(event.getServletContext());
     }
     protected  ContextLoader createContextLoader() {
         return  new  ContextLoader();
     }
<wiz_tmp_tag class="wiz-block-scroll">
 

 

1
2
3
4
this .context = createWebApplicationContext(servletContext, parent);
             servletContext.setAttribute(
//建立好的spring context交给application内置对象,使监听器,过滤器,拦截器均可以访问。
     WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,  this .context);

 

1
2
3
4
5
6
7
8
9
//获取spring配置文件路径
String configLocation = servletContext.getInitParameter(CONFIG_LOCATION_PARAM);
         if  (configLocation !=  null ) {
     wac.setConfigLocations(StringUtils.tokenizeToStringArray(configLocation,                ConfigurableWebApplicationContext.CONFIG_LOCATION_DELIMITERS));
         }
//加载spring文件
         customizeContext(servletContext, wac);
         wac.refresh();
         return  wac;
1
2
3
4
5
6
// 解决方案二,项目在启动时,把Spring配置文件经过Spring的监听器加载,存储到ServletContext中,咱们只要在ServletContext中获取便可。 
//方法传入对象ServletContextEvent event
    ApplicationContext context = (ApplicationContext) event.getServletContext().getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
//工具类WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(event.getServletContext());
    productService = (ProductService) context.getBean( "productService" ); 
    System.out.println(productService);

 

 

 开发一个过滤器必须实现java定义好的javax.servlet.Filter接口:      (Servlet的特性)

       这一接口含有三个过滤器必须执行的方法:

doFilter(ServletRequest, ServletResponse, FilterChain):这是一个完成过滤行为的方法。这一样是上游过滤器调用的方法。

        引入的FilterChain对象提供了后续过滤器所要调用的信息。若是该过滤器是过滤器链中的最后一个过滤器,则将请求交给被请求资源。也能够直接给客户端返回响应信息。

init(FilterConfig):由Web容器来调用完成过滤器的初始化工做。它保证了在第一次doFilter()调用前由容器调用。您能获取在 web.xml 文件中指定的初始化参数。

destroy():由Web容器来调用来释放资源,doFilter()中的全部活动都被该实例终止后,调用该方法。

 

开发一个拦截器必须实现HandlerInterceptor接口:

preHandle():这个方法在handler执行以前被调用,在该方法中对用户请求 request 进行处理。若是程序员决定该拦截器对 请求进行拦截处理后还要调用其余的拦截器,或者是业务处理器去进行处理,则返回true;若是程序员决定不须要再调用其余的组件去处理请求,则返回false。

postHandle():这个方法在handler执行后,可是DispatcherServlet 向客户端返回响应前被调用,在该方法中对用户请求request进行处理。

afterCompletion():这个方法在 DispatcherServlet 彻底处理完请求后被调用,能够在该方法中进行一些资源清理的操做。view渲染完成、dispatcherServlet返回以前执行。

相关文章
相关标签/搜索