在 Spring Boot 應用開發中,有時候需要在非 Spring 管理的類中獲取 Spring 容器中的 Bean,這就需要獲取 ApplicationContext。本文將詳細介紹如何通過工具類的方式在 Spring Boot 應用中獲取應用上下文,並提供完整的代碼示例。
主要分為三個步驟:定義上下文工具類、在啟動類中注入 ApplicationContext、在業務代碼中調用工具類獲取 Bean。
創建一個工具類 SpringContextUtil,用於靜態保存 ApplicationContext 實例並提供獲取 Bean 的方法。
package com.alimama.config;
import org.springframework.context.ApplicationContext;
/**
* Spring 上下文獲取工具類
*/
public class SpringContextUtil {
private static ApplicationContext applicationContext;
/**
* 設置 ApplicationContext
* @param context 應用上下文
*/
public static void setApplicationContext(ApplicationContext context) {
applicationContext = context;
}
/**
* 根據 Bean ID 獲取 Bean 實例
* @param beanId Bean 名稱
* @return Bean 實例
*/
public static Object getBean(String beanId) {
return applicationContext.getBean(beanId);
}
}
在 Spring Boot 主啟動類中,通過 SpringApplication.run() 返回的 ApplicationContext 實例,調用工具類的設置方法。
package com.alimama;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import com.alimama.config.SbootConfig;
import com.alimama.config.SpringContextUtil;
import com.alimama.config.ZKConfig;
import com.alimama.quartz.InitTask;
/**
* Spring Boot 啟動入口類
*/
@ComponentScan
@SpringBootApplication
@EnableConfigurationProperties({ZKConfig.class, SbootConfig.class})
public class SbootApplication implements EmbeddedServletContainerCustomizer {
public static void main(String[] args) {
ApplicationContext applicationContext = SpringApplication.run(SbootApplication.class, args);
// 關鍵步驟:將 ApplicationContext 設置到工具類中
SpringContextUtil.setApplicationContext(applicationContext);
}
@Override
public void customize(ConfigurableEmbeddedServletContainer container) {
// 容器自定義配置
}
}
在非 Spring 管理的類(如 Quartz 任務類)中,通過工具類獲取所需的 Bean。
package com.alimama.quartz;
import java.io.IOException;
import org.phoenix.api.action.IInterfaceAPI;
import org.phoenix.api.action.InterfaceAPI;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.springframework.beans.factory.annotation.Autowired;
import com.alimama.config.SpringContextUtil;
import com.alimama.dto.TaskBean;
import com.alimama.service.IConfigService;
import com.alimama.service.impl.ConfigService;
/**
* 任務執行處理器
*/
public class TaskHandler implements Job {
// 通過工具類獲取 Spring 管理的 Bean
private ConfigService configService = (ConfigService) SpringContextUtil.getBean("configService");
private IInterfaceAPI interf = new InterfaceAPI();
@Override
public void execute(JobExecutionContext context) {
String watchDogServer = configService.getwatchDogServer();
System.out.println(watchDogServer);
}
}
SpringApplication.run() 之後調用 setApplicationContext@Autowired 注入的場景,如第三方庫回調、定時任務等通過定義靜態工具類持有 ApplicationContext 引用,我們可以在 Spring 容器之外的任何地方獲取 Spring 管理的 Bean。這種模式在處理舊代碼遷移、第三方框架整合、定時任務等場景中非常實用。