一、ShiroFilterFactoryBean源码分析
Spring整合shiro后,shiro是通过ShiroFilterFactoryBean加入到Spring容器中的,下面看其源码:
public class ShiroFilterFactoryBean implements FactoryBean, BeanPostProcessor
可以看到,它实现了FactoryBean接口和BeanPostProcessor接口。下面看这两个接口的实现方法:
public Object getObject() throws Exception {
if (instance == null) {
instance = createInstance();
}
return instance;
}
getObject方法将instance返回到了Spring容器中,instance对象是:
private AbstractShiroFilter instance;
是一个ShiroFilter。下面看createInstance()方法,看AbstractShiroFilter对象是如何创建出来的。
protected AbstractShiroFilter createInstance() throws Exception {
log.debug("Creating Shiro Filter instance.");
SecurityManager securityManager = getSecurityManager();
if (securityManager == null) {
String msg = "SecurityManager property must be set.";
throw new BeanInitializationException(msg);
}
if (!(securityManager instanceof WebSecurityManager)) {
String msg = "The security manager does not implement the WebSecurityManager interface.";
throw new BeanInitializationException(msg);
}
FilterChainManager manager = createFilterChainManager();
//Expose the constructed FilterChainManager by first wrapping it in a
// FilterChainResolver implementation. The AbstractShiroFilter implementations
// do not know about FilterChainManagers - only resolvers:
PathMatchingFilterChainResolver chainResolver = new PathMatchingFilterChainResolver();
chainResolver.setFilterChainManager(manager);
//Now create a concrete ShiroFilter instance and apply the acquired SecurityManager and built
//FilterChainResolver. It doesn't matter that the instance is an anonymous inner class
//here - we're just using it because it is a concrete AbstractShiroFilter instance that accepts
//injection of the SecurityManager and FilterChainResolver:
return new SpringShiroFilter((WebSecurityManager) securityManager, chainResolver);
}
这段代码的重点在:
FilterChainManager manager = createFilterChainManager();
这个方法创建了拦截器链,Shiro的权限控制都是靠一系列拦截器实现的,通过debug,看有哪些默认的拦截器链。
首先,manager对象有三个属性:filterConfig,filters和filterChains。看filters里有哪些内容:
可以看到,里面存放了shiro默认的filter和我们程序中自定义的filter。
再看filterChains中的内容:
可以看到,里面存放的是我们配置的资源权限认证映射,filterChains是一个LinkedHashMap,key是资源,value是过滤器拦截链,即这个资源,需要经过哪些filters过滤,如下图所示:
分析到这里,有两个疑问:1.shiro的默认filter都是什么作用? 2.filterChains中每个资源的filtersChain个数都不一样,是如何判断哪个资源用哪个filter的?
这样,shiro中的过滤器就加入到了Spring容器中。分析完如何加入Spring容器的,我们分析上面提到的两点疑问。