如何構建Subejct
上一篇我們講了Subject這個類,知道了在每一次訪問時都會創建一個新的subject,而這個subject會綁定到ThreadContext上,然後通過SecurityUtils在程序的任何地方調用getSubject時都會返回同一個subject。以用戶登錄時的例子分析源碼:
通過查看SecurityUtils源碼可以看到,它是通過從ThreadContext上獲取Subject,如果存在直接返回,否則通過Subject.Builder().buildSubject()去創建Subject,創建後再將Subject綁定到ThreadContext
接着通過查看Subject源碼發現,其實它是一個interface,其中聲明瞭一個Builder類
Builder類中有這麼一個方法buildSubject(),它通過shiro核心組件SecurityManager調用createSubject()去創建需要的Subject,其中通過傳入參數可以知道,它是使用SubjectContext來構建我們需要的Subject
查看SubjectContext源碼可以知道其實它就是一個Map
DefaultSubjectContext是SubjectContext的實現類,又是MapContext的子類
而這一系列過程都是爲了將構建subject的所有屬性都組織到一起,然後傳遞給一個subjectFactory,用於構建一個subject
在DefaultSecurityManager中,通過doCreateSubject()方法將SubjectContext傳遞給SubjectFactory
通過SubjectFactory構建Subject,返回Subject的實現類DelegatingSubject,以及DelegatingSubject的子類WebDelegatingSubject