获取Spring ApplicationContext容器上下文对象实例
Spring ApplicationContext 容器可以加載配置文件中定義的 bean,將所有的 bean 集中在一起,當有請求的時候分配 bean。如果說BeanFactory是Spring的心臟,那么ApplicationContext就是完整的身軀了。ApplicationContext由BeanFactory派生而來,提供了更多面向實際應用的功能。另外,它增加了企業所需要的功能,比如,從屬性文件中解析文本信息和將事件傳遞給所指定的監聽器。這個容器在 org.springframework.context.ApplicationContext interface 接口中定義。
ApplicationContext的初始化和BeanFactory有一個重大的區別:BeanFactory在初始化容器時,并未實例化Bean,直到第一次訪問某個Bean時才實例目標Bean;而ApplicationContext則在初始化應用上下文時就實例化所有單實例的Bean。因此ApplicationContext的初始化時間會比BeanFactory稍長一些,不過稍后的調用則沒有這樣的缺陷了。
傳統的獲取ApplicationContext的方式有很多種,下面小編簡單地介紹幾種常用的方式!在獲取ApplicationContext實例后,就可以調用getBean(beanName)返回Bean了。
為了驗證,假設已經構建了Spring Boot項目,在包com.eg.wiener.config中新增測試類。
package com.eg.wiener.config; import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service; @Service
public class BeanTest { @Bean
public BeanTest getBeanObj() {
BeanTest bean = new BeanTest();
System.out.println("調用方法:" + bean);
return bean;
} }
直接注入
@Autowired
private ApplicationContext ctx; @GetMapping("/getContext")
public String getContext(){
Object bean1 = ctx.getBean("getBeanObj");
return String.format(" ctx 打印bean %s", bean1);
}
啟動項目,可以找到日志:
2020-06-27 10:50:16.879 INFO 12272 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2187 ms
調用方法:com.eg.wiener.config.BeanTest@3c74aa0d
說明bean已經被注入Spring容器,默認bean的名稱就是其方法名。在瀏覽器訪問函數getContext() 時,會返回bean【getBeanObj】的信息:
ctx 打印bean com.eg.wiener.config.BeanTest@3c74aa0d
和啟動時日志打印的bean 信息一致,而且,沒有執行方法getBeanObj()。
實現ApplicationContextAware接口
創建一個實體類并實現ApplicationContextAware接口,重寫接口內的setApplicationContext方法來完成獲取ApplicationContext實例的方法,代碼如下所示:
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component; @Component
public class ApplicationContextProvider implements ApplicationContextAware {
/**
* 上下文對象實例
*/
private ApplicationContext applicationContext; @Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
} /**
* 獲取applicationContext
*
* @return
*/
public ApplicationContext getApplicationContext() {
return applicationContext;
} /**
* 通過name獲取 Bean.
*
* @param name
* @return
*/
public Object getBean(String name) {
return getApplicationContext().getBean(name);
} /**
* 通過class獲取Bean.
*
* @param clazz
* @param <T>
* @return
*/
public <T> T getBean(Class<T> clazz) {
return getApplicationContext().getBean(clazz);
} /**
* 通過name,以及Clazz返回指定的Bean
*
* @param name
* @param clazz
* @param <T>
* @return
*/
public <T> T getBean(String name, Class<T> clazz) {
return getApplicationContext().getBean(name, clazz);
}
}
在拿到ApplicationContext對象實例后就可以獲取Bean的注入實例對象,在ApplicationContextProvider類內簡單的實現了幾個方法來獲取指定的Bean實例,也可以添加更多的方法來完成更多的業務邏輯。
這里要注意ApplicationContextProvider類上的@Component注解是不可以去掉的,去掉后Spring就不會自動調用setApplicationContext方法來為我們設置上下文實例。我簡單的創建了一個API,以便測試,效果可以達到要求,代碼如下:
@Autowired
private ApplicationContextProvider provider; @GetMapping("/getContextProd")
public String getContextProd(){
Object bean = provider.getBean("getBeanObj");
return String.format(" ApplicationContextProvider 打印bean %s", bean);
}
在自定義AutoConfiguration中獲取
有時候我們需要實現自定義的Spring starter,并在自定義的AutoConfiguration中使用ApplicationContext,Spring在初始化AutoConfiguration時會自動傳入ApplicationContext,這時我們就可以使用下面的方式來獲取ApplicationContext:
@Configuration
@EnableFeignClients("com.yidian.data.interfaces.client")
public class FeignAutoConfiguration { FeignAutoConfiguration(ApplicationContext context) {
// 在初始化AutoConfiguration時會自動傳入ApplicationContext
doSomething(context);
}}
啟動時獲取ApplicationContext
在啟動Spring Boot項目時,需要調用SpringApplication.run()方法,而run()方法的返回值就是ApplicationContext,我們可以把run()方法返回的ApplicationContext對象保存下來,方便隨時使用。下面使用這個返回示例獲取Bean示例:
private static ApplicationContext applicationContext;
public static void main(String[] args) {
applicationContext = SpringApplication.run(WienerApplication.class, args);
Object bean1 = applicationContext.getBean("getBeanObj");
System.out.println(String.format("打印bean1 %s", bean1));
bean1 = applicationContext.getBean("getBeanObj");
System.out.println(String.format("打印bean2 %s", bean1));
}
項目啟動后,在日志中可以發現如下三條記錄:
調用方法:com.eg.wiener.config.BeanTest@3c74aa0d
打印bean1 com.eg.wiener.config.BeanTest@3c74aa0d
打印bean2 com.eg.wiener.config.BeanTest@3c74aa0d
通過WebApplicationContextUtils獲取
Spring提供了一個工具類WebApplicationContextUtils用于獲取ApplicationContext對象,它是Spring框架基礎包中的類,該方法必須依賴Servlet容器。
WebApplicationContextUtils.getRequiredWebApplicationContext(ServletContext sc);
WebApplicationContextUtils.getWebApplicationContext(ServletContext sc);
測試用例:
關于以上5種獲取ApplicationContext上下文對象實例的方式,大家有什么看法,歡迎留言討論,也希望大家多多點贊,祝各位生活愉快。
Reference
https://www.jianshu.com/p/ef7739a01cb0
總結
以上是生活随笔為你收集整理的获取Spring ApplicationContext容器上下文对象实例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 「Log」2023.8.23 小记
- 下一篇: 做思维导图?chatmoney轻轻松松拿