Loading

Spring Aware分析

在Spring中,有很多xxxAware接口,这些xxxAware接口的作用是把Spring的xxx组件依赖注入到实现了Aware接口的对象实例中;可在自定义的组件需要Spring的内部组件时使用;

以下Spring版本为5.2.4.RELEASE

 

Aware的层次图如下;

 

org.springframework.beans.factory.AwarexxxAware的顶层接口,而该接口没有声明任何的方法,它的作用是Spring容器中一些特定对象进行回调的时候,它作为一个标识接口

  

Spring提供了两种类型的容器,BeanFactoryApplicationContext

BeanFactory是基础类型IoC容器,提供完整的IoC服务支持;如果没有特殊指定,默认采用懒加载;只有当客户端对象需要访问容器中的某个受管对象的时候,才对该受管对象进行初始化以及依赖注入操作;所以,相对来说,容器启动初期速度较快,所需要的资源有限;

ApplicationContext是在BeanFactory的基础上构建,是相对比较高级的容器实现,除了拥有BeanFactory的所有支持,ApplicationContext还提供了其他高级特性,比如事件发布、国际化信息支持等;ApplicationContext所管理的对象,在该类型容器启动之后,默认全部初始化并绑定完成(即非懒加载);

 

所以,相对于BeanFactory来说,ApplicationContext要求更多的系统资源,同时,因为在启动时就完成所有初始化,容器启动时间较之BeanFactory也会长一些;

BeanFactoryApplicationContext的本质区别是前者采用懒加载后者是采用的是非懒加载

 

当对象实例化完成并且相关属性以及依赖设置完成之后, Spring容器会检查当前对象实例是否实现了一系列的以Aware命名结尾的接口定义;如果是,则将这些Aware接口定义中规定的依赖注入给当前对象实例

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean

 

在Spring内部,xxxAware提供属性赋值的注入方法,注入的是xxxAware的前缀名称,大白话就是xxxAware接口它提供的xxx的属性注入的方法供Spring容器进行回调

 

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeAwareMethods

这部分涉及的Aware接口如下;

  • org.springframework.beans.factory.BeanNameAware

  如果Spring容器检测到当前对象实例实现了该接口,会将该对象实例的bean定义对应的beanName设置到当前对象实例;

 

  • org.springframework.beans.factory.BeanClassLoaderAware

  如果容器检测到当前对象实例实现了该接口,会将对应加载当前bean的Classloader注入当前对象实例。默认会使用加载org.springframework.util.ClassUtils类的Classloader;

 

  • org.springframework.beans.factory.BeanFactoryAware

  如果对象声明实现了BeanFactoryAware接口,BeanFactory容器会将自身设置到当前对象实例;这样,当前对象实例就拥有了一个BeanFactory容器的引用,并且可以对这个容器内允许访问的对象按照需要进行访问;

 

上面这几个Aware接口只是针对BeanFactory类型的容器而言,对于ApplicationContext类型的容器,也存在几个Aware相关接口;

  • org.springframework.context.ResourceLoaderAware

  ApplicationContext 实 现 了SpringResourceLoader接口,即资源加载策略;当容器检测到当前对象实例实现了ResourceLoaderAware接口之后,会将当前ApplicationContext自身设置到对象实例,这样当前对象实例就拥有了其所在ApplicationContext容器的一个引用;

 

  • org.springframework.context.ApplicationEventPublisherAware

   ApplicationContext作为一个容器,同时还实现了ApplicationEventPublisher接口,即事件发布器,这样,它就可以作为ApplicationEventPublisher来使用;所以,当前ApplicationContext容器如果检测到当前实例化的对象实例声明了ApplicationEventPublisherAware接口,则会将自身注入当前对象;

  • org.springframework.context.MessageSourceAware

  ApplicationContext通过MessageSource接口提供国际化的信息支持,即I18nInternationalization);它自身就实现了MessageSource接口,所以当检测到当前对象实例实现了MessageSourceAware接口,则会将自身注入当前对象实例的MessagSource,获取国际化的配置信息;

  • org.springframework.context.ApplicationContextAware

   如果ApplicationContext容器检测到当前对象实现了ApplicationContextAware接口,则会将自身注入当前对象实例的ApplicationContext,获取容器的上下文;

  • org.springframework.context.EnvironmentAware

  如果ApplicationContext容器检测到当前对象实现了EnvironmentAware接口,则会将自身注入当前对象实例的Environment属性,获取容器的环境信息;

 

  • org.springframework.context.EmbeddedValueResolverAware

  如果ApplicationContext容器检测到当前对象实现了EmbeddedValueResolverAware接口,则会将自身注入当前对象实例的EmbeddedValueResolver属性,获取Spring容器加载的properties属性值;

 

  参考:[https://docs.spring.io/spring-framework/docs/5.2.4.RELEASE/spring-framework-reference/core.html#beans-java-lifecycle-callbacks]

     [https://docs.spring.io/spring-framework/docs/5.2.4.RELEASE/spring-framework-reference/core.html#aware-list]      

 

  当ApplicationContext中每个对象的实例化完,初始化过程走到BeanPostProcessor前置处理这一步时(即执行org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization方法), ApplicationContext容器会检测到之前注册到容器的ApplicationContextAwareProcessor这个BeanPostProcessor的实现类,然后就会调用其postProcessBeforeInitialization方法,检查并设置Aware相关依赖;
  

  org.springframework.context.support.ApplicationContextAwareProcessor#postProcessBeforeInitialization

 

  org.springframework.context.support.ApplicationContextAwareProcessor#invokeAwareInterfaces

 

  为何是使用的是ApplicationContextAwareProcessor这个后置处理器?

  org.springframework.context.support.AbstractApplicationContext#prepareBeanFactory该方法是用于设置BeanFactory的配置;

  BeanFactory访问Spring容器的顶层接口,通过getBean方法获取容器里的实例对象;

  ApplicationContext即应用上下文,继承自BeanFactory接口,可用于获取Spring 管理的Bean对象实例;

  Aware是属性注入,ApplicationContextAware与ApplicationContext不同的是,当Spring容器初始化的时候,实现了 ApplicationContextAware 接口的 Bean会自动注入ApplicationContext;

posted @ 2021-03-16 00:02  街头卖艺的肖邦  阅读(249)  评论(0编辑  收藏  举报