Spring中IoC的入门实例详解

本文通过对比工厂模式和Spring的IoC容器,详细介绍了如何使用Spring的IoC容器来管理和创建对象,展示了IoC容器的优势及应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Spring的模块化是很强的,各个功能模块都是独立的,我们可以选择的使用。这一章先从Spring的IoC开始。所谓IoC就是一个用XML来定义生成对象的模式,我们看看如何来使用的。

数据模型

  1、如下图所示有三个类,Human(人类)是接口,Chinese(中国人)是一个子类,American(美国人)是另外一个子类。

 

 

 

源代码

 

package cn.com.chengang.spring;
public interface Human {
  void eat();
    void walk();
}
 
package cn.com.chengang.spring;
public class Chinese implements Human {
public void eat() {
    System.out.println("中国人对吃很有一套");

 public void walk() {
    System.out.println("中国人行如飞");
}
}
 
package cn.com.chengang.spring;
public class American implements Human {
bpublic void eat() {
    System.out.println("美国人主要以面包为主");
}

public void walk() {
    System.out.println("美国人以车代步,有四肢退化的趋势");
}
}
2、对以上对象采用工厂模式的用法如下
 创建一个工厂类Factory,如下。这个工厂类里定义了两个字符串常量,所标识不同的人种。getHuman方法根据传入参数
  的字串,来判断要生成什么样的人种。
package cn.com.chengang.spring;
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 new Chinese();
        else if (ethnic.equals(AMERICAN))
            return new American();
        else
            throw new IllegalArgumentException("参数(人种)错误");
    }
}
 
下面是一个测试的程序,使用工厂方法来得到了不同的“人种对象”,并执行相应的方法。
 
package cn.com.chengang.spring;
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文件
     
 
修改ClientTest程序如下:
package cn.com.chengang.spring;
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) {
    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类里,整个程序结构基本一样。
 
配置文件如下:
 
<?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.chengang.spring.Chinese" singleton="true"/>
    <bean id="American" class="cn.com.chengang.spring.American"/>
</beans>
再回头看原来的bean.xml文件的这一句:
  <bean id="Chinese" class="cn.com.chengang.spring.Chinese"/>
  id就是ctx.getBean的参数值,一个字符串。class就是一个类(包名+类名)。然后在ClientTest类里获得Chinese
    对象就是这么一句
   human = (Human) ctx.getBean(CHINESE);
   因为getBean方法返回的是Object类型,所以前面要加一个类型转换。
 
总结
  (1)也许有人说,IoC和工厂模式不是一样的作用吗,用IoC好象还麻烦一点。
  举个例子,如果用户需求发生变化,要把Chinese类修改一下。那么前一种工厂模式,就要更改Factory类的方法,并且
   重新编译布署。而IoC只需要将class属性改变一下,并且由于IoC利用了Java反射机制,这些对象是动态生成的,这时我们就可以热插拨Chinese对象(不必把原程序停止下来重新编译布署)
  (2)也许有人说,即然IoC这么好,那么我把系统所有对象都用IoC方式来生成。
  注意,IoC的灵活性是有代价的:设置步骤麻烦、生成对象的方式不直观、反射比正常生成对象在效率上慢一点。因此使用IoC要看有没有必要,我认为比较通用的判断方式是:用到工厂模式的地方都可以考虑用IoC模式。
  (3)在上面的IoC的方式里,还有一些可以变化的地方。比如,bean.xml不一定要放在项目录下,也可以放在其他地方,比如cn.com.chengang.spring包里。不过在使用时也要变化一下,如下所示:
  new  FileSystemXmlApplicationContext("src/cn/com/chengang/spring/bean.xml");
  另外,bean.xml也可以改成其他名字。这样我们在系统中就可以分门别类的设置不同的bean.xml.
  (4)关于IoC的低侵入性。
  什么是低侵入性?如果你用过Struts或EJB就会发现,要继承一些接口或类,才能利用它们的框架开发。这样,系统就被绑定在Struts、EJB上了,对系统的可移植性产生不利的影响。如果代码中很少涉及某一个框架的代码,那么这个框架就可以称做是一个低侵入性的框架。
  Spring的侵入性很低,Humen.java、Chinese.java等几个类都不必继承什么接口或类。但在ClientTest里还是有一些Spring的影子:FileSystemXmlApplicationContext类和ctx.getBean方式等。
  现在,低侵入性似乎也成了判定一个框架的实现技术好坏的标准之一。
 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值