Spring框架-Spring IOC

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):

  1. FileSystemXmlApplicationContext

Java代码

1
ApplicationContext ctx = new FileSystemXmlApplicationContext("bean.xml"); //加载单个配置文件

Java代码

1
2
String[] locations = {"bean1.xml", "bean2.xml", "bean3.xml"};  
ApplicationContext ctx = new FileSystemXmlApplicationContext(locations ); //加载多个配置文件

Java代码

1
ApplicationContext ctx =new FileSystemXmlApplicationContext("D:roject/bean.xml");//根据具体路径加载文件
  1. ClassPathXmlApplicationContext

Java代码

1
ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml");

Java代码

1
2
String[] locations = {"bean1.xml", "bean2.xml", "bean3.xml"};  
ApplicationContext ctx = new ClassPathXmlApplication(locations);

注:其中FileSystemXmlApplicationContext和ClassPathXmlApplicationContext与BeanFactory的xml文件定位方式一样是基于路径的。

​ 3. XmlWebApplicationContext

Java代码

1
2
ServletContext servletContext = request.getSession().getServletContext();      
ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(servletContext);
2.3 依赖注入的类型

Spring框架依赖注入通常有两种实现方式,一种是使用构造方法注入,另一种是使用属性的setter方法注入。

(一般用setter方法注入)

我将会以代码的形式来展示。

一、构造方法注入

首先展示目录结构:

1570102183676

可以看到项目中有dao,service,test包分别建立在项目下。

TestDao.java

1
2
3
4
5
6
package dao;

public interface TestDao {
public void sayHello();

}

TestDaoImpl.java

1
2
3
4
5
6
7
8
9
10
package dao;

public class TestDaoImpl implements TestDao {
@Override
public void sayHello() {
// TODO Auto-generated method stub
System.out.println("hello you need study hard!");

}
}

TestService.java

1
2
3
4
5
6
package service;

public interface TestService {
public void sayHello();

}

TestServiceImpl.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package service;

import dao.TestDao;

public class TestServiceImpl implements TestService {
private TestDao testDao;
public TestServiceImpl(TestDao testDao){
super();
this.testDao=testDao;
}


@Override
public void sayHello() {
// TODO Auto-generated method stub
testDao.sayHello();
System.out.println("构造方法注入");
}


}

applicationContext.xml

这里的constructor-arg元素用于定义类构造方法的参数,index定义参数的位置,ref是指某个实例的引用由于这里引用了testDao的方法所以ref为testDao的id

1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<bean id="testDao" class="dao.TestDaoImpl"></bean>
<bean id="testService" class="service.TestServiceImpl">
<constructor-arg index="0" ref="testDao"/>
</bean>

</beans>

TESTDI.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import service.TestService;

public class TESTDI {
public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
TestService ts=(TestService) ac.getBean("testService");
ts.sayHello();
}



}

运行结果:

hello you need study hard!
构造方法注入

二、setter方法注入

这里只需要更改TestServiceImpl的代码和applicationContext的配置

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package service;

import dao.TestDao;

public class TestServiceImpl implements TestService {
private TestDao testDao;
public TestDao getTestDao() {
return testDao;
}

public void setTestDao(TestDao testDao) {
this.testDao = testDao;
}
@Override
public void sayHello() {
// TODO Auto-generated method stub
testDao.sayHello();
System.out.println("setter方法注入");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<bean id="testDao" class="dao.TestDaoImpl"></bean>
<bean id="testService" class="service.TestServiceImpl">
<property name="testDao" ref="testDao"></property>
</bean>

</beans>

输出结果:

hello you need study hard!
setter方法注入

-------------本文结束感谢您的阅读-------------
0%