Springboot扩展点系列_ApplicationContextAwareProcessor

功能特性

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
@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的上下文环境application被注入");
    }
}

@Test
    public void test3(){
        log.info("----单元测试执行开始");
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext("com.fanfu");
        log.info("----单元测试执行完毕");
 
    }

单元测执行结果

img

工作原理

注册时机

ApplicationContextAwareProcessor的注册时机,即准备BeanFactory的时候,注册的入口在AbstractApplicationContext#refresh----->AbstractApplicationContext#prepareBeanFactory方法中。

img

执行逻辑

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,这里就不再反复赘述了。

img

总结

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

1、ApplicationContextAwareProcessor实现BeanPostProcessor接口,是Spring扩展点之BeanPostProcessor的内部经典实现。

2、ApplicationContextAwareProcessor#postProcessBeforeInitialization内部逻辑很简单,主要是执行了XxxAware相关扩展接口具体实现;

3、ApplicationContextAwareProcessor注册时机相对比较早,即BeanFactory实例化后,相关属性初始化时;

4、ApplicationContextAwareProcessor#postProcessBeforeInitialization的执行时机,是在Spring管理的Bean实例化、属性注入完成后,InitializingBean#afterPropertiesSet方法以及自定义的初始化方法之前;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值