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

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

     編輯:Java 相關知識

在 Spring 應用開發中,如何從非 Spring 管理的程式碼(如舊系統整合、工具類、第三方庫回呼)獲取容器管理的 Bean,是常見且關鍵的問題。本文系統整理五種標準獲取策略,涵蓋獨立應用、Web 環境、繼承體系、感知介面四大場景,並說明適用條件與最佳實踐。

前置知識:ApplicationContext 核心角色

ApplicationContext 是 Spring 容器核心介面,提供 getBean(name)、getBean(type)、getBeansOfType(type) 等查詢方法。所有獲取 Bean 的本質,都是先拿到 ApplicationContext(或 WebApplicationContext)參考。

方式一:手動建立容器(獨立應用、測試、批次程式)


// 載入檔案系統路徑配置
ApplicationContext ctx = new FileSystemXmlApplicationContext("config/applicationContext.xml");

// 或載入類路徑配置
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

// 獲取 Bean
MyService service = ctx.getBean("myService", MyService.class);

適用:無 Servlet 容器的獨立 JVM 程式(main 方法、批次作業、單元測試不使用 @ContextConfiguration 時)。
缺點:每次呼叫會重新啟動容器,極度低效,**嚴禁在長期運行程式中重複建立**。

方式二:WebApplicationContextUtils(傳統 Web 專案、Servlet/Filter/Listener)


import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.context.WebApplicationContext;
import javax.servlet.ServletContext;

// 在 ServletContext 可取得處(Servlet.init、Filter.doFilter、Listener.contextInitialized)
WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
// 或允許 null
WebApplicationContext wac = WebApplicationContextUtils.getWebApplicationContext(servletContext);

MyService service = wac.getBean(MyService.class);

適用:傳統 web.xml 配置的 Spring MVC 專案、需在 Servlet/Filter/Listener 中獲取 Bean。
關鍵:需持有 ServletContext 參考,通常從 ServletConfig.getServletContext() 或 HttpSession.getServletContext() 取得。

方式三:繼承 ApplicationObjectSupport(Spring 提供的便利基類)


public class MyHelper extends ApplicationObjectSupport {
    public void doWork() {
        ApplicationContext ctx = getApplicationContext(); // 受保護方法
        MyService service = ctx.getBean(MyService.class);
        service.execute();
    }
}

機制:Spring 容器啟動時,會自動呼叫 setApplicationContext() 將容器注入此基類。
適用:需容器感知的工具類、協助類,且願意繼承 Spring 基類(耦合 Spring API)。

方式四:繼承 WebApplicationObjectSupport(Web 環境專用)


public class MyWebHelper extends WebApplicationObjectSupport {
    public void doWork() {
        WebApplicationContext wac = getWebApplicationContext();
        MyService service = wac.getBean(MyService.class);
    }
}

差異:提供 getWebApplicationContext() 直接回傳 Web 專用上下文,可存取 ServletContext 等 Web 資源。

方式五:實作 ApplicationContextAware(最推薦、非侵入式)


@Component // 或在 XML 定義 bean
public class MyBeanHolder implements ApplicationContextAware {
    private static ApplicationContext context;
    
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {
        context = applicationContext;
    }
    
    public static  T getBean(Class type) {
        return context.getBean(type);
    }
    
    public static  T getBean(String name, Class type) {
        return context.getBean(name, type);
    }
}

機制:Spring 掃描到實作 ApplicationContextAware 的 Bean,自動回呼 setApplicationContext() 注入容器。
優點:不強制繼承基類、靜態方法方便全域呼叫、符合依賴倒置原則。
注意:靜態持有容器參考需確保單例 Bean、容器啟動完成後才呼叫,避免循環依賴或空指標。

現代化替代方案(Spring Boot 2.0+)

  • @Autowired ApplicationContext:直接注入容器至任何 Spring Bean,無需實作介面。
  • ApplicationContextProvider 單例:官方範例模式,封裝靜態 getApplicationContext()。
  • 避免在 @Configuration / @Bean 方法中獲取 Bean:容器尚未完全初始化,易導致循環依賴或 BeanCreationException。

選擇指南

場景推薦方式關鍵限制
獨立 JVM 程式(main/批次/測試)方式一(僅啟動一次)勿重複建立容器
傳統 Web 專案 Servlet/Filter方式二需 ServletContext
工具類、第三方庫回呼方式五(ApplicationContextAware)需為 Spring Bean、啟動後可用
Spring Boot 專案任意 Bean 內部@Autowired ApplicationContext最簡潔、類型安全
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved