攔截器、過濾器、監聽器的區別和使用


攔截器與過濾器的區別 : 
    1. 攔截器是基於java的反射機制的。而過濾器是基於函數回調,Spring框架支持,可Spring中的數據源、事務管理等。
    2. 使用范圍不同:攔截器不依賴與servlet容器,過濾器依賴與servlet容器。 
    3. 攔截器只能對action請求起作用,針對類,攔截器可以多次被調用。

             而過濾器則可以對幾乎所有的請求起作用,在容器啟動是初始化調用init方法,以后每個請求都調用doFilter()。作用范圍包含攔截器。
    4. 攔截器可以訪問action上下文、值棧里的對象(即方法中的對象),而過濾器不能訪問。 
    5. 攔截器可以在方法前后,異常前請求后各調用一次后等調用,

            而過濾器只能在請求前和。

    6.深度不同:Filter在Servlet前后作用,Interceptor在方法的前后作用,異常拋出前后,具有更大的彈性。所以優先使用攔截器。

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

攔截器是AOP的一種實現策略,可實現依賴注入。

 

因此它的完整加載順序就是 :ServletContext -> context-param -> listener-> filter -> servlet

 

開發一個監聽器,實現  ServletContextListener 接口

不過有一點需要注意的是: spring容器的加載要在servlet之后,因此在有些過濾器當中需要提前用到spring bean的時候,就需要改成 Listener 的方式

org.springframework.web.context.ContextLoaderListener

ContextLoaderListener的作用就是啟動Web容器時,自動裝配ApplicationContext的配置信息。因為它實現了ServletContextListener這個接口,在web.xml配置這個監聽器,啟動容器時,就會默認執行它實現的方法。

容器監聽器ServletContextListener 是 ServletContext 的監聽者,如果 ServletContext 發生變化,如服務器啟動時 ServletContext 被創建,服務器關閉時 ServletContext 將要被銷毀。

要求每次訪問action都無需加載新的xml文件,利用框架的監聽器實現只在服務器啟動時加載一次xml配置,用於提高性能。

監聽器內如何引用對象:

1、直接加載“bean.xml”文件,bean被實例化了兩次,不可取。

2、從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返回之前執行。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM