在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安全