這篇文章主要來分享Springboot的擴展點之ApplicationContextAwareProcessor,而ApplicationContextAwareProcessor本身并不是擴展點,而是BeanPostProcessor擴展接口的具體實現,關于BeanPostProcessor擴展接口的功能特性、實現方式和工作原理可以移步Springboot擴展點之BeanPostProcessor,但是還是要當作Springboot的擴展點來分析,是因為其內部有6個擴展點可供實現,分別是EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAware,這幾個接口都是Spring預留的重點擴展實現,與Spring的Bean的生命周期密切相關。
ApplicationContextAwareProcessor本身并不是擴展點,而是實現了BeanPostProcessor,并實現postProcessBeforeInitialization(),所以并不需要去實現它,但是其內部包含了以下6個接口實現的執行時機,這幾個接口的功能作用分別是:
1、EnvironmentAware:用于獲取Enviroment,Enviroment可以獲得系統內的所有參數;另外也可以通過注入的方式來獲得Environment,用哪種方式需要以實現場景而決定。
2、EmbeddedValueResolverAware:用于獲取StringValueResolver,StringValueResolver可以獲取基于String類型的properties的變量;另外還可以使用@Value的方式來獲取properties的變量,用哪種方式需要以實現場景而決定。
3、ResourceLoaderAware:用于獲取ResourceLoader,ResourceLoader可以用于獲取classpath內所有的資源對象。
4、ApplicationEventPublisherAware:用于獲取ApplicationEventPublisher,ApplicationEventPublisher可以用來發布事件,當然這個對象也可以通過spring注入的方式來獲得,具體的實現方式可以參考Springboot事件監聽機制的實戰應用。
5、MessageSourceAware:用于獲取MessageSource,MessageSource主要用來做國際化。
6、ApplicationContextAware:用來獲取ApplicationContext,ApplicationContext就是Spring上下文管理器。
下面定義一個Bird類,實現ApplicationContextAware接口,以Bird為例分享ApplicationContextAwareProcessor的功能特性。
@Component@Slf4jpublic class Bird implements ApplicationContextAware { private String name="xiao niao"; private ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext=applicationContext; log.info("----Spring的上下文環境application被注入"); }}
@Test public void test3(){ log.info("----單元測試執行開始"); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext("com.fanfu"); log.info("----單元測試執行完畢"); }
圖片
ApplicationContextAwareProcessor的注冊時機,即準備BeanFactory的時候,注冊的入口在AbstractApplicationContext#refresh----->AbstractApplicationContext#prepareBeanFactory方法中。
圖片
ApplicationContextAwareProcessor#postProcessBeforeInitialization的擴展邏輯很簡單:即當前Bean是否實現了EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAware,如果不是,則直拉返回,如果是,則執行XxxAware接口的擴展邏輯;
class ApplicationContextAwareProcessor implements BeanPostProcessor { private final ConfigurableApplicationContext applicationContext; private final StringValueResolver embeddedValueResolver; public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) { this.applicationContext = applicationContext; this.embeddedValueResolver = new EmbeddedValueResolver(applicationContext.getBeanFactory()); } @Override @Nullable public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { //如果非實現EnvironmentAware、EmbeddedValueResolverAware、 //ResourceLoaderAware、ApplicationEventPublisherAware、 //MessageSourceAware、ApplicationContextAware,則直拉返回; if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware || bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware || bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)){ return bean; } AccessControlContext acc = null; if (System.getSecurityManager() != null) { acc = this.applicationContext.getBeanFactory().getAccessControlContext(); } if (acc != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareInterfaces(bean); return null; }, acc); } else { //如果實現XXXAware接口,則執行相關Aware接口的擴展方法; invokeAwareInterfaces(bean); } return bean; } private void invokeAwareInterfaces(Object bean) { if (bean instanceof EnvironmentAware) { ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment()); } if (bean instanceof EmbeddedValueResolverAware) { ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver); } if (bean instanceof ResourceLoaderAware) { ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext); } if (bean instanceof ApplicationEventPublisherAware) { ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext); } if (bean instanceof MessageSourceAware) { ((MessageSourceAware) bean).setMessageSource(this.applicationContext); } if (bean instanceof ApplicationContextAware) { ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext); } }}
因為ApplicationContextAwareProcessor實現了BeanPostProcessor接口,并重寫了postProcessBeforeInitialization()。關于BeanPostProcessor接口的執行時機可移步Springboot擴展點之BeanPostProcessor,這里就不再反復贅述了。
圖片
通過以上的分析,可以了解到:
1、ApplicationContextAwareProcessor實現BeanPostProcessor接口,是Spring擴展點之BeanPostProcessor的內部經典實現。
2、ApplicationContextAwareProcessor#postProcessBeforeInitialization內部邏輯很簡單,主要是執行了XxxAware相關擴展接口具體實現;
3、ApplicationContextAwareProcessor注冊時機相對比較早,即BeanFactory實例化后,相關屬性初始化時;
4、ApplicationContextAwareProcessor#postProcessBeforeInitialization的執行時機,是在Spring管理的Bean實例化、屬性注入完成后,InitializingBean#afterPropertiesSet方法以及自定義的初始化方法之前;
本文鏈接:http://www.www897cc.com/showinfo-26-38123-0.html理解Spring Boot的ApplicationContextAwareProcessor:擴展點背后的魔法
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com
上一篇: 特殊線程池ForkJoinPool 要合理運用,不是什么樣的任務都拿來用
下一篇: 如何優雅的組織Golang項目結構