用途和意义
回忆一下quickStart中的配置过程不难得出结论,shiro的核心配置应当位于Spring的applicationContext中的id为shiroFilter的bean。但我们在web.xml中还有一个name为shiroFilter的Filter的配置,它的类型是org.springframework.web.filter.DelegatingFilterProxy。
DelegatingFilterProxy的作用是:到spring容器中查找与该filter相应的filter(也就是同名)的bean。
这个作用带来的意义是,如果我们使用的不是shiro过滤器,而是其他的安全框架,那么,只需要在spring容器中配置相应的filter即可,降低了代码的耦合性。
接下来我们查看一下源码,以便了解其原理。该类继承GenericFilterBean。有几个私有属性:
//即将获取的shiro核心过滤器的id的值,如果该值没有指定
private String targetBeanName;
private boolean targetFilterLifecycle;
//获取的spring中shiro核心过滤器bean实例
private volatile Filter delegate;
Filter初始化方法:
protected void initFilterBean() throws ServletException {
Object var1 = this.delegateMonitor;
synchronized(this.delegateMonitor) {
if (this.delegate == null) {
//如果targetBeanName没有指定,则调用getFilterName方法
if (this.targetBeanName == null) {
this.targetBeanName = this.getFilterName();
}
//此处获取webApplicationContext
WebApplicationContext wac = this.findWebApplicationContext();
if (wac != null) {
this.delegate = this.initDelegate(wac);
}
}
}
}
getFilterName方法:
protected final String getFilterName() {
//查看是否拥有filter相关配置,如果有,那么将filter的name作为作为beanName值
return this.filterConfig != null ? this.filterConfig.getFilterName() : this.beanName;
}
由于targetBeanName是一个初始化参数,因而,在web.xml中使用filter的init-param来指定也是可以的。
protected Filter initDelegate(WebApplicationContext wac) throws ServletException {
//反射方式获取filter实例
Filter delegate = (Filter)wac.getBean(this.getTargetBeanName(), Filter.class);
if (this.isTargetFilterLifecycle()) {
delegate.init(this.getFilterConfig());
}
return delegate;
}