Spring Boot 与 IBM WebSphere MQ集成配置

Spring Boot JMS与IBM WebSphere MQ集成配置

[TOC]

Spring Boot作为简化Spring开发的框架,已经为我们集成了ActiveMQ和RabbitMQ。只需在Spring Boot配置几个MQ的连接方式即可开箱即用。大大简化了开发配置过程。
Spring的JavaConfig相比传统的XML的配置方式使得配置更加的可靠和方便。
本文将会说明如何用JavaConfig的方式将Spring与IBM WebSphere MQ(以下简称IBM MQ)集成配置,也可以作为其他MQ的配置参考。

  • IntelliJ Idea
  • JDK 1.8.0_121
  • Maven
  • 获取IBM MQ依赖包

    17年后官方maven仓库以有相关依赖

    <!-- https://mvnrepository.com/artifact/com.ibm.mq/com.ibm.mq.allclient -->
    <dependency>
        <groupId>com.ibm.mq</groupId>
        <artifactId>com.ibm.mq.allclient</artifactId>
        <version>9.1.1.0</version>
    </dependency>
    

    IBM MQ相关的连接依赖包为com.ibm.mq.allclient.jar,该包不存在于公共Maven仓库,所以我们需要找到该依赖包并手动安装到我们本机的Maven仓库中。
    该依赖包位于[IBM MQ 安装路径]\java\lib下,Windows下的默认安装路径为C:\Program Files\IBM\WebSphere MQ\,Linux下的默认安装路径为/opt/mqm/。可以将该包复制到开发机上。
    通过以下命令安装该包到本地仓库

    mvn install:install-file -Dfile=[jar包所在路径] -DgroupId=com.ibm -DartifactId=mq.allclient -Dversion=1.0 -Dpackaging=jar
    

    在Idea中可以按四次Shift键调出全局搜索框,键入Execute Maven Goal,等待搜索结果后按回车,即可执行Maven命令,在此执行命令时不需要键入命令开头的mvn

    添加依赖到项目

    编辑项目pom.xml文件,添加以下三个依赖,分别为

  • spring-boot-starter-activemq:即Spring JMS
  • javax.jms-api
  • mq.allclient:即上一步中安装到本地的包
  • <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-activemq</artifactId>
    </dependency>
    <dependency>
        <groupId>javax.jms</groupId>
        <artifactId>javax.jms-api</artifactId>
        <version>2.0.1</version>
    </dependency>
    <dependency>
        <groupId>com.ibm.mq</groupId>
        <artifactId>com.ibm.mq.allclient</artifactId>
        <version>9.1.1.0</version>
    </dependency>
    

    MQ连接参数

    配置Spring Boot配置文件,application.yml,此处用的是yaml格式配置文件,application.properties的配置方法可以参考Spring Boot的说明。

    project:  
        host: 192.168.1.180
        port: 1416
        queue-manager: QM         #队列管理器
        channel: mqm.SVRCONN      #服务器连接通道
        username: mqm             #用户名
        password: 123456          #密码
        receive-timeout: 2000     #连接超时
    

    JmsConfig

    注入连接参数

    建立JmsConfig类,添加注解@Configuration,并将以上属性注入到此类。

    @Configuration
    public class JmsConfig {    
        @Value("${project.mq.host}")
        private String host;
        @Value("${project.mq.port}")
        private Integer port;
        @Value("${project.mq.queue-manager}")
        private String queueManager;
        @Value("${project.mq.channel}")
        private String channel;
        @Value("${project.mq.username}")
        private String username;
        @Value("${project.mq.password}")
        private String password;
        @Value("${project.mq.receive-timeout}")
        private long receiveTimeout;
    

    配置连接工厂

    在JmsConfig类添加以下方法。

    CCSID要与连接到的队列管理器一致,Windows下默认为1381,Linux下默认为1208。1208表示UTF-8字符集,建议把队列管理器的CCSID改为1208

    @Bean
    public MQQueueConnectionFactory mqQueueConnectionFactory() {
        MQQueueConnectionFactory mqQueueConnectionFactory = new MQQueueConnectionFactory();
        mqQueueConnectionFactory.setHostName(host);
        try {
            mqQueueConnectionFactory.setTransportType(WMQConstants.WMQ_CM_CLIENT);
            mqQueueConnectionFactory.setCCSID(1208);
            mqQueueConnectionFactory.setChannel(channel);
            mqQueueConnectionFactory.setPort(port);
            mqQueueConnectionFactory.setQueueManager(queueManager);
        } catch (Exception e) {
            e.printStackTrace();
        return mqQueueConnectionFactory;
    

    配置连接认证

    如不需要账户密码链接可以跳过此步,直接将mqQueueConnectionFactory注入下一步的缓存连接工厂。

    @Bean
    UserCredentialsConnectionFactoryAdapter userCredentialsConnectionFactoryAdapter(MQQueueConnectionFactory mqQueueConnectionFactory) {
        UserCredentialsConnectionFactoryAdapter userCredentialsConnectionFactoryAdapter = new UserCredentialsConnectionFactoryAdapter();
        userCredentialsConnectionFactoryAdapter.setUsername(username);
        userCredentialsConnectionFactoryAdapter.setPassword(password);
        userCredentialsConnectionFactoryAdapter.setTargetConnectionFactory(mqQueueConnectionFactory);
        return userCredentialsConnectionFactoryAdapter;
    

    配置缓存连接工厂

    不配置该类则每次与MQ交互都需要重新创建连接,大幅降低速度。

    @Bean
    @Primary
    public CachingConnectionFactory cachingConnectionFactory(UserCredentialsConnectionFactoryAdapter userCredentialsConnectionFactoryAdapter) {
        CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory();
        cachingConnectionFactory.setTargetConnectionFactory(userCredentialsConnectionFactoryAdapter);
        cachingConnectionFactory.setSessionCacheSize(500);
        cachingConnectionFactory.setReconnectOnException(true);
        return cachingConnectionFactory;
    

    配置事务管理器

    不使用事务可以跳过该步骤。如需使用事务,可添加注解@EnableTransactionManagement到程序入口类中,事务的具体用法可参考Spring Trasaction。

    @Bean
    public PlatformTransactionManager jmsTransactionManager(CachingConnectionFactory cachingConnectionFactory) {
        JmsTransactionManager jmsTransactionManager = new JmsTransactionManager();
        jmsTransactionManager.setConnectionFactory(cachingConnectionFactory);
        return jmsTransactionManager;
    

    配置JMS模板

    JmsOperations为JmsTemplate的实现接口。

    重要:不设置setReceiveTimeout时,当队列为空,从队列中取出消息的方法将会一直挂起直到队列内有消息

    @Bean
    public JmsOperations jmsOperations(CachingConnectionFactory cachingConnectionFactory) {
        JmsTemplate jmsTemplate = new JmsTemplate(cachingConnectionFactory);
        jmsTemplate.setReceiveTimeout(receiveTimeout);
        return jmsTemplate;
    

    可直接使用jmsOperations的convertAndSend(String, Object)方法,第一个参数为队列名称,第二个参数为需发送的对象。

    重要:发送的对象需实现序列化接口

    @Autowired
    JmsOperations jmsOperations;
    public void send(User user){
      jmsOperations.convertAndSend("QUEUE.USER", user);
    

    可直接使用jmsOperations的receiveAndConvert(String)方法,第一个参数为队列名称。

    @Autowired
    JmsOperations jmsOperations;
    public void receive(User user){
      jmsOperations.receiveAndConvert("QUEUE.USER");