1.shiro有哪些隐含变量可以在shiro.ini里面直接使用呢。
2.shiro.ini的[main]结构里的语句是怎么解析的?
首先看第一点:找到 IniSecurityManagerFactory 这个类,这是一个ini安全管理创建工厂,处理ini的逻辑都在这里。首先按照语句
public static void main(String[] args) throws InterruptedException {
Factory<SecurityManager> factory = new IniSecurityManagerFactory();
SecurityManager manager = factory.getInstance();
SecurityUtils.setSecurityManager(manager);
Subject subject = SecurityUtils.getSubject();
}
先从SecurityManager manager = factory.getInstance();语句入手,找到AbstractFactory类,类里有一个需要实现的方法,这个类采用了模板方法(老外写的代码里有很多实用模板方法的),后面的类也用了模板方法。关键处理的代码直到最{IniSecurityManagerFactory # IniSecurityManagerFactory}里才有展现。
private SecurityManager createSecurityManager(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 createSecurityManager(ini, mainSection);
}
在这个方法中有取得[main] section 的 “MAIN_SECTION_NAME” 。在createSecurityManager方法内部分别调用了两个很关键的方法:
1. Map<String, ?> defaults = createDefaults(ini, mainSection);
2. Map<String, ?> objects = buildInstances(mainSection, defaults);
先创建默认的初始化容器,一个名称为securityManager,和iniRealm的对象被放入map<String, Object>容器中(这两个对象名称是可以在shiro.ini直接使用的,后面再反射里面又发现一个可以使用的变量shiro,以shiro开头的全局设置,所谓全局设置,是遍历map容器,查看对方是否有shiro.* 的 * 名称属性,如果有就设置(设置好后继续遍历,直至map容器遍历完)。非全局设置就是map容器里取得key对应的value对象,设置,对象属性值)。后面代码的实现是关于shiro.ini为啥可以直接使用,以上变量的原因。
第二点:实现过程
实现过程在Map<String, ?> objects = buildInstances(mainSection, defaults); 这个方法内部。
基本思路是先把创建对象和设置值分开,创建对象使用反射方式,设置值使用commons-beanutils类库。
shiro使用ReflectionBuilder类来完成这件事,设置值和对象创建是有顺序的,必须先创建了后面才能引用,和编写执行代码的顺序是一样的。