领先一步
VMware 提供培训和认证,以加速您的进步。
了解更多在我最近的文章中,我提到过 Spring Integration 的 Subversion 存储库很快就会公开访问,我很高兴现在提供该链接。您可以使用以下命令检出项目
svn co https://anonsvn.springframework.org/svn/spring-integration/base/trunk spring-integration
如果检出成功,您应该会看到以下目录结构
spring-integration/
+--build-spring-integration/
+--spring-build/
+--spring-integration-core/
+--spring-integration-samples/
我想借此机会浏览一下“spring-integration-samples”中的一些示例。请记住,这个项目绝对是一个正在进行中的工作(目前是 0.5 SNAPSHOT),但是这些示例应该让您了解编程模型的形成方式,我非常期待收到一些反馈。
public class HelloService {
public String sayHello(String name) {
return "Hello " + name;
}
}
此示例使用基于 XML 的配置来配置消息端点(我们将在后面看到注解方法)
<endpoint input-channel="inputChannel"
default-output-channel="outputChannel"
handler-ref="helloService"
handler-method="sayHello"/>
您在那里看到“handler-ref”只是指向一个 Spring 托管的 Bean。如果您已将 Spring 的MessageListenerAdapter用于异步 JMS 接收,那么这应该看起来很熟悉——特别是如果您使用 Spring 2.5 的新jms命名空间和“jms:listener”元素。最后,HelloWorldDemo启动应用程序上下文,然后与通道交互
ChannelRegistry channelRegistry = (ChannelRegistry) context.getBean(MessageBusParser.MESSAGE_BUS_BEAN_NAME);
MessageChannel inputChannel = channelRegistry.lookupChannel("inputChannel");
MessageChannel outputChannel = channelRegistry.lookupChannel("outputChannel");
inputChannel.send(new StringMessage(1, "World"));
System.out.println(outputChannel.receive().getPayload());
该示例涉及 MessageBus Bean 的查找——它实现了 ChannelRegistry 接口。但是,在非演示“现实世界”场景中,任何访问通道的组件都可以通过依赖注入提供注册表。它只需要实现ChannelRegistryAware(或使用 @Autowired)即可。这与 Spring 中其他地方使用的相同方法——例如ApplicationEventPublisherAware。
@MessageEndpoint(defaultOutput="quotes")
public class QuotePublisher {
@Polled(period=300)
public Quote getQuote() {
BigDecimal price = new BigDecimal(new Random().nextDouble() * 100);
return new Quote(generateTicker(), price.setScale(2, RoundingMode.HALF_EVEN));
}
private String generateTicker() {
// randomly generates 3-letter tickers
}
}
在接收端,有一个 @Subscriber 注解
public class QuoteSubscriber {
@Subscriber(channel="quotes")
public void log(Object o) {
System.out.println(o);
}
}
这是注册注解后处理器和 2 个 Spring 托管 Bean 的 XML(注意此示例使用“spring-integration”模式作为主要命名空间)。
<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">
<message-bus/>
<annotation-driven/>
<channel id="quotes"/>
<beans:bean id="publisher" class="org.springframework.integration.samples.quote.QuotePublisher"/>
<beans:bean id="subscriber" class="org.springframework.integration.samples.quote.QuoteSubscriber"/>
</beans:beans>
顺便说一下,“annotation-driven”元素还启用了 @Publisher 注解,该注解会触发创建 AOP 建议,以将任何带注解方法的返回值异步发送到通道。
@MessageEndpoint
public class Counter {
private AtomicInteger count = new AtomicInteger();
@Polled(period=3000)
public int getNumber() {
return count.incrementAndGet();
}
@Router
public String resolveChannel(int i) {
if (i % 2 == 0) {
return "even";
}
return "odd";
}
}
在这些通道的接收端,我们有 2 种不同的方法,它们只是记录消息有效负载
@Component
public class NumberLogger {
@Subscriber(channel="even")
public void even(int i) {
System.out.println("even: " + i);
}
@Subscriber(channel="odd")
public void odd(int i) {
System.out.println("odd: " + i);
}
}
顺便说一下,请注意NumberLogger使用 Spring 的 @Component 进行注解。@MessageEndpoint 注解还包含 @Component 作为元注解。因此,两者都是“立体类型”,并且可以使用 Spring 2.5 的类路径扫描进行自动检测。此示例的 XML 非常简单
<context:component-scan base-package="org.springframework.integration.samples.oddeven"/>
<message-bus auto-create-channels="true"/>
<annotation-driven/>