目录:
shiro(1)-架构
shiro(2)-有状态身份认证和无状态身份认证
shiro(3)-DelegatingFilterProxy的作用
shiro(4)-有状态认证-sessionManager会话
shiro(5)-有状态认证-Realm认证的实现
Shiro(6)-有状态认证-会话管理(整合Redis实现共享Session)
shiro(7)-有状态认证-会话管理(单处登录-改进版)
org.springframework.web.filter.DelegatingFilterProxy
一般情况下,创建一个Filter是交给自己来实现的。基于servlet规范,在web.xml中配置,自定义filter实现的Filter接口:
public interface Filter {
void init(FilterConfig var1) throws ServletException;
void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;
void destroy();
}
而DelegatingFilterProxy是一个servlet filter的代理。它的优点如下:
- 通过spring容器来管理servlet filter的生命周期。
- 如果filter中需要Spring容器的实例,可以通过spring直接注入。
- 读取配置文件这些便利操作都可以通过Spring来配置实现。
首先在web.xml中配置:
<filter>
<filter-name>myFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>myFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
然后再Spring的配置文件中,配置具体的Filter类的实例。
<bean name="myFilter"class="com.*.MyFilter"></bean>
需要注意的是:在Spring中配置的bean的name要和web.xml中的<filter-name>保持相同。
1. filter的配置
- 若不和<filter-name>保持相同
可以在DelegatingFilterProxy的filter配置初始化参数:targetBeanName
,对应到Spring配置中的beanName。
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<!-- 设置spring容器filter的bean id,如果不设置则找与filter-name一致的bean-->
<init-param>
<param-name>targetBeanName</param-name>
<param-value>shiroFilter</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
- 若保留Filter原有的init,destory方法调用
如果保留Filter原有的init、destory方法的调用,还需要配置初始化参数targetFilterLifecycle
为true,该参数默认为false。
<filter>
<filter-name>shiroFilter</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>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2. shiro的配置
一般情况下,创建一个Filter是交给自己来实现的。但是shiro的操作方式来看,这个反过来:spring提供了DelegatingFilterProxy作为通用Filter代理类,shiro以factoryBean的形式来构造自己的filter。
- 利用初始化方法获取被代理的对象delegate。
protected Filter initDelegate(WebApplicationContext wac) throws ServletException {
Filter delegate = wac.getBean(getTargetBeanName(), Filter.class);
if (isTargetFilterLifecycle()) {
delegate.init(getFilterConfig());
}
return delegate;
}
- 通过doFilter方法调用目标过滤器的doFilter方法
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) {
if (this.delegate == null) {
WebApplicationContext wac = findWebApplicationContext();
if (wac == null) {
throw new IllegalStateException("No WebApplicationContext found: no ContextLoaderListener registered?");
}
this.delegate = initDelegate(wac);
}
delegateToUse = this.delegate;
}
}
// Let the delegate perform the actual doFilter operation.
invokeDelegate(delegateToUse, request, response, filterChain);
}
//以factoryBean的形式来构造自己的filter。
protected void invokeDelegate(
Filter delegate, ServletRequest request, ServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
delegate.doFilter(request, response, filterChain);
}
- 通过destory方法释放一些资源
@Override
public void destroy() {
Filter delegateToUse = this.delegate;
if (delegateToUse != null) {
destroyDelegate(delegateToUse);
}
}
protected void destroyDelegate(Filter delegate) {
if (isTargetFilterLifecycle()) {
delegate.destroy();
}
}
通过以上操作,将完全的实现转移到被代理的Filter。
转载于:https://www.jianshu.com/p/a7cd47f38d0c