SpringAware到底是什么?

Spring Aware到底是什么?

创新互联于2013年成立,先为双河等服务建站,双河等地企业,进行企业商务咨询服务。为双河企业网站制作PC+手机+微官网三网同步一站式服务解决您的所有建站问题。

通过如下前序两篇文章:

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

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

Spring Aware到底是什么?

  1. 在 Spring Bean Ready for Use之前的起源当然是要调用构造器,所以 Constructor 毋庸置疑是创建 Spring Bean 的第一步
  2. 通过 Setter 方法完成依赖注入,SDI (Setter Dependency Injection)
  3. 依赖注入一旦结束,BeanNameAware.setBeanName() 会被调用,它设置该 bean 在 Bean Factory 中的名称
  4. 接下来调用 BeanClassLoaderAware.setBeanClassLoader(),为 bean 实例提供类加载器,我们知道所有类都是要通过类加载器加载到上下文的,关于类的加载机制/双亲委派模型(大厂都爱问的面试题)内容会在后续给出来,让你透彻的了解
  5. 然后 BeanFactoryAware.setBeanFactory() 会被调用为 bean 实例提供其所拥有的 factory

关于 1、2 两点我要额外多说一些内容,请看下面代码:
Spring Aware到底是什么?

这里,我们尝试通过构造器访问自动注入的 field Environment env,当构造器被调用时,Spring Bean 还没被完全初始化,这就会导致 NullPointerExceptions
我们变换一下方式:
Spring Aware到底是什么?

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

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

敲黑板

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

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

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

Aware

Spring Aware到底是什么?

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 获取资源加载器,这样获取外部资源文件

来看类关系图:
Spring Aware到底是什么?

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

代码示例

BeanNameAware

自定义 bean 实现 BeanNameAware
Spring Aware到底是什么?

注册 bean
Spring Aware到底是什么?

运行
Spring Aware到底是什么?

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

总结

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

灵魂追问

  1. 框架中有哪些经典的 Aware 应用?
  2. 到现在你能很好的理解 Spring Bean 的生命周期吗?

新闻标题:SpringAware到底是什么?
浏览地址:http://scyanting.com/article/gegcch.html