spring的模块化是很强的,各个功能模块都是独立的,我们可以选择的使用。这一章先从spring的ioc开始。所谓ioc就是一个用xml来定义生成对象的模式,我们看看如果来使用的。
数据模型
1、如下图所示有三个类,human(人类)是接口,chinese(中国人)是一个子类,american(美国人)是另外一个子类。
源代码如下:
2、对以上对象采用工厂模式的用法如下
创建一个工厂类factory,如下。这个工厂类里定义了两个字符串常量,所标识不同的人种。gethuman方法根据传入参数的字串,来判断要生成什么样的人种。
下面是一个测试的程序,使用工厂方法来得到了不同的“人种对象”,并执行相应的方法。
控制台的打印结果如下:
3、采用spring的ioc的用法如下:
在项目根目录下创建一个bean.xml文件
bean.xml的位置如下图,注意不要看花眼把它看成是lib目录下的了,它是在myspring目录下的。
修改clienttest程序如下:
从这个程序可以看到,ctx就相当于原来的factory工厂,原来的factory就可以删除掉了。然后又把factory里的两个常量移到了clienttest类里,整个程序结构基本一样。
再回头看原来的bean.xml文件的这一句:
id就是ctx.getbean的参数值,一个字符串。class就是一个类(包名+类名)。然后在clienttest类里获得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包里。不过在使用时也要变化一下,如下所示:
另外,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对象实例。
数据模型
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的用法如下:
在项目根目录下创建一个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目录下的。
![]() |
修改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类型,所以前面要加一个类型转换。
总结
(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> |



闽公网安备 35060202000074号