《shiro源碼分析【整合spring】》(一)——Shiro初始化

  • 注:以下分析是整合了spring框架之后的整個工作流程分析。

前言 Shiro簡介

這是shiro官方給出的功能模塊詳細的介紹可以跳轉(zhuǎn)到張開濤老師的博客:我是傳送門

本人打算從整個shiro工作的流程出發(fā),對其每一步的工作進行追蹤玻驻,因此側(cè)重于源碼的分析,對于具體如何使用识腿,大家也可以參考張開濤老師的博客牲阁。

由于本人剛參加工作,經(jīng)驗還不夠夭禽,如有錯誤的地方,望各位不吝賜教谊路。

一讹躯、Shiro初始化

在未整合spring之前,shiro在應用到web應用時,是通過對訪問路徑的過濾來進行權(quán)限控制的潮梯,也就會再web.xml中直接定義過濾器即可(mapping配置省略)骗灶,如下:

<filter>
    <filter-name>ShiroFilter</filter-name>
    <filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
</filter>

shiro的初始化工作是在web.xml中設置監(jiān)聽器完成的,配置如下:

<listener>
    <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
</listener>

而在整合spring之后秉馏,shiro為了將整個生命周期托管給spring耙旦,當然包括初始化的工作,有點不同的是過濾器采用了Spring的代理過濾器萝究。

<filter>
    <filter-name>shiroFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    <init-param>
        <!--允許代理注入免都,方便spring容器管理filter的生命周期,詳細情況帆竹,大家自行百度-->
        <param-name>targetFilterLifecycle</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>

我們就從這里開始跟蹤一下spring的代理過濾器是怎么個流程绕娘。

1、代理過濾器初始化

配置是按照官網(wǎng)的配置來進行的栽连。這里的啟動調(diào)用的是這個代理類的無參的構(gòu)造方法险领。
接下來是對真實的過濾器進行初始化:調(diào)用initFilterBean()方法。
我們來看一下這個方法的代碼秒紧。


@Override
protected void initFilterBean() throws ServletException {
    synchronized (this.delegateMonitor) {
        if (this.delegate == null) {
            // 如果目標bean的名字沒有指定绢陌,那么就使用過濾器的名字,
            // 也就是前面配置:<filter-name>shiroFilter</filter-name>(注意是shiroFilter)
            if (this.targetBeanName == null) {
                this.targetBeanName = getFilterName();
            }
            // 這里就可以根據(jù)目標bean的名字熔恢,從spring工廠中獲取相應的實例了下面。
            // 至于具體如何獲取實例,稍后會進行說明
            WebApplicationContext wac = findWebApplicationContext();
            if (wac != null) {
                this.delegate = initDelegate(wac);
            }
        }
    }
}

  • 注意:spring的代理過濾器有一個懶加載的過程绩聘,因此在執(zhí)行doFilter()的時候會判斷一次是否有初始化Filter類沥割。具體代碼如下(應該很容易看懂的,就不詳細說明了):
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
        throws ServletException, IOException {

    // 懶加載
    Filter delegateToUse = this.delegate;
    if (delegateToUse == null) {
        synchronized (this.delegateMonitor) {
            if (this.delegate == null) {
                WebApplicationContext wac = findWebApplicationContext();
                if (wac == null) {
                    throw new IllegalStateException("No WebApplicationContext found: no ContextLoaderListener registered?");
                }
                this.delegate = initDelegate(wac);
            }
            delegateToUse = this.delegate;
        }
    }
    
    // 執(zhí)行真正的過濾器的doFilter()方法
    invokeDelegate(delegateToUse, request, response, filterChain);
}

2凿菩、shiroFilter實例的創(chuàng)建

shiroFilter在集成spring之后的創(chuàng)建是由:java org.apache.shiro.spring.web.ShiroFilterFactoryBean這一工廠類進行實例化的机杜。

2.1、工廠類的初始化配置

這一工廠類的初始化是由spring進行的衅谷,我們來看看配置即可椒拗。

<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
    <!--shiro的核心就是這個manager,這里是說明過濾器的初始化工作获黔,就暫不進行詳細分析-->
    <property name="securityManager" ref="securityManager"/>
    <property name="loginUrl" value="/index/login"/>
    <property name="filterChainDefinitions">
        <value>
            /static/**=anon
            /logout=logout
        </value>
    </property>
</bean>
  • 注意這里的id要與web.xml中代理過濾器的filter-name保持一致

至此蚀苛,shiro的初始化配置工作算是基本結(jié)束了。但是想必有些人會覺得迷茫玷氏,你明明使用的java org.apache.shiro.spring.web.ShiroFilterFactoryBean堵未,這是一個工廠類,而我們需要的應該是一個javax.servlet.Filter類才對盏触。一開始我也很迷糊渗蟹,不知道咋地块饺,在突然想起一個鬼東西,spring的什么鬼工廠雌芽,然后就去找spring的源碼了授艰。然后就找到這么一個東西,現(xiàn)在貼出來給大家看看(相信大家一看就能懂了)世落,順便也復習一下spring淮腾。

這個類是:java org.springframework.beans.factory.support.StaticListableBeanFactory

graph BT
org.springframework.beans.factory.support.StaticListableBeanFactory-->org.springframework.beans.factory.ListableBeanFactory
org.springframework.beans.factory.ListableBeanFactory-->org.springframework.beans.factory.BeanFactory
@Override
public Object getBean(String name) throws BeansException {
    String beanName = BeanFactoryUtils.transformedBeanName(name);
    Object bean = this.beans.get(beanName);
    
    if (bean == null) {
        throw new NoSuchBeanDefinitionException(beanName,
        "Defined beans are [" + StringUtils.collectionToCommaDelimitedString(this.beans.keySet()) + "]");
    }
    
    // Don't let calling code try to dereference the
    // bean factory if the bean isn't a factory
    if (BeanFactoryUtils.isFactoryDereference(name) && !(bean instanceof FactoryBean)) {
        throw new BeanIsNotAFactoryException(beanName, bean.getClass());
    }
    
    if (bean instanceof FactoryBean && !BeanFactoryUtils.isFactoryDereference(name)) {
        try {
            // 大家注意這里
            return ((FactoryBean<?>) bean).getObject();
        }
        catch (Exception ex) {
            throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
        }
    }
    else {
        return bean;
    }
}
  • 這篇其實還沒有涉及到shiro的源碼,都還是spring的知識屉佳。在完成了初始化工作之后谷朝,我們來看看shiro是怎樣進行驗證的,下圖是shiro官方提供的驗證步驟忘古。(更新中)

簡化驗證流程圖。

細化驗證流程圖(好像不是那么詳細哈哈诅诱,看有沒有時間髓堪,自己做一張更詳細的)

《shiro源碼分析【整合spring】》(二)——Shiro過濾器

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市娘荡,隨后出現(xiàn)的幾起案子干旁,更是在濱河造成了極大的恐慌,老刑警劉巖炮沐,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件争群,死亡現(xiàn)場離奇詭異,居然都是意外死亡大年,警方通過查閱死者的電腦和手機换薄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來翔试,“玉大人轻要,你說我怎么就攤上這事】衙澹” “怎么了冲泥?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長壁涎。 經(jīng)常有香客問我凡恍,道長,這世上最難降的妖魔是什么怔球? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任嚼酝,我火速辦了婚禮,結(jié)果婚禮上竟坛,老公的妹妹穿的比我還像新娘革半。我一直安慰自己碑定,他們只是感情好,可當我...
    茶點故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布又官。 她就那樣靜靜地躺著延刘,像睡著了一般。 火紅的嫁衣襯著肌膚如雪六敬。 梳的紋絲不亂的頭發(fā)上碘赖,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天,我揣著相機與錄音外构,去河邊找鬼普泡。 笑死,一個胖子當著我的面吹牛审编,可吹牛的內(nèi)容都是我干的撼班。 我是一名探鬼主播,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼垒酬,長吁一口氣:“原來是場噩夢啊……” “哼砰嘁!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起勘究,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤矮湘,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后口糕,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體缅阳,經(jīng)...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年景描,在試婚紗的時候發(fā)現(xiàn)自己被綠了十办。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,646評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡超棺,死狀恐怖橘洞,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情说搅,我是刑警寧澤炸枣,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站弄唧,受9級特大地震影響适肠,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜候引,卻給世界環(huán)境...
    茶點故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一侯养、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧澄干,春花似錦逛揩、人聲如沸柠傍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽惧笛。三九已至,卻和暖如春逞泄,著一層夾襖步出監(jiān)牢的瞬間患整,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工喷众, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留各谚,地道東北人。 一個月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓到千,卻偏偏與公主長得像昌渤,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子憔四,可洞房花燭夜當晚...
    茶點故事閱讀 43,514評論 2 348

推薦閱讀更多精彩內(nèi)容