前言

我们在编写代码的时候,有的时候想要使用Spring的底层组件,类似于 ApplicationContext, BeanFactory等等

那我们实现Spring提供的钩子方法xxxAware。在创建对象的时候,会调用接口规定的方法注入相关的组件。

Aware接口

 /**
* A marker superinterface indicating that a bean is eligible to be notified by the
* Spring container of a particular framework object through a callback-style method.
* The actual method signature is determined by individual subinterfaces but should
* typically consist of just one void-returning method that accepts a single argument.
*
* <p>Note that merely implementing {@link Aware} provides no default functionality.
* Rather, processing must be done explicitly, for example in a
* {@link org.springframework.beans.factory.config.BeanPostProcessor}.
* Refer to {@link org.springframework.context.support.ApplicationContextAwareProcessor}
* for an example of processing specific {@code *Aware} interface callbacks.
*
* @author Chris Beams
* @author Juergen Hoeller
* @since 3.1
*/
public interface Aware {}

一个标记的超级接口,表明这个bean会被spring容器注意到,通过一个回调的风格。这个我也称之为钩子方法。

我们可以看到如下图片,实现了Aware的接口的接口特别多,他们都是Spring自带的组件,我们通过Aware可以很方便的使用他们

在此列举几个比较重要的接口,都是我经常用到的。

Aware子接口 描述  
BeanNameAware 获取容器中 Bean 的名称  
BeanFactoryAware 获取当前 BeanFactory ,这样可以调用容器的服务  
ApplicationContextAware 注入IOC容器的,可以使用容器绝大部分功能
MessageSourceAware 获取 Message Source 相关文本信息  
EmbeddedValueResolverAware 值解析器,比如{}  #{}等等
EnvironmentAware 环境解析器,可以拿properties的时候挺好用的

ApplicationContextAware接口

 public interface ApplicationContextAware extends Aware {

     /**
* Set the ApplicationContext that this object runs in.
* Normally this call will be used to initialize the object.
* <p>Invoked after population of normal bean properties but before an init callback such
* as {@link org.springframework.beans.factory.InitializingBean#afterPropertiesSet()}
* or a custom init-method. Invoked after {@link ResourceLoaderAware#setResourceLoader},
* {@link ApplicationEventPublisherAware#setApplicationEventPublisher} and
* {@link MessageSourceAware}, if applicable.
* @param applicationContext the ApplicationContext object to be used by this object
* @throws ApplicationContextException in case of context initialization errors
* @throws BeansException if thrown by application context methods
* @see org.springframework.beans.factory.BeanInitializationException
*/
void setApplicationContext(ApplicationContext applicationContext) throws BeansException; }

这个可以获取Spring的IOC容器。拿到这个IOC容器,你可以拥有Spring的绝大多数功能。

我们以ApplicationContextAware为例。直接继承XxxAware接口,就可以拿到他的相应字段了。

 @Component
@Slf4j
public class Person implements ApplicationContextAware, BeanFactoryAware,
BeanNameAware, EnvironmentAware, EmbeddedValueResolverAware { @Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
log.info("applicationContext = {}", applicationContext.getBean("person"));
} @Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
log.info("beanFactory = {}", beanFactory.containsBean("person"));
} @Override
public void setBeanName(String name) {
log.info("name = {}", name);
} @Override
public void setEmbeddedValueResolver(StringValueResolver resolver) {
// 字符解析器
log.info("val = {}", resolver.resolveStringValue("#{5 * 10}"));
} @Override
public void setEnvironment(Environment environment) {
// 这个可以获取环境变量的值
log.info("app = {}", environment.getProperty("app.secret"));
}
}

结果:

 2020-04-04 21:35:39.474 [main] [] INFO  - [com.gdufe.osc.controller.Person java:37] [name = person]
2020-04-04 21:35:39.475 [main] [] INFO - [com.gdufe.osc.controller.Person java:32] [beanFactory = true]
2020-04-04 21:35:39.475 [main] [] INFO - [com.gdufe.osc.controller.Person java:48] [app = wenbochang888]
2020-04-04 21:35:39.491 [main] [] INFO - [com.gdufe.osc.controller.Person java:42] [val = 50]
2020-04-04 21:35:39.493 [main] [] INFO - [com.gdufe.osc.controller.Person java:27] [applicationContext = com.gdufe.osc.controller.Person@24386839]

Aware接口底层实现原理

我们看下如下的代码

 class ApplicationContextAwareProcessor implements BeanPostProcessor {

     @Override
@Nullable
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException { .....
invokeAwareInterfaces(bean);
..... return bean;
} 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);
}
}
}
}

这里我稍微解释一下 BeanPostProcessor 方法。在初始化bean之前,以及之后,可以执行相应的方法。类似有点AOP的功能。

那么ApplicationContextAwareProcessor 就很好理解了。

在一个bean实例初始化之前调用postProcessBeforeInitialization方法。然后判断该bean有没有实现相应的aware接口,将对于的aware set进去即可,非常的方便。

Spring钩子接口Aware的更多相关文章

  1. Spring(七)核心容器 - 钩子接口

    目录 前言 1.Aware 系列接口 2.InitializingBean 3.BeanPostProcessor 4.BeanFactoryPostProcessor 5.ImportSelecto ...

  2. spring中的aware接口

    1.实现了相应的aware接口,这个类就获取了相应的资源. 2.spring中有很多aware接口,包括applicationContextAware接口,和BeanNameAware接口. 实现了这 ...

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

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

  4. spring源码分析系列 (2) spring拓展接口BeanPostProcessor

    Spring更多分析--spring源码分析系列 主要分析内容: 一.BeanPostProcessor简述与demo示例 二.BeanPostProcessor源码分析:注册时机和触发点 (源码基于 ...

  5. SpringBoot2.x入门:使用CommandLineRunner钩子接口

    前提 这篇文章是<SpringBoot2.x入门>专辑的第6篇文章,使用的SpringBoot版本为2.3.1.RELEASE,JDK版本为1.8. 这篇文章主要简单聊聊钩子接口Comma ...

  6. spring源码分析系列 (3) spring拓展接口InstantiationAwareBeanPostProcessor

    更多文章点击--spring源码分析系列 主要分析内容: 一.InstantiationAwareBeanPostProcessor简述与demo示例 二.InstantiationAwareBean ...

  7. WebService—CXF整合Spring实现接口发布和调用过程

    一.CXF整合Spring实现接口发布 发布过程如下: 1.引入jar包(基于maven管理) <!-- cxf --> <dependency> <groupId> ...

  8. spring boot 接口返回值封装

    Spring Boot 集成教程 Spring Boot 介绍 Spring Boot 开发环境搭建(Eclipse) Spring Boot Hello World (restful接口)例子 sp ...

  9. 换一种方式编写 Spring MVC 接口

    1. 前言 通常我们编写 Spring MVC 接口的范式是这样的: @RestController @RequestMapping("/v1/userinfo") public ...

随机推荐

  1. Spring Boot从入门到精通(七)集成Redis实现Session共享

    单点登录(SSO)是指在多个应用系统中,登录用户只需要登录验证一次就可以访问所有相互信任的应用系统,Redis Session共享是实现单点登录的一种方式.本文是通过Spring Boot框架集成Re ...

  2. node代理遇到的坑记

    在进行前端mock地址代理时候,进行了webpack的node反向代理: 实际mock地址是:http://10.118.183.10/mock/hb/startwork/openredpacket ...

  3. js之重写原型对象

    “实例中的指针仅指向原型,而不是指向构造函数”. “重写原型对象切断了现有原型与任何之前已经存在的对象实例之间的关系:它们引用的仍然是最初的原型”.——前记 var fun = function(){ ...

  4. 7种你应该知道的JavaScript常见的错误

    转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 原文出处:https://blog.bitsrc.io/types-of-native-errors-in- ...

  5. unzip详解,Linux系统如何解压缩zip文件?

    通常在使用linux时会自带了unzip,但是在最小化安装之后,可能系统里就无法使用此命令了. yum list unzip 查看是否安装 如果没安装过就继续 yum install unzip 安装 ...

  6. 实验二 Samba服务器配置

    实验二 实 验 基 本 信 息 实验名称:Samba服务器配置 实验时间:    年 月 日 实验地点: 实验目的: 了解Samba环境及协议 掌握Samba的工作原理 掌握主配置文件Samba.co ...

  7. 在Java中使用Collections.sort 依据多个字段排序

    一.如何使用Collections工具类进行排序 使用Collections工具类进行排序主要有两种方式: 1.对象实现Comparable接口,重写compareTo方法 /** * @author ...

  8. 记 2020蓝桥杯校内预选赛(JAVA组) 赛后总结

    目录 引言 结果填空 1. 签到题 2. 概念题 3. 签到题 4. 签到题 程序题 5. 递增三元组[遍历] 6. 小明的hello[循环] 7. 数位递增[数位dp] 8. 小明家的草地[bfs] ...

  9. vuepress-theme-reco + Github Actions 构建静态博客,部署到第三方服务器

    最新博客链接 Github链接 查看此文档前应先了解,vuepress基本操作 参考官方文档进行配置: vuepress-theme-reco VuePress SamKirkland / FTP-D ...

  10. 基于 HTML5 WebGL 与 GIS 的智慧机场大数据可视化分析

    前言:大数据,人工智能,工业物联网,5G 已经或者正在潜移默化地改变着我们的生活.在信息技术快速发展的时代,谁能抓住数据的核心,利用有效的方法对数据做数据挖掘和数据分析,从数据中发现趋势,谁就能做到精 ...