最近在分析源碼時發現了一個配置以下:web
#web.xml文件中 <filter> <filter-name>cacheSessionFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> <init-param> <param-name>targetFilterLifecycle</param-name> <param-vale>true</param-value> </init-param> </filter> <filter-mapping> <filter-name></filter-name> <url-pattern>/*</url-pattern> </filter-mapping> #applicationContext.xml文件 <bean name="cacheSessionFilter" class="xxxx.xxx.xxFilter"/>
那麼這個DelegatingFilterProxy究竟是幹嗎用的那???網上查了不少,最終總結爲一句話即:DelegateFilterProxy實現了服務器容器(tomcate was等)中的filter調用spring容器中類的功能,那這是如何實現的那?spring
觀察web.xml文件,spring的初始化通常都是在很是靠前的,也就是說在使用delegatingfilterproxy以前,spring容器已經初始化完成了,而後觀察delegatingfilterproxy的源碼會發現有這麼一段tomcat
protected void initFilterBean() throws ServletException { synchronized (this.delegateMonitor) { if (this.delegate == null) { // If no target bean name specified, use filter name. if (this.targetBeanName == null) { this.targetBeanName = getFilterName(); } // Fetch Spring root application context and initialize the delegate early, // if possible. If the root application context will be started after this // filter proxy, we'll have to resort to lazy initialization. WebApplicationContext wac = findWebApplicationContext(); if (wac != null) { this.delegate = initDelegate(wac); } } } }
沒錯WebApplicationContext其實就是spring容器,也就是說DelegatingFilterProxy中保存有spring的容器,而在WebApplicationContext中有一個和DelegatingFilerProxy同名的類(這個類就是咱們本身的類),DelegatingFilterProxy會從WebApplicationContext中尋找那個和其同名的類,而後將全部的動做賦予給它。服務器
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws ServletException, IOException { // Lazily initialize the delegate if necessary. Filter delegateToUse = this.delegate; if (delegateToUse == null) { synchronized (this.delegateMonitor) { delegateToUse = this.delegate; if (delegateToUse == null) { WebApplicationContext wac = findWebApplicationContext(); if (wac == null) { throw new IllegalStateException("No WebApplicationContext found: " + "no ContextLoaderListener or DispatcherServlet registered?"); } delegateToUse = initDelegate(wac); } this.delegate = delegateToUse; } } // Let the delegate perform the actual doFilter operation. invokeDelegate(delegateToUse, request, response, filterChain); }
其中的delegateToUse就是從webapplicationcontext中取出來的:app
@Override protected void initFilterBean() throws ServletException { synchronized (this.delegateMonitor) { if (this.delegate == null) { // If no target bean name specified, use filter name. if (this.targetBeanName == null) { this.targetBeanName = getFilterName(); } // Fetch Spring root application context and initialize the delegate early, // if possible. If the root application context will be started after this // filter proxy, we'll have to resort to lazy initialization. WebApplicationContext wac = findWebApplicationContext(); if (wac != null) { this.delegate = initDelegate(wac); } } } }