领先一步
VMware 提供培训和认证,助您快速提升技能。
了解更多在上周的培训中,我第一次使用了 Spring Web Services 的第一个 Release Candidate 版本。Arjen 发布 RC1 版本才仅仅两周,所以能够向一些参与者展示这个新产品感觉非常棒。
在 Web 服务部分之前,我们做了一些关于 JMX 和远程调用的内容,展示了 Spring 的导出器功能。如你所知,这允许你将任何 Spring 管理的 Bean 导出到远程端点或 JMX 注册表,只需少量声明式配置。
<bean id="myService" class="com.mycompany.MyServiceImpl">
<property name="myDao" ref="myDao"/>
</bean>
<bean class="org.springframework.remoting.rmi.RmiServiceExporter">
<property name="serviceName" value="myService"/>
<property name="serviceInterface" value="com.mycompany.MyService"/>
<property name="service" ref="myService"/>
</bean>
这一切都非常简单,并且与听众迄今为止对 Spring 的普遍认知非常一致:Spring 使过去非常困难的事情变得简单得多;它只需要几行 XML(或我们目前正在实现的其他一些配置选项),然后就完成了。当然,这是事实,但这不是我希望人们带着这种印象离开核心 Spring 培训的。
幸运的是,借助 Spring Web Services,Arjen 为我提供了一些极好的素材,让我可以一劳永逸地告诉大家,我们希望你对 Spring 的思考方式与“只需添加几行 XML 即可完成”完全不同。并非如此!
回到我上周进行的培训;当我们刚完成 JMX 部分时,我开始了关于 Web 服务的惯例讲解。简而言之,它表示:Web 服务 != 远程调用,你最好学会接受这样一个事实,即实现 Web 服务所需的工作量 != 将服务导出到 RMI 端点所需的工作量(我怀疑在所有情况下 != 都很有可能被替换为>)。
Arjen 和我正在撰写一篇更详细解释的文章。在此之前,你可以参考Spring Web Services 参考手册和Arjen 的个人博客,从中获取更多关于所有这些内容背后的原因的信息。
然而,上周让我(非常愉快地)感到惊讶的是,一位培训学员突然打断我,说:“嘿,我现在明白了,Spring 的方法不一定是为了简化我的代码或减少代码量,而是为了消除不必要的复杂性,让我专注于重要的部分。”
这位学员(Thomas,是的,就是你 :)),说得实在是太对了。Spring 产品组合的每个部分都专注于做到这一点。
依赖注入和 AOP专注于提供一种简洁而强大的方法来注入依赖项并实现横切关注点。模块化和关注点分离是应该易于实现且非常重要的问题。Spring 的 DI 容器和 AOP 功能专注于让你实现模块化和良好的关注点分离。它们并非主要专注于简化你的代码。这只是使用 DI 和 AOP 的结果之一,我几乎可以说这是一个不错的副作用 ;-)
Spring 的远程导出器旨在提供一种几乎透明的方式,用于从远程位置调用服务器端代码。当想要实现基于 RMI 的远程端点时,我们隐式地表明我们希望将我们的服务与客户端紧密耦合。Spring 的远程导出器并非旨在通过仅仅四行 XML 来实现这一点。它们的设计初衷是为了获得这种几乎透明的编程体验。它可以通过仅仅四行 XML 完成,这同样也是一个不错的副作用。
现在关键来了……当我们实现 Web 服务时,我们隐式地表明我们希望将我们的服务松散耦合到任何可能使用我们服务的潜在客户端。我们并没有(或不应该)寻找一种使用<soap:Envelope>和<soap:Body>标签透明地发出方法调用的方法。版本管理、灵活性和向后兼容的能力是实现经久耐用且与客户端松散耦合的健壮 Web 服务的关键。Spring Web Services 的设计初衷就是解决这些问题并让你非常轻松地解决这些问题。它并非旨在简化你的代码!尽管我非常确定,在许多情况下,使用 Spring Web Services 最终得到的代码将尽可能简单易懂!
上周五我开车回家时脸上带着灿烂的笑容。我们结束了这次培训,理解了最重要的课程:Spring 的设计初衷并非简化代码;而是让你专注于重要的事情。作为副作用获得的代码简化,当然,我相信我们所有人都对此表示赞赏!