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

Spring JdbcTemplate 在靜態方法中無法注入的解決方案:SpringContextUtil 模式

     編輯:程式設計綜合問答

問題現象

嘗試在工具類 UtilsDao 的靜態方法中使用 @Autowired 注入 JdbcTemplate,發現靜態字段始終為 null。

根本原因

Spring 容器管理的是 Bean 實例,依賴注入(DI)發生在 Bean 創建過程中。靜態字段屬於類,不屬於實例,Spring 無法對靜態字段執行標準注入。即使加上 @Autowired,容器也會忽略。

錯誤代碼示例

public class UtilsDao {
    @Autowired @Qualifier("JdbcTemplate")
    private static JdbcTemplate jdbcTemplate; // 永遠為 null
    public static JSONArray queryList2Json(String sql) { ... }
}

正確方案:SpringContextUtil 獲取 Bean

1. 實現 ApplicationContextAware

@Component
public class SpringContextUtil implements ApplicationContextAware {
    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext context) throws BeansException {
        applicationContext = context;
    }

    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    @SuppressWarnings("unchecked")
    public static <T> T getBean(String name) {
        return (T) applicationContext.getBean(name);
    }

    public static <T> T getBean(Class<T> clazz) {
        return applicationContext.getBean(clazz);
    }
}

2. 在靜態方法中通過工具類獲取

public class UtilsDao {
    public static JSONArray queryList2Json(String sql) {
        JdbcTemplate jdbcTemplate = SpringContextUtil.getBean(JdbcTemplate.class);
        List<Map<String, Object>> lists = jdbcTemplate.queryForList(sql);
        return JSONArray.fromObject(lists);
    }
}

替代方案對比

方案優點缺點適用場景
SpringContextUtil (推薦)通用、非侵入、支援任意 Bean運行時才能檢測 Bean 是否存在工具類、靜態方法、非 Spring 管理類
靜態 setter 手動注入編碼簡單需在配置類/初始化器中顯式調用,易忘、耦合強極簡項目、單一工具類
改為實例方法 + @Component標準 DI、編譯期檢查調用處需注入 UtilsDao 實例新代碼、可重構時
@PostConstruct 初始化靜態字段利用實例方法注入後賦值給靜態字段本質仍是靜態字段,並發安全需自行保證舊代碼最小改動

注意事項

  • SpringContextUtil 必須被 Spring 掃描到(@Component + 掃描路徑正確)。
  • 獲取 Bean 時若 Bean 作用域為 prototype,每次調用會創建新實例,注意效能。
  • 單元測試時需手動設置 applicationContext 或使用 @SpringBootTest 整合測試。

總結

Spring 不支援直接注入靜態字段。標準解法是實現 ApplicationContextAware 封裝 SpringContextUtil,在靜態方法中通過 getBean() 獲取實例。若條件允許,優先將工具類改為 Spring Bean 使用實例方法,更符合依賴倒置原則。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved