posts - 156,  comments - 601,  trackbacks - 0
关于endpoint配置补充
    endpoint配置相对比较灵活,下面再来看一个例子:
        <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         }

 上面这个例子就演示了把 HelloService配置成一个MessageEndpoint组件,消息从"inputChannel"队列接收后,
 调用HelloService.sayHello方法,等sayHello方法返回后,根据default-output-channel="outputChannel"的配置
 把返回的结果保存到message.payload属性后发送给"outputChannel"队列

也可改成Annotation的方式,配置方法如下:
    <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 }

设置并发操作属性
xml配置:
<endpoint input-channel="exampleChannel" handler-ref="exampleHandler"/>
        
<!-- 设置并发设置 core核心线程数 max最大线程数 queue-capacity 队列最大消息数 keep-alive idle线程生命时间-->
    
<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的使用方法
@MessageEndpoint
它表示处理消息对象的终端节点。一般与其它的元数据标记一起使用。
下面会具体介绍与该元数据标记一起使用的其它标识的使用方法。

@MessageEndpoint源代码:

 1 @Target(ElementType.TYPE)
 2 @Retention(RetentionPolicy.RUNTIME)
 3 @Inherited
 4 @Documented
 5 @Component
 6 public @interface MessageEndpoint {
 7 
 8     String input() default ""//接收消息的队列名称
 9     String defaultOutput() default ""//默认发送消息的队列名称(只有在不设置@Router情况下才有效)
10     int pollPeriod() default 0//发送消息的轮循时间间隔(只有在不设置@Router情况下才有效)
11 }

@Handler
消息回调处理的方法。与@MessageEndpoint一起配置(只限M3版,M4以及后续版本可以单独使用,具体使用方法还要等具体的实现出来),收到input队列的消息后,回调@Handler标识的方法
回调方法的参数类型必须与message.payload属性类型相同
注:如果回调方法有返回值, 则回调方法处理完成后,会将返回值设置到message.payload属性后,
发送消息到@MessageEndpoint的defaultOutput队列。如果defaultOutput没有设定,则将抛出异常。

@Handler源代码:

1 @Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
2 @Retention(RetentionPolicy.RUNTIME)
3 @Inherited
4 @Documented
5 public @interface Handler {
6 
7 }

下面的例子演示了,从"channel1"队列接收消息后由@Handler标记的方法处理。消息的payload属性值的类型必须与方法的参数类型相同
1 @MessageEndpoint(input="channel1")
2 public class FooService {
3 
4     @Handler
5     public void bar(Foo foo) {
6         
7     }
8 }


@Polled
必须与@MessageEndPoint 一起使用。但也可以与@Router,@Splitter标识配合使用,后面再分别举例说明。
@Polled 用于开启一个轮循的方式调用方法的功能
它有三个参数:
    period: 轮循时间间隔(单位:微秒) 默认为 1000
    initialDelay:  轮循延迟时间(单位:微秒) 默认为0
    fixedRate: 默认为false
   
@Polled 源代码
 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 
 
   
下面来看几个例子:
例子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 }  

这个例子功能是,MessageBus启动后,由@Polled标记 每3秒触发getNumber方法,当getNumber方法返回后,
把返回值设置到message.payload属性后,发送到outputChannel队列中。


例子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 }   

这个例子功能是,MessageBus启动后,由@Polled标记 每3秒触发getNumber方法, 当getNumber方法返回后,
由于resolveChannel方法设置了@Router 标识,则把有getNumber方法返回值都会传给resolveChannel方法,最后
会根据方法的返回值(即队列名称) (@Router标记功能),把消息发到even队列或是odd队列

注:如果@MessageEndpoint类中,在方法上标记了@Router标记后,@MessageEndpoint的defaultOutput就变成无效了。


@Splitter
必须与@MessageEndPoint 一起使用。
该元数据标识用于分解消息内容,它所在的方法的返回值必须是一个集合(collection).如果集合元素不是Message类型
但发送时,自动把集合中的元素对象保存到Message.payload属性后发送。集合中有多少个元素,则会发送多少次消息。

1 @Target(ElementType.METHOD)
2 @Retention(RetentionPolicy.RUNTIME)
3 @Documented
4 @Handler
5 public @interface Splitter {
6     String channel(); //消息发送的队列名
7 }


下面两个例子实现效果是一样的
例子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 一起使用。
它所在的方法的返回值类型必须是MessageChannle或是String(channel name)类型
具体的例子参考上面。

@Publisher
必须与@MessageEndPoint 一起使用。
说明:@Publisher 标识是根据 after-returning 切面的AOP 在方面返回值时,发送消息到指定消息队列 .    

下面的例子:说明 foo方法调用后,返回值会发送到fooChannel消息队列
1 @Publisher(channel="fooChannel")
2 public String foo() {
3     return "bar";
4 }
 

@Subscriber 
必须与@MessageEndPoint 一起使用。
接收指定队列的消息内容。它实现的异步的消息监听事件。
一旦有消息接收到,则会根据message.payload 值作为参数,回调@Subscriber 标识标记的方法
1 @Subscriber(channel="fooChannel")
2 public void log(String foo) {
3     System.out.println(foo);
4 }


Good Luck!
Yours Matthew!
2008年4月24日




posted on 2008-05-28 21:38 x.matthew 阅读(1926) 评论(1)  编辑  收藏 所属分类: Spring|Hibernate|Other framework

只有注册用户登录后才能发表评论。


网站导航: