Spring Integration集成框架之Message-Channel

Spring对Java企业开发的影响是巨大的,从2004年发布到现在,一直都是Java开发主要的框架,随处可见Spring的身影。我读的Spring源码不多,但不代表我对她理解的不深刻。大众熟知Struts,Hibernate其实我都一知半解,还是上学的时候听“大虾”们说的他们很厉害才学了一些,现在已经放下了好几年了。我喜欢Spring的风格和架构,也是我开发的利器。Spring发展到现在有很多的子项目,如:Spring Batch,Spring Data Redis,Spring Data Neo4j, Spring Data Hadoop, Spring Security等。哦,还有Spring Integration。

如你所见,Integration,集成!也是Spring集大成者。我是这么认为的。

Sping Integration的介绍见:http://blog.csdn.net/slivefox/article/details/3740541

Spring Integration本身并不做任何事,它通过更高层次的抽象把各种技术杂合到一起,组成一个无缝的系统。如果你熟悉UML,你就懂得抽象在软件工程的重要性。

说了这么多,Spring Integration适合做什么?如果你的系统处在各个系统的中间,需要JMS交互,又需要Database/Redis/MongoDB,还需要监听Tcp/UDP等,还有固定的文件转移,分析。还面对着时不时的更改需求的风险。那么,它再适合不过了。

在Spring Integration中,Message是它的基础构件和核心,所有的流程都围绕着Message运转。如:


payload是他可以携带的任何Object对象,Header是她包含的一些头信息。如发mail时就需要,from,to,cc等信息。正文是一段text或者html可以存储在payload中。Message总是由外部系统触发而产生,我们称他为消息生产者Producer。这也很像事件驱动模型。如:

每个Message交互的时候都需要channel。从一个channel进入,从另一个channel流出。同时另一个channel又是下一个系统的流入端。如:

他们都通过一个适配器,把Message导向每一个需要的地方,而不伤害结构。也就是说如果更改了一个地方,我们只需要更改一个适配器。

我通过一个jms做一个简单的示例。

一个简单的Bean

public class JmsMessageBean implements Serializable {
    
    private String name = null;

    private Integer age = null;

    private Date birthday = null;

    private List<String> manbers = null;

    //...getter and setter

}

一个MessageHandler:

public class JmsMessageCustomerHandler implements MessageHandler {
    public JmsMessageCustomerHandler() {
    }

    @Override
    public void handleMessage(Message<?> message) throws MessagingException {
        //输出.
        Object obj = message.getPayload();
        if(obj == null) {
            System.out.println("null");
        } else if(obj instanceof String) {
            System.out.println(obj);
        } else if(obj instanceof JmsMessageBean) {
            JmsMessageBean bean = (JmsMessageBean)obj;
            System.out.println(ReflectionToStringBuilder.reflectionToString(bean));
        } else {
            System.out.println(ReflectionToStringBuilder.reflectionToString(message));
        }
    }
}

一个消息的中转,因为我不是把消息传递给下一个系统,我只是把它简单的输出。

public class JmsMessageCustomerTransformer implements Transformer  {
    public JmsMessageCustomerTransformer() {
    }

    @Override
    public Message<?> transform(Message<?> message) {
        //不做任何事,原样返回
        return message;
    }
}
Spring schema:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:integration="http://www.springframework.org/schema/integration"
       xmlns:jms="http://www.springframework.org/schema/integration/jms"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/integration
           http://www.springframework.org/schema/integration/spring-integration-2.1.xsd
           http://www.springframework.org/schema/integration/jms
		   http://www.springframework.org/schema/integration/jms/spring-integration-jms-2.1.xsd">

    <!-- jms 连接工厂 -->
    <bean id="activeMQJmsFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
        <property name="brokerURL">
            <value>tcp://localhost:61616</value>
        </property>
    </bean>

    <bean id="connectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
        <property name="targetConnectionFactory" ref="activeMQJmsFactory" />
        <property name="sessionCacheSize" value="10"/>
        <property name="cacheProducers" value="false"/>
    </bean>

    <!-- jms Topic -->
    <bean id="myTopic" class="org.apache.activemq.command.ActiveMQTopic"
          autowire="constructor">
        <constructor-arg value="jmstopic" />
    </bean>

    <bean id="messageConverter" class="net.dintegration.jms.JmsMessageConverter" />

    <bean id="messageHander" class="net.dintegration.handler.JmsMessageCustomerHandler" />

    <bean id="messageTransformer" class="net.dintegration.transformer.JmsMessageCustomerTransformer" />

    <!-- jms 模板 -->
    <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
        <property name="connectionFactory" ref="connectionFactory" />
        <property name="defaultDestination" ref="myTopic" />
        <property name="messageConverter" ref="messageConverter" />
    </bean>

    <integration:channel id="jmsinchannel"/>

    <integration:channel id="jmsoutchannel"  />

    <jms:inbound-channel-adapter id="jmsIn" destination="myTopic" channel="jmsinchannel" jms-template="jmsTemplate">
        <integration:poller fixed-rate="30000"/>
    </jms:inbound-channel-adapter>

    <integration:transformer ref="messageTransformer"
                             input-channel="jmsinchannel" output-channel="jmsoutchannel" />
    <integration:service-activator ref="messageHander" input-channel="jmsoutchannel" />
</beans>

测试类:

public static void main(String[] args) {
        ClassPathXmlApplicationContext context =
                new ClassPathXmlApplicationContext("jmsintegration/jmsIntSubscribeContext.xml");
        context.start();
        System.out.println("Please type something and hit return");
    }

我在本机开启了一个ActiveMQ,上述测试类运行了之后线程会阻塞,JDK不会退出。使之接收JMS消息。

我另写了一个测试类发送了一条消息。如:

@Test
    public void testSendJmsMessage() throws Exception {
        System.out.println("=============================================");
        JmsMessageBean bean = new JmsMessageBean();
        bean.setAge(23);
        bean.setBirthday(new Date());
        bean.setManbers(Arrays.asList("123", "234", "345"));
        bean.setName("Jms");
        publisher.sendMessage(bean);
    }

接收消息如下:

net.dintegration.jms.JmsMessageBean@49c54f01[name=Jms,age=23,birthday=Thu Nov 01 20:19:35 CST 2012,manbers=[123, 234, 345]]


有人会问:这些代码是不是太罗嗦了?自己实现一个spring-jms都不会这么麻烦。

不知道你看到没有这样的代码:

<integration:channel id="jmsinchannel"/>

    <integration:channel id="jmsoutchannel"  />

    <jms:inbound-channel-adapter id="jmsIn" destination="myTopic" channel="jmsinchannel" jms-template="jmsTemplate">
        <integration:poller fixed-rate="30000"/>
    </jms:inbound-channel-adapter>

    <integration:transformer ref="messageTransformer"
                             input-channel="jmsinchannel" output-channel="jmsoutchannel" />
    <integration:service-activator ref="messageHander" input-channel="jmsoutchannel" />

inbound-channel-adapter是在把一个jms的输入源绑定到 jmsinchannel上, transformer使用这个输入源转给 jmsoutchannel, jmsoutchannel又是下一个消费者的输入源。假如增加了从文件系统读取文件到jmsoutchannel呢?或者还有Tcp获得的数据到jmsoutchannel呢?因为inbound-channel-adapter可以把任何输入绑定到jmsinchannel。

你觉得呢?


转载于:https://my.oschina.net/zhzhenqin/blog/86586

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值