`
lshh83
  • 浏览: 159665 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Spring学习笔记:第二章 Spring中IoC的入门实例

阅读更多
第二章    Spring中IoC的入门实例
Spring的模块化是很强的,各个功能模块都是独立的,我们可以选择的使用。这一章先从Spring的IoC开始。所谓IoC就是一个用XML来定义生成对象的模式,我们看看如果来使用的。

1、数据模型。
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 {

      /* (非 Javadoc)

       * @see cn.com.chengang.spring.Human#eat()

       */

      public void eat() {

          System.out.println("中国人对吃很有一套");

      }


      /* (非 Javadoc)

       * @see cn.com.chengang.spring.Human#walk()

       */

      public void walk() {

          System.out.println("中国人行如飞");

      }

}


package cn.com.chengang.spring;

public class American implements Human {

      /* (非 Javadoc)

       * @see cn.com.chengang.spring.Human#eat()

       */

      public void eat() {

          System.out.println("美国人主要以面包为主");

      }


      /* (非 Javadoc)

       * @see cn.com.chengang.spring.Human#walk()

       */

      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的用法如下:
1、在项目根目录下创建一个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.chengang.spring.Chinese"/>

         <bean id="American" class="cn.com.chengang.spring.American"/>

</beans>

bean.xml的位置如下图,注意不要看花眼把它看成是lib目录下的了,它是在myspring目录下的。




2、修改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) {

          //          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.chengang.spring.Chinese"/>

id就是ctx.getBean的参数值,一个字符串。class就是一个类(包名+类名)。然后在ClientTest类里获得Chinese对象就是这么一句

human = (Human) ctx.getBean(CHINESE);

因为getBean方法返回的是Object类型,所以前面要加一个类型转换。


4、总结
(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方式等。

现在,低侵入性似乎也成了判定一个框架的实现技术好坏的标准之一。


(5)关于bean.xml的用法

bean.xml的用法还有很多,其中内容是相当丰富的。假设Chinese类里有一个humenName属性(姓名),那么原的bean.xml修改如下。此后生成Chinese对象时,“陈刚”这个值将自动设置到Chinese类的humenName属性中。而且由于singleton为true这时生成Chinese对象将采用单例模式,系统仅存在一个Chinese对象实例。

<?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">

                <property name="humenName">

                       <value>陈刚</value>

                </property>

         </bean>

         <bean id="American" class="cn.com.chengang.spring.American"/>

</beans>


关于bean.xml的其它用法,不再详细介绍了,大家自己拿Spring的文档一看就明白了。
分享到:
评论
1 楼 pengchhx 2010-01-28  
没图没真相

相关推荐

    Spring的学习笔记

    二、 第二步: 首先整合Spring + Hibernate 41 三、 第三步:再来整合Struts2 41 四、 struts的读常量: 43 第十二课:DTO、VO 43 一、 DTO 43 二、 VO 43 第十二课:SSH整合存在的问题 43 一、 Jsp中访问Session时...

    Spring.NET学习笔记-实现一个简易的IoC框架

    在我们使用Spring.NET框架的时候,首先需要实例化Spring.NET容器, 然后调用IoC容器IObjectFactory接口中GetObject方法获取容器中的对象。通过这一点就可以告诉我们制作IoC容器需要写一个获取XML文件内容的方法和申明...

    spring2.5 学习笔记

    二、 第二步: 首先整合Spring + Hibernate 41 三、 第三步:再来整合Struts2 41 四、 struts的读常量: 43 第十二课:DTO、VO 43 一、 DTO 43 二、 VO 43 第十二课:SSH整合存在的问题 43 一、 Jsp中访问Session时...

    spring学习笔记

    这是我自己学习spring时做的总结,主要是原理,实现的实例代码不多,有也只是贴了一部分,有些地方也不是很详细。另外有地方理解错的还望指出。主要包括了spring的核心(ioc、aop)、spring对数据的访问、spring ...

    Java/JavaEE 学习笔记

    Spring学习笔记...............345 第一章 Spring概述..........................345 第二章 Spring IOC(控制反转)........347 第三章 Spring AOP(面向切面编程)..........351 第四章 Spring中的数据访问.............

    J2EE学习笔记(J2ee初学者必备手册)

    Spring学习笔记...............345 第一章 Spring概述..........................345 第二章 Spring IOC(控制反转)........347 第三章 Spring AOP(面向切面编程)..........351 第四章 Spring中的数据访问.............

    Spring.NET学习笔记-控制反转

    控制反转(Inversion of Control,英文缩写为IoC),也叫依赖注入(Dependency Injection)。我个人认为控制反转的意思是依赖对象(控制权)发生转变,由最初的类本身来管理依赖对象转变为IoC框架来管理这些对象,使得...

    【2019版】Spring4.3入门视频课程

    第一个Spring程序、IOC容器的类型、数据装配 bean生命周期、实例化bean的方式和时机、bean的作用域、继承配置 .自动装配、FactoryBean、两种后处理器 二、Spring AOP AOP简介、实现原理、代理技术 Spring AOP的配置...

    java查看sun包源码-learning-spring:Spring框架讲解

    在SpringIOC容器读取bean配置创建bean实例之前,必须对它进行实例化。只有在容器实例化后,才可以从IOC容器里获取bean实例并使用 Spring提供了两种类型的IOC容器实现 BeanFactory:IOC容器的基本实现,在调用getBean...

    MVC使用Spring.Net应用IOC(依赖倒置)学习笔记3

    到现在,我们已经基本搭建起了项目的框架,但是项目中还存在一个问题,就是尽管层与层之间使用了接口进行隔离,但实例化接口的时候,还是引入了接口实现类的依赖,如下面的代码: private IUserService _...

    day_01.rar

    Spring第一天学习笔记,包含使用IOC管理项目资源、实例化Bean的三种方式,以及bean对象生命周期的代码演示

    thinking-in-spring:学春天

    春天学习笔记 Bean初始化 BeanDefinitionBuilder 新的GenericBeanDefinition Bean的命名(非强制性) BeanNameGenerator AnnotationBeanNameGenerator Bean的别名(一般XML配置) 别名 BeanDefinition的注册 ...

    asp.net知识库

    VS2005 ASP.NET本地化学习笔记&感受 在自定义Server Control中捆绑JS文件 Step by Step 深度解析Asp.Net2.0中的Callback机制 使用 Web 标准生成 ASP.NET 2.0 Web 站点 ASP.NET 2.0基于SQLSERVER 2005的aspnetdb.mdf...

Global site tag (gtag.js) - Google Analytics