Spring基于JMS实现远程访问
2011-04-24 20:47
405 查看
使用JMS作为底层通信协议,Spring提供了很好的支持。我们可以基于JMS将服务暴露给外部,这一切对于外部完全透明。这里我们基于开源消息中间件ActiveMQ作为中间代理,通过在服务端将服务以消息的形式发布到代理服务器上,然后客户端通过代理服务器实现对服务的远程调用。
ActiveMQ的BrokerService可以非常容易地实现服务端与客户端进行通信的中间代理,Spring配置broker.xml内容如下所示:
通过Spring的IOC容器来管理BrokerService。实现一个基于ActiveMQ的消息代理服务,如下所示:
启动后,代理监听61616,等待服务端发布服务,以及远程客户端调用服务。
看一下,服务端如何进行实现。
定义服务接口和服务实现。服务接口,代码如下所示:
实现上述接口,示例代码如下所示:
然后,服务端的配置server.xml,内容如下所示:
通过Spring的org.springframework.jms.listener.SimpleMessageListenerContainer实现服务的发布,可以配置的属性有:
connectionFactory 连接工厂
destination 消息目的地,基于ActiveMQ则是一个消息队列
concurrentConsumers 并发消息消费者数量
messageListener 消息监听器
taskExecutor 线程池
通过上面配置可以看到,连接工厂指定了代理监听服务的端口,我们通过服务端发布服务,作为消息生产者将服务以消息的形式发布,然后客户端作为服务的消费者,通过代理来实现对远程发布服务的调用。
服务端启动的实现,如下所示:
再看一下,客户端如何进行远程访问。
对应的客户端的配置client.xml,内容如下所示:
主要是基于Spring提供的org.springframework.jms.remoting.JmsInvokerProxyFactoryBean来实现,通过消息中间件代理,调用远程发布的服务。
需要注意的是,客户端是通过消息队列(org.apache.activemq.command.ActiveMQQueue)的名称(如上述为shirdrnQ)来获取消息(远程服务),如果无法识别消息队列是无法实现服务的远程访问的。
客户端实现远程访问,示例代码如下所示:
ActiveMQ的BrokerService可以非常容易地实现服务端与客户端进行通信的中间代理,Spring配置broker.xml内容如下所示:
<?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:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean id="broker" class="org.apache.activemq.broker.BrokerService" /> </beans>
通过Spring的IOC容器来管理BrokerService。实现一个基于ActiveMQ的消息代理服务,如下所示:
package org.shirdrn.spring.remote.jms; import org.apache.activemq.broker.BrokerService; import org.apache.log4j.Logger; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Broker { private static final Logger LOG = Logger.getLogger(Broker.class); private static final String CONNECTOR_ADDRESS = "tcp://192.168.1.103:61616"; public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext( new String[] { "org/shirdrn/spring/remote/jms/broker.xml" }); BrokerService broker = (BrokerService) ctx.getBean("broker"); try { broker.setBrokerName("myBroker"); broker.setUseJmx(true); broker.addConnector(CONNECTOR_ADDRESS); broker.start(); LOG.info("Broker service started."); Object lock = new Object(); synchronized (lock) { lock.wait(); } } catch (InterruptedException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } }
启动后,代理监听61616,等待服务端发布服务,以及远程客户端调用服务。
看一下,服务端如何进行实现。
定义服务接口和服务实现。服务接口,代码如下所示:
package org.shirdrn.spring.remote.jms; public interface AccountService { int queryBalance(String mobileNo); String shoopingPayment(String mobileNo, byte protocol); }
实现上述接口,示例代码如下所示:
package org.shirdrn.spring.remote.jms; import org.apache.log4j.Logger; public class MobileAccountServiceImpl implements AccountService { private static final Logger LOG = Logger.getLogger(MobileAccountServiceImpl.class); public int queryBalance(String mobileNo) { if (mobileNo != null) return 100; return 0; } public String shoopingPayment(String mobileNo, byte protocol) { StringBuffer sb = new StringBuffer().append("Your mobile number is /"") .append(mobileNo).append("/", protocol type is /"").append( protocol).append("/"."); LOG.info(sb.toString()); return sb.toString(); } }
然后,服务端的配置server.xml,内容如下所示:
<?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:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean class="org.springframework.jms.listener.SimpleMessageListenerContainer"> <property name="connectionFactory" ref="connectionFactory" /> <property name="destination" ref="myQueue" /> <property name="concurrentConsumers" value="3" /> <property name="messageListener" ref="myAccountService" /> <property name="taskExecutor" ref="threadPool" /> </bean> <bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"> <property name="brokerURL" value="tcp://192.168.1.103:61616" /> </bean> <bean id="myQueue" class="org.apache.activemq.command.ActiveMQQueue"> <constructor-arg value="shirdrnQ" /> </bean> <bean id="myAccountService" class="org.springframework.jms.remoting.JmsInvokerServiceExporter"> <property name="serviceInterface" value="org.shirdrn.spring.remote.jms.AccountService" /> <property name="service"> <bean class="org.shirdrn.spring.remote.jms.MobileAccountServiceImpl" /> </property> </bean> <bean id="threadPool" class="org.springframework.core.task.SimpleAsyncTaskExecutor"> <property name="daemon" value="true" /> <property name="concurrencyLimit" value="300" /> <property name="threadNamePrefix" value="SERVICE" /> </bean> </beans>
通过Spring的org.springframework.jms.listener.SimpleMessageListenerContainer实现服务的发布,可以配置的属性有:
connectionFactory 连接工厂
destination 消息目的地,基于ActiveMQ则是一个消息队列
concurrentConsumers 并发消息消费者数量
messageListener 消息监听器
taskExecutor 线程池
通过上面配置可以看到,连接工厂指定了代理监听服务的端口,我们通过服务端发布服务,作为消息生产者将服务以消息的形式发布,然后客户端作为服务的消费者,通过代理来实现对远程发布服务的调用。
服务端启动的实现,如下所示:
package org.shirdrn.spring.remote.jms; import org.apache.log4j.Logger; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Server { private static final Logger LOG = Logger.getLogger(Server.class); public static void main(String[] args) throws Exception { new ClassPathXmlApplicationContext( new String[] { "org/shirdrn/spring/remote/jms/server.xml" }); LOG.info("Server started."); } }
再看一下,客户端如何进行远程访问。
对应的客户端的配置client.xml,内容如下所示:
<?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:p="http://www.springframework.org/schema/p" 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://192.168.1.103:61616" /> </bean> <bean id="myQueue" class="org.apache.activemq.command.ActiveMQQueue"> <constructor-arg value="shirdrnQ" /> </bean> <bean id="myAccountService" class="org.springframework.jms.remoting.JmsInvokerProxyFactoryBean"> <property name="serviceInterface" value="org.shirdrn.spring.remote.jms.AccountService" /> <property name="connectionFactory" ref="connectionFactory" /> <property name="queue" ref="myQueue" /> </bean> </beans>
主要是基于Spring提供的org.springframework.jms.remoting.JmsInvokerProxyFactoryBean来实现,通过消息中间件代理,调用远程发布的服务。
需要注意的是,客户端是通过消息队列(org.apache.activemq.command.ActiveMQQueue)的名称(如上述为shirdrnQ)来获取消息(远程服务),如果无法识别消息队列是无法实现服务的远程访问的。
客户端实现远程访问,示例代码如下所示:
package org.shirdrn.spring.remote.jms; import org.apache.log4j.Logger; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Client { private static final Logger LOG = Logger.getLogger(Client.class); static int index = 0; private static void invoke(AccountService service) { String mobileNo = "1380013800" + (String.valueOf(index++)); String result = service.shoopingPayment(mobileNo, (byte) 3); LOG.info("Client gets result: " + result); } public static void main(String[] args) throws Exception { ApplicationContext ctx = new ClassPathXmlApplicationContext( new String[] { "org/shirdrn/spring/remote/jms/client.xml" }); AccountService service = (AccountService) ctx .getBean("myAccountService"); for(int i=0; i<100; i++) { invoke(service); } } }
相关文章推荐
- Spring基于JMS实现远程访问
- Spring基于JMS实现远程访问
- Spring 实现远程访问详解——jms和activemq
- Spring整合JMS(一)——基于ActiveMQ实现
- Spring整合JMS——基于ActiveMQ实现
- Spring整合JMS(一)——基于ActiveMQ实现
- Spring与RMI集成实现远程访问
- Spring整合JMS——基于ActiveMQ实现
- spring整合JMS - 基于ActiveMQ实现
- Spring整合JMS——基于ActiveMQ实现
- Spring 实现远程访问详解——rmi
- Spring整合JMS——基于ActiveMQ实现
- spring整合JMS(基于ActiveMQ的实现)
- Spring整合JMS(一)——基于ActiveMQ实现
- 实现基于Spring技术应用的远程服务编程
- Spring整合JMS——基于ActiveMQ实现(一)
- Spring整合JMS(一)——基于ActiveMQ实现 (转)
- Spring与RMI集成实现远程访问
- 基于Spring的远程调用的实现