Spring DelegatingFilterProxy 源码分析
博客专区 > 0909 的博客 > 博客详情
Spring DelegatingFilterProxy 源码分析
0909 发表于1年前
Spring DelegatingFilterProxy 源码分析
  • 发表于 1年前
  • 阅读 1116
  • 收藏 18
  • 点赞 1
  • 评论 0

标题:腾讯云 新注册用户域名抢购1元起>>>   

摘要: 在web项目,利用Spirng 管理权限框架时,不管权限框架使用的是Shiro还是SpringSecucrity在web.xml文件中都有一个名org.springframework.web.filter.DelegatingFilterProxy 的Filter。这是为什么呢?Spring是如何识别具体的权限框架是Shiro还是SpringSecurity的呢?

在web项目,利用Spirng 管理权限框架时,不管权限框架使用的是Shiro还是SpringSecucrity在web.xml文件中都有一个名org.springframework.web.filter.DelegatingFilterProxy 的Filter。 配置如下:

<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的具体逻辑。

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

现在,来看看DelegatingFilterProxy#initFilterBean的现实代码

@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对应的代码:

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

共有 人打赏支持
粉丝 21
博文 16
码字总数 25047
×
0909
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: