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

Spring Web 容器中獲取 Bean 的正確姿勢

     編輯:程式設計綜合問答

場景對比

獨立應用(已知)

ApplicationContext ctx = new ClassPathXmlApplicationContext("config.xml");
Quest quest = (Quest) ctx.getBean("quest");

Web 環境(問題場景)

配置了 `ContextLoaderListener`,容器隨 Tomcat 啟動初始化。測試類中如何獲取 Bean?

標準解決方案

方案一:WebApplicationContextUtils(推薦)

// 在 Servlet、Filter、Listener、Controller 中
WebApplicationContext wac = WebApplicationContextUtils.getWebApplicationContext(servletContext);
Quest quest = wac.getBean("quest", Quest.class);

方案二:ContextLoader(Spring 3.0+)

WebApplicationContext wac = ContextLoader.getCurrentWebApplicationContext();
Quest quest = wac.getBean("quest", Quest.class);

方案三:實現 ApplicationContextAware(注入式)

 T getBean(String name, Class type) {
        return context.getBean(name, type);
    }
}

// 任意處調用
Quest quest = BeanAccessor.getBean("quest", Quest.class);

測試類特別說明

若是**單元測試**,不要依賴 Web 容器,應獨立加載上下文:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
public class QuestTest {
    @Autowired
    private Quest quest;
    
    @Test
    public void test() { ... }
}

核心原理

  • `ContextLoaderListener` 啟動時將 `WebApplicationContext` 存入 `ServletContext` 屬性
  • `ContextLoader.getCurrentWebApplicationContext()` 內部調用 `WebApplicationContextUtils`
  • 鍵名:`WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE`

避坑指南

  • 不要在靜態代碼塊/構造函數中獲取 Bean(容器未就緒)
  • 區分「根容器」與「Servlet 容器」,`getCurrentWebApplicationContext()` 獲取根容器
  • 優先使用依賴注入(`@Autowired`),避免手動 `getBean`
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved