Spring DelegatingFilterProxy 源碼分析

在web項目,利用Spirng 管理權限框架時,無論權限框架使用的是Shiro仍是SpringSecucrity在web.xml文件中都有一個名org.springframework.web.filter.DelegatingFilterProxy 的Filter。 配置以下:java

<filter>
		<filter-name>securityFilter</filter-name>
		<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
		<init-param>
			<param-name>targetFilterLifecycle</param-name>
			<param-value>true</param-value>
		</init-param>
</filter>

DelegatingFilterProxy 是Spring web內部一個類,其實現了GenericFilterBean,而GenericFilterBean又實現了javax.servlet.Filter接口,並對Filter#init方法進行了重寫,而Filter#doFilter交給其子類去實現。而GenericFilterBean#init方法內部調用了GenericFilterBean#initFilterBean方法。該方法的默認實現爲空,其採用了模板方法的設計模式交給其子類去實現initFilterBean的具體邏輯。web

public final void init(FilterConfig filterConfig) throws ServletException {
	        ...此處省略部分代碼
		// Let subclasses do whatever initialization they like
		initFilterBean();
		...此處省略部分代碼
}

如今,來看看DelegatingFilterProxy#initFilterBean的現實代碼spring

@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);
				}
			}
		}
	}

該方法中有兩處關鍵的地方this.targetBeanName = getFilterName()與WebApplicationContext wac = findWebApplicationContext()。前者獲得web.xml中filter對應的名字,將其賦予爲targetBeanName;後者 獲得一個WebApplicationContex對象,這個接口你們應該很熟悉其續承了ApplicationContext,而經過其#getBean方法咱們即可以獲得在spring-context.xml配置文件中安全框架的具體實現。 先來看看 initDelegate對應的代碼:apache

protected Filter initDelegate(WebApplicationContext wac) throws ServletException {
		Filter delegate = wac.getBean(getTargetBeanName(), Filter.class);
		if (isTargetFilterLifecycle()) {
			delegate.init(getFilterConfig());
		}
		return delegate;
}

Filter delegate = wac.getBean(getTargetBeanName(), Filter.class),即是利用咱們在web.xml配置文件設置的<filter-name>securityFilter</filter-name>去spring-context.xml配置文件中找到安全框架的具體實現類。 因此,在spring-context.xml文件中org.apache.shiro.spring.web.ShiroFilterFactoryBean對應的id必定要與web.xml中的filter-name一致。而對於SpringSecurity有點不一樣,默認狀況在web.xml中DelegatingFilterProxy的filter-name爲springSecurityFilterChain,能夠在配置文件中使用<alias name="filterChainProxy" alias="securityFilter"/> 指定web.xml 中DelegatingFilterProxy對應的名稱。設計模式

歡迎查看個人另外一篇文章 ** Shiro源碼分析之ShiroFilterFactoryBean ** http://my.oschina.net/u/1421030/blog/731610安全

相關文章
相關標籤/搜索