目录
本关任务:掌握Spring框架中IoC(控制反转)的概念,在Spring中通过XML 配置文件定义一个Bean进行实践。
为了完成本关任务,你需要掌握Spring框架中IoC的概念。
Spring是最受欢迎的企业级Java应用程序开发框架,数以百万的来自世界各地的开发人员使用Spring框架来创建性能好、易于测试、可重用的代码。Spring框架是完全免费开源的,它最初是由Rod Johnson编写,并于 2003年6月首次发布。
Spring的成功源于其设计理念而不是技术本身,IoC(Inversion of Control,控制反转)和AOP(Aspect Oriented Programmnig,面向切面编程)是Spring框架中最为重要的两个理念。下面将简单介绍IoC和AOP的概念。
IoC是一个容器,在Spring中,Spring框架把一切Java资源都看作是Java Bean(所谓Java Bean就是指Java中对象,在Java语言中,一切皆对象),容器的目标就是管理这些Bean和它们之间的关系。所以在Spring IoC里面装载的各种Bean,也可以理解为Java的各种资源,包括Java Bean的创建、行为和事件等,它们由IoC容器统一管理。除此之外,各个Java Bean之间会存在一定的依赖关系,比如班级是依赖于老师和学生组成的,假设老师、学生都是Java Bean,那么二者之间显然存在依赖关系,老师和学生有教育和被教育的关系,这些依赖关系Spring IoC容器都能够自动对其进行管理。管理的方式由人为的主动创建变成Spring IoC通过创建的描述自动管理,也就是说Spring是依靠描述来完成对象的创建及其依赖关系的管理的。
以插座为例,现有两种满足同一国家标准(MySocket)的插座(Socket1和Socket2),如下图所示

图1 插座与国家标准接口
如果两种插座都可以选择,在代码中如果有个user对象选择使用Socket1,那么代码形式可能是下面这个样子:
MySocket socket = new Socket1();//使用Socket1user.setSocket(socket);user.userSocket();
我们需要先手动new一个Socket1对象,然后把它和user绑定,最后再使用Socket1对象。但这样有一个弊端,如果要使用其它的插座,就需要修改代码了。这种情况Socket接口和它的实现类耦合在一起了,如果有一天需要使用Socket2,那就要修改代码为如下所示:
MySocket socket = new Socket2();//使用Socket2user.setSocket(socket);user.userSocket();
如果项目比较小,这种代码改动没有太大的影响,但企业级的互联网项目的代码量都比较大,代码行数达几十万甚至上百万,在此背景下进行这种代码改动很容易产生潜在的 BUG,影响系统的可靠性,Spring IoC可以解决这个问题。
首先,我们不直接使用new的方式创建对象,改为使用一个xml配置文件的方式,然后让Spring IoC容器自己通过xml配置文件自己去找到对应的插座。如下图中的代码所示,用一段xml描述Socket1、User及两者的关系。
这些不是Java代码,而是XML配置文件。我们如果要让用户使用Socket2,只要把XML文件中用Socket2替代Socket1,如下
接下来我们理解下Spring框架中的IoC(控制反转)概念。首先,我们需要明白“控制”是指什么的控制,然后再来看“反转”又是什么。
通过上面的介绍,我们可以看到人工控制依赖关系的方式和Spring IoC容器控制依赖关系的一个区别是:人工是通过new创建对象,然后与其他对象关联起来表达相互之间的依赖关系;Spring框架是通过xml配置文件描述对象间的依赖关系,然后框架自动的创建相关对象并关联起来表达依赖关系。所以,控制反转中控制指的是创建对象的控制权,反转指的是对于创建对象的控制权由人转移到了Spring框架。也就是说使用关键字new创建一个对象的工作由Spring框架帮你完成了,不用你再去手动创建。
根据提示,在右侧编辑器补充代码
Socket3.java文件中补全useSocket方法,输出使用socket3,测试代码中会调用此方法并输出;XML配置文件中定义一个关于Socket3的Java Bean,且id为socket。提示:
public void useSocket() {System.out.println("使用socket1");}
输出:
使用socket1
在编辑器的上面,可以查看其它相关文件,如下图。

图2 查看其它相关文件
平台会对你编写的代码进行测试:
预期输出:
使用socket3
applicationContext.xml
- "1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
-
-
-
-
- <bean id="socket" class="net.educoder.Socket3"/>
-
-
- beans>
Socket3.java
- package net.educoder;
-
- /**
- * 要补充代码的 插座3
- */
- public class Socket3 implements MySocket{
-
- @Override
- public void useSocket() {
- /********** Begin *********/
- System.out.println("使用socket3");
- /********** End *********/
-
- }
- }
