文中涉及的spring版本号为4.1.8.RELEASE;

原文地址:https://blog.csdn.net/boling_cavalry/article/details/81603303

BeanFactory接口

在spring容器中,BeanFactory接口是IOC容器要实现的最基础的接口,定义了管理bean的最基本的方法,例如获取实例、基本的判断等,如下图:

BeanFactory有多个子接口来进一步扩展bean相关的功能,以下两个与本文有直接关系,需要关注:
1. HierarchicalBeanFactory:beanFactory可以设置ParentBeanFactory,这个接口的两个方法都是和ParentBeanFactory相关的,getParentBeanFactory方法返回ParentBeanFactory,containsLocalBean方法是相对containsBean方法而言的,containsBean方法找不到bean的时候会通过ParentBeanFactory去找,而containsLocalBean只在当前beanFactory找;
2. ListableBeanFactory:主要用于获取bean相关信息,例如获取所有bean名称,查找指定类型的所有bean等,如下图:

ApplicationContext接口

关于ApplicationContext和BeanFactory的关系,看类图即可一目了然:

原来ApplicationContext继承了HierarchicalBeanFactory和ListableBeanFactory,也就是说前面看到的接口特性都被ApplicationContext继承下来了,另外通过类图可以发现,ApplicationContext还继承了诸如Environment、Resource、Message、Event
等相关的接口,也就是说除了bean的管理配置相关的能力,ApplicationContext还拥有了Environment(环境)、MessageSource(国际化)、ResourceLoader(资源)、ApplicationEventPublisher(应用事件)等服务相关的接口,简单的说ApplicationContext是以bean管理为基础的综合能力扩展,用于满足业务对Spring综合能力的需要;

再看看ApplicationContext源码,除了继承,它自身也提供了一些扩展的能力:

public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,MessageSource, ApplicationEventPublisher, ResourcePatternResolver {//标识当前context实例的id,最终会通过native方法来生成:System.identityHashCodeString getId();//返回该context所属的应用名称,默认为空字符串,在web应用中返回的是servlet的contextpath String getApplicationName();//返回当前context的名称String getDisplayName();//返回context第一次被加载的时间long getStartupDate();//返回该context的parentApplicationContext getParent();//返回具有自动装配能力的beanFactory,默认返回的就是初始化时实例化的beanFactoryAutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;
}

小结:
1. BeanFactory是基础,BeanFactory和它的子接口定义的API满足了spring环境中对bean管理和配置的需求;
2. ApplicationContext是扩展,以BeanFactory为主线,通过继承的方式综合了环境、国际化、资源、事件等多条支线,自己又规定了一些扩展服务(如返回context的id,应用名称等),而所有支线都以bean服务为基础;

实现类解析

如果有个类实现了ApplicationContext接口,就必须实现上述多个接口定义的方法,这个类岂不是很复杂?我们看看AbstractApplicationContext类的源码,这是个基础抽象类,常用的ClassPathXmlApplicationContext、AnnotationConfigServletWebServerApplicationContext等都继承自AbstractApplicationContext;

先看看是如何实现BeanFactory接口中定义的方法的:

    @Overridepublic Object getBean(String name) throws BeansException {assertBeanFactoryActive();return getBeanFactory().getBean(name);}@Overridepublic <T> T getBean(String name, Class<T> requiredType) throws BeansException {assertBeanFactoryActive();return getBeanFactory().getBean(name, requiredType);}@Overridepublic <T> T getBean(Class<T> requiredType) throws BeansException {assertBeanFactoryActive();return getBeanFactory().getBean(requiredType);}@Overridepublic Object getBean(String name, Object... args) throws BeansException {assertBeanFactoryActive();return getBeanFactory().getBean(name, args);}@Overridepublic <T> T getBean(Class<T> requiredType, Object... args) throws BeansException {assertBeanFactoryActive();return getBeanFactory().getBean(requiredType, args);}@Overridepublic boolean containsBean(String name) {return getBeanFactory().containsBean(name);}@Overridepublic boolean isSingleton(String name) throws NoSuchBeanDefinitionException {assertBeanFactoryActive();return getBeanFactory().isSingleton(name);}@Overridepublic boolean isPrototype(String name) throws NoSuchBeanDefinitionException {assertBeanFactoryActive();return getBeanFactory().isPrototype(name);}@Overridepublic boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException {assertBeanFactoryActive();return getBeanFactory().isTypeMatch(name, targetType);}@Overridepublic Class<?> getType(String name) throws NoSuchBeanDefinitionException {assertBeanFactoryActive();return getBeanFactory().getType(name);}@Overridepublic String[] getAliases(String name) {return getBeanFactory().getAliases(name);}

看过上述代码后恍然大悟,原来AbstractApplicationContext并没有自己来完成bean的管理配置,而是全部委托给了getBeanFactory()方法返回的这个实例,接口是组合,实现也是组合,这种清晰的设计是学习典范;

再来看看getBeanFactory()方法,解释究竟是谁在真正的提供bean的管理配置服务,该方法的实现在AbstractApplicationContext的子类AbstractRefreshableApplicationContext中,代码很简单,返回了成员变量beanFactory:

public final ConfigurableListableBeanFactory getBeanFactory() {synchronized (this.beanFactoryMonitor) {if (this.beanFactory == null) {throw new IllegalStateException("BeanFactory not initialized or already closed - " +"call 'refresh' before accessing beans via the ApplicationContext");}return this.beanFactory;}}

该成员变量在refreshBeanFactory方法中实例化,而refreshBeanFactory方法又是在spring容器初始化的时候调用的,所以容器初始化之后,AbstractApplicationContext就具备了bean管理配置的能力;

扩展思考

看了AbstractApplicationContext类中beanFactory相关的代码,我就猜想:莫非Message支线也是这个套路,委托给Message服务相关的实例来完成?看代码吧:

    @Overridepublic String getMessage(String code, Object args[], String defaultMessage, Locale locale) {return getMessageSource().getMessage(code, args, defaultMessage, locale);}@Overridepublic String getMessage(String code, Object args[], Locale locale) throws NoSuchMessageException {return getMessageSource().getMessage(code, args, locale);}@Overridepublic String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException {return getMessageSource().getMessage(resolvable, locale);}

如上所示,果然如此,Message相关的接口实现,都是getMessageSource()方法返回的实例在承担,getMessageSource()方法返回的是成员变量messageSource,该成员变量也是在spring容器初始化的时候,调用initMessageSource方法生成的;

至此,通过查看源码,我们对spring的BeanFactory和ApplicationContext有了更清晰的认识,又经历了一次结合类图分析源码的实践,在您学习spring的路上,希望本文能助您一臂之力,一起学习、共同进步;

spring的BeanFactory和ApplicationContext相关推荐

  1. 请说明一下Spring中BeanFactory和ApplicationContext的区别是什么?

    请说明一下Spring中BeanFactory和ApplicationContext的区别是什么? BeanFactory: 是spring中比较原始,比较古老的Factory.因为比较古老,所以Be ...

  2. [读书笔记]Spring中BeanFactory和ApplicationContext的联系和区别

    写在前言 依赖反转是指依赖对象的获得被反转了.依赖控制反转的实现有很多方式,Spring中IOC容器是实现这个模式的载体,它可以在对象生成或初始化时直接将数据注入到对象中,也可以通过将对象引用注入到对 ...

  3. Spring 的IOC容器系列的设计与实现:BeanFactory 和 ApplicationContext

    在Spring IOC容器的设计中,我们可以看到两个主要的容器系列,一个是实现BeanFactory接口的简单容器系列,这系列容器只实现了容器的最基本的功能,另一个是ApplicationContex ...

  4. Spring系列之beanFactory与ApplicationContext

    一.BeanFactory BeanFactory 是 Spring 的"心脏".它就是 Spring IoC 容器的真面目.Spring 使用 BeanFactory 来实例化. ...

  5. Spring - Java/J2EE Application Framework 应用框架 第 3 章 Beans, BeanFactory和ApplicationContext

    第 3 章 Beans, BeanFactory和ApplicationContext 3.1. 简介 在Spring中,两个最基本最重要的包是 org.springframework.beans 和 ...

  6. Spring IoC(一)IoC容器的设计与实现:BeanFactory与ApplicationContext

    在写BeanFactory与ApplicationContext 之前,我想先简单聊一聊Spring IoC 容器,希望能给大家一个参考.如果你对这反面的知识比较了解,可以直接跳过. (一)Sprin ...

  7. SSM 整合 4:Spring IoC 容器基于的两个重要接口 BeanFactory 和 ApplicationContext

    文章目录 前言 一.BeanFactory 接口 1.1.加载 Spring 配置文件创建 BeanFactory 接口实例 1.2.开发中的运用以及使用说明 二.ApplicationContext ...

  8. Spring的三大核心接口——BeanFactory、ApplicationContext、WebApplicationContext

    之前也在用这三个接口,但是对于他们的概念还是处于朦胧状态,同时,也不知道他们之间是一个什么关系,趁着现在有点时间总结一下吧,也需要对你有所帮助. 一.BeanFactory        基本认识: ...

  9. 【Spring】IoC容器系列的设计与实现:BeanFactory和ApplicationContext

    在Spring IoC容器的设计中,我们可以看到两个主要的容器系列,一个是实现BeanFactory接口的简单容器系列,这系列容器只实现了容器的最基本功能,另一个是ApplicationContext ...

  10. java基础巩固-宇宙第一AiYWM:为了维持生计,Spring全家桶_Part1-5(学学Spring源码呗:BeanFactory与ApplicationContext的暗潮涌动与争风吃醋)~整起

    上一集说到,天色渐暗- BeanFactory接口说:一大堆XxxFactory,都跟我有关,我好累呀[BeanFacotry作为Spring中容器功能的基础,用于存放所有已经加载的bean]. Xm ...

最新文章

  1. Matrix Power Series
  2. Ext JS学习第五天 Ext_window组件(二)
  3. vue中mixins的理解
  4. 在Spring + Hibernate中使用二级缓存配置步骤
  5. Spring经典面试题
  6. LeetCode 513. Find Bottom Left Tree Value
  7. 视频专家之路【三】:Vs开发环境的搭建
  8. 维纳滤波python 函数_python实现逆滤波与维纳滤波示例
  9. php 真太阳时间修正,真太阳时查询表(建议收藏)
  10. win7计算机扫描仪,win7系统怎么用打印机扫描仪功能|win7系统扫描仪功能的使用方法...
  11. 水果常识大全【图文典藏版】
  12. JSON (JavaScript Object Notation)
  13. Tic tac toe井字棋游戏python实现
  14. 【thinkphp5.1】htmlentities() expects parameter 1 to be string, array given
  15. Scratch软件编程等级考试一级——20200913
  16. 带你了解大数据时代的基本特征
  17. 【GIT】git常用命令
  18. 计算机三级那个比较容易一点,计算机三级,哪一种比较容易过?
  19. Java中xml转义字符和gt,gte,lt,lte缩写
  20. 什么是云仓一件代发?电商物流云仓,新疆云仓

热门文章

  1. linux下.dep文件,Linux 安装 golang 和 dep (附错两个误解决方法)
  2. 9.2 正方形 2711
  3. 数字电路实验怎么接线视频讲解_220V电动葫芦实物接线图
  4. Java doc或docx转pdf文件预览
  5. CentOs7+安装ApacheOpenOffice实现DOC转PDF详解(解决乱码问题)
  6. 研究生学习生活日记——第十三次组会
  7. 吃货在东京 -- 记那段吃不饱的日子 之二 丰州的雪花牛肉
  8. wordpress最佳架构_动物和宠物的24个最佳WordPress主题
  9. NOIP 模拟题 小G的城堡
  10. 数字电子钟—VHDL 设计