shrio-web第二天-ShrioFilter-1

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对象是怎样拦截请求的

猜你喜欢

转载自blog.csdn.net/weixin_42002747/article/details/103686730