【参考:http://cxf.apache.org/docs/jms-transport.html 】
【参考:http://cxf.apache.org/docs/using-the-jmsconfigfeature.html 】
【参考:http://cxf.apache.org/scalable-cxf-applications-using-jms-transport.html 】
前面三节介绍的Server与Client之间的通信方式都是基于HTTP,这节介绍怎么将CXF的服务发布在JMS上,通过发送、接收JMS消息来调用服务。
一、启动JMS Broker
要使用JMS,首先需要有一个JMS服务器,这里我使用Apache ActiveMQ作为JMS的服务器,可以从网上下载,也可以通过执行代码的方式启动,例如:
BrokerService bs = new BrokerService(); bs.setPersistenceAdapter(new MemoryPersistenceAdapter()); bs.addConnector("tcp://localhost:61616"); bs.start(); System.out.println("jms broker started");
上面启动一个ActiveMQ的broker,地址为tcp://localhost:61616,并且消息存储在内存里。
二、定义服务接口
这个和前面介绍的内容差不多,服务接口定义如下:
@WebService(targetNamespace="http://localhost:8080/cxf/jms") public interface OrderProcess { @WebMethod(operationName="processOrder") public String processOrder( @WebParam(name="order") Order order); }
三、发布服务
之前所有的服务都是以缺省的http协议发布的,这里要使用jms协议,就需要让CXF知道,这是通过一个JMSConfigFeature来实现的,如下:
//basic setting on service JaxWsServerFactoryBean jwfb = new JaxWsServerFactoryBean(); jwfb.setServiceClass(OrderProcess.class); jwfb.setServiceBean(new OrderProcessImpl()); jwfb.setAddress("jms://"); //specify jms transport //create jms connection factory ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(); connectionFactory.setBrokerURL("tcp://localhost:61616"); //set target destination queue JMSConfiguration jmsConfig = new JMSConfiguration(); jmsConfig.setTargetDestination("cxf.orderprocess.queue"); jmsConfig.setConnectionFactory(connectionFactory); //add feature JMSConfigFeature jmsFeature = new JMSConfigFeature(); jmsFeature.setJmsConfig(jmsConfig); jwfb.getFeatures().add(jmsFeature); //create jwfb.create();
首先需要指定服务接口和实现类;接下来在address变量里,需要指定的值为"jms://"开头的值,以告知cxf这里使用jms的传输协议。
然后就是普通的jms连接和配置的创建过程:指定broker的url和目标queue,接下来创建一个JMSConfigFeature, 设置它的jms配置信息,最后作为feature添加。这样这个服务就准备就诸,等待请求了。
Spring版本:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <import resource="classpath:META-INF/cxf/cxf.xml" /> <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" /> <import resource="classpath:META-INF/cxf/cxf-servlet.xml" /> <bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"> <property name="brokerURL" value="tcp://localhost:61616" /> </bean> <bean id="jmsConfig" class="org.apache.cxf.transport.jms.JMSConfiguration"> <property name="connectionFactory" ref="connectionFactory" /> <property name="targetDestination" value="cxf.orderprocess.queue" /> </bean> <jaxws:endpoint id="orderProcess" implementor="com.liulutu.liugang.jms.OrderProcessImpl" address="jms://"> <jaxws:features> <bean class="org.apache.cxf.transport.jms.JMSConfigFeature"> <property name="jmsConfig" ref="jmsConfig" /> </bean> </jaxws:features> </jaxws:endpoint> </beans>
四、请求服务
显然和创建服务过程一样,需要配置client的jms信息,以将请求消息发送到jms服务器上,供服务端消费:
//create jms connection and configuration ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(); connectionFactory.setBrokerURL("tcp://localhost:61616"); JMSConfiguration jmsConfig = new JMSConfiguration(); jmsConfig.setTargetDestination("cxf.orderprocess.queue"); jmsConfig.setConnectionFactory(connectionFactory); //create feature and config it with jms configuration JMSConfigFeature jmsFeature = new JMSConfigFeature(); jmsFeature.setJmsConfig(jmsConfig); //create client, and add the feature JaxWsProxyFactoryBean client = new JaxWsProxyFactoryBean(); client.setAddress("jms://"); //specify tranport type client.getFeatures().add(jmsFeature); //call service OrderProcess orderProcess = client.create(OrderProcess.class); String s = orderProcess.processOrder(order); System.out.println(s);
可以看出,无论Server还是Client端,关键步骤都在于添加JMSConfigFeature,并且设置它所需的jms连接信息。
Spring版本:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <import resource="classpath:META-INF/cxf/cxf.xml" /> <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" /> <import resource="classpath:META-INF/cxf/cxf-servlet.xml" /> <bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"> <property name="brokerURL" value="tcp://localhost:61616" /> </bean> <bean id="jmsConfig" class="org.apache.cxf.transport.jms.JMSConfiguration"> <property name="connectionFactory" ref="connectionFactory" /> <property name="targetDestination" value="cxf.orderprocess.queue" /> </bean> <jaxws:client id="orderProcessClient" serviceClass="com.liulutu.liugang.jms.OrderProcess" address="jms://"> <jaxws:features> <bean class="org.apache.cxf.transport.jms.JMSConfigFeature"> <property name="jmsConfig" ref="jmsConfig" /> </bean> </jaxws:features> </jaxws:client> </beans>
然后在代码里: