当前位置:首页 > 科技  > 软件

理解Spring Boot的ApplicationContextAwareProcessor:扩展点背后的魔法

来源: 责编: 时间:2023-12-05 09:25:28 351观看
导读前言这篇文章主要来分享Springboot的扩展点之ApplicationContextAwareProcessor,而ApplicationContextAwareProcessor本身并不是扩展点,而是BeanPostProcessor扩展接口的具体实现,关于BeanPostProcessor扩展接口的功能特

前言

这篇文章主要来分享Springboot的扩展点之ApplicationContextAwareProcessor,而ApplicationContextAwareProcessor本身并不是扩展点,而是BeanPostProcessor扩展接口的具体实现,关于BeanPostProcessor扩展接口的功能特性、实现方式和工作原理可以移步Springboot扩展点之BeanPostProcessor,但是还是要当作Springboot的扩展点来分析,是因为其内部有6个扩展点可供实现,分别是EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAware,这几个接口都是Spring预留的重点扩展实现,与Spring的Bean的生命周期密切相关。n2d28资讯网——每日最新资讯28at.com

功能特性

ApplicationContextAwareProcessor本身并不是扩展点,而是实现了BeanPostProcessor,并实现postProcessBeforeInitialization(),所以并不需要去实现它,但是其内部包含了以下6个接口实现的执行时机,这几个接口的功能作用分别是:n2d28资讯网——每日最新资讯28at.com

1、EnvironmentAware:用于获取Enviroment,Enviroment可以获得系统内的所有参数;另外也可以通过注入的方式来获得Environment,用哪种方式需要以实现场景而决定。n2d28资讯网——每日最新资讯28at.com

2、EmbeddedValueResolverAware:用于获取StringValueResolver,StringValueResolver可以获取基于String类型的properties的变量;另外还可以使用@Value的方式来获取properties的变量,用哪种方式需要以实现场景而决定。n2d28资讯网——每日最新资讯28at.com

3、ResourceLoaderAware:用于获取ResourceLoader,ResourceLoader可以用于获取classpath内所有的资源对象。n2d28资讯网——每日最新资讯28at.com

4、ApplicationEventPublisherAware:用于获取ApplicationEventPublisher,ApplicationEventPublisher可以用来发布事件,当然这个对象也可以通过spring注入的方式来获得,具体的实现方式可以参考Springboot事件监听机制的实战应用。n2d28资讯网——每日最新资讯28at.com

5、MessageSourceAware:用于获取MessageSource,MessageSource主要用来做国际化。n2d28资讯网——每日最新资讯28at.com

6、ApplicationContextAware:用来获取ApplicationContext,ApplicationContext就是Spring上下文管理器。n2d28资讯网——每日最新资讯28at.com

下面定义一个Bird类,实现ApplicationContextAware接口,以Bird为例分享ApplicationContextAwareProcessor的功能特性。n2d28资讯网——每日最新资讯28at.com

@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("----单元测试执行完毕");    }

单元测执行结果

图片图片n2d28资讯网——每日最新资讯28at.com

工作原理

注册时机

ApplicationContextAwareProcessor的注册时机,即准备BeanFactory的时候,注册的入口在AbstractApplicationContext#refresh----->AbstractApplicationContext#prepareBeanFactory方法中。n2d28资讯网——每日最新资讯28at.com

图片图片n2d28资讯网——每日最新资讯28at.com

执行逻辑

ApplicationContextAwareProcessor#postProcessBeforeInitialization的扩展逻辑很简单:即当前Bean是否实现了EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAware,如果不是,则直拉返回,如果是,则执行XxxAware接口的扩展逻辑;n2d28资讯网——每日最新资讯28at.com

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,这里就不再反复赘述了。n2d28资讯网——每日最新资讯28at.com

图片图片n2d28资讯网——每日最新资讯28at.com

总结

通过以上的分析,可以了解到:n2d28资讯网——每日最新资讯28at.com

1、ApplicationContextAwareProcessor实现BeanPostProcessor接口,是Spring扩展点之BeanPostProcessor的内部经典实现。n2d28资讯网——每日最新资讯28at.com

2、ApplicationContextAwareProcessor#postProcessBeforeInitialization内部逻辑很简单,主要是执行了XxxAware相关扩展接口具体实现;n2d28资讯网——每日最新资讯28at.com

3、ApplicationContextAwareProcessor注册时机相对比较早,即BeanFactory实例化后,相关属性初始化时;n2d28资讯网——每日最新资讯28at.com

4、ApplicationContextAwareProcessor#postProcessBeforeInitialization的执行时机,是在Spring管理的Bean实例化、属性注入完成后,InitializingBean#afterPropertiesSet方法以及自定义的初始化方法之前;n2d28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-38123-0.html理解Spring Boot的ApplicationContextAwareProcessor:扩展点背后的魔法

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 特殊线程池ForkJoinPool 要合理运用,不是什么样的任务都拿来用

下一篇: 如何优雅的组织Golang项目结构

标签:
  • 热门焦点
  • 红魔电竞平板评测:大屏幕硬实力

    前言:三年的疫情因为要上网课的原因激活了平板市场,如今网课的时代已经过去,大家的生活都恢复到了正轨,这也就意味着,真正考验平板电脑生存的环境来了。也就是面对着这种残酷的
  • 帅气纯真少年!日本最帅初中生选美冠军出炉

    日本第一帅哥初一生选美大赛冠军现已正式出炉,冠军是来自千叶县的宗田悠良。日本一直热衷于各种选美大赛,从&ldquo;最美JK&rdquo;起到&ldquo;最美女星&r
  • 企业采用CRM系统的11个好处

    客户关系管理(CRM)软件可以为企业提供很多的好处,从客户保留到提高生产力。  CRM软件用于企业收集客户互动,以改善客户体验和满意度。  CRM软件市场规模如今超过580
  • 在线图片编辑器,支持PSD解析、AI抠图等

    自从我上次分享一个人开发仿造稿定设计的图片编辑器到现在,不知不觉已过去一年时间了,期间我经历了裁员失业、面试找工作碰壁,寒冬下一直没有很好地履行计划.....这些就放在日
  • .NET 程序的 GDI 句柄泄露的再反思

    一、背景1. 讲故事上个月我写过一篇 如何洞察 C# 程序的 GDI 句柄泄露 文章,当时用的是 GDIView + WinDbg 把问题搞定,前者用来定位泄露资源,后者用来定位泄露代码,后面有朋友反
  • 从零到英雄:高并发与性能优化的神奇之旅

    作者 | 波哥审校 | 重楼作为公司的架构师或者程序员,你是否曾经为公司的系统在面对高并发和性能瓶颈时感到手足无措或者焦头烂额呢?笔者在出道那会为此是吃尽了苦头的,不过也得
  • Python异步IO编程的进程/线程通信实现

    这篇文章再讲3种方式,同时讲4中进程间通信的方式一、 Python 中线程间通信的实现方式共享变量共享变量是多个线程可以共同访问的变量。在Python中,可以使用threading模块中的L
  • 华为Mate60系列模具曝光:采用硕大圆形后置相机模组+拼接配色方案

    据此前多方爆料,今年华为将开始恢复一年双旗舰战略,除上半年推出的P60系列外,往年下半年的Mate系列也将迎来更新,有望在9-10月份带来全新的华为Mate60
  • 联想YOGA 16s 2022笔记本将要推出,屏幕支持触控功能

    联想此前宣布,将于11月2日19:30召开联想秋季轻薄新品发布会,推出联想 YOGA 16s 2022 笔记本等新品。官方称,YOGA 16s 2022 笔记本将搭载 16 英寸屏幕,并且是一
Top