17.6. JMS

Spring Framework

17.6. JMS

使用JMS来作为底层的通信协议透明暴露服务也是可能的。Spring框架中对JMS的远程支持也很基础 - 它在同一线程同一个非事务 Session上发送和接收,这些吞吐量将非常依赖于实现。

The following interface is used on both the server and the client side.

下面的接口可同时用在服务端和客户端。

package com.foo;

public interface CheckingAccountService {

    public void cancelAccount(Long accountId);
}

对于上面接口的使用在服务的端简单实现如下。

package com.foo;

public class SimpleCheckingAccountService implements CheckingAccountService {

    public void cancelAccount(Long accountId) {
        System.out.println("Cancelling account [" + accountId + "]");
    }
}

这个包含JMS设施的bean的配置文件可同时用在客户端和服务端。

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

    <bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
        <property name="brokerURL" value="tcp://ep-t43:61616"/>
    </bean>

    <bean id="queue" class="org.apache.activemq.command.ActiveMQQueue">
        <constructor-arg value="mmm"/>
    </bean>

</beans>

17.6.1. 服务端配置

在服务端你只需要使用JmsInvokerServiceExporter来暴露服务对象。

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

    <bean id="checkingAccountService"
          class="org.springframework.jms.remoting.JmsInvokerServiceExporter">
        <property name="serviceInterface" value="com.foo.CheckingAccountService"/>
        <property name="service">
            <bean class="com.foo.SimpleCheckingAccountService"/>
        </property>
   </bean>

   <bean class="org.springframework.jms.listener.SimpleMessageListenerContainer">
       <property name="connectionFactory" ref="connectionFactory"/>
       <property name="destination" ref="queue"/>
       <property name="concurrentConsumers" value="3"/>
       <property name="messageListener" ref="checkingAccountService"/>
   </bean>

</beans>
package com.foo;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Server {

    public static void main(String[] args) throws Exception {
        new ClassPathXmlApplicationContext(new String[]{"com/foo/server.xml", "com/foo/jms.xml"});
    }
}

17.6.2. 客户端配置

客户端仅仅需要创建一个客户端代理来实现上面的接口(CheckingAccountService)。根据后面的bean定义创建的结果对象可以被注入到其它客户端对象中,而这个代理会负责通过JMS将调用转发到服务端。

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

    <bean id="checkingAccountService"
          class="org.springframework.jms.remoting.JmsInvokerProxyFactoryBean">
        <property name="serviceInterface" value="com.foo.CheckingAccountService"/>
        <property name="connectionFactory" ref="connectionFactory"/>
        <property name="queue" ref="queue"/>
    </bean>

</beans>
package com.foo;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Client {

    public static void main(String[] args) throws Exception {
        ApplicationContext ctx = new ClassPathXmlApplicationContext(
                new String[] {"com/foo/client.xml", "com/foo/jms.xml"});
        CheckingAccountService service = (CheckingAccountService) ctx.getBean("checkingAccountService");
        service.cancelAccount(new Long(10));
    }
}

你可能也希望研究Lingo 项目提供的支持,它(引用到主页) “... 是一个基于轻量级POJO的远程核消息代码库,它使用并扩展了Spring框架的远程代码库以支持JMS。