IOC:控制反转(Inversion of control),是一种设计思想。DI(依赖注入)是实现IOC的一种方法。
一、概述
Spring IOC是一种思想,假如一个系统中有大量组件,都需要我们去手动管理他们的生命周期和维持他们之间的关系,对于程序员来说,是非常不好管理的,不仅增加了系统的开发难度,也使他们的依赖具有很强的耦合性,为了更好的管理组件,由此引入了Spring IOC的思想,利用Spring容器去管理大量组件。
把原先代码中需要开发者实现的对象创建和关系依赖,反转交给Spring IOC容器管理对象的生命周期和对象之前的依赖关系。
Spring通过配置文件描述Bean及Bean之间的依赖关系(或者是注解@annotation),利用Java语言的反射功能实例化Bean并建立Bean之间的依赖关系。
IOC容器主要好处:
- 容器管理所有的对象,不需要我们手动创建对象;
- 容器管理所有的依赖,在创建实例的时候不需要了解其中的细节。
二、依赖倒置
造汽车例子:先设计轮子,然后根据轮子大小设计底盘,接着根据底盘大小设计车身,然后完成整体。
依赖关系:汽车依赖车身,车身依赖底盘,底盘依赖轮子。
这样耦合度极高,一旦修改底层,就需要大动干戈。
如果反向设计,依赖倒置:轮子依赖底盘, 底盘依赖车身, 车身依赖汽车。就不会出现上面牵一发而动全身的情况。
三、控制反转
控制反转是依赖倒置原则的一种代码设计思路,具体采用的方法是依赖注入(Dependency Injection)。所谓依赖注入,上层控制底层,底层类作为参数传入上层类。
四、常用容器
1.BeanFactory
BeanFactory是Spring框架的基础设施,是IOC容器的基础接口,所有容器都是从它这里继承实现而来。BeanFactory作为Spring IOC容器,为了能够明确描述各个对象之间的依赖关系,Spring提供了三种管理方式:
- xml中进行显示配置;
- java中进行显示配置(实现依赖implements、继承依赖extends、关联依赖);
- 注解方式;
Spring依赖注入方式:
- 构造方法注入
- setter方法注入
- 注解方式注入
2.ApplicationContext
如果说BeanFactory是Spring的“心脏”,那么ApplicationContext 就是完整的“身躯”了。ApplicationContext由BeanFactory派生而来,提供了更多面向实际应用的功能。在BeanFactory中,很多功能需要以编程的方式实现,而在ApplicationContext中则可以通过配置的方式实现。 从图可以看出,ApplicationContext 继承了HierarchicalBeanFactory 和ListableBeanFactory接口,在此基础上,还通过多个其他的接口扩展了BeanFactory 的功能。这些接口如下:
- BeanFactory:能够管理和装配Bean。
- ResourcePatternResolver:能够加载资源文件。
- MessageResource:能够实现国际化等功能。
- ApplicationEventPublisher:能够注册监听器,实现监听机制。
- LifeCycle:提供了start和stop两个方法,主要用于控制异步处理过程。
Spring自带多种类型的应用上下文:
1.AnnotationConfigApplicationContext:从一个或多个基于Java的配置类中加载Spring应用上下文。
ApplicationContext context = new AnnotatinonConfigApplicationContext(com.cmos.DemoConfig.class);
2.AnnotationConfigWebApplicationContext:从一个或多个基于Java的配置类中加载SpringWeb应用上下文。
3.ClassPathXmlApplicationContext:从类路径下的一个或多个XML配置文件中加载上下文定义,把应用上下文的定义文件作为类资源。
ApplicationContext context = new ClassPathXmlApplicationContext("demo.xml");
4. FileSystemXmlApplicationContext:从文件系统下的一个或多个XML配置文件中加载上下文定义。
ApplicationContext context = new FileSystemXmlApplicationContext("c:/demo.xml");
5.XmlWebApplicationContext:从Web应用下的一个或多个XML配置文件中加载上下文定义。
五、Bean的作用域
- singleton:这种Bean范围是默认的。确保不管接受到多个请求,每个容器中只有一个Bean的实例,单例模式由BeanFactory自身来维护。
- prototype:原型范围与单例范围相反,为每一个Bean请求提供一个实例。
- request:在请求Bean范围内会为每一个来自客户端的网络请求创建一个实例,在请求完成以后,Bean会失效并被垃圾回收器回收。
- session:与请求范围类似,确保每个session中有一个Bean的实例,在session过期后,Bean会随之失效。
- global-session:global-session和Portlet应用相关。当你的应用部署在Portlet容器中工作时,它包含很多 portlet。如果你想要声明让所有的 portlet 共用全局的存储变量的话,那么这全局变量需要存储在global-session 中。全局作用域与Servlet中的session 作用域效果相同。