Spring/Spring Boot整合Weblogic JMS實戰


本文主要介紹weblogic jms的配置,包括JMS 服務器和JMS 模塊(連接工廠、隊列、遠程 SAF 上下文、SAF 導入目的地、SAF 錯誤處理)的配置;並在Spring/Spring Boot環境下進行消息的監聽及發送;為了更多的使用webloigc jms的功能,發送的隊列使用saf配置的遠程weblogic jms隊列(兩邊的weblogic版本須一致),當然本地也是可以的。本文中demo所使用的軟件環境為:Weblogic 10.3.6.0、Spring 5.1.2.RELEASE/Spring Boot 2.1.4.RELEASE、jdk8

注:saf配置的遠程隊列只能發送消息,不能監聽消息。

1、Weblogic JMS配置

1.1、配置JMS 服務器

 注:需配置持久性存儲,沒有就創建一個

1.2、配置JMS 模塊

 

下面的功能都是在JMS 模塊中配置:連接工廠、隊列、遠程 SAF 上下文、SAF 導入目的地、SAF 錯誤處理

這里就不一一截圖配置過程了,按頁面提示配置就行;配置結果如下

連接工廠需設置jndi,程序里會用到

SAF 遠程上下文配置的遠程地址及用戶名密碼信息

SAF 導入目的地配置的遠程的隊列消息及對應到本地的jndi

SAF 錯誤處理程序配置錯誤處理策略屬性,選配

隊列需設置jndi,程序里會用到

 

SAF 導入目的地配置的隊列消息如下:

  點擊隊列名稱:

 本地 JNDI 名稱程序里會用到,向該jndi發送消息實際會發送到遠程的隊列里。

2、編寫程序

2.1、Spring程序

2.1.1、applicationContext-jms.xml

增加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" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:security="http://www.springframework.org/schema/security"
    xmlns:task="http://www.springframework.org/schema/task"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
                        http://www.springframework.org/schema/aop
                        http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
                        http://www.springframework.org/schema/tx
                        http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
                        http://www.springframework.org/schema/context
                        http://www.springframework.org/schema/context/spring-context-4.3.xsd
                        http://www.springframework.org/schema/security
                        http://www.springframework.org/schema/security/spring-security-4.3.xsd
                        http://www.springframework.org/schema/task
                        http://www.springframework.org/schema/task/spring-task-4.3.xsd">

    <bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
        <property name="environment">
            <props>
                <prop key="java.naming.factory.initial">weblogic.jndi.WLInitialContextFactory</prop>
                <prop key="java.naming.provider.url">t3://10.39.196.10:7001</prop>
                <prop key="java.naming.security.principal">weblogic</prop>
                <prop key="java.naming.security.credentials">weblogic1</prop>
            </props>
        </property>
    </bean>
    <bean id="jmsConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiTemplate" ref="jndiTemplate" />
        <property name="proxyInterface" value="javax.jms.ConnectionFactory" />
        <property name="jndiName" value="ConnectionFactory-test" />
    </bean>
    <bean id="testQueueSend" class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiName" value="testQueueSend" />
        <property name="jndiTemplate" ref="jndiTemplate" />
    </bean>
    <bean id="testQueueReceive" class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiName" value="testQueue" />
        <property name="jndiTemplate" ref="jndiTemplate" />
    </bean>
    <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
        <property name="connectionFactory" ref="jmsConnectionFactory" />
    </bean>

    <bean id="sender" class="com.inspur.demo.jms.Sender">
    </bean>
    <task:scheduled-tasks>
        <task:scheduled ref="sender" method="hello" cron="0/5 * * * * ?" />
    </task:scheduled-tasks>
    <bean id="receiver" class="com.inspur.demo.jms.Receiver">
    </bean>
    <bean id="listenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
        <property name="connectionFactory" ref="jmsConnectionFactory" />
        <property name="destination" ref="testQueueReceive" />
        <property name="messageListener" ref="receiver" />
        <property name="autoStartup" value="true" />
    </bean>
</beans>

jndiTemplate配置weblogic的連接信息

jmsConnectionFactory配置連接工廠

testQueueSend向該隊列發送消息,對應上面saf遠程目的地里隊列的本地jndi名稱,

testQueueReceive對該隊列進行監聽,接受消息

jmsTemplate配置jms的模板

sender發送消息的類,把該類配置為定時任務,定時發送消息;

receiver監聽的類

listenerContainer監聽容器

2.1.2、發送者

package com.inspur.demo.jms;

import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;

public class Sender {
    protected static Logger logger = LoggerFactory.getLogger(Sender.class);
    
    //發送消息的隊列
    @Autowired
    @Qualifier("testQueueSend")
    private Destination destination;
    
    @Autowired
    private JmsTemplate jmsTemplate;
    
    public void hello() {
        String message = System.currentTimeMillis() + "-hello";
        logger.info("Message Send:{}", message);
        jmsTemplate.send(destination, new MessageCreator() {
            @Override
            public Message createMessage(Session session) throws JMSException {
                return session.createTextMessage(message);
            }
        });
    }
}

使用JmsTemplate來發送消息。

 2.1.3、接受者

package com.inspur.demo.jms;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Receiver implements MessageListener {
    protected static Logger logger = LoggerFactory.getLogger(Receiver.class);
    
    @Override
    public void onMessage(Message message) {
        try {
            String text = "";   
            if (message instanceof TextMessage) {   
                text = ((TextMessage) message).getText();   
            } 
            logger.info("Message received:{}", text);
        } catch (JMSException e) {
            e.printStackTrace();
        }
    }
    
}

2.2、Spring Boot程序

2.2.1、引入依賴

<dependency>
    <groupId>javax.jms</groupId>
    <artifactId>javax.jms-api</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jms</artifactId>
</dependency>
<dependency>
    <groupId>weblogic</groupId>
    <artifactId>wlfullclient</artifactId>
    <version>1.0.0</version>
    <systemPath>D:\Oracle\Middleware\wlserver_10.3\server\lib\wlfullclient.jar</systemPath>
    <scope>system</scope>
</dependency>

引入的weblogic jar包wlfullclient.jar默認室不存在的,需在D:\Oracle\Middleware\wlserver_10.3\server\lib目錄下通過命令生成:java -jar wljarbuilder.jar

2.2.2、Weblogic JMS的配置類

package com.inspur.webframe.config;

import java.util.Properties;

import javax.jms.ConnectionFactory;
import javax.jms.Destination;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.listener.DefaultMessageListenerContainer;
import org.springframework.jndi.JndiObjectFactoryBean;
import org.springframework.jndi.JndiTemplate;

import com.inspur.demo.jms.Receiver;

@Configuration
public class WeblogicJmsConfig {
    private static Logger logger = LoggerFactory.getLogger(WeblogicJmsConfig.class);
    
    @Autowired
    private Receiver receiver;
    
    @Bean
    public JndiTemplate jndiTemplate() {
        Properties properties = new Properties();
        properties.setProperty("java.naming.factory.initial", "weblogic.jndi.WLInitialContextFactory");
        properties.setProperty("java.naming.provider.url", "t3://10.39.196.10:9001");
        properties.setProperty("java.naming.security.principal", "weblogic");
        properties.setProperty("java.naming.security.credentials", "weblogic1");
        JndiTemplate jndiTemplate = new JndiTemplate();
        jndiTemplate.setEnvironment(properties);
        return jndiTemplate;
    }

    @Bean
    public JndiObjectFactoryBean jmsConnectionFactory() {
        JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean();
        jndiObjectFactoryBean.setJndiName("ConnectionFactory-test");
        jndiObjectFactoryBean.setJndiTemplate(jndiTemplate());
        return jndiObjectFactoryBean;
    }

    @Bean("testQueueSend")
    public JndiObjectFactoryBean testQueueSend() {
        JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean();
        jndiObjectFactoryBean.setJndiName("testQueueSend");
        jndiObjectFactoryBean.setJndiTemplate(jndiTemplate());
        return jndiObjectFactoryBean;
    }
    
    @Bean("testQueueReceive")
    public JndiObjectFactoryBean testQueueReceive() {
        JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean();
        jndiObjectFactoryBean.setJndiName("testQueue");
        jndiObjectFactoryBean.setJndiTemplate(jndiTemplate());
        return jndiObjectFactoryBean;
    }
    
    @Bean("jmsTemplate")
    @ConditionalOnMissingBean
    public JmsTemplate jmsTemplate() {
        JmsTemplate jmsTemplate = new JmsTemplate();
        jmsTemplate.setConnectionFactory((ConnectionFactory) jmsConnectionFactory().getObject());
        jmsTemplate.setDefaultDestination((Destination) testQueueSend().getObject());
        logger.info("jmsTemplate.isExplicitQosEnabled()={}", jmsTemplate.isExplicitQosEnabled());
        return jmsTemplate;
    }
    
    @Bean
    @ConditionalOnMissingBean
    public DefaultMessageListenerContainer listenerTopic() {
        DefaultMessageListenerContainer listener = new DefaultMessageListenerContainer();
        listener.setConnectionFactory((ConnectionFactory) jmsConnectionFactory().getObject());
        listener.setDestination((Destination)testQueueReceive().getObject());
        listener.setAutoStartup(true);
        listener.setMessageListener(receiver);
        return listener;
    }
}

這里配置的信息與上面applicationContext-jms.xml中配置的內容一致,只不過是通過程序的方式。這里面的一些變動的信息可以配置到application.properties中,如weblogic地址、用戶名、密碼、隊列jndi等。

2.2.3、發送者

package com.inspur.demo.jms;

import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class Sender {
    private static Logger logger = LoggerFactory.getLogger(Sender.class);
    
    //發送消息的隊列
    @Autowired
    @Qualifier("testQueueSend")
    private Destination destination;
    
    @Autowired
    private JmsTemplate jmsTemplate;
    
    @Scheduled(cron = "0/5 * * * * ?")
    public void hello() {
        final String message = System.currentTimeMillis() + "-hello";
        logger.info("Message Send:{}", message);
        jmsTemplate.send(destination, new MessageCreator() {
            @Override
            public Message createMessage(Session session) throws JMSException {
                return session.createTextMessage(message);
            }
        });
    }
}

通過注解來定時發送。

2.2.4、接受者

package com.inspur.demo.jms;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Component
public class Receiver implements MessageListener {
    protected static Logger logger = LoggerFactory.getLogger(Receiver.class);
    
    @Override
    public void onMessage(Message message) {
        try {
            String text = "";   
            if (message instanceof TextMessage) {   
                text = ((TextMessage) message).getText();   
            } 
            logger.info("Message received:{}", text);
        } catch (JMSException e) {
            e.printStackTrace();
        }
    }
    
}

增加@Component注解,方便配置類中引用。

2.2.5、啟動類

在啟動類中需增加@EnableAutoConfiguration(exclude = JmxAutoConfiguration.class)注解,否則會報javax.naming.NameNotFoundException: remaining name: env/jmx/runtime異常。原因可能是Spring boot啟動時試圖創建一個在weblogic api庫中檢測到的bean(mbeanExporter),這個bean需要env/jmx/runtime JNDI;所以要去除JMX的自動配置。

3、測試

1.發送消息

啟動Spring或Spring Boot程序后,每隔5秒中會往testQueueSend隊列(遠程隊列)中發送一條消息,可到Weblogic控制台查看消息.

2.接受消息

在Weblogic控制台手工往testQueueReceive隊列插入一條消息,程序日志會打印該消息內容。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM