Spring JMS (ActiveMQ)和使用基于JMS的RPC

在实践Spring JMS的过程中,遇到如下问题:

使用的ActiveMQ的版本为: 5.15.9

详细的代码在github上:SpringJMSSpittr (服务端,发送消息)SpringJMSSpittrCustomer (客户端,消费消息)

说明: 在实践下面内容之前,要先安装一个流程的开源消息代理: ActiveMQ

如下是在macOS系统中启动和关闭activeMQ的命令:

// 启动activemq服务
cd ${apache-activemq}/bin/macosx
sudo ./activemq start

// 停止activemq服务
sudo ./activemq stop

一、Serializable class not available to broker

Serializable class not available to broker. Reason: java.lang.ClassNotFoundException: Forbidden class com.hef.spittr.domain.Spitter

解决:

在客户端使用如下配置:

<amq:connectionFactory id="connectionFactory" brokerURL="tcp://localhost:61616" trustAllPackages="true"/>

二、使用convertAndSend 和 MappingJackson2MessageConverter

需要对MappingJackson2MessageConverter进行一些配置,否则会报错。

/**
     * 配置消息转换器
     * @return
     */
    @Bean
    public MappingJackson2MessageConverter messageConverter(){
        MappingJackson2MessageConverter messageConverter =
                new MappingJackson2MessageConverter();
        messageConverter.setEncoding("UTF-8");
        messageConverter.setTargetType(MessageType.TEXT);
        Map<String, Class<?>> typMap = new HashMap<>();
        typMap.put("spitter", Spitter.class);
        messageConverter.setTypeIdMappings(typMap);
        messageConverter.setTypeIdPropertyName("spitter");
        return messageConverter;
    }

三、 创建消息驱动的POJO

创建消息驱动的POJO的目的是:让消息接受者异步接收消息。

因此,只需要在消费者应用端进行创建和配置。

3.1 创建消息监听器

@Configuration
public class SpitterAlertAsychronizationHandlerImpl implements SpitterAlertAsychronizationHandler {
    @Override
    public void handleSpittleAlert(Spitter spitter) {
        System.out.println("asychronization begin...");
        System.out.println(spitter);
        System.out.println("asychronization end...");
    }
}

3.2 配置消息监听器

<!--第一步: 将处理器声明为bean-->
    <bean id="spitterAlertAsychronizationHandler" class="com.hef.spittr.service.impl.SpitterAlertAsychronizationHandlerImpl"/>
    <!--第二步: 将SpitterAlertAsychronizationHandlerImpl 转变为消息驱动的POJO-->
    <jms:listener-container>
        <jms:listener destination="spitter.alert.queue" ref="spitterAlertAsychronizationHandler" method="handleSpittleAlert"/>
    </jms:listener-container>

3.3 测试异步消息

测试基于消息的驱动

四、使用基于JMS的服务

4.1 在服务端应用程序中

4.1.1 定义服务接口

import com.hef.spittr.domain.Spitter;

public interface JMSRPCService {

    Spitter findSpitterById(long id);
}

4.1.2 实现服务接口

import com.hef.spittr.domain.Spitter;
import com.hef.spittr.service.JMSRPCService;
import com.hef.spittr.service.SpitterService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @Date 2019-04-27
 * @Author lifei
 */
@Component
public class JMSRPCServiceImpl implements JMSRPCService {

    @Autowired
    private SpitterService spitterService;
    @Override
    public Spitter findSpitterById(long id) {
        System.out.println("id:" + id);
        return spitterService.getSpitter(id);
    }
}

4.1.3 装配导出器

import com.hef.spittr.service.JMSRPCService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.remoting.JmsInvokerServiceExporter;

/**
 * @Date 2019-04-27
 * @Author lifei
 */
@Configuration
public class JMSRPCServiceConfig {
    /**
     * 装配 导出器
     * @param service
     * @return
     */
    @Bean
    public JmsInvokerServiceExporter jmsInvokerServiceExporter(JMSRPCService service){
        JmsInvokerServiceExporter jmsInvokerServiceExporter = new JmsInvokerServiceExporter();
        jmsInvokerServiceExporter.setService(service);
        jmsInvokerServiceExporter.setServiceInterface(JMSRPCService.class);
        return jmsInvokerServiceExporter;
    }
}

4.1.4 导出服务

<!-- 导出基于JMS的服务-->
    <bean class="config.JMSRPCServiceConfig"/>
    <jms:listener-container>
        <jms:listener destination="spitter.rpc.queue" ref="jmsInvokerServiceExporter"/>
    </jms:listener-container>

4.2 客户端应用程序

4.2.1 使用服务的配置

<!-- 练习第四部分: 使用基于JMS的服务-->
    <bean id="jmsrpcService" class="org.springframework.jms.remoting.JmsInvokerProxyFactoryBean"
          p:connectionFactory-ref="connectionFactory"
          p:queueName="spitter.rpc.queue"
          p:serviceInterface="com.hef.spittr.service.JMSRPCService"/>

4.3 测试JMS的RPC

4.3.1 启动服务端

/**
 * @Date 2019-04-27
 * @Author lifei
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {RootConfig.class})
public class JMSRPCServiceTest {

    @Autowired
    private JMSRPCService jmsrpcService;

    @Test
    public void waritRPCInvokerTest(){
        System.out.println("service begin:");
        while (true){
            try {
                Thread.sleep(5000l);
                System.out.println("welcome...");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }
}

启动服务端

4.3.2 启动服务端

/**
 * @Date 2019-04-27
 * @Author lifei
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {RootConfig.class})
public class JMSRPCServiceTest {

    @Autowired
    private JMSRPCService jmsrpcService;

    @Test
    public void waritRPCInvokerTest(){
        System.out.println("service begin:");
        while (true){
            try {
                Thread.sleep(5000l);
                System.out.println("welcome...");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }
}

启动客户端

服务端打印日志:

服务端打印的内容

猜你喜欢

转载自blog.csdn.net/hefrankeleyn/article/details/89530301
jms
今日推荐