DelegatingFilterProxy
DelegatingFilterProxy的作用:传统方式通过web.xml注入filter,该filter就交给web容器来管理了,但是该filter也就不能注入spring容器的某些bean。DelegatingFilterProxy就是为了解决这类问题,虽然DelegatingFilterProxy实现了Filter接口,但是内部没有任何关于过滤方面的逻辑,它只是spring容器里某个实现了Filter接口的过滤器Bean的代理,实际使用的是它所代理的那个过滤器的过滤逻辑(ps:DelegatingFilterProxy与spring容器的过滤器bean是通过beanName建立联系的)。因此,spring的DelegatingFilterProxy提供了在 web.xml和application context之间的联系。另外需要注意的是,虽然DelegatingFilterProxy内部没有过滤器相关逻辑,但是它本质还是一个过滤器,使用任然需要在web.xml里面配置,而filter-name的值就是它所代理filter的bean的name。
DelegatingFilterProxy这个作用带来的意义是,如果我们使用的不是shiro过滤器,而是其他的安全框架,那么,只需要在spring容器中配置相应的filter,交由DelegatingFilterProxy代理即可,降低了代码的耦合性。
ShiroFilterFactoryBean之AbstractShiroFilter
AbstractShiroFilter是shiro的全局过滤器,所有的请求都会经过该过滤器,在该过滤器内部,每次访问都会调用session.touch()方法更新会话最后访问时间。但是使用的时候,并没有注入AbstractShiroFilter,那么AbstractShiroFilter是如何配置和使用的呢?
使用过shiro都知道,过滤器是通过ShiroFilterFactoryBean进行注入的,但是其并不是一个过滤器,只是有个AbstractShiroFilter过滤器属性。
个人理解在springboot中,springboot完成了DelegatingFilterProxy的相关配置(ps:如果不使用springboot,那么这一步需要自己手动配置,配置方式看上面的DelegatingFilterProxy过滤器配置),然后DelegatingFilterProxy从spring容器中获取AbstractShiroFilter类型的bean进行了代理。
DelegatingFilterProxy从spring容器中获取AbstractShiroFilter类型的bean进行代理,但是我们在使用的过程中并没有将AbstractShiroFilter交由spring容器管理,只将ShiroFilterFactoryBean添加到了spring容器中,它是如何获取的呢,这里就要谈谈FactoryBean这个接口了。
FactoryBean主要方法
package org.springframework.beans.factory;
import org.springframework.lang.Nullable;
public interface FactoryBean<T> {
//获取实例
T getObject() throws Exception;
//获取提供实例的类型
Class<?> getObjectType();
//是否单例,个人认为如果不是单例将会把实例放到spring容器里
default boolean isSingleton() {
return true;
}
}
在spring通过类型获取AbstractShiroFilter类型bean的时候(ps:注意,在spring容器里没有AbstractShiroFilter类型的bean),会将所有beanName获取出来,然后遍历beanName集合,根据beanName获取bean并判断该bean是否实现了FactoryBean,如果实现了FactoryBean就调用该bean实现的FactoryBean的getObjectType获取类型,判断需要的类型与该类型是否匹配,如果匹配,通过其实现的getObject()获取创建一个实例作为bean。而看ShiroFilterFactoryBean源码,由于其实现了FactoryBean接口,在spring上下文获取其的时候,会调用getObject方法获取,实际获取的是其属性AbstractShiroFilter的过滤器。而AbstractShiroFilter内部维护着定义好的过滤器链。
ShiroFilterFactoryBean的getObject源码
public Object getObject() throws Exception {
if (this.instance == null) {
this.instance = this.createInstance();
}
return this.instance;
}
protected AbstractShiroFilter createInstance() throws Exception {
log.debug("Creating Shiro Filter instance.");
SecurityManager securityManager = this.getSecurityManager();
String msg;
if (securityManager == null) {
msg = "SecurityManager property must be set.";
throw new BeanInitializationException(msg);
} else if (!(securityManager instanceof WebSecurityManager)) {
msg = "The security manager does not implement the WebSecurityManager interface.";
throw new BeanInitializationException(msg);
} else {
FilterChainManager manager = this.createFilterChainManager();
PathMatchingFilterChainResolver chainResolver = new PathMatchingFilterChainResolver();
chainResolver.setFilterChainManager(manager);
return new ShiroFilterFactoryBean.SpringShiroFilter((WebSecurityManager)securityManager, chainResolver);
}
}
实际返回的是其内部类AbstractShiroFilter。该类就是shiro核心的过滤器。