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

Spring 容器中獲取 Bean 的五種核心方式:從獨立應用到 Web 環境全覆蓋

     編輯:Java 程式設計入門

在 Spring 體系中,ApplicationContext 是 Bean 容器的核心介面。根據應用類型(獨立程序、Web 應用、單元測試)與代碼所在位置(普通類、Controller、Filter、Listener),獲取 Bean 的最佳路徑各不相同。本文系統梳理五種主流方式,附適用場景與代碼範例。

方式一:手動構建 ApplicationContext(獨立應用 / 單元測試)

適用於 main 方法、批處理任務、JUnit 測試 等非 Web 環境,或需加載多個配置文件時。

// 經典 XML 配置
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
// 或註解配置
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);

MyService bean = ctx.getBean(MyService.class);
// 使用完畢關閉容器(釋放資源、調用 destroy-method)
((ConfigurableApplicationContext) ctx).close();

優點: 完全可控;缺點: 每次調用都會重新啟動容器,生產環境嚴禁在請求鏈路中使用。

方式二:WebApplicationContextUtils(傳統 Web 環境 / Filter / Listener / Interceptor)

在 ServletContext 可獲取的場景下(如 Filter.doFilter、ServletContextListener、Struts2 Action),通過工具類從 ServletContext 屬性中取出容器。

import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.context.WebApplicationContext;

public class MyFilter implements Filter {
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
        WebApplicationContext ctx = WebApplicationContextUtils
                .getRequiredWebApplicationContext((ServletContext) req.getServletContext());
        MyService service = ctx.getBean(MyService.class);
        // ...
    }
}

getRequiredWebApplicationContext() 找不到時拋異常,getWebApplicationContext() 返回 null,按需選擇。

方式三:實現 ApplicationContextAware(任意 Spring 管理 Bean 內部)

最推薦的「非侵入式」方式:讓任意 Spring Bean 實現該接口,容器啟動時自動回調注入 ApplicationContext。

 T getBean(Class clazz) {
        return context.getBean(clazz);
    }
    public static Object getBean(String name) {
        return context.getBean(name);
    }
}

隨後在任意處(包括非 Spring 管理的工具類)調用 SpringContextHolder.getBean(MyService.class)。注意: 僅在容器完全啟動後可用,構造器/字段注入階段不可用。

方式四:@Autowired 注入 ApplicationContext(現代 Spring Boot 風格)

在 Spring 管理的 Bean 中直接注入容器引用,類型安全、IDE 友好。

方式五:繼承 Spring 基類(歷史遺留代碼常見)

  • ApplicationObjectSupport:提供 getApplicationContext()
  • WebApplicationObjectSupport:提供 getWebApplicationContext()

早期 Spring MVC Controller、HibernateDAOSupport 等均繼承此類。新項目不建議使用,耦合度高、難測試。

對比總結表

方式適用場景耦合度推薦指數
手動構建main、批處理、測試低⭐⭐⭐(特定場景)
WebApplicationContextUtilsFilter、Listener、非 Spring Bean中⭐⭐
ApplicationContextAware工具類、靜態方法、跨層調用低(靜態持有)⭐⭐⭐⭐
@Autowired 注入Service、Component、Controller 內部零(框架原生)⭐⭐⭐⭐⭐
繼承基類舊項目維護高⭐

最佳實踐建議

  1. 優先構造器注入 ApplicationContext,保證不可變、可測試。
  2. 需在靜態工具類中獲取 Bean 時,採用 ApplicationContextAware + 靜態字段模式,並提供 clear() 方法供測試清理。
  3. 避免在高頻調用路徑(如攔截器、AOP 切面)重複 getBean(),改為啟動時緩存 Bean 引用。
  4. Spring Boot 2.6+ 啟用 spring.main.allow-bean-definition-overriding=false 防止 Bean 覆蓋導致運行時不一致。

核心原則: 「依賴查找」應作為「依賴注入」的補充,而非替代。90% 以上場景下,直接 @Autowired 目標 Bean 而非容器本身。

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