故事的背景是:博主正在研究shiro的原理及源码。
本篇博文研究的代码块为:
// 创建 securityManager工厂,通过配置文件ini创建
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:Shiro.ini");
SecurityManager securityManager = factory.getInstance();
附上Shiro.ini文件的内容
[users]
user1= 123, root, admin
user2 = 456, user
[roles]
root = *
admin = video:delete,video:add,video:update
user = video:find,video:buy
好的,话不多说,直接进入正题
第一行代码之源码的世界:
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:Shiro.ini");
第一步:我们在使用new IniSecurityManagerFactory("classpath:Shiro.ini")时,会去调用IniSecurityManagerFactory中的new Ini().fromResourcePath(String path),想以此来获取一个Ini实例。
第二步:在Ini.fromResourcePath()中,会调用Ini类的loadFromPath(String path)来获取到一个ini实例,这个实例中会包含一个map,这个map的内容就是我们Shiro.ini文件中[users]和[roles]中的信息了。
第三步:在获取到了ini实例之后,又回到了IniSecurityManagerFactory类中,先是调用自身的构造方法获取一个factory实例,然后就去调用其父类IniFactorySupport的setIni(ini)方法,去初始化IniFactorySupport中的ini变量。
至此,我们的第一行代码解析完毕。
第二行代码之源码的世界:
SecurityManager securityManager = factory.getInstance();
第四步:通过调用factory.getInstance()方法,去调用AbstracFactory类的子类IniFactorySupport的createInstance()去获取securityManager实例。
第五步:在IniFactorySupport类中,先通过resolveIni()获取第三步初始化的ini实例,然后调用其子类IniSecurityManagerFactory的createInstance(Ini ini)去获取securityManager
第六步:在IniSecurityManagerFactory的createInstance()方法中,会调用createSecurityManager(Ini ini)方法
第七步:在createSecurityManager(Ini ini)方法中,主要通过以下几个步骤最终得到一个SecurityManager,并设置其realms
先是通过buildInstance()方法,根据ini得到一个map,map中会有我们Shiro.ini文件的相关配置信息。
然后调用getSecurityManager()方法获取bean,此处获取到的是DefaultSecurityManager的bean。
然后根据上面得到的map创建realms。具体源码为:Collection<Realm> realms = getRealms(map);
然后调用applyRealmsToSecurityManager(realms, securityManager)方法。
在applyRealmsToSecurityManager()方法中,通过调用DefaultSecurityManager的setRealms(realms)方法,将realms设置到securityManager中,并返回securityManager实例。
到此,第二行的代码也解析完毕啦。
这也是博主本次研究的心得,给大家分享一下~
后续会持续更新,带来一些默认realm的生成的源码世界探究 ^-^