Spring钩子接口Aware
前言
我们在编写代码的时候,有的时候想要使用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的更多相关文章
- Spring(七)核心容器 - 钩子接口
目录 前言 1.Aware 系列接口 2.InitializingBean 3.BeanPostProcessor 4.BeanFactoryPostProcessor 5.ImportSelecto ...
- spring中的aware接口
1.实现了相应的aware接口,这个类就获取了相应的资源. 2.spring中有很多aware接口,包括applicationContextAware接口,和BeanNameAware接口. 实现了这 ...
- Spring InitializingBean 接口以及Aware接口实现的原理
关于Spring InitializingBean 接口以及Aware接口实现的其实都在 第11步中: finishBeanFactoryInitialization() 方法中完成了3部分的内容: ...
- spring源码分析系列 (2) spring拓展接口BeanPostProcessor
Spring更多分析--spring源码分析系列 主要分析内容: 一.BeanPostProcessor简述与demo示例 二.BeanPostProcessor源码分析:注册时机和触发点 (源码基于 ...
- SpringBoot2.x入门:使用CommandLineRunner钩子接口
前提 这篇文章是<SpringBoot2.x入门>专辑的第6篇文章,使用的SpringBoot版本为2.3.1.RELEASE,JDK版本为1.8. 这篇文章主要简单聊聊钩子接口Comma ...
- spring源码分析系列 (3) spring拓展接口InstantiationAwareBeanPostProcessor
更多文章点击--spring源码分析系列 主要分析内容: 一.InstantiationAwareBeanPostProcessor简述与demo示例 二.InstantiationAwareBean ...
- WebService—CXF整合Spring实现接口发布和调用过程
一.CXF整合Spring实现接口发布 发布过程如下: 1.引入jar包(基于maven管理) <!-- cxf --> <dependency> <groupId> ...
- spring boot 接口返回值封装
Spring Boot 集成教程 Spring Boot 介绍 Spring Boot 开发环境搭建(Eclipse) Spring Boot Hello World (restful接口)例子 sp ...
- 换一种方式编写 Spring MVC 接口
1. 前言 通常我们编写 Spring MVC 接口的范式是这样的: @RestController @RequestMapping("/v1/userinfo") public ...
随机推荐
- 痞子衡嵌入式:恩智浦i.MX RTxxx系列MCU启动那些事(6.1)- FlexSPI NOR连接方式大全(RT600)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦i.MX RT600的FlexSPI NOR启动的连接方式. 痞子衡前段时间一鼓作气写完了三篇关于i.MXRT1xxx系列Flex ...
- vue-cli脚手架目录(2.0)
vue-cli脚手架目录一览 最近在学习vue,看的稀里糊涂.今天从头开始,把cli配置的vue项目目录和配置文件搞清楚. 先看看整个项目目录结构: 再看看build文件夹下相关文件及目录: co ...
- php判断二个数最大公约数
$m = isset($_GET['m']) ? $_GET['m'] : 12; $n = isset($_GET['n']) ? $_GET['n'] : 8; //判断mn的大小 if($m&g ...
- Gorm 预加载及输出处理(一)- 预加载应用
单条关联查询 先创建两个关联模型: // 用户模型 type User struct { gorm.Model Username string `gorm:"type:varchar(20) ...
- django 知识点小结
以下内容为用django写blog中的一些知识点,权当复习. 一.定义view 1.get_object_or_404()是用get()查询数据,如果不存在就直接返回404 参数: get_objec ...
- 深入理解React key
一 react 组件元素的 diff 算法 二 key 的理解 概述 react 中的key 属性,它是一个特殊的属性,它的出现不是给开发者用的(例如你为一个组件设置key之后不能获取组件的这个key ...
- 1构建个人博客--使用Hugo快速成型
概述 人在武汉,病毒肆虐. 隔离久了,有点闷,闲余时间找点事情做. 建个博客吧, 内容不重要,写不写也不那么要紧,目前水平也写不出什么有深度的东西. 但是这个姿势一定要优美, 过程一定要折腾. OK, ...
- 设计模式之委派模式,大名鼎鼎的Spring都在用
什么是委派模式 虽然说委派模式不属于Gof23中设计模式,但这并不影响它成为一种经典的设计模式. "委派"字面意思就是指派一件事情给某人.类比到生活中的场景,比如项目leader指 ...
- Netty Hello World 入门源码分析
第一节简单提了什么是网络编程,Netty 做了什么,Netty 都有哪些功能组件.这一节就具体进入 Netty 的世界,我们从用 Netty 的功能实现基本的网络通信开始分析 各个组件的使用. 1. ...
- 小米官网轮播图js+css3+html实现
官网轮播: 我的轮播: 重难点: 1.布局 2.图片和右下角小圆点的同步问题 3.setInterval定时器的使用 4.淡入淡出动画效果 5.左右箭头点击时,图片和小圆点的效果同步 6.另一种轮播思 ...