成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

理解Spring Boot的ApplicationContextAwareProcessor:擴(kuò)展點背后的魔法

開發(fā) 前端
ApplicationContextAwareProcessor#postProcessBeforeInitialization內(nèi)部邏輯很簡單,主要是執(zhí)行了XxxAware相關(guān)擴(kuò)展接口具體實現(xiàn)。

前言

這篇文章主要來分享Springboot的擴(kuò)展點之ApplicationContextAwareProcessor,而ApplicationContextAwareProcessor本身并不是擴(kuò)展點,而是BeanPostProcessor擴(kuò)展接口的具體實現(xiàn),關(guān)于BeanPostProcessor擴(kuò)展接口的功能特性、實現(xiàn)方式和工作原理可以移步Springboot擴(kuò)展點之BeanPostProcessor,但是還是要當(dāng)作Springboot的擴(kuò)展點來分析,是因為其內(nèi)部有6個擴(kuò)展點可供實現(xiàn),分別是EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAware,這幾個接口都是Spring預(yù)留的重點擴(kuò)展實現(xiàn),與Spring的Bean的生命周期密切相關(guān)。

功能特性

ApplicationContextAwareProcessor本身并不是擴(kuò)展點,而是實現(xiàn)了BeanPostProcessor,并實現(xiàn)postProcessBeforeInitialization(),所以并不需要去實現(xiàn)它,但是其內(nèi)部包含了以下6個接口實現(xiàn)的執(zhí)行時機(jī),這幾個接口的功能作用分別是:

1、EnvironmentAware:用于獲取Enviroment,Enviroment可以獲得系統(tǒng)內(nèi)的所有參數(shù);另外也可以通過注入的方式來獲得Environment,用哪種方式需要以實現(xiàn)場景而決定。

2、EmbeddedValueResolverAware:用于獲取StringValueResolver,StringValueResolver可以獲取基于String類型的properties的變量;另外還可以使用@Value的方式來獲取properties的變量,用哪種方式需要以實現(xiàn)場景而決定。

3、ResourceLoaderAware:用于獲取ResourceLoader,ResourceLoader可以用于獲取classpath內(nèi)所有的資源對象。

4、ApplicationEventPublisherAware:用于獲取ApplicationEventPublisher,ApplicationEventPublisher可以用來發(fā)布事件,當(dāng)然這個對象也可以通過spring注入的方式來獲得,具體的實現(xiàn)方式可以參考Springboot事件監(jiān)聽機(jī)制的實戰(zhàn)應(yīng)用。

5、MessageSourceAware:用于獲取MessageSource,MessageSource主要用來做國際化。

6、ApplicationContextAware:用來獲取ApplicationContext,ApplicationContext就是Spring上下文管理器。

下面定義一個Bird類,實現(xiàn)ApplicationContextAware接口,以Bird為例分享ApplicationContextAwareProcessor的功能特性。

@Component
@Slf4j
public 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的上下文環(huán)境application被注入");
    }
}
@Test
    public void test3(){
        log.info("----單元測試執(zhí)行開始");
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext("com.fanfu");
        log.info("----單元測試執(zhí)行完畢");


    }

單元測執(zhí)行結(jié)果

圖片圖片

工作原理

注冊時機(jī)

ApplicationContextAwareProcessor的注冊時機(jī),即準(zhǔn)備BeanFactory的時候,注冊的入口在AbstractApplicationContext#refresh----->AbstractApplicationContext#prepareBeanFactory方法中。

圖片圖片

執(zhí)行邏輯

ApplicationContextAwareProcessor#postProcessBeforeInitialization的擴(kuò)展邏輯很簡單:即當(dāng)前Bean是否實現(xiàn)了EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAware,如果不是,則直拉返回,如果是,則執(zhí)行XxxAware接口的擴(kuò)展邏輯;

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 {
       //如果非實現(xiàn)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 {
          //如果實現(xiàn)XXXAware接口,則執(zhí)行相關(guān)Aware接口的擴(kuò)展方法;
         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);
      }
   }
}

執(zhí)行時機(jī)

因為ApplicationContextAwareProcessor實現(xiàn)了BeanPostProcessor接口,并重寫了postProcessBeforeInitialization()。關(guān)于BeanPostProcessor接口的執(zhí)行時機(jī)可移步Springboot擴(kuò)展點之BeanPostProcessor,這里就不再反復(fù)贅述了。

圖片圖片

總結(jié)

通過以上的分析,可以了解到:

1、ApplicationContextAwareProcessor實現(xiàn)BeanPostProcessor接口,是Spring擴(kuò)展點之BeanPostProcessor的內(nèi)部經(jīng)典實現(xiàn)。

2、ApplicationContextAwareProcessor#postProcessBeforeInitialization內(nèi)部邏輯很簡單,主要是執(zhí)行了XxxAware相關(guān)擴(kuò)展接口具體實現(xiàn);

3、ApplicationContextAwareProcessor注冊時機(jī)相對比較早,即BeanFactory實例化后,相關(guān)屬性初始化時;

4、ApplicationContextAwareProcessor#postProcessBeforeInitialization的執(zhí)行時機(jī),是在Spring管理的Bean實例化、屬性注入完成后,InitializingBean#afterPropertiesSet方法以及自定義的初始化方法之前;

責(zé)任編輯:武曉燕 來源: 凡夫編程
相關(guān)推薦

2023-12-08 07:52:51

Spring項目開發(fā)

2025-02-05 12:28:44

2017-05-09 10:34:21

Spring BootDubbo Activ擴(kuò)展

2017-04-28 08:32:40

Spring BootDubbo Activ使用

2025-01-14 14:54:57

2023-09-28 08:49:41

springBean

2021-04-12 06:09:38

Spring擴(kuò)展點應(yīng)用

2025-04-18 05:50:59

Spring接口Aware

2022-09-16 11:41:17

Spring代碼

2024-02-19 08:17:10

Kafka消息隊列收發(fā)消息

2023-06-07 15:34:21

架構(gòu)層次結(jié)構(gòu)

2019-01-17 23:12:58

快手“萌面”KmojiAI技術(shù)

2014-07-30 09:13:07

2018-11-19 14:29:17

Spring BootXML支持

2009-06-18 14:45:55

Spring Fram

2023-11-24 08:00:00

2009-08-13 18:00:48

Eclipse重構(gòu)功能擴(kuò)展點

2020-08-10 14:39:30

搜索引擎

2011-12-05 13:44:34

JavaSpringMVC
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 国产香蕉视频在线播放 | 欧美 日韩 国产 一区 | 国产精品久久久久久久久 | 国产精品久久久久久久久久东京 | 日韩成人| 国产精品九九九 | 91成人免费电影 | 国产精品久久视频 | 人人人人人爽 | 一区二区福利视频 | 九九热精品在线 | 国产视频一区二区在线观看 | 日韩精品久久 | 国产色 | 中文字幕视频在线观看 | 久久夜夜 | 亚洲国产高清高潮精品美女 | 国产91黄色 | 欧美大片一区 | 日本一区二区三区在线观看 | 亚洲一区二区免费看 | 国产一区二区久久 | 欧美成视频在线观看 | 亚洲成网站| 91福利在线观看视频 | 国产成人精品午夜视频免费 | 欧美精品在线免费 | 一区二区三区av | 日韩成人久久 | 日韩久久久久 | 欧美一区二区三 | 国产精品久久久久一区二区三区 | 九九九视频在线 | 综合色站导航 | 欧美一级精品片在线看 | 精品国产乱码久久久久久中文 | 精品九九在线 | 男女网站免费观看 | 精品日本中文字幕 | 中文字幕一区二区三区乱码在线 | 婷婷一级片 |