指甲油有哪些牌子:ESB学习笔记(Spring Integration实战)

来源:百度文库 编辑:中财网 时间:2024/04/28 15:06:30
2009-11-23 来源:网络
介绍
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.(美妙现实世界产品)
源码下载打开它的网页,http://www.springsource.org/spring-integration
主页上也没有东东,但有个下源代码的地方,svn开工啦。
Java代码 
svn co https://src.springframework.org/svn/spring-integration/trunk  springintegration
svn co https://src.springframework.org/svn/spring-integration/trunk springintegration 下载完后,进入build-spring-integration目录执行ant.完成后,导入到Eclipse中。
导入项目会有很多,先添加时会有报错。这里需要添加一个变量。
IVY_CACHE=/ivy-cache/repository
这里要注意的事,也是我遇到问题。执行ant时,他会去下载lvy,如果你本身在%ANT_HOME%\lib里有lvy.jar包,由于我暂时找不到如何处理,我就直接将Ant中的jar删除掉后就没有问题。
另外在ant过程中,测试步骤可能会在file模块中出现问题,可以将相关test类中代码注释掉。
HelloWorld源码分析在samples项目中,打开helloworld包里面有三个文件。
Java代码 
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代码 

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">




output-channel="outputChannel"
ref="helloService"
method="sayHello"/>



HelloWorldDemo.java
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(); }}
Cafe源码分析 Cafe示例描述的是星巴克的订单处理故事。
其示例描述在:http://www.enterpriseintegrationpatterns.com/ramblings/18_starbucks.html
这里简单描述一下,以免大家看英文太累
文章讲在星巴克喝咖啡时,收银员可能只有一个,而冲咖啡员工会有多个,如何让收银员产生订单异步发送给冲咖啡员工。并且冲咖啡员工可能是竞争上岗的,就当他们是计件工吧。
这里要考虑问题:
1,冲咖啡员工使用不同设备,不同咖啡冲调时间可能不同。
2,冲咖啡员工可能会将相同类型的咖啡同时一起冲调。
星巴克如何处理这个问题?
就当他解决了这个问题,它是如何把每个咖啡又送回给每个客户呢?当然,星巴克采用“标识关系模式”,将每个咖啡杯上标上名称,并通过叫喊方式。
但并不是每天都是美好的,总有出错的时候。例如,收银员无法支付?冲调一杯你不喜欢的咖啡,你要换一杯?冲咖啡的设备坏了,星巴克要退你钱...这些异常情况如何处理。
因此就会有以下三种方式异常处理:
1,关闭交易,什么都不做。
2,重做,重新发起行为。
3,修正行为,相当于退钱这种行为。
因此,这里这篇文章后面讨论一下两阶段提交为什么不适合星巴克,如果你让收银员、冲咖啡员工,买单的人需要在一个“事务”中,交易所有完成后,再进行下一个业务。估计星巴克会马上倒闭啦。因此星巴克采用“Conversation pattern”模式。
好啦,业务了解清楚,我们再来看一下完整XML文件。在这里我没有采用示例详细的xml方式,而没有采用annotation方式。
以下是参考文档中的示例描述图:

CafeDemo代码创建了订单。这家咖啡店有两种饮料,一种是热的,一种是冷的,消息将这订单包装到一个"orders"的channel(频道)。一个endpoint侦听到订单频道并根据订单情况进行分开处理。
完成分开处理后,程序交给DrinksRouter经过drink频道。而DrinkRouter一个职责就是将订单内容中的热咖啡和冷咖啡交给不同的channel处理。
Xml代码 


这里Gateway主要是根据接口生成代理类。
Java代码 
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); } Java代码 
@MessageEndpoint(input="orders", output="drinks")
public class OrderSplitter {
@Splitter
public List split(Message orderMessage) {
return orderMessage.getPayload().getDrinks();
}
}
@MessageEndpoint(input="orders", output="drinks")public class OrderSplitter { @Splitter public List split(Message orderMessage) { return orderMessage.getPayload().getDrinks(); }} Java代码 
@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"; }}Xml代码 
method="prepareColdDrink">

method="prepareHotDrink">

 Java代码 
public void prepareColdDrink(Message drinkMessage) {
Drink drink = drinkMessage.getPayload();
//no changes to the rest of the code
}