spring ioc
软件152 程永绩
1.什么是IOC:
Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想。在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。如何理解好Ioc呢?理解好Ioc的关键是要明确“谁控制谁,控制什么,为何是反转(有反转就应该有正转了),哪些方面反转了”,那我们来深入分析一下:
●谁控制谁,控制什么:传统Java SE程序设计,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象;而IoC是有专门一个容器来创建这些对象,即由Ioc容器来控制对 象的创建;谁控制谁?当然是IoC 容器控制了对象;控制什么?那就是主要控制了外部资源获取(不只是对象包括比如文件等)。
●为何是反转,哪些方面反转了:有反转就有正转,传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,也就是正转;而反转则是由容器来帮忙创建及注入依赖对象;为何是反转?因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转;哪些方面反转了?依赖对象的获取被反转了。
2.IOC实例:
数据模型
1、如下图所示有三个类,Human(人类)是接口,Chinese(中国人)是一个子类,American(美国人)是另外一个子类。 如图:
代码如下:
package cqvie.com;
public interface Human {
void eat();
void walk();
}
package cqvie.com;
public class Chinese implements Human {
public void eat() {
System.out.println("中国人对吃很有一套");
}
public void walk() {
System.out.println("中国人行如飞");
}
}
package cqvie.com;
public class American implements Human {
public void eat() {
System.out.println("美国人主要以面包为主");
}
public void walk() {
System.out.println("美国人以车代步,有四肢退化的趋势");
}
}
2、对以上对象采用工厂模式的用法如下:
创建一个工厂类Factory,如下。这个工厂类里定义了两个字符串常量,所标识不同的人种。getHuman方法根据传入参数的字串,来判断要生成什么样的人种。
package cqvie.com;
public class Factory {
public final static String CHINESE = "Chinese";
public final static String AMERICAN = "American";
public Human getHuman(String ethnic) {
if (ethnic.equals(CHINESE))
return (Human) new Chinese();
else if (ethnic.equals(AMERICAN))
return new American();
else
throw new IllegalArgumentException("参数(人种)错误");
}
}
下面是一个测试的程序,使用工厂方法来得到了不同的“人种对象”,并执行相应的方法。
public class ClientTest {
public static void main(String[] args) {
Human human = null;
human = new Factory().getHuman(Factory.CHINESE);
human.eat();
human.walk();
human = new Factory().getHuman(Factory.AMERICAN);
human.eat();
human.walk();
}
}
打印结果如下
3、采用Spring的IoC的用法如下:
在项目根目录下创建一个bean.xml文件,代码如下
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="Chinese" class="cn.com.cqvie.spring.Chinese"/>
<bean id="American" class="cn.com.cqvie.spring.American"/>
</beans>
修改ClientTest程序如下:
package cqvie.com;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class ClientTest {
public final static String CHINESE = "Chinese";
public final static String AMERICAN = "American";
public static void main(String[] args) {
// Human human = null;
// human = new Factory().getHuman(Factory.CHINESE);
// human.eat();
// human.walk();
// human = new Factory().getHuman(Factory.AMERICAN);
// human.eat();
// human.walk();
ApplicationContext ctx = new FileSystemXmlApplicationContext("bean.xml");
Human human = null;
human = (Human) ctx.getBean(CHINESE);
human.eat();
human.walk();
human = (Human) ctx.getBean(AMERICAN);
human.eat();
human.walk();
}
}
从这个程序可以看到,ctx就相当于原来的Factory工厂,原来的Factory就可以删除掉了。然后又把Factory里的两个常量移到了ClientTest类里,整个程序结构基本一样。
再回头看原来的bean.xml文件的这一句:
<bean id="Chinese" class="cn.com.cqvie.spring.Chinese"/>
id就是ctx.getBean的参数值,一个字符串。class就是一个类(包名+类名)。然后在ClientTest类里获得Chinese对象就是这么一句:
human = (Human) ctx.getBean(CHINESE);
因为getBean方法返回的是Object类型,所以前面要加一个类型转换。