SpringBoot 獲取上下文,獲取bean的幾種中方式


傳統Spring項目

在寫傳統的spring項目中,一般通過初始化抽象類AbstractXmlApplicationContext 的實現類,並傳入spring.xml,來獲取應用上下文,最終通過getBean方法獲取bean,如下:

	ApplicationContext app1 = new FileSystemXmlApplicationContext("applicationContext.xml");
	app1.getBean("beanName");
	ApplicationContext app2 = new ClassPathXmlApplicationContext("applicationContext.xml");
	app2.getBean("beanName");

SpringBoot項目獲取bean的幾種方式

1. 通過啟動類中返回的上下文獲取

	ConfigurableApplicationContext app = SpringApplication.run(BeanDemoApplication.class, args);
	SpringUtil.setAppContext(app);
public class SpringUtil {

	private static ApplicationContext appContext;
	
	public static void setAppContext(ApplicationContext appContext) {
		SpringUtil.appContext = appContext;
	}
	
	public static ApplicationContext getAppContext() {
		return appContext;
	}
	
}

在第三方類中使用:

	ApplicationContext appContext = SpringUtil.getAppContext();
	appContext.getBean("beanName");

2. 通過工具類獲取

RequestContextUtils.findWebApplicationContext(HttpServletRequest request),WebApplicationContextUtils.getWebApplicationContext(ServletContext sc)
a. 在controller中傳入request,例如:

    public String test(HttpServletRequest request,HttpServletRequest response) {
		WebApplicationContext wc = RequestContextUtils.findWebApplicationContext(request);
		wc.getBean("beanName");
		
		WebApplicationContext wc2 = WebApplicationContextUtils.getWebApplicationContext(request.getServletContext());
		wc2.getBean("beanName");
	}

b. 在service中或者其他后端服務中獲取:

HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
WebApplicationContext wc = RequestContextUtils.findWebApplicationContext(request);
WebApplicationContext wc2 = WebApplicationContextUtils.getWebApplicationContext(request.getServletContext());

wc.getBean("beanName");
wc2.getBean("beanName");

3. 通過實現接口ApplicationContextAware

@Component
public class TestApplicationContextAware implements ApplicationContextAware {

	private  ApplicationContext applicationContext;

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		this.applicationContext = applicationContext;
	}
	
	public Object getBean(String beanName) {
		return applicationContext.getBean(beanName);
	}
	
	public ApplicationContext getApplicationContext() {
		return applicationContext;
	}

}

在其他類中調用

	@Autowired
	private TestApplicationContextAware app;
	public void testMethod() {
		app.getBean("beanName");
	}

4. 通過繼承抽象類:ApplicationObjectSupport,WebApplicationObjectSupport

原理參考第3點

5. 其他方式

在網上看,發現也可以直接調用:ContextLoader.getCurrentWebApplicationContext(),或者 ContextLoaderListener.getCurrentWebApplicationContext() 其實都是調用同一段代碼,如下:

	@Nullable
	public static WebApplicationContext getCurrentWebApplicationContext() {
		ClassLoader ccl = Thread.currentThread().getContextClassLoader();
		if (ccl != null) {
			WebApplicationContext ccpt = currentContextPerThread.get(ccl);
			if (ccpt != null) {
				return ccpt;
			}
		}
		return currentContext;
	}

說明:目前通過這種方式獲取上下文為null,從代碼可以看出,上下文是通過currentContextPerThread.get(ccl) 來獲取的,而currentContextPerThread緩存是通過方法contextInitialized(ServletContextEvent event) 來初始化的,至於為何獲取為空,參考:https://www.cnblogs.com/xysn/p/14863896.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM