闲来无事,对这个ShiroFilterFactoryBean,
不理解为什么不直接注入一个Filter,而是一个什么ShiroFilterFactoryBean,于是扒了扒源码,来瞅瞅到底内部是干了什么,
属于spring包的,那就和spring有关系了,
是属于shiro-spring的一个兼容包吧,
通过spring得bean注入,
实际上该类实现了FactoryBean接口,FactoryBean是spring提供的一个接口;
实现该接口可以返回定义的类,
内部属性:
用来放置过滤器的;
Map<String, Filter> filters = new LinkedHashMap();
用来放置url与过滤权限字符串的,例如每个key-value为 “/index”,“anon”
private Map<String, String> filterChainDefinitionMap = new LinkedHashMap();
//主要该类最终还是提供的是这个东东
private AbstractShiroFilter instance;
//剩下的暂时先不管了,不扯那么多,容易理解;
先看看FactoryBean有什么吧;
其实这个类是一个spring的工厂bean,可以帮助你创建bean,
实现该接口,
设置getObjectType时返回你需要注入的类的class类,
在getObject时返回需要注入的bean即可。
下面的isSingleton意思是是否需要单例。
通过spring的注入方式注入该接口的实现类,即可实现注入指定的类,
ShiroFilterFactoryBean实现了它,
那么看一看它的实现,
返回了一个内部类SpringShiroFilter,看一看上面的属性,是不是有个AbstractShiroFilter的属性呢?
实际上AbstractShiroFilter类是SpringShiroFilter的父类,
实现了FactoryBean的getObject方法,返回了AbstractShiroFilter的实例,
主要看一下this.createInstance()这个方法。
protected AbstractShiroFilter createInstance() throws Exception {
log.debug("Creating Shiro Filter instance.");
SecurityManager securityManager = this.getSecurityManager();
String msg;
//这些都不看,在shiroFactorybean配置的时候我们都会配置这个安全管理器,
都挺熟的,不说了,
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 {
//以上对安全管理器的的问题确认之后,才是正文
//这里使用了一个过滤器链管理器,重点是 this.createFilterChainManager()这个方法
FilterChainManager manager = this.createFilterChainManager();
PathMatchingFilterChainResolver chainResolver = new PathMatchingFilterChainResolver();
//使用了一个过滤器链解析器,最终返回了作为参数,返回了一个过滤器
chainResolver.setFilterChainManager(manager);
return new ShiroFilterFactoryBean.SpringShiroFilter((WebSecurityManager)securityManager, chainResolver);
}
}
再看一下createFilterChainManager() 方法
protected FilterChainManager createFilterChainManager() {
//创建了一个链管理器,
DefaultFilterChainManager manager = new DefaultFilterChainManager();
//刚创建的就获取filters,怎么还要迭代,里面已经有东西了?等会我们去看下它的构造器,先不管了,肯定里面是有的,
Map<String, Filter> defaultFilters = manager.getFilters();
Iterator var3 = defaultFilters.values().iterator();
//这些迭代的处理this.applyGlobalPropertiesIfNecessary(filter);这个方法没什么看的,无非是放行一些登陆地址,什么成功地址之类的,
while(var3.hasNext()) {
Filter filter = (Filter)var3.next();
this.applyGlobalPropertiesIfNecessary(filter);
}
//获取当前类的过滤器
Map<String, Filter> filters = this.getFilters();
String name;
Filter filter;
if (!CollectionUtils.isEmpty(filters)) {
for(Iterator var10 = filters.entrySet().iterator(); var10.hasNext(); manager.addFilter(name, filter, false)) {
Entry<String, Filter> entry = (Entry)var10.next();
name = (String)entry.getKey();
filter = (Filter)entry.getValue();
this.applyGlobalPropertiesIfNecessary(filter);
if (filter instanceof Nameable) {
((Nameable)filter).setName(name);
}
}
}
//这里的filterChainDefinitionMap其实就是我们放入的验证规则,
Map<String, String> chains = this.getFilterChainDefinitionMap();
if (!CollectionUtils.isEmpty(chains)) {
Iterator var12 = chains.entrySet().iterator();
while(var12.hasNext()) {
Entry<String, String> entry = (Entry)var12.next();
String url = (String)entry.getKey();
String chainDefinition = (String)entry.getValue();
//通过管理器进行创建链,主要看这个方法,后面会介绍
manager.createChain(url, chainDefinition);
}
}
return manager;
}
然后看下这个过滤器链管理器吧
构造器:
看到构造器调用了addDefaualtFilter方法,咱看下吧;
protected void addDefaultFilters(boolean init) {
//这个是什么鬼?
//其实是个枚举类啦!
就是添加了一堆过滤器
DefaultFilter[] var2 = DefaultFilter.values();
int var3 = var2.length;
for(int var4 = 0; var4 < var3; ++var4) {
DefaultFilter defaultFilter = var2[var4];
//defaultFilter.newInstance(),创建实例
this.addFilter(defaultFilter.name(), defaultFilter.newInstance(), init, false);
}
}
下面是这个枚举类的源码:
public enum DefaultFilter {
//声明了一堆我们shiro自带的过滤器,名称(对应的过滤器类)
anon(AnonymousFilter.class),
authc(FormAuthenticationFilter.class),
authcBasic(BasicHttpAuthenticationFilter.class),
logout(LogoutFilter.class),
noSessionCreation(NoSessionCreationFilter.class),
perms(PermissionsAuthorizationFilter.class),
port(PortFilter.class),
rest(HttpMethodPermissionFilter.class),
roles(RolesAuthorizationFilter.class),
ssl(SslFilter.class),
user(UserFilter.class);
private final Class<? extends Filter> filterClass;
private DefaultFilter(Class<? extends Filter> filterClass) {
this.filterClass = filterClass;
}
//调用这个方法创建了一个实例
public Filter newInstance() {
return (Filter)ClassUtils.newInstance(this.filterClass);
}
public Class<? extends Filter> getFilterClass() {
return this.filterClass;
}
......
}
再看下上面说的 manager.createChain(url, chainDefinition);这个方法;
这个就是根据你的url进行配置对应的过滤器了,
大致就扯到这里吧,反正东扯西扯,也不一定讲的很明白。