24.6 JMS
使用JMS来作为底层的通信协议透明暴露服务也是可能的。Spring框架中对JMS的远程支持也很基础 – 它在同一线程和同一个非事务 Session上发送和接收,这些吞吐量将非常依赖于实现。需要注意的是这些单线程和非事务的约束仅适用于Spring的JMS远程处理支持。请参见 第26章, JMS (Java消息服务),Spring对基于JMS的消息的丰富支持。 下面的接口可同时用在服务端和客户端。
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″?>
<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.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>
24.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/beanshttp://www.springframework.org/schema/beans/spring-beans.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"});}}
24.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/beanshttp://www.springframework.org/schema/beans/spring-beans.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));}}
