Spring中IoC的入门实例详解
Spring的模块化是很强的 各个功能模块都是独立的 我们可以选择的使用 这一章先从Spring的IoC开始 所谓IoC就是一个用XML来定义生成对象的模式 我们看看如果来使用的
数据模型
如下图所示有三个类 Human(人类)是接口 Chinese(中国人)是一个子类 American(美国人)是另外一个子类
源代码如下
package chengang spring;public interface Human {void eat();void walk();}
package chengang spring;public class Chinese implements Human {/* (非 Javadoc)* @see chengang spring Human#eat()*/public void eat() {System out println( 中国人对吃很有一套 );}
/* (非 Javadoc)* @see chengang spring Human#walk()*/public void walk() {System out println( 中国人行如飞 );}}
package chengang spring;public class American implements Human {/* (非 Javadoc)* @see chengang spring Human#eat()*/public void eat() {System out println( 美国人主要以面包为主 );}
/* (非 Javadoc)* @see chengang spring Human#walk()*/public void walk() {System out println( 美国人以车代步 有四肢退化的趋势 );}}
对以上对象采用工厂模式的用法如下
创建一个工厂类Factory 如下 这个工厂类里定义了两个字符串常量 所标识不同的人种 getHuman方法根据传入参数的字串 来判断要生成什么样的人种
package 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();elsethrow new IllegalArgumentException( 参数(人种)错误 );}}
下面是一个测试的程序 使用工厂方法来得到了不同的 人种对象 并执行相应的方法
package 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();}}
控制台的打印结果如下
采用Spring的IoC的用法如下
在项目根目录下创建一个bean xml文件
<?xml version= encoding= UTF ?><!DOCTYPE beans PUBLIC //SPRING//DTD BEAN//EN beans dtd ><beans><bean id= Chinese class= chengang spring Chinese /><bean id= American class= chengang spring American /></beans>
bean xml的位置如下图 注意不要看花眼把它看成是lib目录下的了 它是在myspring目录下的
修改ClientTest程序如下
package chengang spring;import ntext ApplicationContext;import ntext 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= chengang spring Chinese />
id就是ctx getBean的参数值 一个字符串 class就是一个类(包名+类名) 然后在ClientTest类里获得Chinese对象就是这么一句
human = (Human) ctx getBean(CHINESE)
因为getBean方法返回的是Object类型 所以前面要加一个类型转换
总结
( )也许有人说 IoC和工厂模式不是一样的作用吗 用IoC好象还麻烦一点
举个例子 如果用户需求发生变化 要把Chinese类修改一下 那么前一种工厂模式 就要更改Factory类的方法 并且重新编译布署 而IoC只需要将class属性改变一下 并且由于IoC利用了Java反射机制 这些对象是动态生成的 这时我们就可以热插拨Chinese对象(不必把原程序停止下来重新编译布署)
( )也许有人说 即然IoC这么好 那么我把系统所有对象都用IoC方式来生成
注意 IoC的灵活性是有代价的 设置步骤麻烦 生成对象的方式不直观 反射比正常生成对象在效率上慢一点 因此使用IoC要看有没有必要 我认为比较通用的判断方式是 用到工厂模式的地方都可以考虑用IoC模式
( )在上面的IoC的方式里 还有一些可以变化的地方 比如 bean xml不一定要放在项目录下 也可以放在其他地方 比如 chengang spring包里 不过在使用时也要变化一下 如下所示
new FileSystemXmlApplicationContext( src/cn//chengang/spring/bean xml )
另外 bean xml也可以改成其他名字 这样我们在系统中就可以分门别类的设置不同的bean xml
( )关于IoC的低侵入性
什么是低侵入性?如果你用过Struts或EJB就会发现 要继承一些接口或类 才能利用它们的框架开发 这样 系统就被绑定在Struts EJB上了 对系统的可移植性产生不利的影响 如果代码中很少涉及某一个框架的代码 那么这个框架就可以称做是一个低侵入性的框架
Spring的侵入性很低 Humen java Chinese java等几个类都不必继承什么接口或类 但在ClientTest里还是有一些Spring的影子 FileSystemXmlApplicationContext类和ctx getBean方式等
现在 低侵入性似乎也成了判定一个框架的实现技术好坏的标准之一
( )关于bean xml的用法
bean xml的用法还有很多 其中内容是相当丰富的 假设Chinese类里有一个humenName属性(姓名) 那么原的bean xml修改如下 此后生成Chinese对象时 陈刚 这个值将自动设置到Chinese类的humenName属性中 而且由于singleton为true这时生成Chinese对象将采用单例模式 系统仅存在一个Chinese对象实例
<?xml version= encoding= UTF ?><!DOCTYPE beans PUBLIC //SPRING//DTD BEAN//EN beans dtd ><beans><bean id= Chinese class= chengang spring Chinese singleton= true ><property name= humenName ><value>陈刚</value></property></bean><bean id= American class= chengang spring American /></beans>
lishixinzhi/Article/program/Java/ky/201311/28795