在Spring中,有很多xxxAware接口,这些xxxAware接口的作用是把Spring的组件依赖注入到实现了Aware接口的对象实例中;可在自定义的组件需要Spring的内部组件时使用;
以下Spring版本为5.2.4.RELEASE;
Aware的层次图如下;
org.springframework.beans.factory.Aware为xxxAware的顶层接口,而该接口没有声明任何的方法,它的作用是Spring容器中一些特定对象进行回调的时候,它作为一个标识接口;
Spring提供了两种类型的容器,BeanFactory和ApplicationContext;
BeanFactory是基础类型IoC容器,提供完整的IoC服务支持;如果没有特殊指定,默认采用懒加载;只有当客户端对象需要访问容器中的某个受管对象的时候,才对该受管对象进行初始化以及依赖注入操作;所以,相对来说,容器启动初期速度较快,所需要的资源有限;
ApplicationContext是在BeanFactory的基础上构建,是相对比较高级的容器实现,除了拥有BeanFactory的所有支持,ApplicationContext还提供了其他高级特性,比如事件发布、国际化信息支持等;ApplicationContext所管理的对象,在该类型容器启动之后,默认全部初始化并绑定完成(即非懒加载);
所以,相对于BeanFactory来说,ApplicationContext要求更多的系统资源,同时,因为在启动时就完成所有初始化,容器启动时间较之BeanFactory也会长一些;
BeanFactory和ApplicationContext的本质区别是前者采用懒加载,后者是采用的是非懒加载;
当对象实例化完成并且相关属性以及依赖设置完成之后, 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 实 现 了Spring的ResourceLoader接口,即资源加载策略;当容器检测到当前对象实例实现了ResourceLoaderAware接口之后,会将当前ApplicationContext自身设置到对象实例,这样当前对象实例就拥有了其所在ApplicationContext容器的一个引用;
-
org.springframework.context.ApplicationEventPublisherAware
ApplicationContext作为一个容器,同时还实现了ApplicationEventPublisher接口,即事件发布器,这样,它就可以作为ApplicationEventPublisher来使用;所以,当前ApplicationContext容器如果检测到当前实例化的对象实例声明了ApplicationEventPublisherAware接口,则会将自身注入当前对象;
- org.springframework.context.MessageSourceAware
ApplicationContext通过MessageSource接口提供国际化的信息支持,即I18n( Internationalization);它自身就实现了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属性值;
当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;