// 從 classpath 載入
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
// 從文件系統絕對路徑載入
ApplicationContext ctx = new FileSystemXmlApplicationContext("/opt/config/app-context.xml");
// 獲取 Bean
UserService service = ctx.getBean("userService", UserService.class);
適用場景:Main 方法啟動、單元測試、批處理程序、非 Web 容器環境。
缺點:每次調用構建上下文極其耗時,嚴禁在高頻調用處使用。
// 在 Controller/Filter/Interceptor 中
ServletContext sc = request.getServletContext(); // 或 session.getServletContext()
ApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(sc);
UserService service = ctx.getBean(UserService.class);
前置條件:web.xml 配置 ContextLoaderListener:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
適用場景:非 Spring 管理的類(如 Servlet、Filter、JSP、舊代碼整合)需獲取 Bean。
缺點:強依賴 Servlet API、難以單元測試、每次調用需獲取 ServletContext。
public class MyHelper extends ApplicationObjectSupport {
public void doSomething() {
ApplicationContext ctx = getApplicationContext(); // 父類提供
UserService service = ctx.getBean(UserService.class);
}
}
配置:<bean class="com.example.MyHelper"/>
原理:Spring 初始化時調用 setApplicationContext() 注入上下文。
適用場景:工具類、基類、需訪問上下文的輔助組件。
public class WebHelper extends WebApplicationObjectSupport {
public void doWebThing(HttpServletRequest req) {
WebApplicationContext wac = getWebApplicationContext();
// 可直接訪問 ServletContext
ServletContext sc = wac.getServletContext();
}
}
差異:返回 WebApplicationContext,可訪問 ServletContext、主題解析器等 Web 特有功能。
@Component
public class SpringContextHolder implements ApplicationContextAware {
private static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext ctx) throws BeansException {
context = ctx;
}
// 靜態獲取,任意處調用
public static T getBean(String name, Class clazz) {
return context.getBean(name, clazz);
}
public static T getBean(Class clazz) {
return context.getBean(clazz);
}
public static ApplicationContext getContext() { return context; }
}
優勢:
注意:必須掃描到該 Bean(@Component 或 XML 配置),否則 context 為 null。
@SpringBootApplication
public class App {
public static void main(String[] args) {
ConfigurableApplicationContext ctx = SpringApplication.run(App.class, args);
// 程式化獲取
UserService service = ctx.getBean(UserService.class);
}
}
// 組件中注入(標準方式,非手動獲取)
@Service
public class OrderService {
private final UserService userService; // 建構子注入
public OrderService(UserService userService) { this.userService = userService; }
}
| 場景 | 推薦方式 | 關鍵點 |
|---|---|---|
| Main 方法/批處理/測試 | 方式一 | 手動構建上下文 |
| Servlet/Filter/JSP 非 Spring 類 | 方式二 | WebApplicationContextUtils |
| 通用工具類/基類/框架擴展 | 方式三/四 | 繼承 *ObjectSupport |
| 任意非 Spring 類靜態獲取(最通用) | 方式五 | ApplicationContextAware + 靜態 holder |
| Spring 管理的 Service/Component/Controller | 建構子/Setter/@Autowired 注入 | 首選依賴注入,避免手動獲取 |
ApplicationContextAware 靜態 Holder 是通用性最強、副作用最小的方案。ClassPathXmlApplicationContext。