1. Spring Ioc的基本概念
控制反转(Inversion of Control,IoC),是一个比较抽象的概念,是Spring框架的核心,用来削减计算机程序的耦合问题。依赖注入(Dependency Injection,DI)是IoC另一个说法,只是从不同的角度描述相同的概念。
当某个对象需要调用另一个对象,在传统方式中调用,需要通过new的方式来创建对象。但是这种方式会增加调用者与被调用者之间的耦合性,不利于后期代码的维护和升级。
当Spring框架出现后,对象的实例不再由调用者创建,而是由Spring框架来创建。Spring容器负责控制程序之间的关系,而不是由调用者的程序代码直接控制。这样,控制权由调用者调用者转移到Spring容器,控制权发生了变化,这就是IOC。
从Spring容器角度看,Spring容器负责将被依赖的对象赋值给调用者的成员变量,相当于为调用者注入它所依赖的实例,这就是Spring的依赖注入。
可以说,Spring中实现控制反转的是IOc容器,其实现方法是依赖注入。
2. Spring IoC 容器
Spring Ioc 容器的设计主要是基于BeanFactory和ApplicationContext两个接口。
2.1 BeanFactory
BeanFactory由org.springframework.beans.factory.BeanFactory接口定义,它提供了完整的IoC服务支持,是一个管理Bean的工厂,主要负责初始化各种Bean。BeanFactory接口有多个实现类,其中比较常见的是org.springframework.beans.factory.xml.XmlBeanFactory,该类会根据配置文件中的定义来装配Bean。由于BeanFactory实例加载Spring配置文件在实际开发中并不常见,所以在这里便不写这个代码了
2.2 ApplicationContext
ApplicationContext是BeanFactory的子接口,也称应用上下文,由springframework.context.ApplicationContext接口定义。ApplicationContext接口除了包含BeanFactory的所有功能外,还添加了对国际化、资源访问、事件传播等内容的支持。
创建ApplicationContext接口实例有三种方法(通常用FileSystemXmlApplicationContext):
- FileSystemXmlApplicationContext
Java代码
1 | ApplicationContext ctx = new FileSystemXmlApplicationContext("bean.xml"); //加载单个配置文件 |
Java代码
1 | String[] locations = {"bean1.xml", "bean2.xml", "bean3.xml"}; |
Java代码
1 | ApplicationContext ctx =new FileSystemXmlApplicationContext("D:roject/bean.xml");//根据具体路径加载文件 |
- ClassPathXmlApplicationContext
Java代码
1 | ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml"); |
Java代码
1 | String[] locations = {"bean1.xml", "bean2.xml", "bean3.xml"}; |
注:其中FileSystemXmlApplicationContext和ClassPathXmlApplicationContext与BeanFactory的xml文件定位方式一样是基于路径的。
3. XmlWebApplicationContext
Java代码
1 | ServletContext servletContext = request.getSession().getServletContext(); |
2.3 依赖注入的类型
Spring框架依赖注入通常有两种实现方式,一种是使用构造方法注入,另一种是使用属性的setter方法注入。
(一般用setter方法注入)
我将会以代码的形式来展示。
一、构造方法注入
首先展示目录结构:
可以看到项目中有dao,service,test包分别建立在项目下。
TestDao.java
1 | package dao; |
TestDaoImpl.java
1 | package dao; |
TestService.java
1 | package service; |
TestServiceImpl.java
1 | package service; |
applicationContext.xml
这里的constructor-arg元素用于定义类构造方法的参数,index定义参数的位置,ref是指某个实例的引用由于这里引用了testDao的方法所以ref为testDao的id
1 | <?xml version="1.0" encoding="UTF-8"?> |
TESTDI.java
1 | package test; |
运行结果:
hello you need study hard!
构造方法注入
二、setter方法注入
这里只需要更改TestServiceImpl的代码和applicationContext的配置
代码如下:
1 | package service; |
1 | <?xml version="1.0" encoding="UTF-8"?> |
输出结果:
hello you need study hard!
setter方法注入