org.apache.shiro.web.servlet.ShiroFilter的架构图如下:
前面我们说到shrio会初始化一个ServletContextLoaderListener-EnvironmentLoaderListener,这个类初始化一个WebEnvironment对象,然后与当前应用的ServletContext对象进行关联-相互关联,我们可以先得到ServletContext对象从而得到key为**EnvironmentLoader.class.getName() + “.ENVIRONMENT_ATTRIBUTE_KEY”**的WebEnvironment对象,这个对象里面包含有
org.apache.shiro.mgt.SecurityManager和org.apache.shiro.web.filter.mgt.FilterChainResolver对象
那这两个对象与下面的ShrioFilter类有什么联系呢?
打开这个类的源码,
public void init() throws Exception {
WebEnvironment env = WebUtils.getRequiredWebEnvironment(getServletContext());
setSecurityManager(env.getWebSecurityManager());
FilterChainResolver resolver = env.getFilterChainResolver();
if (resolver != null) {
setFilterChainResolver(resolver);
}
}
发现这个类会将这两个对象取出来,方法是先获取WebEnvironment对象,从这里我们也学会了怎样获取WebEnvironment对象了
WebEnvironment env = WebUtils.getRequiredWebEnvironment(getServletContext());
这两个对象在它的父类中定义:
那Servlet容器怎样初始化这个Filter呢,当然是找到实现了Filter接口的初始化方法了:
public void init(FilterConfig filterConfig) throws ServletException;
翻下源码,可以知道AbstractFilter这个类实现了这个方法:
第一步是先初始化AbstractFilter类的成员变量FilterConfig对象,该对象可以得到ServletContext对象,然后就初始化ServletContextSupport类的ServletContext对象
public class ServletContextSupport {
//TODO - complete JavaDoc
private ServletContext servletContext = null;
第二步是调用**onFilterConfigSet()**这个方法,这是重点:
这个类是个模板方法,在子类AbstractShiroFilter中实现
protected void onFilterConfigSet() throws Exception {
}
protected final void onFilterConfigSet() throws Exception {
//获取Filter对象中key为“staticSecurityManagerEnabled” 的值,
//然后赋值给成员变量 private boolean staticSecurityManagerEnabled
//这是什么意思呢?下面再解释
applyStaticSecurityManagerEnabledConfig();
//本类中没有实现,是public方法?在子类ShrioFilter中实现,图如下:
init();
//检查是否SecurityManager对象已经初始化,如果没有,则用默认的
//从这里可以可以知道可以不配置EnvironmentLoaderListener对象也可以
//因为可以用默认的,只在web.xml配置Filter对象就行
ensureSecurityManager();
//判断上面赋值的布尔型变量,然后调用方法
//猜想如果为真则可以通过SecurityUtils类的静态方法获取SecurityManager对象
if (isStaticSecurityManagerEnabled()) {
SecurityUtils.setSecurityManager(getSecurityManager());
}
}
public void init() throws Exception {
}
@Override
public void init() throws Exception {
WebEnvironment env = WebUtils.getRequiredWebEnvironment(getServletContext());
setSecurityManager(env.getWebSecurityManager());
FilterChainResolver resolver = env.getFilterChainResolver();
if (resolver != null) {
setFilterChainResolver(resolver);
}
}
这个方法在上面已经说过了就不做详细解释了,只是初始化两个大Boss对象用的
private void ensureSecurityManager() {
WebSecurityManager securityManager = getSecurityManager();
if (securityManager == null) {
log.info("No SecurityManager configured. Creating default.");
securityManager = createDefaultSecurityManager();
setSecurityManager(securityManager);
}
}
protected WebSecurityManager createDefaultSecurityManager() {
return new DefaultWebSecurityManager();
}
下篇文章我们来讲述ShiroFilter对象是怎样拦截请求的