shiro攔截器處理鏈執行順序
A1:根據<filter-name>到spring容器查找實現bean,並根據配置把相應的url請求委托給它去執行。
A21:SpringShiroFilter是ShiroFilterFactoryBean的內部類,會執行doFilter()方法。A21沒有重寫父類的doFilter方法,因此會去尋找父類中的實現,最終調用OncePerRequestFilter(A23)的該方法。
A23:執行doFilter方法,調用doFilterInternal()方法。
A31:doFilterInternal()方法,OncePerRequestFilter的抽象方法,會去子類中尋找它的實現,最終在子類AbstractShiroFilter(A32)找到實現並執行。
B11:AbstractShiroFilter執行doFilterInternal()方法后會調用excuteChain()里面的chain.doFilter()
B12:AbstractShiroFilter(B11)方法中的chain.doFilter()會調用它的(B12)doFilter()。它沒有重寫父類的doFilter方法,因此會去尋找父類中的實現,最終調用OncePerRequestFilter(B18)的該方法。這個B12可以是表單攔截器,也可以是其它攔截器實現。
B21:doFilterInternal()方法,OncePerRequestFilter的抽象方法,會去子類中尋找它的實現,最終在子類AdviceFilter(B22)找到實現並執行。
B31:AdviceFilter執行doFilterInternal()方法后調用,會調用preHandle()方法,該方法在子類PathMatchingFilter(B32)中實現。
B33:PathMatchingFilter執行preHandle()時調用了onpreHandle()方法。
onpreHandle隨后會繼續調用其它方法.......... 最終調用onAccessDenied方法,該方法在子類B99中實現了
onPreHandle主要流程:
1、首先判斷是否已經登錄過了,如果已經登錄過了繼續攔截器鏈即可;
2、如果沒有登錄,看看是否是登錄請求,如果是get方法的登錄頁面請求,則繼續攔截器鏈(到請求頁面),否則如果是get方法的其他頁面請求則保存當前請求並重定向到登錄頁面;
3、如果是post方法的登錄頁面表單提交請求,則收集用戶名/密碼登錄即可,如果失敗了保存錯誤消息到“shiroLoginFailure”並返回到登錄頁面;
4、如果登錄成功了,且之前有保存的請求,則重定向到之前的這個請求,否則到默認的成功頁面。