Spring容器及应用上下文

关于Spring的这个容器你最常听闻的一个术语就是IOC容器。所谓IOC,是一种叫控制反转的编程思想,把对象创建、管理的控制权都交给Spring容器,这是一种控制权的反转,所以Spring容器才能称为IOC容器。不过这里要厘清一点:并不是说只有Spring的容器才叫IOC容器,基于IOC容器的框架还有很多,并不是Spring特有的。

什么是应用上下文呢?应用上下文即是Spring容器的一种抽象化表述;而我们常见的ApplicationContext本质上说就是一个维护Bean定义以及对象之间协作关系的高级接口。这里,我们必须明确,Spring的核心是容器,而容器并不唯一,框架本身就提供了很多个容器的实现,大概分为两种类型:一种是不常用的BeanFactory,这是最简单的容器,只能提供基本的DI功能;还有一种就是继承了BeanFactory后派生而来的应用上下文,其抽象接口也就是我们上面提到的的ApplicationContext,它能提供更多企业级的服务,例如解析配置文本信息等等,这也是应用上下文实例对象最常见的应用场景。有了上下文对象,我们就能向容器注册需要Spring管理的对象了。对于上下文抽象接口,Spring也为我们提供了多种类型的容器实现,供我们在不同的应用场景选择——

AnnotationConfigApplicationContext:从一个或多个基于java的配置类中加载上下文定义,适用于java注解的方式;
ClassPathXmlApplicationContext:从类路径下的一个或多个xml配置文件中加载上下文定义,适用于xml配置的方式;
FileSystemXmlApplicationContext:从文件系统下的一个或多个xml配置文件中加载上下文定义,也就是说系统盘符中加载xml配置文件;
AnnotationConfigWebApplicationContext:专门为web应用准备的,适用于注解方式;
XmlWebApplicationContext:从web应用下的一个或多个xml配置文件加载上下文定义,适用于xml配置方式。
有了以上理解,问题就很好办了。你只要将你需要IOC容器替你管理的对象基于xml也罢,java注解也好,总之你要将需要管理的对象(Spring中我们都称之问bean)、bean之间的协作关系配置好,然后利用应用上下文对象加载进我们的Spring容器,容器就能为你的程序提供你想要的对象管理服务了。

1、两种配置方式

1、通过xml配置的方式配置bean,然后通过应用上下文将配置加载到IOC容器,让Spring替我们管理对象,待我们需要使用对象的时候,再从容器中获取bean就ok了:

springcloud上下文 spring上下文容器_java注解


还可以以数组形式:

springcloud上下文 spring上下文容器_加载_02

2、以上测试中,将配置文件applicationContext.xml分别放在项目中和任意的系统盘符下,只需要使用相应的上下文对象去加载配置文件,最后的结果是完全一样的。当然,现在项目中越来越多的使用java注解,所以注解的方式必不可少:

springcloud上下文 spring上下文容器_springcloud上下文_03


springcloud上下文 spring上下文容器_java注解_04


控制台输出:

springcloud上下文 spring上下文容器_spring_05

2、java注解配置基本注解

1、@Component注解

@Component是所有受Spring 管理组件的通用形式,@Component注解可以放在类的头上,把普通pojo实例化到spring容器中,告知Spring要为这类创建bean,相当于配置文件中的:

springcloud上下文 spring上下文容器_加载_06


泛指各种组件,就是说当我们的类不属于各种归类的时候(不属于@Controller、@Services等的时候,不好归类时),我们就可以使用@Component来标注这个类;

2、@ComponentScan注解:为扫描包注解,只能作用于类上,spring并不能自动启用组件扫描,需要进行显式的配置,使用了@CompontentScan注解来启用组件扫描。一个类上可以有多个@CompentScan注解。

springcloud上下文 spring上下文容器_加载_07


@CompentScan注解中配置baskPackage属性来完成设置。如果自动完成的配置中包含了我们不需要的部分,则可以使用注解中的exclude属性来剔除。如果不配置任何属性则扫描当前包及其子包

@controller 、@service、@repository 、@component 注解的类,都会把这些类纳入进spring容器中进行管理(被@ComponentScan扫描到);

3、@ComponentScans注解:

存在多个@ComponentScan时,可以使用@ComponentScans将这些@ComponentScan放在里面统一管理,@ComponentScans是一个数组。

springcloud上下文 spring上下文容器_加载_08

主类与配置类解耦:

之前都是使用main方法来进行测试的,在实际开发的过程中,如果我们不使用main方法来调用应用程序,也就是说我们的应用程序有可能是通过其他的手段来调用的,比如通过Controller、微信端、安卓端、或者直接通过web浏览器端等等,那么主类可能不存在,这时候@ComponentScan注解将没有地方放置,也就是说应用程序没有办法进行自动的组件扫描了,因此我们需要将主类与组件扫描注解@ComponentScan进行解耦,具体的解耦方式就是创建一个类进行组件扫描的配置,也就是配置类:

1、创建bean

springcloud上下文 spring上下文容器_springcloud上下文_09


2、创建配置类

springcloud上下文 spring上下文容器_java注解_10


3、主类

springcloud上下文 spring上下文容器_xml配置_11


4、运行,测试结果和之前一样

springcloud上下文 spring上下文容器_java注解_12