真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

ApacheShiro源碼解讀之SecurityManager的創(chuàng)建

對于Shiro(v1.2+)的SecurityManager的創(chuàng)建,在普通的應用程序中一般可以在main方法中這么創(chuàng)建

成都創(chuàng)新互聯(lián)主營洪洞網(wǎng)站建設的網(wǎng)絡公司,主營網(wǎng)站建設方案,重慶App定制開發(fā),洪洞h5微信小程序開發(fā)搭建,洪洞網(wǎng)站營銷推廣歡迎洪洞等地區(qū)企業(yè)咨詢

Factory factory = new IniSecurityManagerFactory("classpath:shiro.ini");
SecurityManager securityManager = factory.getInstance();

該方法讀取classpath路徑下的shiro.ini文件來構建SecurityManager,然而在web應用程序中,其是怎么創(chuàng)建的我們接下來逐步分析。

在web環(huán)境中我們會使用以下的Listener,而SecurityManager的創(chuàng)建就在Listener的初始化過程中【該Listener在shrio-web.jar中】


        org.apache.shiro.web.env.EnvironmentLoaderListener

EnvironmentLoaderListener的繼承關系很簡單,如下所示
Apache Shiro源碼解讀之SecurityManager的創(chuàng)建

EnvironmentLoader的作用是負責在應用程序啟動的時候負責加載Shiro,同時將org.apache.shiro.web.mgt.WebSecurityManager設置到ServletContext中。

在初始化Shiro的過程中,在web.xml文件中配置的上下文參數(shù)“shiroEnvironmentClass”和“shiroConfigLocations”可以指導Shiro的初始化過程,當然,這兩個參數(shù)不是必須配置的,有默認值。

shiroEnvironmentClass:制定繼承自WebEnvironment的自定義類,默認對象為IniWebEnvironment。
shiroConfigLocations:制定shiro初始化時用的配置文件路徑,默認會先查詢/WEB-INF/shiro.ini,如果沒找到再查找classpath:shiro.ini。

public class EnvironmentLoaderListener extends EnvironmentLoader implements ServletContextListener {

    /**
     * Initializes the Shiro {@code WebEnvironment} and binds it to the {@code ServletContext} at application
     * startup for future reference.
     *
     * @param sce the ServletContextEvent triggered upon application startup
     */
    public void contextInitialized(ServletContextEvent sce) {
        initEnvironment(sce.getServletContext());
    }

    /**
     * Destroys any previously created/bound {@code WebEnvironment} instance created by
     * the {@link #contextInitialized(javax.servlet.ServletContextEvent)} method.
     *
     * @param sce the ServletContextEvent triggered upon application shutdown
     */
    public void contextDestroyed(ServletContextEvent sce) {
        destroyEnvironment(sce.getServletContext());
    }
}
public class EnvironmentLoader {
    public WebEnvironment initEnvironment(ServletContext servletContext) throws IllegalStateException {

        if (servletContext.getAttribute(ENVIRONMENT_ATTRIBUTE_KEY) != null) {
            String msg = "There is already a Shiro environment associated with the current ServletContext.  " +
                    "Check if you have multiple EnvironmentLoader* definitions in your web.xml!";
            throw new IllegalStateException(msg);
        }

        servletContext.log("Initializing Shiro environment");
        log.info("Starting Shiro environment initialization.");

        long startTime = System.currentTimeMillis();

        try {

            WebEnvironment environment = createEnvironment(servletContext);
            servletContext.setAttribute(ENVIRONMENT_ATTRIBUTE_KEY,environment);

            log.debug("Published WebEnvironment as ServletContext attribute with name [{}]",
                    ENVIRONMENT_ATTRIBUTE_KEY);

            if (log.isInfoEnabled()) {
                long elapsed = System.currentTimeMillis() - startTime;
                log.info("Shiro environment initialized in {} ms.", elapsed);
            }

            return environment;
        } catch (RuntimeException ex) {
            log.error("Shiro environment initialization failed", ex);
            servletContext.setAttribute(ENVIRONMENT_ATTRIBUTE_KEY, ex);
            throw ex;
        } catch (Error err) {
            log.error("Shiro environment initialization failed", err);
            servletContext.setAttribute(ENVIRONMENT_ATTRIBUTE_KEY, err);
            throw err;
        }
    }

    protected WebEnvironment createEnvironment(ServletContext sc) {

        //查找WebEnvironment對象,并將其實例化
        WebEnvironment webEnvironment = determineWebEnvironment(sc);
        if (!MutableWebEnvironment.class.isInstance(webEnvironment)) {
            throw new ConfigurationException("Custom WebEnvironment class [" + webEnvironment.getClass().getName() +
                    "] is not of required type [" + MutableWebEnvironment.class.getName() + "]");
        }

        String configLocations = sc.getInitParameter(CONFIG_LOCATIONS_PARAM);
        boolean configSpecified = StringUtils.hasText(configLocations);

        if (configSpecified && !(ResourceConfigurable.class.isInstance(webEnvironment))) {
            String msg = "WebEnvironment class [" + webEnvironment.getClass().getName() + "] does not implement the " +
                    ResourceConfigurable.class.getName() + "interface.  This is required to accept any " +
                    "configured " + CONFIG_LOCATIONS_PARAM + "value(s).";
            throw new ConfigurationException(msg);
        }

        MutableWebEnvironment environment = (MutableWebEnvironment) webEnvironment;
        //保存當前的ServletContext對象
        environment.setServletContext(sc);

        //如果在web.xml設置了配置文件的路徑,則在此設置到environment中
        if (configSpecified && (environment instanceof ResourceConfigurable)) {
            ((ResourceConfigurable) environment).setConfigLocations(configLocations);
        }

        //構造方法,默認未實現(xiàn)
        customizeEnvironment(environment);

        //調用environment的init方法初始化environment對象
        LifecycleUtils.init(environment);

        return environment;
    }

    protected WebEnvironment determineWebEnvironment(ServletContext servletContext) {

        //從ServletContext的參數(shù)中獲取WebEnvironment的配置--shiroEnvironmentClass,如果有則創(chuàng)建實例返回
        Class webEnvironmentClass = webEnvironmentClassFromServletContext(servletContext);
        WebEnvironment webEnvironment = null;

        // 嘗試通過Java的ServiceLoader來查找WebEnvironment的實現(xiàn)類
        if (webEnvironmentClass == null) {
            webEnvironment = webEnvironmentFromServiceLoader();
        }

        // 如果上面的步驟都沒找到,則使用默認的WebEnvironment實現(xiàn)類IniWebEnvironment
        if (webEnvironmentClass == null && webEnvironment == null) {
            webEnvironmentClass = getDefaultWebEnvironmentClass();
        }

        // 創(chuàng)建WebEnvironment的實例
        if (webEnvironmentClass != null) {
            webEnvironment = (WebEnvironment) ClassUtils.newInstance(webEnvironmentClass);
        }

        return webEnvironment;
    }

    private WebEnvironment webEnvironmentFromServiceLoader() {

        WebEnvironment webEnvironment = null;
        /*
         * 使用Java的ServiceLoader方式來查找WebEnvironment的實現(xiàn)類(查找jar包中META-INF下的services文件夾中的文件);
         * 例如在某個services文件夾中有個名為org.apache.shiro.web.env.WebEnvironment的文件,然后在文件里面保存WebEnvironment的實現(xiàn)類全路徑;
         * 可見,文件名為接口的全路徑,里面的內容為接口的實現(xiàn)類
         * */
        ServiceLoader serviceLoader = ServiceLoader.load(WebEnvironment.class);
        Iterator iterator = serviceLoader.iterator();

        // 如果找到則使用第一個
        if (iterator.hasNext()) {
            webEnvironment = iterator.next();
        }
        // 如果不止找到一個,則拋出異常
        if (iterator.hasNext()) {
            List allWebEnvironments = new ArrayList();
            allWebEnvironments.add(webEnvironment.getClass().getName());
            while (iterator.hasNext()) {
                allWebEnvironments.add(iterator.next().getClass().getName());
            }
            throw new ConfigurationException("ServiceLoader for class [" + WebEnvironment.class + "] returned more then one " +
                    "result.  ServiceLoader must return zero or exactly one result for this class. Select one using the " +
                    "servlet init parameter '"+ ENVIRONMENT_CLASS_PARAM +"'. Found: " + allWebEnvironments);
        }
        return webEnvironment;
    }
}

綜上得知,查找WebEnvironment的實現(xiàn)類經(jīng)歷了三次查找
1)從ServletContext的初始化參數(shù)
2)從jar包查找實現(xiàn)類
3)使用默認的IniWebEnvironment

在得到WebEnvironment的實現(xiàn)類并創(chuàng)建好實例后,接著便會調用其init方法,這里假設得到的是默認的IniWebEnvironment。

public class IniWebEnvironment extends ResourceBasedWebEnvironment implements Initializable, Destroyable {

    public static final String DEFAULT_WEB_INI_RESOURCE_PATH = "/WEB-INF/shiro.ini";
    public static final String FILTER_CHAIN_RESOLVER_NAME = "filterChainResolver";

    private static final Logger log = LoggerFactory.getLogger(IniWebEnvironment.class);

    /**
     * The Ini that configures this WebEnvironment instance.
     */
    private Ini ini;

    private WebIniSecurityManagerFactory factory;

    public IniWebEnvironment() {
        //實例化WebIniSecurityManagerFactory對象
        factory = new WebIniSecurityManagerFactory();
    }

    /**
     * 初始化本實例
     */
    public void init() {
        //解析shiiro.ini配置文件并生成對應的Ini實例
        setIni(parseConfig());

        //使用Ini信息,通過WebIniSecurityManagerFactory創(chuàng)建WebSecurityManager實例
        configure();
    }
}

protected Ini parseConfig() {
        //直接取,首次運行肯定為null
        Ini ini = getIni();

        //獲取配置文件路徑【該路徑信息就是web.xml文件中配置的,實例化該類的時候已經(jīng)在EnvironmentLoader中設置】
        String[] configLocations = getConfigLocations();

        if (log.isWarnEnabled() && !CollectionUtils.isEmpty(ini) &&
                configLocations != null && configLocations.length > 0) {
            //如果Ini對象不為空,并且configLocations也不為空,給出提示信息
            log.warn("Explicit INI instance has been provided, but configuration locations have also been " +
                    "specified.  The {} implementation does not currently support multiple Ini config, but this may " +
                    "be supported in the future. Only the INI instance will be used for configuration.",
                    IniWebEnvironment.class.getName());
        }

        if (CollectionUtils.isEmpty(ini)) {
            log.debug("Checking any specified config locations.");
            //從指定路徑下的配置文件中創(chuàng)建Ini實例
            ini = getSpecifiedIni(configLocations);
        }

        if (CollectionUtils.isEmpty(ini)) {
            log.debug("No INI instance or config locations specified.  Trying default config locations.");
            /*
             * 如果沒有在web.xml中配置,則從默認的路徑下讀取配置文件并創(chuàng)建實例
             * 1,/WEB-INF/shiro.ini
             * 2,classpath:shiro.ini
             * */
            ini = getDefaultIni();
        }

        /*
         * 為了保持向后兼容而提供getFrameworkIni方法來創(chuàng)建Ini對象并與上面得到的Ini對象合并.
         * getFrameworkIni的默認實現(xiàn)返回null,經(jīng)過合并處理后返回的還是上面的Ini對象
         * */
        ini = mergeIni(getFrameworkIni(), ini);

        if (CollectionUtils.isEmpty(ini)) {
            String msg = "Shiro INI configuration was either not found or discovered to be empty/unconfigured.";
            throw new ConfigurationException(msg);
        }
        return ini;
    }

        /**
     * 解析配置文件創(chuàng)建Ini實例對象
     * */
    protected Ini createIni(String configLocation, boolean required) throws ConfigurationException {

        Ini ini = null;

        if (configLocation != null) {
            ini = convertPathToIni(configLocation, required);
        }
        if (required && CollectionUtils.isEmpty(ini)) {
            String msg = "Required configuration location '" + configLocation + "' does not exist or did not " +
                    "contain any INI configuration.";
            throw new ConfigurationException(msg);
        }

        return ini;
    }

        /**
     * 加載制定路徑的配置文件,然后將文件流作為參數(shù)調用Ini實例對象的load方法來初始化Ini對象
     * */
    private Ini convertPathToIni(String path, boolean required) {

        Ini ini = null;

        if (StringUtils.hasText(path)) {
            InputStream is = null;

            //SHIRO-178: Check for servlet context resource and not only resource paths:
            if (!ResourceUtils.hasResourcePrefix(path)) {
                is = getServletContextResourceStream(path);
            } else {
                try {
                    is = ResourceUtils.getInputStreamForPath(path);
                } catch (IOException e) {
                    if (required) {
                        throw new ConfigurationException(e);
                    } else {
                        if (log.isDebugEnabled()) {
                            log.debug("Unable to load optional path '" + path + "'.", e);
                        }
                    }
                }
            }
            if (is != null) {
                ini = new Ini();
                ini.load(is);
            } else {
                if (required) {
                    throw new ConfigurationException("Unable to load resource path '" + path + "'");
                }
            }
        }

        return ini;
    }

再看看Ini對象的初始化過程

public class Ini implements Map {
    private static transient final Logger log = LoggerFactory.getLogger(Ini.class);

    public static final String DEFAULT_SECTION_NAME = ""; //empty string means the first unnamed section
    public static final String DEFAULT_CHARSET_NAME = "UTF-8";

    public static final String COMMENT_POUND = "#";
    public static final String COMMENT_SEMICOLON = ";";
    public static final String SECTION_PREFIX = "[";
    public static final String SECTION_SUFFIX = "]";

    protected static final char ESCAPE_TOKEN = '\\';

    private final Map sections;

    /**
     * Creates a new empty {@code Ini} instance.
     */
    public Ini() {
        this.sections = new LinkedHashMap();
    }

    public void load(InputStream is) throws ConfigurationException {
        if (is == null) {
            throw new NullPointerException("InputStream argument cannot be null.");
        }
        InputStreamReader isr;
        try {
            isr = new InputStreamReader(is, DEFAULT_CHARSET_NAME);
        } catch (UnsupportedEncodingException e) {
            throw new ConfigurationException(e);
        }
        load(isr);
    }

    public void load(Reader reader) {
        Scanner scanner = new Scanner(reader);
        try {
            load(scanner);
        } finally {
            try {
                scanner.close();
            } catch (Exception e) {
                log.debug("Unable to cleanly close the InputStream scanner.  Non-critical - ignoring.", e);
            }
        }
    }

        public void load(Scanner scanner) {

        String sectionName = DEFAULT_SECTION_NAME;
        StringBuilder sectionContent = new StringBuilder();

        //循環(huán)讀取每一行
        while (scanner.hasNextLine()) {

            String rawLine = scanner.nextLine();
            //取出兩邊的空格
            String line = StringUtils.clean(rawLine);

            if (line == null || line.startsWith(COMMENT_POUND) || line.startsWith(COMMENT_SEMICOLON)) {
                //忽略空行和注釋
                continue;
            }
            //獲取section名稱,格式為 [main] 這種,此時返回“main”
            String newSectionName = getSectionName(line);
            if (newSectionName != null) {
                //前面section的配置信息收集完成,添加section配置
                addSection(sectionName, sectionContent);

                //為本次的section重置StringBuilder對象,用戶存放該section的配置信息
                sectionContent = new StringBuilder();

                sectionName = newSectionName;

                if (log.isDebugEnabled()) {
                    log.debug("Parsing " + SECTION_PREFIX + sectionName + SECTION_SUFFIX);
                }
            } else {
                //添加配置信息
                sectionContent.append(rawLine).append("\n");
            }
        }

        //添加Section的配置信息
        addSection(sectionName, sectionContent);
    }

    private void addSection(String name, StringBuilder content) {
        if (content.length() > 0) {
            String contentString = content.toString();
            String cleaned = StringUtils.clean(contentString);
            if (cleaned != null) {
                //構建Section對象【靜態(tài)內部類】
                Section section = new Section(name, contentString);
                if (!section.isEmpty()) {
                    //以鍵值對的方式保存Section對象
                    sections.put(name, section);
                }
            }
        }
    }

    public static class Section implements Map {
            private final String name;
            private final Map props;

            /*
         * 解析收集的配置信息,將配置信息保存到props對象中
         * */
        private Section(String name, String sectionContent) {
            if (name == null) {
                throw new NullPointerException("name");
            }
            this.name = name;
            Map props;
            if (StringUtils.hasText(sectionContent) ) {
                props = toMapProps(sectionContent);
            } else {
                props = new LinkedHashMap();
            }
            if ( props != null ) {
                this.props = props;
            } else {
                this.props = new LinkedHashMap();
            }
        }

    }
}

到此,在IniWebEnvironment實例中通過解析配置文件得到了Ini對象,該對象里面保存了配置文件中的每個Section信息,那么接著就要使用該Ini對象來構建WebSecurityManager了,也就是調用IniWebEnvironment 的configure方法

public class IniWebEnvironment extends ResourceBasedWebEnvironment implements Initializable, Destroyable {
    protected void configure() {
        //Map對象
        this.objects.clear();

        WebSecurityManager securityManager = createWebSecurityManager();
        setWebSecurityManager(securityManager);

        FilterChainResolver resolver = createFilterChainResolver();
        if (resolver != null) {
            setFilterChainResolver(resolver);
        }
    }

    protected Map getDefaults() {
        Map defaults = new HashMap();
        defaults.put(FILTER_CHAIN_RESOLVER_NAME, new IniFilterChainResolverFactory());
        return defaults;
    }

    protected WebSecurityManager createWebSecurityManager() {
        //已經(jīng)創(chuàng)建好的Ini對象
        Ini ini = getIni();
        if (!CollectionUtils.isEmpty(ini)) {
            factory.setIni(ini);
        }

        Map defaults = getDefaults();
        if (!CollectionUtils.isEmpty(defaults)) {
            factory.setDefaults(defaults);
        }
        //從WebIniSecurityManagerFactory實例中創(chuàng)建WebSecurityManager
        WebSecurityManager wsm = (WebSecurityManager)factory.getInstance();

        //SHIRO-306 - get beans after they've been created (the call was before the factory.getInstance() call,
        //which always returned null.
        Map beans = factory.getBeans();
        if (!CollectionUtils.isEmpty(beans)) {
            this.objects.putAll(beans);
        }

        return wsm;
    }
}

接著看看WebIniSecurityManagerFactory的getInstance方法的實現(xiàn)

Apache Shiro源碼解讀之SecurityManager的創(chuàng)建

由圖可見,在調用getInstance方法的時候,其實執(zhí)行的是位于AbstractFactory中的getInstance方法

public abstract class AbstractFactory implements Factory {
    public T getInstance() {
        T instance;
        if (isSingleton()) {
            if (this.singletonInstance == null) {
                this.singletonInstance = createInstance();
            }
            instance = this.singletonInstance;
        } else {
            instance = createInstance();
        }
        if (instance == null) {
            String msg = "Factory 'createInstance' implementation returned a null object.";
            throw new IllegalStateException(msg);
        }
        return instance;
    }
     /*
     * 子類(IniFactorySupport)實現(xiàn)創(chuàng)建實例的過程
     * */
    protected abstract T createInstance();
}
public abstract class IniFactorySupport extends AbstractFactory {
    public T createInstance() {
        /*
         * 獲取Ini對象,前面已經(jīng)設置進來。
         * 如果ini對象不存在,還會從默認的路徑來創(chuàng)建Ini對象
         * */
        Ini ini = resolveIni();

        T instance;

        if (CollectionUtils.isEmpty(ini)) { 
            //如果Ini對象不存在,則調動子類(IniSecurityManagerFactory)使用默認的SecurityManager實例對象
            log.debug("No populated Ini available.  Creating a default instance.");
            instance = createDefaultInstance();
            if (instance == null) {
                String msg = getClass().getName() + " implementation did not return a default instance in " +
                        "the event of a null/empty Ini configuration.  This is required to support the " +
                        "Factory interface.  Please check your implementation.";
                throw new IllegalStateException(msg);
            }
        } else {
            log.debug("Creating instance from Ini [" + ini + "]");
            //調用子類(IniSecurityManagerFactory),根據(jù)Ini對象的信息來構建SecurityManager對象
            instance = createInstance(ini);
            if (instance == null) {
                String msg = getClass().getName() + " implementation did not return a constructed instance from " +
                        "the createInstance(Ini) method implementation.";
                throw new IllegalStateException(msg);
            }
        }

        return instance;
    }

    protected abstract T createInstance(Ini ini);

    protected abstract T createDefaultInstance();
}
public class IniSecurityManagerFactory extends IniFactorySupport {
    public static final String MAIN_SECTION_NAME = "main";

    public static final String SECURITY_MANAGER_NAME = "securityManager";
    public static final String INI_REALM_NAME = "iniRealm";

    private ReflectionBuilder builder;

    public IniSecurityManagerFactory() {
        this.builder = new ReflectionBuilder();
    }

    //默認的SecurityManager對象【其實被WebIniSecurityManagerFactory復寫,返回的是DefaultWebSecurityManager】
    protected SecurityManager createDefaultInstance() {
        return new DefaultSecurityManager();
    }

    //根據(jù)Ini來創(chuàng)建SecurityManager對象
    protected SecurityManager createInstance(Ini ini) {
        if (CollectionUtils.isEmpty(ini)) {
            throw new NullPointerException("Ini argument cannot be null or empty.");
        }
        SecurityManager securityManager = createSecurityManager(ini);
        if (securityManager == null) {
            String msg = SecurityManager.class + " instance cannot be null.";
            throw new ConfigurationException(msg);
        }
        return securityManager;
    }

    private SecurityManager createSecurityManager(Ini ini) {
        return createSecurityManager(ini, getConfigSection(ini));
    }

    //獲取[main]的配置,如果沒得到則獲取默認的配置
    private Ini.Section getConfigSection(Ini ini) {

        Ini.Section mainSection = ini.getSection(MAIN_SECTION_NAME);
        if (CollectionUtils.isEmpty(mainSection)) {
            //try the default:
            mainSection = ini.getSection(Ini.DEFAULT_SECTION_NAME);
        }
        return mainSection;
    }

    @SuppressWarnings({"unchecked"})
    private SecurityManager createSecurityManager(Ini ini, Ini.Section mainSection) {
        /*
         * 注意,createDefaults被子類WebIniSecurityManagerFactory復寫,
         * 但其實也會首先調用本類的createDefaults方法,只是在結果中再添加了些默認的Filter實例。
         * 
         * 然后將結果保存在ReflectionBuilder對象的objects【Map】屬性中,此時里面包含了默認的SecurityManager、Realm以及各種默認Filter實例;
         * 
         * 最后將createDefaults返回的Map全部加到ReflectionBuilder對象的objects【Map】中取緩存
         * */
        getReflectionBuilder().setObjects(createDefaults(ini, mainSection));

        //使用ReflectionBuilder構建對象【創(chuàng)建實例對象,加入到objects變量中,然后執(zhí)行各個對象的init方法,同時返回objects對象】
        Map objects = buildInstances(mainSection);

        //直接從ReflectionBuilder對象中取出SecurityManager類型的對象
        SecurityManager securityManager = getSecurityManagerBean();

        /*
         * 如果securityManager不為RealmSecurityManager類型則返回true;
         * 如果是RealmSecurityManager類型,但是里面沒有Realm實例,返回為true;
         * 否則返回false
         * */
        boolean autoApplyRealms = isAutoApplyRealms(securityManager);

        if (autoApplyRealms) {
            //篩選其中的Realms對象【Realm或RealmFactory類型】
            Collection realms = getRealms(objects);

            if (!CollectionUtils.isEmpty(realms)) {
                //如果securityManager不是RealmSecurityManager類型則拋出異常,否則給securityManager設置Realms
                applyRealmsToSecurityManager(realms, securityManager);
            }
        }
        return securityManager;
    }
}

到此,SecurityManager實例創(chuàng)建完成,并設置到IniWebEnvironment的屬性objects[Map]中

public class IniWebEnvironment extends ResourceBasedWebEnvironment implements Initializable, Destroyable {
    protected void configure() {

        //Map對象
        this.objects.clear();

        WebSecurityManager securityManager = createWebSecurityManager();
        setWebSecurityManager(securityManager);

        //獲取shiro.ini文件中配置的'filters' 或 'urls'項的Filter,加入objects對象中
        FilterChainResolver resolver = createFilterChainResolver();
        if (resolver != null) {
            setFilterChainResolver(resolver);
        }
    }
}

到此,Shiro的初始化過程完成,在EnvironmentLoaderListener 中將會把該IniWebEnvironment對象保存在ServletContext下供后面使用。

大致流程總結

系統(tǒng)啟動的時候執(zhí)行EnvironmentLoaderListener初始化方法并創(chuàng)建WebEnvironment實例,同時將實例對象保存到ServletContext中

1,創(chuàng)建WebEnvironment對象
1)讀取web.xml中的上下文參數(shù)shiroEnvironmentClass
2)通過ServiceLoader方式查找jar包中的配置
3)是用默認的IniWebEnvironment類型

2,調用WebEnvironment的init方法初始化WebEnvironment實例
注:WebEnvironment構造犯法里面會創(chuàng)建WebIniSecurityManagerFactory實例factory。
1)從指定或默認的路徑下解析shiro.ini文件生成Ini實例
2)將Ini實例設置給factory的ini屬性
3)將默認的IniFilterChainResolverFactory設置給factory的defaultBeans(Map)屬性
4)調用factory的getInstance方法創(chuàng)建SecurityManager對象
--解析Ini對象里面的信息,創(chuàng)建Realm等對象并設置給SecurityManager實例
5)將SecurityManager返回的objects(Map)添加到WebEnvironment的objects中。

默認的SecurityManager: DefaultWebSecurityManager

后面講接著介紹Session和Realm的使用


網(wǎng)站題目:ApacheShiro源碼解讀之SecurityManager的創(chuàng)建
當前地址:http://weahome.cn/article/iigiee.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部