Spring容器

正如大家熟知的那样,我们的电脑是由各种部件组成的。比如中央处理器,内存,硬盘,网卡,电源,等等。这些部件一起运转,彼此合作,各显神通。由是电脑跑起来了,我们可以用它写代码,玩游戏,上网,工作,听歌,画画,等等。

软件开发也是一样的。我们需要定义各种各样的类,每个类都有自己的功能,作用,职责。之后,我们使用这些定义好的类创建各种对象。这些对象相互合作,彼此依赖,各显神通。由是软件跑起来了,能够按照我们期望的那样工作。

由此可见,一款软件是由各种对象组成的。对象之间一定是相互合作,彼此依赖的。这种依赖就是我们通常所说的耦合。试想,当我们的软件非常庞大,由成千上万个对象组成时,这些对象通过各种关系紧紧耦合在一起,将使软件多么复杂,多么难以维护,多么容易出错!难道就没有什么办法能够解耦,以降低对象之间的耦合,降低软件开发的复杂度吗?

当然有的。实践证明,正确使用Spring容器(Spring Container)是能降低对象之间的耦合,降低软件开发的复杂度的。问题在于,Spring容器是什么?为何它能降低对象之间的耦合,降低软件开发的复杂度?为了弄清这些问题,让我们先来看看什么是控制反转(Inversion of Control,IoC),什么是依赖注入(Dependency Injection,DI)

不知大家可还记得,前文实现Hello World的时候曾经提到两种创建对象的方式:一种方式是传统的,我们自己创建对象;一种方式是Spring的,我们只需提供配置文件,告诉Spring应用上下文需要创建哪些对象,再由Spring应用上下文根据配置文件提供的信息创建相应的对象即可。可以看到,这种方式把创建对象的控制权让了出来,转而交给Spring应用上下文。也就是说,创建对象的方式反转了,由我们自己创建转向由Spring应用上下文创建。于是,一种全新的编程思想出现了,这就是控制反转。

那么,依赖注入又是什么呢?

其实,依赖注入和控制反转是同种东西,只是叫法不同而已。这就好比计算机又叫电脑一样。至于控制反转因何又叫依赖注入,可从什么是依赖,什么是依赖注入谈起。而这,主要涉及对象之间的关系。比如,现有类A和类B,它们之间的关系如下:

 1 public class A {
 2 }
 3 
 4 public class B {
 5     private A a;
 6 
 7     public A getA() {
 8         return this.a;
 9     }
10 
11     public void setA(A a) {
12         this.a = a;
13     }
14 }

假如我们需要创建类B的对象,这时可以这样做:

1 var a = new A();
2 var b = new B();
3 b.setA(a);

这段代码创建了两个对象:对象a和对象b。它们之间是有关系的,对象b需要对象a。也就是说,对象b依赖于对象a。这就是依赖了。我们调用b.setA(a)方法把a赋给b时,其实就是把a这个依赖注入到b这个对象里去。这就是依赖注入了。

正如前文所言,控制反转是指把那些关于创建对象的事交给Spring应用上下文做。Spring应用上下文创建对象的过程其实就是Spring应用上下文根据配置文件提供的信息创建对象,注入对象所需的依赖的过程。因此,控制反转又叫依赖注入。

那么,Spring容器又是什么?它和控制反转之间是否存在着某些亲密的关系?

其实,Spring容器同大家熟知的Web容器一样,也是一种容器。而容器,简单来说就是一个环境,一个采用Java这种编程语言实现的环境。这个环境提供了一些服务,用于服务跑在这个环境里的程序。只是不同的容器提供的服务不同而已。比如,Web容器主要提供了处理请求,响应请求等服务;Spring容器则不同,主要提供了创建对象,装配对象,管理对象等服务。

于是Spring定义了ApplicationContext接口,采用多种方式对其进行实现,使之作为一个容器具有加载配置文件,解析配置文件,根据配置文件提供的信息创建对象的功能。于是,开发人员写好配置文件交给Spring容器,Spring容器就能根据配置文件提供的信息生成Bean的定义交给Bean工厂(Bean Factory)进行对象的创建。对象的创建分为两步:第一步是采用反射技术调用类的构建函数创建对象;第二步是注入对象所需的依赖,把对象关联起来,完成对象的装配(Wiring)。Bean工厂完成对象的创建之后,这些对象就存在Spring容器里,由Spring容器管理着。这些由Spring容器创建,装配和管理着的对象,通常称为Bean。我们需要Bean时,只需从Spring容器那里获取就行。

可以看到Spring容器与控制反转这种编程思想所提倡的对象创建方式是一样的。这是因为Spring容器就是Spring根据控制反转这种编程思想进行实现的。因此,Spring容器又叫控制反转容器(Inversion of Control Container),IoC容器(IoC Container),依赖注入容器(Dependency Injection Container),DI容器(DI Container)

又因Spring定义了ApplicationContext接口用于Spring容器的实现,ApplicationContext接口俗称Spring应用上下文。因此,Spring容器又叫Spring应用上下文。

另外,Spring应用上下文的实现并非只有一种;而是根据使用场景的不同具有多种不同的实现。常用的有以下五种:
1.ClassPathXmlApplicationContext
2.FileSystemXmlApplicationContext
3.AnnotationConfigApplicationContext
4.AnnotationConfigWebApplicationContext
5.XmlWebApplicationContext

不同的实现除了加载配置文件的方式不同之外,其它都是相似的。我们将从下章开始分篇介绍这些Spring应用上下文实现,进而揭开它们神秘而又强大的面纱。这里暂不详述。

至此,我们已然知道什么是Spring容器。只是关于配置文件能够怎么写,为何Spring容器能够降低对象之间的耦合,降低软件开发的复杂度这些事依旧一头雾水。俗话常言:“合抱之木,生于毫末;九层之台,起于累土。”事情总得一件一件慢慢完成,知识总得一点一点慢慢积累。匆忙之间,必难进益。因此,我们将从下章开始分篇介绍配置那些事。至于为何Spring容器能够降低对象之间的耦合,降低软件开发的复杂度;则将在介绍Spring MVC的时候进行讲解,这样大家理解起来比较容易。

返回目录    下载代码

posted @ 2020-04-07 10:32  林雪波  阅读(727)  评论(0编辑  收藏  举报