引言

Spring中提供了各种Aware接口,方便从上下文中获取当前的运行环境,比较常见的几个子接口有:BeanFactoryAware,BeanNameAware,ApplicationContextAware,EnvironmentAware,BeanClassLoaderAware等,这些Aware的作用都可以从命名得知

Aware处理

其中BeanNameAwareBeanClassLoaderAwareBeanFactoryAware这三个是直接在bean的初始化之前就处理了的,具体代码在AbstractAutowireCapableBeanFactory.initializeBean方法中:

protected Object initializeBean(String beanName, Object bean, RootBeanDefinition mbd) {
// 判断对象实现的接口类型,处理特定的三种接口类型:BeanNameAware、BeanClassLoaderAware和BeanFactoryAware。
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
} if (bean instanceof BeanClassLoaderAware) {
((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
} if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(this);
}
// 开始Bean初始化前处理、初始化、初始化后处理
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
} try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
} if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}

除了这三种之外的那些Aware接口的实现就不太一样了,它们都是利用BeanPostProcessor接口完成的,关于BeanPostProcessor接口的原理可以这篇文章:Spring扩展点之BeanPostProcessor

ApplicationContextAware就是利用ApplicationContextAwareProcessor实现的:

public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
AccessControlContext acc = null; if (System.getSecurityManager() != null &&
(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
acc = this.applicationContext.getBeanFactory().getAccessControlContext();
} if (acc != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
//具体实现
invokeAwareInterfaces(bean);
return null;
}, acc);
}
else {
//具体实现
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);
}
}
}

ApplicationContextAwareProcessor的注册奥秘在AbstractApplicationContext.prepareBeanFactory方法中:

beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this));
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

Spring扩展点之Aware接口族的更多相关文章

  1. Spring扩展点之FactoryBean接口

    前言 首先看一下接口定义 public interface FactoryBean<T> { /** * 返回对象实例 */ @Nullable T getObject() throws ...

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

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

  3. spring源码:Aware接口

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

  4. Spring扩展点-v5.3.9

    Spring 扩展点 **本人博客网站 **IT小神 www.itxiaoshen.com 官网地址****:https://spring.io/projects/spring-framework T ...

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

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

  6. Spring扩展点之BeanPostProcessor

    前言 BeanPostProcessor接口是Spring中一个非常重要的接口,它的接口定义如下 public interface BeanPostProcessor { Object postPro ...

  7. Spring扩展点之BeanFactoryPostProcessor

    前言 BeanFactoryPostProcessor接口是Spring中一个非常重要的接口,它的接口定义如下 public interface BeanFactoryPostProcessor { ...

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

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

  9. spring扩展点之PropertyPlaceholderConfigurer

    原理机制讲解 https://leokongwq.github.io/2016/12/28/spring-PropertyPlaceholderConfigurer.html 使用时多个配置讲解 ht ...

随机推荐

  1. flask 基础2

    一.装饰器的坑 在使用装饰器函数时候,当一个装饰器装饰多个函数的时候,会由于内存地址相同时发生报错,因为装饰的都是一个函数 所以就需要引入 import functools  重新定义每一个函数的名称 ...

  2. E10【选款式】I don't like that style

    核心句型 I don't like that style. 我不喜欢那个款式 场景对话 A:Look at those shoes. They're really nice. 瞧那双鞋.可真漂亮 B: ...

  3. django学习-安装、创建应用、编写视图

    快速安装指南 py -3 -m pip install django >>> import django >>> django.get_version() '2.2 ...

  4. 获取 Docker 容器的 IP 地址

    docker inspect --format='{{.NetworkSettings.IPAddress}}' yourContainerIdOrContainerName

  5. 【NodeJS】Vue-d2Admin

    INFO Starting development server... 10% building 2/2 modules 0 active ERROR Error: Watching remote f ...

  6. python27期day04:列表、元组、range、作业题。

    1.for循环套for循环: for i in "abc": for x in "egf: print(x) 结果是:e g f e g f e g f  2.99乘法表 ...

  7. centos7 扩容

    用 df -h, 看到磁盘满了 (注意:如果是二,或者第三次扩容,下面的参数就不一样) fdisk /dev/sda 但是失败了,显示没有多余的分区 可以看到 有个/dev/sda4 是我在这之前刚刚 ...

  8. CF1076D Edge Deletion 最短路树

    问题描述 Codeforces 洛谷(有翻译) 题解 最短路树,是一棵在最短路过程中构建的树. 在\(\mathrm{Dijkstra}\)过程中,如果最终点\(y\)是由点\(x\)转移得到的,则在 ...

  9. docker--(MAC ubuntu centos)安装

    MacOS 安装 1.homebrew安装(需要mac密码) brew cask install docker 2.手动下载安装 如果需要手动下载,请点击以下链接下载 Stable 或 Edge 版本 ...

  10. [Taro] taro 缓存

    taro 缓存 Taro.clearStorageSync() 清除全部缓存 Taro.setStorage(key,value)设置缓存 Taro.getStorage(key)获取缓存 Taro. ...