1. Action接口:
Action 接口定义了一个execute 方法,在我们示例中,不同的Action 实现提供了各自的
execute方法,以完成目标逻辑。
public interface Action {
public String execute(String str);
}
2. Action接口的两个实现UpperAction、LowerAction
public class UpperAction implements Action {
private String message;
public String getMessage() {
return message;
}
public void setMessage(String string) {
message = string;
}
public String execute(String str) {
return (getMessage() + str).toUpperCase();
}
}
UpperAction将其message属性与输入字符串相连接,并返回其大写形式。
public class LowerAction implements Action {
private String message;
public String getMessage() {
return message;
}
public void setMessage(String string) {
message = string;
}
public String execute(String str) {
return (getMessage()+str).toLowerCase();
}
}
LowerAction将其message属性与输入字符串相连接,并返回其小写形式。
3. Spring配置文件(bean.xml)
<beans>
<description>Spring Quick Start</description>
<bean id="TheAction"
class="net.xiaxin.spring.qs.UpperAction">
<property name="message">
<value>HeLLo</value>
</property>
</bean>
</beans>
(请确保配置bean.xml位于工作路径之下,注意工作路径并不等同于CLASSPATH ,eclipse
的默认工作路径为项目根路径,也就是.project文件所在的目录,而默认输出目录/bin是项目
CLASSPATH的一部分,并非工作路径。)
4. 测试代码
public void testQuickStart() {
ApplicationContext ctx=new
FileSystemXmlApplicationContext("bean.xml");
Action action = (Action) ctx.getBean("TheAction");
System.out.println(action.execute("Rod Johnson"));
}
可以看到,上面的测试代码中,我们根据"bean.xml"创建了一个ApplicationContext实
例,并从此实例中获取我们所需的Action实现。
运行测试代码,我们看到控制台输出:
……
HELLO ROD JOHNSON
我们将bean.xml中的配置稍加修改:
<bean id="TheAction" class="net.xiaxin.spring.qs.LowerAction"/>
再次运行测试代码,看到:
……
hello rod johnson
示例完成!
很简单的示例,的确很简单,甚至简单到了不够真实。不过,不知大家从这个最简单的例子中看出了什么?真的只是打印输出了两行不痛不痒的问候语?
仔细观察一下上面的代码,可以看到:
1. 我们的所有程序代码中(除测试代码之外),并没有出现Spring中的任何组件。
2. UpperAction和LowerAction的Message属性均由Spring通过读取配置文件(bean.xml)动
态设置。
3. 客户代码(这里就是我们的测试代码)仅仅面向接口编程,而无需知道实现类的具体名称。同时,
我们可以很简单的通过修改配置文件来切换具体的底层实现类。
上面所说的这些,对于我们的实际开发有何帮助?
Ø 首先,我们的组件并不需要实现框架指定的接口,因此可以轻松的将组件从Spring中脱离,甚至不需要任何修改(这在基于EJB框架实现的应用中是难以想象的)。
Ø 其次,组件间的依赖关系减少,极大改善了代码的可重用性。
Spring的依赖注入机制,可以在运行期为组件配置所需资源,而无需在编写组件代码时就加以指定,从而在相当程度上降低了组件之间的耦合。
上面的例子中,我们通过Spring,在运行期动态将字符串 “HeLLo” 注入到Action实现类的Message属性中。
现在假设我们回到传统的实现模式,应该如何处理?
一般的处理办法也就是编写一个Helper类(辅助类),完成配置文件读写功能,然后在各个Action的构造函数中,调用这个Helper类设置message属性值。此时,我们的组件就与这个Helper类库建立了依赖关系,之后我们需要在其他系统中重用这个组件的话,也必须连同这个Helper类库一并移植。实际开发中,依赖关系往往并非如此简单,组件与项目基层代码之间复杂的关联,使得组件重用性大大下降。
Spring通过依赖注入模式,将依赖关系从编码中脱离出来,从而大大降低了组件之间的耦合,
实现了组件真正意义上的即插即用。这也是Spring最具价值的特性之一。
Ø 面向接口编程。
诚然,即使没有Spring,实现面向接口的设计也不困难。Spring对于面向接口设计的意义,在于它为面向接口编程提供了一个更加自然的平台。基于Spring开发,程序员会自然而然倾向于使用接口来定义不同层次之间的关联关系,这种自发的倾向性,来自于Spring所提供的简单舒适的依赖注入实现。Spring使得接口的定义和使用不再像传统编码过程中那么繁琐(传统编码过程中,引入一个接口,往往也意味着同时要引入一个Factory类,也许还有一个额外的配置文件及其读写代码)。
posted on 2006-03-19 20:12
★yesjoy★ 阅读(314)
评论(0) 编辑 收藏 所属分类:
Structs学习