首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Shiro Realm @Autowired 注入失效根因分析:Spring 父子容器掃描衝突與配置調優

     編輯:Java 綜合教學

Shiro Realm @Autowired 注入失效根因分析

專案中 Shiro Realm 實作類使用 @Autowired 注入 Service 失效 (為 null)。經排查,根因是 **Spring 父子容器掃描順序衝突**:DispatcherServlet 容器在事務配置前掃描 Service,導致事務失效,同時 Realm 實例化時機早於 Service 注入完成。

現象與臨時方案

  • 方案一:ApplicationContextUtils.getApplicationContext().getBean() 手動查找。
  • 方案二:Setter 方法設為 static 靜態欄位注入 (惡心但有效)。

根因深度分析

專案採用經典 ContextLoaderListener (根容器) + DispatcherServlet (子容器) 架構:

  • 根容器 (ApplicationContext):負責資料源、事務、Service、DAO、Shiro 等核心 Bean。
  • 子容器 (DispatcherServlet):負責 Controller、ViewResolver、HandlerMapping 等 Web Bean。
  • **錯誤配置**:所有掃描 (component-scan) 集中在子容器,根容器僅載入 shiro.xml,導致:
    1. Service 被子容器掃描,但事務配置 (tx:annotation-driven) 在掃描**之後**載入,Service 失去事務增強。
    2. Realm 由 Shiro (根容器管理) 實例化,需注入 Service (子容器),父容器不可見子容器 Bean → 注入失敗。

正確配置調整

根容器 applicationContext.xml (或 root-context.xml)

<context:component-scan base-package="com.example" /> <!-- 掃描 Service、DAO、Realm 等 -->
<import resource="mybatis.xml" />           <!-- 資料源、SqlSessionFactory、事務管理器 -->
<import resource="redis-context.xml" />
<import resource="spring-shiro-web.xml" />   <-- Shiro 配置,含 Realm Bean 定義 -->

子容器 spring-mvc.xml (DispatcherServlet)

<context:component-scan base-package="com.example">
    <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service" />
</context:component-scan>
<!-- 僅掃描 Controller、Interceptor 等 Web 組件 -->

調整效果

  • 根容器飽滿:事務、資料源、Service、Realm 統一管理。
  • 子容器輕量:僅負責 Web 層,避免重複掃描。
  • Realm 正常注入 Service,事務生效,移除臨時方案。

關鍵原則

  1. 核心業務 Bean (Service/DAO/資料源/事務/安全) 放入**根容器**。
  2. Web 層 Bean (Controller/Resolver/Interceptor) 放入**子容器**。
  3. 子容器掃描**排除** Service/Repository 等核心註解,避免雙重代理。
  4. 單 Servlet 專案可考慮合併為單一容器,簡化結構。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved