BeanFactory和 ApplicationContext的关系详解

Spring 作者 Rod Johnson 设计了两个接口用以表示容器。

BeanFactory

ApplicationContext

BeanFactory 简单粗暴,可以理解为就是个 HashMapKey  BeanNameValue  Bean 实例。通常只提供注册(put),获取(get)这两个功能。我们可以称之为 “低级容

ApplicationContext 可以称之为 “高级容器。因为他比 BeanFactory 多了更多的功能。他继承了多个接

口。因此具备了更多的功能。例如资源的获取,支持多种消息(例如 JSP tag 的支持),对

BeanFactory 多了工具级别的支持等待。所以你看他的名字,已经不是 BeanFactory 之类的工厂了,而

 “应用上下文, 代表着整个大容器的所有功能。该接口定义了一个 refresh 方法,此方法是所有阅读

Spring 源码的人的最熟悉的方法,用于刷新整个容器,即重新加载/刷新所有的 bean

当然,除了这两个大接口,还有其他的辅助接口,这里就不介绍他们了。

BeanFactoryApplicationContext的关系

为了更直观的展示 “低级容器 “高级容器的关系,这里通过常用的

ClassPathXmlApplicationContext 类来展示整个容器的层级 UML 关系。

有点复杂? 先不要慌,我来解释一下。

最上面的是 BeanFactory,下面的 3 个绿色的,都是功能扩展接口,这里就不展开讲。

看下面的隶属 ApplicationContext 粉红色的 “高级容器,依赖着 “低级容器,这里说的是依赖,不是继

承哦。他依赖着 “低级容器 getBean

能。而高级容器有更多的功能:支持不同的信息源头,可以访问文件资源,支持应用事件(Observer

式)。

通常用户看到的就是 “高级容器。 但 BeanFactory 也非常够用啦!左边灰色区域的是 “低级容器, 只

负载加载 Bean,获取 Bean。容器其他的高级功能是没有的。例如上图画的 refresh 刷新 Bean 工厂所

有配置,生命周期事件回调等。

小结

说了这么多,不知道你有没有理解Spring IoC? 这里小结一下:IoC  Spring 里,只需要低级容器就可

以实现,2 个步骤:

1. 加载配置文件,解析成 BeanDefinition 放在 Map 里。

2. 调用 getBean 的时候,从 BeanDefinition 所属的 Map 里,拿出

Class 对象进行实例化,同时,如果有依赖关系,将递归调用 getBean 方法 —— 完成依赖注入。上面就是 Spring 低级容器(BeanFactory)的 IoC

至于高级容器 ApplicationContext,他包含了低级容器的功能,当他执行 refresh 模板方法的时候,将

刷新整个容器的 Bean。同时其作为高级容器,包含了太多的功能。一句话,他不仅仅是 IoC。他支持不

同信息源头,支持

BeanFactory 工具类,支持层级容器,支持访问文件资源,支持事件发布通知,支持接口回调等等。

ApplicationContext通常的实现是什么?

FileSystemXmlApplicationContext :此容器从一个XML文件中加载beans 的定义,XML Bean 配置文

件的全路径名必须提供给它的构造函数。

ClassPathXmlApplicationContext:此容器也从一个XML文件中加载beans 的定义,这里,你需要正确

设置classpath因为这个容器将在classpath里找 bean配置。

WebXmlApplicationContext:此容器加载一个XML文件,此文件定义了一个WEB应用的所有bean

什么是Spring的依赖注入?

控制反转IoC是一个很大的概念,可以用不同的方式来实现。其主要实现方式有两种:依赖注入和依赖查

找依赖注入:相对于IoC而言,依赖注入(DI)更加准确地描述了IoC的设计理念。所谓依赖注入

Dependency Injection),即组件之间的依赖关系由容器在应用系统运行期来决定,也就是由容器动

态地将某种依赖关系的目标对象实例注入到应用系统中的各个关联的组件之中。组件不做定位查询,只

提供普通的Java方法让容器去决定依赖关系。

依赖注入的基本原则

依赖注入的基本原则是:应用组件不应该负责查找资源或者其他依赖的协作对象。配置对象的工作应该

IoC容器负责,查找资源的逻辑应该从应用组件的代码中抽取出来,交给IoC容器负责。容器全权负

责组件的装配,它会把符合依赖关系的对象通过属性(JavaBean中的setter)或者是构造器传递给需要

的对象。

依赖注入有什么优势

依赖注入之所以更流行是因为它是一种更可取的方式:让容器全权负责依赖查询,受管组件只需要暴露

JavaBeansetter方法或者带参数的构造器或者接

口,使容器可以在初始化时组装对象的依赖关系。其与依赖查找方式相比,主要优势为:

查找定位操作与应用代码完全无关。

不依赖于容器的API,可以很容易地在任何容器以外使用应用对象。

不需要特殊的接口,绝大多数对象可以做到完全不必依赖容器。

有哪些不同类型的依赖注入实现方式?

依赖注入是时下最流行的IoC实现方式,依赖注入分为接口注入(Interface Injection),Setter方法注

入(Setter Injection)和构造器注入(Constructor

Injection)三种方式。其中接口注入由于在灵活性和易用性比较差,现在从Spring4开始已被废弃。

构造器依赖注入:构造器依赖注入通过容器触发一个类的构造器来实现的,该类有一系列参数,每个参

数代表一个对其他类的依赖。

Setter方法注入:Setter方法注入是容器通过调用无参构造器或无参static工厂 方法实例化bean之后,

调用该beansetter方法,即实现了基于setter的依赖注入。构造函数注入

setter注 入

没有部分注入

有部分注入

不会覆盖 setter 属 性

会覆盖 setter 属 性

任意修改都会创建一个新实例

任意修改不会创建一个新实例

适用于设置很多属性

适用于设置少量属性

构造器依赖注入和 Setter方法注入的区别

两种依赖方式都可以使用,构造器注入和Setter方法注入。最好的解决方案是用构造器参数实现强制依

赖,setter方法实现可选依赖。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

伟大先锋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值