故事的背景是:部落客正在研究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的生成的源碼世界探究 ^-^