爱上极客's Archivers

From yan on 2018-04-12 13:53:05

Spring基础——容器和应用上下文的理解

Spring的核心之一——IOC容器,通过依赖注入(DI)的方式用来管理关联对象的生命周期。使得业务代码只需要关注业务本身的流程,需要另外的对象来协助了,就跟Spring说,我想要个对象——于是Spring就很贴心的给你个对象,但是这是怎么实现的呢?本文将简单剖析这些间的关系与理解,不做源码的追究

Spring容器


前文已经说了,Spring的容器就是负责管理对象的,你需要的时候,一张嘴就给你了。那么Spring既然要负责系统中那么多对象的创建管理,就像苹果要生产那么多的手机(对象)一样,肯定有一个专门搞对象的地方。苹果生产手机的地方叫工厂,比如富士康,但放在软件开发中,对于Spring搞对象的地方我们就不叫工厂了,而叫做容器

容器的概念在java中最熟悉的莫过于Tomcat了,它正是一个运行Servlet的web容器,而Spring要想实现依赖注入功能,就离不开对象生产的容器——如果没有容器负责对象的创建管理,你的程序代码只是喊要对象了,Spring也无处给你啊。实际上,容器是Spring框架实现功能的核心,容器不只是帮我们创建了对象那么简单,它负责了对象整个的生命周期的管理——创建、装配、销毁。

关于Spring的这个容器最常听闻的一个术语就是IOC容器。所谓IOC,是一种叫控制反转的编程思想,网上有很通俗易懂的总结,我就不胡乱阐述了。总之一句话,我的应用程序里不用再过问对象的创建和管理对象之间的依赖关系了,都让IOC容器给代劳吧,也就是说,我把对象创建、管理的控制权都交给Spring容器,这是一种控制权的反转,所以Spring容器才能称为IOC容器。

但是说清一点,并不是只有Spring的容器才叫IOC容器,基于IOC容器的框架还有很多,并不是Spring特有的。本文只是用最常用的Spring容器来讲解IOC,以便于大家理解。

IOC和DI


说完了容器,那么IOC和DI之间是什么关系呢?

IOC容器像是一个大盒子,里面放了很多对象实例,并且维护它们的创建、销毁等生命周期。DI是指一种方法,当你使用某个对象时候,你喊一声,盒子就自动把对象拿出来给你,省去了自己创建的步骤,这个过程叫做依赖注入。

应用上下文


好了,终于把Spring的容器概念阐述的差不多了,但有什么卵用呢?光有容器你其实什么都干不了!你以为容器那么科幻,跟叮当猫面前的百宝袋一样,你想要啥它就给你啥?实际上,容器里面什么都没有,决定容器里面放什么对象的是我们自己,决定对象之间的依赖关系的,也是我们自己,容器只是给我们提供一个管理对象的空间而已。

那么,我们怎么向容器中放入我们需要容器代为管理的对象呢?这就涉及到Spring的应用上下文了。什么是应用上下文呢?

应用上下文可以简单的理解成Spring容器的一种实现,即用于操作容器的容器类对象。通过上下文可以将需要Spring帮你管理的对象放入容器中,使用时调用上下文的方法取得容器里的Bean。

比如我们常见的应用上下文ApplicationContext接口,本质目的就是维护容器中bean定义以及对象之间关系,在使用时通过getBean方法获得容器中的Bean。

这里,我们必须明确,Spring的核心是容器,而容器并不唯一,框架本身就提供了很多个容器的实现,大概分为两种类型:一种是不常用的BeanFactory,这是最简单的容器,只能提供基本的DI功能;还有一种就是继承了BeanFactory后派生而来的应用上下文,其抽象接口也就是我们上面提到的的ApplicationContext,它能提供更多企业级的服务,例如解析配置文本信息等等,这也是应用上下文实例对象最常见的应用场景。有了上下文对象,我们就能向容器注册需要Spring管理的对象了。

对于上下文抽象接口,Spring也为我们提供了多种类型的容器实现,供我们在不同的应用场景选择——

  1. AnnotationConfigApplicationContext:从一个或多个基于java的配置类中加载上下文定义,适用于java注解的方式;

  2.  ClassPathXmlApplicationContext:从类路径下的一个或多个xml配置文件中加载上下文定义,适用于xml配置的方式;

  3.  FileSystemXmlApplicationContext:从文件系统下的一个或多个xml配置文件中加载上下文定义,也就是说系统盘符中加载xml配置文件;

  4.  AnnotationConfigWebApplicationContext:专门为web应用准备的,适用于注解方式;

  5.  XmlWebApplicationContext:从web应用下的一个或多个xml配置文件加载上下文定义,适用于xml配置方式。


有了以上理解,问题就很好办了。你只要将你需要IOC容器替你管理的对象基于xml也罢,java注解也好,总之你要将需要管理的对象(Spring中我们都称之问bean)、bean之间的协作关系配置好,然后利用应用上下文对象加载进我们的Spring容器,容器就能为你的程序提供你想要的对象管理服务了。

示例


XML形式


先采用xml配置的方式配置bean和建立bean之间的协作关系:








然后通过应用上下文将配置加载到IOC容器,让Spring替我们管理对象,待我们需要使用对象的时候,再从容器中获取bean就ok了:
public class Test {
public static void main(String[] args) {
//加载项目中的spring配置文件到容器
// ApplicationContext context = new ClassPathXmlApplicationContext("resouces/applicationContext.xml");
//加载系统盘中的配置文件到容器
ApplicationContext context = new FileSystemXmlApplicationContext("E:/Spring/applicationContext.xml");
//从容器中获取对象实例
Man man = context.getBean(Man.class);
man.driveCar();
}
}

Java注解形式


类中配置:
//同xml一样描述bean以及bean之间的依赖关系
@Configuration
public class ManConfig {
@Bean
public Man man() {
return new Man(car());
}
@Bean
public Car car() {
return new QQCar();
}
}

通过容器调用:
public class Test {
public static void main(String[] args) {
//从java注解的配置中加载配置到容器
ApplicationContext context = new AnnotationConfigApplicationContext(ManConfig.class);
//从容器中获取对象实例
Man man = context.getBean(Man.class);
man.driveCar();
}
}

总结


容器和应用上下文是密不可分的,或者可以理解成是一样的(ApplicationContext继承自BeanFactory,上下文是容器实现的一种)。容器是个抽象的概念,上下文是其具体实现,让开发者利用上下文完成对容器的操作功能。

查看完整版本: Spring基础——容器和应用上下文的理解

Tags:


©爱上极客