endpoint配置相对比较灉|Q下面再来看一个例子:(x)
<endpoint input-channel="inputChannel"
default-output-channel="outputChannel"
handler-ref="helloService"
handler-method="sayHello"/>
<beans:bean id="helloService" class="org.springframework.integration.samples.helloworld.HelloService"/>
1 public class HelloService {
2
3 public String sayHello(String name) {
4 return "Hello " + name;
5 }
6 }
上面q个例子演CZ(jin)?HelloService配置成一个MessageEndpointlgQ消息从"inputChannel"队列接收后,
调用HelloService.sayHelloҎ(gu)Q等sayHelloҎ(gu)q回后,Ҏ(gu)default-output-channel="outputChannel"的配|?br />
把返回的l果保存到message.payload属性后发送给"outputChannel"队列
也可Ҏ(gu)Annotation的方式,配置Ҏ(gu)如下Q?br />
<annotation-driven/>
<message-bus auto-create-channels="true"/>
<context:component-scan base-package="org.springframework.integration.samples.helloworld"/>
<beans:bean id="helloService" class="org.springframework.integration.samples.helloworld.HelloService"/>
1 @MessageEndpoint(input="inputChannel", defaultOutput="outputChannel")
2 public class HelloService {
3
4 @Handler
5 public String sayHello(String name) {
6 return "Hello " + name;
7 }
8 }
讄q发操作属?br />
xml配置Q?br />
<endpoint input-channel="exampleChannel" handler-ref="exampleHandler"/>
<!-- 讄q发讄 core核心(j)U程?nbsp;max最大线E数 queue-capacity 队列最大消息数 keep-alive idleU程生命旉-->
<concurrency core="5" max="25" queue-capacity="20" keep-alive="120"/>
</endpoint>
annotation配置
1 @MessageEndpoint(input="fooChannel")
2 @Concurrency(coreSize=5, maxSize=20, queueCapacity=20, keepAliveSeconds=120)
3 public class FooService {
4
5 @Handler
6 public void bar(Foo foo) {
7 
8 }
9 }
下面ȝ一下常见的annotation的用方?br />
@MessageEndpoint
它表C处理消息对象的l端节点。一般与其它的元数据标记一起用?br />
下面?x)具体介l与该元数据标记一起用的其它标识的用方法?br />
@MessageEndpoint源代码:(x)
1 @Target(ElementType.TYPE)
2 @Retention(RetentionPolicy.RUNTIME)
3 @Inherited
4 @Documented
5 @Component
6 public @interface MessageEndpoint {
7
8 String input() default ""; //接收消息的队列名U?/span>
9 String defaultOutput() default ""; //默认发送消息的队列名称(只有在不讄@Router情况下才有效)
10 int pollPeriod() default 0; //发送消息的轮@旉间隔(只有在不讄@Router情况下才有效)
11 }
@Handler
消息回调处理的方法。与@MessageEndpoint一起配|?span style="color: red;">(只限M3版,M4以及(qing)后箋版本可以单独使用,具体使用Ҏ(gu)q要{具体的实现出来)Q收到input队列的消息后Q回调@Handler标识的方?br />
回调Ҏ(gu)的参数类型必Mmessage.payload属性类型相?br />
注:(x)如果回调Ҏ(gu)有返回? 则回调方法处理完成后Q会(x)返回D|到message.payload属性后Q?br />
发送消息到@MessageEndpoint的defaultOutput队列。如果defaultOutput没有讑֮Q则抛出异常?br />
@Handler源代码:(x)
1 @Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
2 @Retention(RetentionPolicy.RUNTIME)
3 @Inherited
4 @Documented
5 public @interface Handler {
6
7 }
下面的例子演CZ(jin)Q从"channel1"队列接收消息后由@Handler标记的方法处理。消息的payload属性值的cd必须与方法的参数cd相同
1 @MessageEndpoint(input="channel1")
2 public class FooService {
3
4 @Handler
5 public void bar(Foo foo) {
6 
7 }
8 }
@Polled
必须与@MessageEndPoint 一起用。但也可以与@Router,@Splitter标识配合使用Q后面再分别举例说明?br />
@Polled 用于开启一个轮循的方式调用Ҏ(gu)的功?br />
它有三个参数Q?br />
period: 轮@旉间隔(单位:微秒) 默认?1000
initialDelay: 轮@延迟旉(单位:微秒) 默认?
fixedRate: 默认为false
@Polled 源代?br />
1 @Target(ElementType.METHOD)
2 @Retention(RetentionPolicy.RUNTIME)
3 @Inherited
4 @Documented
5 public @interface Polled {
6 int period() default 1000;
7 long initialDelay() default PollingSchedule.DEFAULT_INITIAL_DELAY;
8 boolean fixedRate() default PollingSchedule.DEFAULT_FIXED_RATE;
9
10 }
下面来看几个例子Q?br />
例子1:
1 @MessageEndpoint(defaultOutput="outputChannel")
2 public class Counter {
3
4 private AtomicInteger count = new AtomicInteger();
5
6 @Polled(period=3000)
7 public int getNumber() {
8 return count.incrementAndGet();
9 }
10 }
q个例子功能是,MessageBus启动后,由@Polled标记 ?U触发getNumberҎ(gu)Q当getNumberҎ(gu)q回后,
把返回D|到message.payload属性后Q发送到outputChannel队列中?br />
例子2:
1 @MessageEndpoint
2 public class Counter {
3
4 private AtomicInteger count = new AtomicInteger();
5
6 @Polled(period=3000)
7 public int getNumber() {
8 return count.incrementAndGet();
9 }
10
11 @Router
12 public String resolveChannel(int i) {
13 if (i % 2 == 0) {
14 return "even";
15 }
16 return "odd";
17 }
18 }
q个例子功能是,MessageBus启动后,由@Polled标记 ?U触发getNumberҎ(gu), 当getNumberҎ(gu)q回?
׃resolveChannelҎ(gu)讄?jin)@Router 标识Q则把有getNumberҎ(gu)q回值都?x)传lresolveChannelҎ(gu)Q最?br />
?x)根据方法的q回?即队列名U? (@Router标记功能)Q把消息发到even队列或是odd队列
注:(x)如果@MessageEndpointcMQ在Ҏ(gu)上标C(jin)@Router标记后,@MessageEndpoint的defaultOutput变成无效了(jin)?/span>
@Splitter
必须与@MessageEndPoint 一起用?br />
该元数据标识用于分解消息内容Q它所在的Ҏ(gu)的返回值必L一个集?collection).如果集合元素不是Messagecd
但发送时Q自动把集合中的元素对象保存到Message.payload属性后发送。集合中有多个元素Q则?x)发送多次消息?br />
1 @Target(ElementType.METHOD)
2 @Retention(RetentionPolicy.RUNTIME)
3 @Documented
4 @Handler
5 public @interface Splitter {
6 String channel(); //消息发送的队列?/span>
7 }
下面两个例子实现效果是一L(fng)
例子1
1 @MessageEndpoint(input="inputChannel")
2 public class HelloService {
3
4 @Splitter(channel="outputChannel")
5 public List<String> sayHello(String name) {
6 String s = "Hello " + name;
7 List<String> list = new ArrayList<String>();
8 list.add(s);
9 return list;
10 }
11 }
12
例子2
1 @MessageEndpoint(input="inputChannel")
2 public class HelloService {
3
4 @Splitter(channel="outputChannel")
5 public List<Message> sayHello(String name) {
6 String s = "Hello " + name;
7 List<Message> list = new ArrayList<Message>();
8 Message message = new GenericMessage<String>(s);
9 list.add(message);
10 return list;
11 }
12 }
@Router
消息队列路由功能?必须与@MessageEndPoint 一起用?br />
它所在的Ҏ(gu)的返回值类型必LMessageChannle或是String(channel name)cd
具体的例子参考上面?br />
@Publisher
必须与@MessageEndPoint 一起用?br />
说明Q@Publisher 标识是根?after-returning 切面的AOP 在方面返回值时Q发送消息到指定消息队列 .
下面的例子:(x)说明 fooҎ(gu)调用后,q回g(x)发送到fooChannel消息队列
1 @Publisher(channel="fooChannel")
2 public String foo() {
3 return "bar";
4 }
@Subscriber
必须与@MessageEndPoint 一起用?br />
接收指定队列的消息内宏V它实现的异步的消息监听事g?br />
一旦有消息接收刎ͼ则会(x)Ҏ(gu)message.payload g为参敎ͼ回调@Subscriber 标识标记的方?br />
1 @Subscriber(channel="fooChannel")
2 public void log(String foo) {
3 System.out.println(foo);
4 }
Good Luck!
Yours Matthew!
2008q??4?br />

]]>