容器管理的Bean一般不需要了解容器的状态和直接使用Bean,但是在某些情况下,是需要在Bean中直接对IOC容器进行操作的,这时候,就需要在Bean中设定对容器的感知。Spring IOC也提供了该功能,它是通过特定的aware接口来完成的。aware接口有如下这些:

BeanNameAware:可以在Bean中得到它在IOC容器中的Bean的实例名称

BeanFactoryAware:可以在Bean中得到Bean所在的IOC容器,从而直接在Bean中使用IOC容器的服务

ApplicationContextAware:可以在Bean中得到Bean所在的应用上下文,从而直接在Bean中使用应用上下文的服务

MessageSourceAware:在Bean中可以得到消息源

ApplicationEventPublisherAware:在Bean中可以得到应用上下文的事件发布器,从而可以在Bean中发布应用上下文的事件

ResourceLoaderAware:在Bean中可以得到resourceloader,从而在Bean中使用ResourceLoader加载外部对应的Resource资源

要在自定义的Bean中获取上述资源,只需要让Bean实现对应的接口,并覆写set方法,如下:

public class TestSpring implements ApplicationContextAware{private ApplicationContext applicationContext;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext = applicationContext;}
}

这样这个Bean实现了ApplicationContextAware接口,并覆写setApplicationContext方法,就可以获取到ApplicationContext对象。

这个setApplicationContext方法的回调是容器自动完成的,容器调用该方法的时候,我们就可以将容器传入的参数applicationContext保存起来以供使用

setApplicationContext方法被容器的自动调用是在BeanPostProcessor接口的方法postProcessBeforeInitialization中完成的,实现是在ApplicationContextAwareProcessor类中,具体代码如下:

class ApplicationContextAwareProcessor implements BeanPostProcessor {private final ConfigurableApplicationContext applicationContext;private final StringValueResolver embeddedValueResolver;/*** Create a new ApplicationContextAwareProcessor for the given context.*/public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) {this.applicationContext = applicationContext;this.embeddedValueResolver = new EmbeddedValueResolver(applicationContext.getBeanFactory());}@Overridepublic 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(new PrivilegedAction<Object>() {@Overridepublic Object run() {invokeAwareInterfaces(bean);return null;}}, acc);}else {invokeAwareInterfaces(bean);}return bean;}
//这里就是容器自动调用set方法的地方,其实就是调用自定义的TestSpring类实现的setApplicationContext方法,这样TestSpring类就获取到了applicationContextprivate 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);}}}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) {return bean;}}

Spring IOC学习心得之Bean对IOC容器的感知相关推荐

  1. Spring IOC学习心得之注册bean的依赖关系

    registerDependentBean方法的解析(注册bean的依赖关系) 源码如下: public void registerDependentBean(String beanName, Str ...

  2. Spring IOC学习心得之IOC容器的初始化过程

    注:本文大多数内容都是摘自<Spring技术内幕>这本书 简单来说,Ioc容器的初始化过程是在refresh()方法中启动的,包括BeanDefinition的Resource定位,载入和 ...

  3. Spring IOC学习心得之源码级分析ContextLoaderListener的作用(IOC容器初始化入口)

    ContextLoaderListener类是负责初始化IOC容器,即在我们的web项目中,这里就是IOC容器初始化的入口,由这个类启动IOC容器的初始化. 它配置在web.xml中,比如如下配置: ...

  4. spring深入学习(十九) IOC 之 Factory 实例化 bean

    这篇我们关注创建 bean 过程中的第一个步骤:实例化 bean,对应的方法为:createBeanInstance(),如下: protected BeanWrapper createBeanIns ...

  5. Java学习笔记-Spring IoC 通过XML把Bean给IoC容器

    运行截图如下: 程序结构: 源码如下: Bean.java package springioc.demo.bean;public class Bean {public Bean(){System.ou ...

  6. Spring IOC学习心得之BeanPostProcessor,BeanNameAware,BeanClassLoaderAware,BeanFactoryAware接口是如何起作用的

    1. 首先说下BeanPostProcessor接口中的两个方法,如下: package org.springframework.beans.factory.config;import org.spr ...

  7. spring的学习心得

    IOC模块 什么是ioc IOC 是Inversion of Control的缩写,多数书籍翻译成"控制反转" IOC的核心是通过set注入来实现控制的反转. 代码案例: 一个us ...

  8. Spring框架学习3:bean元素属性

    Spring的bean的常用属性 1.scope scope用来配置bean对象是否是单例模式.单例模式是java的23种设计模式之一,指在这个项目运行中一个类的对象只会实例化一次,一般工厂创建的类都 ...

  9. spring cloud 学习心得

    学习记录 近一个月,因水利厅短信平台改造的需要,我开始学习Spring Boot和如何构建Spring Cloud分布式项目,但是因为我学力有限,未能完成此项目的改造,但从中学习到了很多新的知识,在此 ...

最新文章

  1. 2021-07-27 对labelme标注出来的JSON文件进行灰度图转化(标签值0.1.2.3.4)
  2. uva 12426 Counting Triangles 计算几何
  3. 设置元素的宽和高 元素的left和top 元素卷曲出去的值 为元素绑定事件
  4. 审稿意见说我引言和结论写的毫无差别!
  5. php 页面异步刷新,php+jQuery+Ajax简单实现页面异步刷新
  6. assemblyinstaller 无法启动计算机.上的服务,本地计算机上的Windows Search服务启动然后停止 | MOS86...
  7. Springboot的工作机制:1 Springboot初体验
  8. kepware odata 接口访问地址
  9. 大家崇拜凯文.米特尼克吗?
  10. CMakeLists.txt范例
  11. D200和D2X区别
  12. 群晖java安装失败_群晖NAS安装Jenkins
  13. 五星填数(全排列问题)
  14. 一男老师每日百词转载+连载(2)
  15. 关于printf输出之左对齐与右对齐
  16. Python 网络编程之网络协议(未完待续)
  17. 大厂对软件测试的误解这么深吗?测试岗会越来越少吗?该怎样提升技术?
  18. 华润置地php面试题_华润置地有限公司面试攻略,面试题,面试技巧及流程(附笔试,评论,薪资)-金针菇企评网...
  19. 《HelloGitHub》第 39 期
  20. 实施顾问试水软件开发,只要1天培训,搭搭云全家桶果真神奇

热门文章

  1. CentOS7虚拟机优化
  2. Nodejs模块初始化
  3. 20171113_Python学习五周一次课
  4. MySQL性能优化(来源于简书)
  5. php 日期时间操作-可算出几天后的时间
  6. 用“混序”替代鲍尔默
  7. 使用beanShell来解析执行java的String方法,类似javascipt的eval方法
  8. windows8 开发教程 教你制作 多点触控Helper可将任意容器内任意对象进行多点缩放...
  9. 文件传送,如此简单--ESFramework 4.0 快速上手(13)
  10. SQL Sever 错误和异常处理