Spring Aware 到底是什么?

简介: Spring Aware 到底是什么?

微信图片_20220509194714.jpg


通过如下前序两篇文章:


  1. Spring Bean 生命周期之“我从哪里来”?


  1. Spring Bean 生命周期之“我要到哪里去”?


我们了解了 Spring Bean 的生命周期核心内容,bean 是如何被初始化变为 Ready for Use 的状态,当资源被回收时又是如何被 destroy 的,但 Spring Bean Life Cycle图并未被全部点亮,这篇文章将点亮剩余内容,同时说说你常见的 XxxxAware 接口


为什么要说 Spring Bean 生命周期又说 Aware 呢?下来点亮剩下内容你也许就明白了:


微信图片_20220509194757.jpg


  1. 在 Spring Bean Ready for Use之前的起源当然是要调用构造器,所以 Constructor 毋庸置疑是创建 Spring Bean 的第一步


  1. 通过 Setter 方法完成依赖注入,SDI (Setter Dependency Injection)


  1. 依赖注入一旦结束,BeanNameAware.setBeanName() 会被调用,它设置该 bean 在 Bean Factory 中的名称


  1. 接下来调用 BeanClassLoaderAware.setBeanClassLoader() ,为 bean 实例提供类加载器,我们知道所有类都是要通过类加载器加载到上下文的,关于类的加载机制/双亲委派模型(大厂都爱问的面试题)内容会在后续给出来,让你透彻的了解


  1. 然后 BeanFactoryAware.setBeanFactory() 会被调用为 bean 实例提供其所拥有的 factory


关于 1、2 两点我要额外多说一些内容,请看下面代码:


微信图片_20220509194911.png


这里,我们尝试通过构造器访问自动注入的 field Environment env,当构造器被调用时,Spring Bean 还没被完全初始化,这就会导致 NullPointerExceptions


我们变换一下方式:


微信图片_20220509194942.png


这种方式,Environment 实例被安全注入之后才调用 @PostConstruct标记的方法,这样就不会抛出 NullPointerException 了。


这会回看周期图,有没有豁然开朗?


敲黑板


等所有 Spring Bean 都完成依赖注入(周期图中的 Setter Methods 部分)再使用 bean 的引用才是安全的方式,


后续会有一个章节专门说一说面试经常被问起的 Spring 有几种依赖注入方式的尴尬问题,请关注后续文章


到这里终于可以说一说 Aware 了,且看


Aware


微信图片_20220509195010.png


Aware 翻译过来可以理解为"察觉的;注意到的;感知的" ,XxxxAware 也就是对....感知的,没有 Aware 就是无感知的吗?对喽


Spring 的依赖注入最大亮点就是所有的 Bean 对 Spring 容器的存在是没有意识的,拿 [Spring Bean 生命周期之“我从哪里来”?]() 文章中“小学生入少先队”为例子说明,小学生还是那个小学生,加入少先队还是加入共青团只不过规则不一样罢了但是在实际项目中,我们不可避免的要用到 Spring 容器本身提供的资源(难免要有事情需要少先队组织的帮助),这时候要让 Bean 主动意识到 Spring 容器的存在,才能调用 Spring 所提供的资源,这就是 Spring Aware. 其实 Spring Aware 是 Spring 设计为框架内部使用的,若使用了,你的 Bean 将会和 Spring 框架耦合,所以自己不单独使用,但是在读框架源码时希望你不再模糊.


常见的 Spring Aware 接口


Aware子接口 描述
BeanNameAware 获取容器中 Bean 的名称
BeanFactoryAware 获取当前 BeanFactory ,这样可以调用容器的服务
ApplicationContextAware 同上,在BeanFactory 和 ApplicationContext 的区别 中已明确说明
MessageSourceAware 获取 Message Source 相关文本信息
ApplicationEventPublisherAware 发布事件
ResourceLoaderAware 获取资源加载器,这样获取外部资源文件


来看类关系图:


微信图片_20220509195053.jpg


当然不止以上这些 Aware, 通常使用 Spring Aware 的目的是为了让 Bean 获得 Spring 容器的服务。


代码示例


BeanNameAware


自定义 bean 实现 BeanNameAware


微信图片_20220509195230.png


注册 bean


微信图片_20220509195255.png


运行


微信图片_20220509195317.png


和预想一样,Bean Name 输出结果为 myCustomBeanName,如果移除掉 @Bean 注解的 name 属性, 输出结果为 getMyBeanName


总结


在大多数情况下,我们应该避免使用任何 Aware 接口,除非我们需要它们。实现这些接口会将代码耦合到Spring框架,但是希望看过本节内容之后阅读框架源码思维更加清晰


灵魂追问


  1. 框架中有哪些经典的 Aware 应用?


  1. 到现在你能很好的理解 Spring Bean 的生命周期吗?


相关文章
|
2月前
|
传感器 Java API
Spring揭秘:Aware接口应用场景及实现原理!
Aware接口赋予了Bean更多自感知的能力,通过实现不同的Aware接口,Bean可以轻松地获取到Spring容器中的其他资源引用,像ApplicationContext、BeanFactory等。 这样不仅增强了Bean的功能,还提高了代码的可维护性和扩展性,从而让Spring的IoC容器变得更加强大和灵活。
127 0
Spring揭秘:Aware接口应用场景及实现原理!
|
4月前
|
Java Spring 容器
深入Spring原理-4.Aware接口、初始化和销毁执行顺序、Scope域
深入Spring原理-4.Aware接口、初始化和销毁执行顺序、Scope域
73 0
|
4天前
|
XML Java 数据格式
手写spring第八章-定义标记类型Aware接口,实现感知容器对象
手写spring第八章-定义标记类型Aware接口,实现感知容器对象
4 0
|
11月前
|
Java Spring 容器
深入理解Spring IOC之扩展篇(四)、Aware接口
深入理解Spring IOC之扩展篇(四)、Aware接口
107 0
|
12月前
|
设计模式 Java Spring
Spring Aware接口详解
若 Spring 检测到 bean 实现了 Aware 接口,则会为其注入相应的依赖。所以通过让bean 实现 Aware 接口,则能在 bean 中获得相应的 Spring 容器资源。
151 0
|
Java 程序员 网络安全
spring4.1.8扩展实战之二:Aware接口揭秘
Aware.java是个没有定义任何方法的接口,拥有众多子接口,在spring源码中有多处都在使用这些子接口完成各种场景下的回调操作,当业务有需要时,我们只需创建类来实现相关接口,再声明为bean,就可以被spring容器主动回调
234 0
spring4.1.8扩展实战之二:Aware接口揭秘
|
缓存 Java Spring
Spring Aware 介绍
读完这篇文章你将会收获到 • Aware 的使用和介绍 • BeanFactoryAware 的触发时机 • ApplicationContextAware 的触发时机以及它通过扩展 BeanPostProcessor 来实现
189 0
|
Java Maven Spring
【Spring】Spring高级话题-Spring Aware
【Spring】Spring高级话题-Spring Aware
176 0
【Spring】Spring高级话题-Spring Aware
|
设计模式 XML Java
《Spring 手撸专栏》第 9 章:虎行有雨,定义标记类型Aware接口,实现感知容器对象
实现 1. 工程结构 2. 定义标记接口 3. 容器感知类 4. 包装处理器(ApplicationContextAwareProcessor) 5. 注册 BeanPostProcessor 6. 感知调用操作 测试 1. 事先准备 2. 配置文件 3. 单元测试
158 0
《Spring 手撸专栏》第 9 章:虎行有雨,定义标记类型Aware接口,实现感知容器对象