在 Spring 框架中有一个 org.springframework.beans.factory.Aware 接口,

Aware 是感知感应的意思,那么此接口的作用就是为 Spring 中的 bean 提供了感知外界的能力。

Aware接口本身只是一个标记接口,Spring 中提供了一系列具有具体感知能力的接口,它们都继承自 Aware 接口,

  部分如下:

  LoadTimeWeaverAware:加载 Spring Bean 时织入第三方模块,如AspectJ

  BeanClassLoaderAware:加载 Spring Bean 的类加载器

  BootstrapContextAware:资源适配器 BootstrapContext,如JCA,CCI

  ResourceLoaderAware:底层访问资源的加载器

  BeanFactoryAware:声明 BeanFactory

  PortletConfigAware:PortletConfig

  PortletContextAware:PortletContext

  ServletConfigAware:ServletConfig

  ServletContextAware:ServletContext

  MessageSourceAware:国际化

  ApplicationEventPublisherAware:应用事件

  NotificationPublisherAware:JMX通知

  BeanNameAware:声明 Spring Bean 的名字

  此处以 BeanNameAware 举例,其内部包含了一个 setBeanName 方法,所以当一个 bean 继承了此接口,并定义一个 beanName 的属性,

则在 Spring 容器初始化这个 bean 的时候,会调用这个 setBeanName 方法,注入这个 beanName。

  不同的 Aware 注入对应的外界信息的时机是不一样的,具体也分为两类:

  1. BeanNameAware/BeanClassLoaderAware/BeanFactoryAware

  这三类 Aware 生效的时机是在容器创建 bean 的最后一步完成,具体的调用顺序如下:

  getBean(String beanName)

    doGetBean(final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)

      getSingleton(String beanName, ObjectFactory<?> singletonFactory)

  在 getSingleton 会回调

  createBean(String beanName, RootBeanDefinition mbd, Object[] args)

    doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)

      initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd)

  最终在 initializeBean 内会调用如下方法,此处分别调用了对应的 setXXX 方法,外部信息得以注入

private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}

  2. LoadTimeWeaverAware/ApplicationContextAware/ServletContextAware/MessageSourceAware 等

  这一类 Aware 是通过 BeanPostProcessor bean后置处理器实现外部信息注入的。

  同样在上述的 initializeBean 方法内会调用如下方法

public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException { Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
result = beanProcessor.postProcessBeforeInitialization(result, beanName);
if (result == null) {
return result;
}
}
return result;
}

此处会调用容器中注册的所有的 BeanPostProcessor 的 postProcessBeforeInitialization 方法,而 ApplicationContextAwareProcessor 是默认注册到容器内的,其 postProcessBeforeInitialization 方法内会调用如下方法:

private void invokeAwareInterfaces(Object bean) {
if (bean instanceof Aware) {
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);
}
}
}

所以 bean 只要继承了 EnvironmentAware,ResourceLoaderAware 就具备相应的感知能力。

Spring的感知能力 Aware的更多相关文章

  1. 手写Spring,定义标记类型Aware接口,实现感知容器对象

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 同事写的代码,我竟丝毫看不懂! 大佬的代码,就像 "赖蛤蟆泡青蛙,张的丑玩 ...

  2. 想减少代码量,快设置一个有感知的 Aware Spring Bean

    摘要:正常情况下,Spring 中的 Bean 对 Spring 是无感知的,Spring 框架提供了这种扩展能力,能让一个 bean 成为有感知的. 本文分享自华为云社区<有感知的 Aware ...

  3. spring源码:Aware接口(li)

    一.spring容器中的aware接口介绍 Spring中提供了各种Aware接口,比较常见的如BeanFactoryAware,BeanNameAware,ApplicationContextAwa ...

  4. spring源码:Aware接口

    一.spring容器中的aware接口介绍 Spring中提供了各种Aware接口,比较常见的如BeanFactoryAware,BeanNameAware,ApplicationContextAwa ...

  5. Spring InitializingBean 接口以及Aware接口实现的原理

    关于Spring InitializingBean 接口以及Aware接口实现的其实都在 第11步中: finishBeanFactoryInitialization() 方法中完成了3部分的内容: ...

  6. Spring扩展点之Aware接口族

    引言 Spring中提供了各种Aware接口,方便从上下文中获取当前的运行环境,比较常见的几个子接口有:BeanFactoryAware,BeanNameAware,ApplicationContex ...

  7. Spring扩展之五:Aware接口等

    ApplicationContextAwareProcessor 1.介绍 ApplicationContextAwareProcessor是一个Spring内部工具,它实现了接口BeanPostPr ...

  8. spring扩展点之四:Spring Aware容器感知技术,BeanNameAware和BeanFactoryAware接口,springboot中的EnvironmentAware

    aware:英 [əˈweə(r)] 美 [əˈwer] adj.意识到的;知道的;觉察到的 XXXAware在spring里表示对XXX感知,实现XXXAware接口,并通过实现对应的set-XXX ...

  9. 对Spring aware理解

    aware翻译过来时就是意识到,我对他的理解就是spring的感知器.是不是很诡异这个名字起得^_^ 先来看看aware接口的结构 spring提供了许多的aware,Aware.java也只是做一个 ...

随机推荐

  1. nexus php composer 私服搭建

    nexus 社区也提供了php composer 私服(当前还在开发中,还没有ga),测试使用构建好的docker 镜像 环境准备 docker-compose 文件 version: "3 ...

  2. <Random> 384 398

    384. Shuffle an Array random.nextInt(n) 返回[0, n) 的随机数,故要+1: class Solution { private int[] nums; pri ...

  3. CSP考前复习

    前言 因为loceaner太菜了,他什么东西都不会 所以他打算学一个东西就记录一下 不过因为他很菜,所以他不会写原理-- 而且,他希望在2019CSP之前不会断更 就酱紫,就是写给他自己的--因为他太 ...

  4. 【LG5171】Earthquake

    [LG5171Earthquake] 题面 洛谷 题解 本题需要用到类欧几里得算法. 前置知识:类欧几里得 就是求函数\[\varphi (a,b,c,n)=\sum_{i=0}^n \left\lf ...

  5. [LeetCode] 189. Rotate Array 旋转数组

    Given an array, rotate the array to the right by k steps, where k is non-negative. Example 1: Input: ...

  6. python开发--信息处理系统

    #!/usr/bin/python card_list=[] #定义列表变量 def show_menu(): print("*" * 10) print("名片管理系统 ...

  7. c# 自动给版本升级,遇9变0且前面一个版本加1

    /// <summary> /// 版本辅助类 /// 创建人: /// 创建时间:2019-11-18 13:53:55 /// </summary> public clas ...

  8. HUE-hive常用查询语句整理

    通过hue进行数据导入: ,create table demo_id(`id` string) row format serde 'org.apache.hadoop.hive.serde2.Open ...

  9. find命令常用参数

    目录 -name -type -size -empty -inum -links -perm -user -group -atime -ctime -mtime -amin -cmin -mmin - ...

  10. Larave框架下Contracts契约的解析

    本篇文章给大家带来的内容是关于Larave框架下Contracts契约的解析,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. Contracts Laravel 的契约是一组定义框架提 ...