- 浏览: 500827 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
michao:
大哥,还有aperture.exe吗? 发我一份,找不到呀,m ...
使用aperture框架让AS3与C++通信,执行本地代码 -
Aaron-Joe-William:
文件被删除了。下不了。
SQLite 数据库加密的一种解决方案 -
hanmiao:
樓主的文章不就是來自IBM Developers里的http: ...
mina 入门 -
howesen:
断包与粘包问题,需要处理下就好了
mina接收数据不全(2) -
sniciq:
git clone --recursive git://git ...
ESB学习笔记(Spring Integration实战)
ESB学习笔记(Spring Integration实战)
Spring Integration是Spring公司的一套ESB框架。
前面ESB介绍中我也做了一定了解。我们来看一下它主要做什么的。
Spring Integration is motivated by the following goals:
- Provide a simple model for implementing complex enterprise integration solutions.(暂时相信它吧,谁让它搞个Spring框架,的确给人方便一把。)
- Facilitate asynchronous, message-driven behavior within a Spring-based application.(这个不谈,Spring框架就是它玩的。再说这一点与它竞争只有Mule啦。)
- Promote intuitive, incremental adoption for existing Spring users. (也暂时相信它,别人都只说给用户提升。)
Spring Integration is guided by the following principles:
- Components should be loosely coupled for modularity and testability.(松耦合,好像很早很早就听说过。像做梦一样)
- The framework should enforce separation of concerns between business logic and integration logic.(分开程度要取决业务吧。)
- Extension points should be abstract in nature but within well-defined boundaries to promote reuse and portability.(美妙现实世界产品)
主页上也没有东东,但有个下源代码的地方,svn开工啦。
svn co https://src.springframework.org/svn/spring-integration/trunk springintegration
下载完后,进入build-spring-integration目录执行ant.完成后,导入到Eclipse中。
导入项目会有很多,先添加时会有报错。这里需要添加一个变量。
IVY_CACHE=<checkout-dir>/ivy-cache/repository
这里要注意的事,也是我遇到问题。执行ant时,他会去下载lvy,如果你本身在%ANT_HOME%\lib里有lvy.jar包,由于我暂时找不到如何处理,我就直接将Ant中的jar删除掉后就没有问题。
另外在ant过程中,测试步骤可能会在file模块中出现问题,可以将相关test类中代码注释掉。
- package org.springframework.integration.samples.helloworld;
- /**
- * @author Mark Fisher
- */
- public class HelloService {
- public String sayHello(String name) {
- return "Hello " + name;
- }
- }
package org.springframework.integration.samples.helloworld; /** * @author Mark Fisher */ public class HelloService { public String sayHello(String name) { return "Hello " + name; } }
helloworldDemo.xml
- <?xml version="1.0" encoding="UTF-8"?>
- <beans:beans xmlns="http://www.springframework.org/schema/integration"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:beans="http://www.springframework.org/schema/beans"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
- http://www.springframework.org/schema/integration
- http://www.springframework.org/schema/integration/spring-integration-1.0.xsd">
- <channel id="inputChannel"/>
- <channel id="outputChannel">
- <queue capacity="10"/>
- </channel>
- <service-activator input-channel="inputChannel"
- output-channel="outputChannel"
- ref="helloService"
- method="sayHello"/>
- <beans:bean id="helloService" class="org.springframework.integration.samples.helloworld.HelloService"/>
- </beans:beans>
<?xml version="1.0" encoding="UTF-8"?> <beans:beans xmlns="http://www.springframework.org/schema/integration" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-1.0.xsd"> <channel id="inputChannel"/> <channel id="outputChannel"> <queue capacity="10"/> </channel> <service-activator input-channel="inputChannel" output-channel="outputChannel" ref="helloService" method="sayHello"/> <beans:bean id="helloService" class="org.springframework.integration.samples.helloworld.HelloService"/> </beans:beans>
HelloWorldDemo.java
- package org.springframework.integration.samples.helloworld;
- import org.springframework.context.support.AbstractApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- import org.springframework.integration.channel.BeanFactoryChannelResolver;
- import org.springframework.integration.channel.ChannelResolver;
- import org.springframework.integration.channel.PollableChannel;
- import org.springframework.integration.core.MessageChannel;
- import org.springframework.integration.message.StringMessage;
- /**
- * Demonstrates a basic message endpoint.
- *
- * @author Mark Fisher
- */
- public class HelloWorldDemo {
- public static void main(String[] args) {
- AbstractApplicationContext context = new ClassPathXmlApplicationContext("helloWorldDemo.xml", HelloWorldDemo.class);
- ChannelResolver channelResolver = new BeanFactoryChannelResolver(context);
- MessageChannel inputChannel = channelResolver.resolveChannelName("inputChannel");
- PollableChannel outputChannel = (PollableChannel) channelResolver.resolveChannelName("outputChannel");
- inputChannel.send(new StringMessage("World"));
- System.out.println(outputChannel.receive(0).getPayload());
- context.stop();
- }
- }
package org.springframework.integration.samples.helloworld; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.integration.channel.BeanFactoryChannelResolver; import org.springframework.integration.channel.ChannelResolver; import org.springframework.integration.channel.PollableChannel; import org.springframework.integration.core.MessageChannel; import org.springframework.integration.message.StringMessage; /** * Demonstrates a basic message endpoint. * * @author Mark Fisher */ public class HelloWorldDemo { public static void main(String[] args) { AbstractApplicationContext context = new ClassPathXmlApplicationContext("helloWorldDemo.xml", HelloWorldDemo.class); ChannelResolver channelResolver = new BeanFactoryChannelResolver(context); MessageChannel inputChannel = channelResolver.resolveChannelName("inputChannel"); PollableChannel outputChannel = (PollableChannel) channelResolver.resolveChannelName("outputChannel"); inputChannel.send(new StringMessage("World")); System.out.println(outputChannel.receive(0).getPayload()); context.stop(); } }
其示例描述在:http://www.enterpriseintegrationpatterns.com/ramblings/18_starbucks.html
这里简单描述一下,以免大家看英文太累
文章讲在星巴克喝咖啡时,收银员可能只有一个,而冲咖啡员工会有多个,如何让收银员产生订单异步发送给冲咖啡员工。并且冲咖啡员工可能是竞争上岗的,就当他们是计件工吧。
这里要考虑问题:
1,冲咖啡员工使用不同设备,不同咖啡冲调时间可能不同。
2,冲咖啡员工可能会将相同类型的咖啡同时一起冲调。
星巴克如何处理这个问题?
就当他解决了这个问题,它是如何把每个咖啡又送回给每个客户呢?当然,星巴克采用“标识关系模式”,将每个咖啡杯上标上名称,并通过叫喊方式。
但并不是每天都是美好的,总有出错的时候。例如,收银员无法支付?冲调一杯你不喜欢的咖啡,你要换一杯?冲咖啡的设备坏了,星巴克要退你钱...这些异常情况如何处理。
因此就会有以下三种方式异常处理:
1,关闭交易,什么都不做。
2,重做,重新发起行为。
3,修正行为,相当于退钱这种行为。
因此,这里这篇文章后面讨论一下两阶段提交为什么不适合星巴克,如果你让收银员、冲咖啡员工,买单的人需要在一个“事务”中,交易所有完成后,再进行下一个业务。估计星巴克会马上倒闭啦。因此星巴克采用“Conversation pattern”模式。
好啦,业务了解清楚,我们再来看一下完整XML文件。在这里我没有采用示例详细的xml方式,而没有采用annotation方式。
- <?xml version="1.0" encoding="UTF-8"?>
- <beans:beans xmlns="http://www.springframework.org/schema/integration"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:beans="http://www.springframework.org/schema/beans"
- xmlns:stream="http://www.springframework.org/schema/integration/stream"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
- http://www.springframework.org/schema/integration
- http://www.springframework.org/schema/integration/spring-integration-1.0.xsd
- http://www.springframework.org/schema/integration/stream
- http://www.springframework.org/schema/integration/stream/spring-integration-stream-1.0.xsd">
- <gateway id="cafe" service-interface="org.springframework.integration.samples.cafe.Cafe"/>
- <channel id="orders"/>
- <splitter input-channel="orders" ref="orderSplitter" method="split" output-channel="drinks"/>
- <channel id="drinks"/>
- <router input-channel="drinks" ref="drinkRouter" method="resolveOrderItemChannel"/>
- <channel id="coldDrinks">
- <queue capacity="10"/>
- </channel>
- <service-activator input-channel="coldDrinks" ref="barista"
- method="prepareColdDrink" output-channel="preparedDrinks"/>
- <channel id="hotDrinks">
- <queue capacity="10"/>
- </channel>
- <service-activator input-channel="hotDrinks" ref="barista"
- method="prepareHotDrink" output-channel="preparedDrinks"/>
- <channel id="preparedDrinks"/>
- <aggregator input-channel="preparedDrinks" ref="waiter"
- method="prepareDelivery" output-channel="deliveries"/>
- <stream:stdout-channel-adapter id="deliveries"/>
- <beans:bean id="orderSplitter"
- class="org.springframework.integration.samples.cafe.xml.OrderSplitter"/>
- <beans:bean id="drinkRouter"
- class="org.springframework.integration.samples.cafe.xml.DrinkRouter"/>
- <beans:bean id="barista" class="org.springframework.integration.samples.cafe.xml.Barista"/>
- <beans:bean id="waiter" class="org.springframework.integration.samples.cafe.xml.Waiter"/>
- <poller id="poller" default="true">
- <interval-trigger interval="1000"/>
- </poller>
- </beans:beans>
<?xml version="1.0" encoding="UTF-8"?> <beans:beans xmlns="http://www.springframework.org/schema/integration" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:stream="http://www.springframework.org/schema/integration/stream" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-1.0.xsd http://www.springframework.org/schema/integration/stream http://www.springframework.org/schema/integration/stream/spring-integration-stream-1.0.xsd"> <gateway id="cafe" service-interface="org.springframework.integration.samples.cafe.Cafe"/> <channel id="orders"/> <splitter input-channel="orders" ref="orderSplitter" method="split" output-channel="drinks"/> <channel id="drinks"/> <router input-channel="drinks" ref="drinkRouter" method="resolveOrderItemChannel"/> <channel id="coldDrinks"> <queue capacity="10"/> </channel> <service-activator input-channel="coldDrinks" ref="barista" method="prepareColdDrink" output-channel="preparedDrinks"/> <channel id="hotDrinks"> <queue capacity="10"/> </channel> <service-activator input-channel="hotDrinks" ref="barista" method="prepareHotDrink" output-channel="preparedDrinks"/> <channel id="preparedDrinks"/> <aggregator input-channel="preparedDrinks" ref="waiter" method="prepareDelivery" output-channel="deliveries"/> <stream:stdout-channel-adapter id="deliveries"/> <beans:bean id="orderSplitter" class="org.springframework.integration.samples.cafe.xml.OrderSplitter"/> <beans:bean id="drinkRouter" class="org.springframework.integration.samples.cafe.xml.DrinkRouter"/> <beans:bean id="barista" class="org.springframework.integration.samples.cafe.xml.Barista"/> <beans:bean id="waiter" class="org.springframework.integration.samples.cafe.xml.Waiter"/> <poller id="poller" default="true"> <interval-trigger interval="1000"/> </poller> </beans:beans>
以下是参考文档中的示例描述图:
CafeDemo代码创建了订单。这家咖啡店有两种饮料,一种是热的,一种是冷的,消息将这订单包装到一个"orders"的channel(频道)。一个endpoint侦听到订单频道并根据订单情况进行分开处理。
完成分开处理后,程序交给DrinksRouter经过drink频道。而DrinkRouter一个职责就是将订单内容中的热咖啡和冷咖啡交给不同的channel处理。
<gateway id="cafe" service-interface="org.springframework.integration.samples.cafe.Cafe"/>
这里Gateway主要是根据接口生成代理类。
- Cafe cafe = (Cafe) context.getBean("cafe");
- DrinkOrder order = new DrinkOrder();
- Drink hotDoubleLatte = new Drink(DrinkType.LATTE, 2, false);
- Drink icedTripleMocha = new Drink(DrinkType.MOCHA, 3, true);
- order.addDrink(hotDoubleLatte);
- order.addDrink(icedTripleMocha);
- for (int i = 0; i < 100; i++) {
- cafe.placeOrder(order);
- }
Cafe cafe = (Cafe) context.getBean("cafe"); DrinkOrder order = new DrinkOrder(); Drink hotDoubleLatte = new Drink(DrinkType.LATTE, 2, false); Drink icedTripleMocha = new Drink(DrinkType.MOCHA, 3, true); order.addDrink(hotDoubleLatte); order.addDrink(icedTripleMocha); for (int i = 0; i < 100; i++) { cafe.placeOrder(order); }
- @MessageEndpoint(input="orders", output="drinks")
- public class OrderSplitter {
- @Splitter
- public List<Drink> split(Message<DrinkOrder> orderMessage) {
- return orderMessage.getPayload().getDrinks();
- }
- }
@MessageEndpoint(input="orders", output="drinks") public class OrderSplitter { @Splitter public List<Drink> split(Message<DrinkOrder> orderMessage) { return orderMessage.getPayload().getDrinks(); } }
- @MessageEndpoint(input="drinks")
- public class DrinkRouter {
- @Router
- public String resolveDrinkChannel(Drink drink) {
- return (drink.isIced()) ? "coldDrinks" : "hotDrinks";
- }
- }
@MessageEndpoint(input="drinks") public class DrinkRouter { @Router public String resolveDrinkChannel(Drink drink) { return (drink.isIced()) ? "coldDrinks" : "hotDrinks"; } }
- <handler-endpoint handler="coldBarista" input-channel="coldDrinks"
- method="prepareColdDrink">
- </handler-endpoint>
- <handler-endpoint handler="hotBarista" input-channel="hotDrinks"
- method="prepareHotDrink">
- </handler-endpoint>
<handler-endpoint handler="coldBarista" input-channel="coldDrinks" method="prepareColdDrink"> </handler-endpoint> <handler-endpoint handler="hotBarista" input-channel="hotDrinks" method="prepareHotDrink"> </handler-endpoint>
评论
4 楼
sniciq
2012-08-22
git clone --recursive git://github.com/SpringSource/spring-integration.git
3 楼
longlong850525
2012-03-12
Spring Integration 不能完全算作是一个esb,只能算作是一个集成框架而已,和camel完成的事情差不多,不过没有camel强大
2 楼
longlong850525
2012-03-12
写得不错,顶曾经我上铺的兄弟一个
1 楼
InnocentBoy
2011-08-22
spring integration官方的下载地址不能下载!
发表评论
-
艰苦的岁月-camel成功部署mina:tcp
2009-03-27 16:04 2848下面就把camel部署mina:tcp时候遇到一些问题为大 ... -
camel入门 xmpp tcp 配置 之结束
2009-03-24 17:49 1194好了,camel没什么好说的,很简单,很灵活,很小,但也很强大 ... -
camel入门 xmpp tcp 配置 之XmppSender
2009-03-24 17:47 1528我这么厚道的把源代码贴回来,兄弟们是不是应该给点支持啊! ... -
camel入门 xmpp tcp 配置 之XMPPReceiver
2009-03-24 17:45 1855这个是服务器 packag ... -
camel入门 xmpp tcp 配置 之开篇
2009-03-24 17:43 1703搞了一周的mule实在被它的配置项搞晕了,虽然配置出来了,但要 ... -
什么是EIP
2009-03-18 17:35 1635什么是EIP EIP企业信息平台(Enterprise ... -
camel 入门(2)
2009-03-18 14:34 1918建议还是好好读读Camel的wikihttp://cwiki. ... -
camel 入门(1)
2009-03-18 14:26 1729前段时间和一些朋友聊 ...
相关推荐
自己辛苦整理的网上的JBoss ESB学习笔记 ,非常详细,代码操作都有截图; 希望大家多支持! 学习笔记PDF的目录如下: 1——搭建ESB开发环境 2 2——第一个ESB代码Hello World 12 3——第二个ESB代码Hello World ...
JBossESB学习笔记 收集了网上1-16系列教程,笔记详细介绍了JBossESB各个组件的特性及配置文件的说明
Jboss_ESB学习笔记,介绍的很详细,可以作为入门文档来看。
Jboss_ESB学习笔记.doc
Jboss_ESB学习笔记以及总结和实例
ESB应用Spring_AOP
是讲解通过springsorce进行系统集成的经典,你可以当做轻量级的ESB使用
ESB应用Spring_Hello_World
。。。
MuleESB是一个基于Java的轻量级企业服务总线和集成平台,允许开发人员快速便利地连接多个应用,并支持应用间的数据交换。MuleESB支持集成现有系统而无论其底层采用何种技术,如JMS、WebServices、JDBC、HTTP以及其他...
ESB实战篇共享
NULL 博文链接:https://topmanopensource.iteye.com/blog/1931175
ESB ESB技术学习教程ESB ESB技术学习教程ESB ESB技术学习教程ESB ESB技术学习教程ESB ESB技术学习教程ESB ESB技术学习教程
最全的esb学习资料,包括各种开源和商业ESB系统的分析和对比,以及基本的原理和架构方式
Fuse ESB 4.3.1 个人使用 笔记
jboss esb 实例及讲解,我收集的资料整理做成书
基本教程ule子红5 Spring启动基础皮草STSTest SampleDROOLS spring-boot-oauth2-master Spring启动休息大师spring-boot-reference.pdf spring-data-jpa-reference.pdf spring-security-reference.pdf 。 。 。 。 ...
ESB学习总结,关于MULE开源ESB使用心得。
JBOSS_Esb学习资料包含各种基础学习资料与协议交互资料