點擊上方“程序員蝸牛g”,選擇“設為星標”
跟蝸牛哥一起,每天進步一點點
程序員蝸牛g
大廠程序員一枚 跟蝸牛一起 每天進步一點點
33篇原創內容
公眾號
在Spring中,ApplicationContext接口是Spring IoC容器的核心接口之一,用於管理和組織應用程序中的Bean。它擴展了BeanFactory接口,此外它還擴展了其他接口,以更面向應用程序框架的風格提供額外的功能,其中包括如下功能:
- 通過 MessageSource 接口以 i18n 風格訪問消息
- 通過 ResourceLoader 接口訪問資源,如 URL 和文件
- 通過使用 ApplicationEventPublisher 接口,向實現 ApplicationListener 接口的 Bean 發佈事件
- 通過 HierarchicalBeanFactory 接口加載多個(分層)上下文,讓每個上下文都專注於一個特定層,例如應用程序的web層
接下來將詳細介紹上面這些功能
2. 實戰案例
2.1 國際化資源訪問
ApplicationContext 接口擴展了一個名為 MessageSource 的接口,因此提供了國際化("i18n")功能。
Spring容器啓動時,會自動搜索上下文中定義的 MessageSource Bean。該 Bean 的名稱必須是 messageSource。如果找到了這樣一個 Bean,對資源所有調用都會委託給消息源。如果沒有找到消息源,則會實例化一個空的 DelegatingMessageSource,以便能夠調用MessageSource方法。
在SpringBoot環境中自動為我們配置了一個MessageSource,而我們只需要做如下資源配置即可:
spring:
messages:
basename: i18n/message
注:這裏可以配置多個basename,實用逗號","分割即可。如上配置,我們在對應的src下建立對應的資源文件
#有佔位符的資源配置
pack.name=\u5F20\u4E09,\u4ECA\u5E74{0}\u5C81
使用
@Resource
private ApplicationContext context ;
// 獲取資源
this.context.getMessage("pack.name", new Object[]{22}, Locale.CHINA)
而在SpringBoot環境下,我們可以通過如下方式訪問資源
private final ApplicationContext context ;
@GetMapping("/index")
public Object index() {
return this.context.getMessage("pack.name", newObject[] {22},
LocaleContextHolder.getLocale()
) ;
}
通過LocaleContextHolder訪問當前請求的Locale。
2.2 事件發佈
ApplicationContext 中的事件處理是通過 ApplicationEvent 類和 ApplicationListener 接口提供的。如果在上下文中定義註冊了 ApplicationListener 接口的 Bean,那麼每次 ApplicationEvent 發佈到 ApplicationContext 時,都會通知該 Bean。從本質上講,這就是標準的觀察者設計模式。
// 自定義事件監聽器
@Component
public class PackApplicationListener implements ApplicationListener<PackApplicationEvent> {
@Override
public void onApplicationEvent(PackApplicationEvent event) {
// TODO
}
}
// 自定義事件對象
public class PackApplicationEvent extends ApplicationEvent{
public PackApplicationEvent(Object source) {
super(source);
}
}
通過ApplicationContext發佈事件
@Resource
private ApplicationContext context ;
this.context.publishEvent(new PackApplicationEvent(this)) ;
有關事件的更多知識,請查看下面這篇文章
【專家級】Spring事件機制,深入剖析,提升你的技術水平!
2.3 訪問資源
ApplicationContext繼承了ResourceLoader接口,可用於加載 Resource 對象。
@Resource
private ApplicationContext context ;
this.context.getResource("pack.properties") ;
getResource方法參數可以添加前綴,具體支持如下模式:
- 支持完全限定的url,例如:“file:C:/test.dat”
- 支持類路徑偽url,例如:“classpath:test.dat”
- 支持相對文件路徑,例如:“WEB-INF/test.dat”
對於資源訪問,我們還可以通過如下方式:
public class ResourceService implements ResourceLoaderAware{
private ResourceLoader loader ;
public void getRes(String location){
this.loader.getResource(location) ;
}
public void setResourceLoader(ResourceLoader resourceLoader){
this.loader = resourceLoader ;
}
}
以上是比較常用的獲取資源方式。
2.4 應用啓動跟蹤
使用特定指標跟蹤應用程序的啓動步驟有助於瞭解啓動階段的時間使用情況,同時也可用於更好地瞭解整個上下文生命週期。AbstractApplicationContext(及其子類)使用 ApplicationStartup 工具,該工具收集有關各啓動階段的 StartupStep 數據,其中包括了以下啓動階段的統計:
- 應用程序上下文生命週期(基礎包掃描、配置類管理)
- bean 生命週期(實例化、smart初始化、後處理)
- 應用事件處理
在SpringBoot環境,我們需要手動配置ApplicationStartup,默認的沒有任何記錄功能
SpringApplication application = new SpringApplication(PackApplication.class) ;
// 設置,BufferingApplicationStartup該具備統計功能
application.setApplicationStartup(new BufferingApplicationStartup(2048)) ;
application.run(args);
通過設置BufferingApplicationStartup後,還需要藉助actuator來查看具體的統計信息,通過/startup接口查看統計信息
在我們的實際業務代碼中也可以記錄業務相關的統計信息
@Service
public class BusinessService implements SmartInitializingSingleton {
private final AbstractApplicationContext context ;
public BusinessService(AbstractApplicationContext context) {
this.context = context ;
}
@Override
public void afterSingletonsInstantiated() {
// 執行初始化動作
ApplicationStartup bsStartup = this.context.getApplicationStartup() ;
StartupStep ss = bsStartup.start("com.pack.test.startup.BusinessService") ;
// TODO
// 這裏模擬動作
TimeUnit.SECONDS.sleep(2) ;
ss.end() ;
}
}
統計結果
如果這篇文章對您有所幫助,或者有所啓發的話,求一鍵三連:點贊、轉發、在看。
關注公眾號:woniuxgg,在公眾號中回覆:筆記 就可以獲得蝸牛為你精心準備的java實戰語雀筆記,回覆面試、開發手冊、有超讚的粉絲福利