使用org.springframework.jms.listener.SimpleMessageListenerContainer从Listener中读取消息

时间:2015-11-23 07:20:19

标签: java spring spring-mvc jms spring-jms

我正在使用Spring Configuration开发独立应用程序。我必须从队列中读取消息。因此,我在Spring ApplicationContext.xml中使用org.springframework.jms.listener.SimpleMessageListenerContainer。我的ApplicationContext.xml文件包含。

<!-- Config property -->
<bean id="propertyConfigurer"
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <list>
            <value>file:resources/config.properties</value>
        </list>
    </property>
    <property name="ignoreUnresolvablePlaceholders" value="true" />
    <property name="order" value="0" />
</bean>

<!-- App config properties -->

<bean id="configProperties" class="aero.sita.uatp.server.utilities.ConfigProperties">
    <property name="properties">
        <props>
                    <prop key="prefix.correlation">${prefix.correlation}</prop>
        </props>
    </property>
</bean>


<!-- jndi Template -->
<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
    <property name="environment">
        <props>
            <prop key="java.naming.factory.initial">${broker.initialContexFactory}</prop>
            <prop key="java.naming.provider.url">${broker.provide.url}</prop>
        </props>
    </property>
</bean>

<!-- JMS Connection factory -->
<bean id="connectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiTemplate">
        <ref bean="jndiTemplate" />
    </property>
    <property name="jndiName">
        <value>${broker.connectionFactory}</value>
    </property>
</bean>

<!-- Auth (Payment) Request queue -->
<bean id="paymentRequestQueue" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiTemplate">
        <ref bean="jndiTemplate" />
    </property>
    <property name="jndiName">
        <value>${payment.request}</value>
    </property>
</bean>

<!-- Auth (Payment) Response queue -->
<bean id="paymentResponseQueue" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiTemplate">
        <ref bean="jndiTemplate" />
    </property>
    <property name="jndiName">
        <value>${payment.response}</value>
    </property>
</bean>

<!-- JMS Template -->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
    <property name="connectionFactory" ref="connectionFactory" />
    <property name="explicitQosEnabled" value="true" />
    <property name="timeToLive" value="${payment.request.expiration}" />
    <property name="receiveTimeout" value="${payment.response.receive.timeout}" />
</bean>

<bean id="messageSender" class="aero.sita.uatp.server.MessageSender">
    <property name="jmsTemplate" ref="jmsTemplate" />
    <property name="queue" ref="paymentResponseQueue" />
    <property name="configProperties" ref="configProperties" />
</bean>

<bean id="authorisationServiceImpl" class="aero.sita.uatp.server.AuthorisationServiceImpl">
    <property name="messageSender" ref="messageSender" />
    <property name="configProperties" ref="configProperties" />
</bean>


<bean id="authorisationResponseHandler" class="aero.sita.uatp.server.AuthorisationResponseHandler">
    <property name="configProperties" ref="configProperties" />
    <property name="messageSender" ref="messageSender" />
</bean>



<!-- and this is the message listener container -->

<bean id="jmsContainer" class="org.springframework.jms.listener.SimpleMessageListenerContainer">
    <property name="autoStartup" value="TRUE" />
    <property name="connectionFactory" ref="connectionFactory" />
    <property name="destination" ref="paymentRequestQueue" />
    <property name="messageListener" ref="authorisationResponseHandler" />

</bean>

我的Main Class加载ApplicationContext XML。

public class MainTestClient {

public static void main(String[] args) {
    System.out.println("Starting Client Application");
    AbstractApplicationContext context = new FileSystemXmlApplicationContext("resources/applicationContext.xml");
    System.out.println("Spring context loaded.");
    context.registerShutdownHook();
    System.out.println("ShutdownHook registered.");

}

以下是侦听队列的侦听器AuthorisationResponseHandler类的类。

public class AuthorisationResponseHandler implements MessageListener {

private ConfigProperties configProperties;

/**
 * Gets triggered when a message is arrived at the queue. It adds the
 * response received to a concurrent hash map
 * @param message
 */
public void onMessage(Message message) {
    try {
        System.out.println("First Node received message with JMSCorrelationID:"
                + message.getJMSCorrelationID());


    } catch (JMSException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

这是我的问题。当我启动应用程序时,我的监听器类不等待消息获取。而是通过监听队列来初始化和关闭类。

启动课程的命令

/app/sw/oracle/mw/sunjdk-7-x64/bin/java -cp /app/dev-data/node1/support/tactical_tools/gwatest/server/GWAServerTest.jar aero.sita.uatp.server.MainTestClient

我收到的输出。

   Starting Client Application
Nov 23, 2015 7:13:08 AM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.FileSystemXmlApplicationContext@610d3d99: startup date [Mon Nov 23 07:13:08 UTC 2015]; root of context hierarchy
Nov 23, 2015 7:13:08 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from file [/app/dev-data/node1/support/tactical_tools/gwatest/server/resources/applicationContext.xml]
Nov 23, 2015 7:13:08 AM org.springframework.core.io.support.PropertiesLoaderSupport loadProperties
INFO: Loading properties file from URL [file:resources/config.properties]
Nov 23, 2015 7:13:08 AM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1c9e8392: defining beans [propertyConfigurer,configProperties,jndiTemplate,connectionFactory,paymentRequestQueue,paymentResponseQueue,jmsTemplate,messageSender,authorisationServiceImpl,authorisationResponseHandler,jmsContainer]; root of factory hierarchy
Nov 23, 2015 7:13:10 AM org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup start
INFO: Starting beans in phase 2147483647
Spring context loaded.
ShutdownHook registered.
Nov 23, 2015 7:13:10 AM org.springframework.context.support.AbstractApplicationContext doClose
INFO: Closing org.springframework.context.support.FileSystemXmlApplicationContext@610d3d99: startup date [Mon Nov 23 07:13:08 UTC 2015]; root of context hierarchy
[alaric@lautpyy003d ~/support/tactical_tools/gwatest/server]$

在这里我可以看到Spring Context正确加载但是控制台没有等待AuthorizationResponseHandler Class中编写的onMessage方法。我期待控制台等待消息进入并在消息进入后打印消息。我是否在初始化监听器时遗漏了什么?

上述问题已得到解答。但现在我正面临一个新问题。我从Main方法调用sendMessage函数,它给出Null指针异常。

主要方法:

public void start()
    {
        AuthorisationServiceImpl authorisationServiceImpl = new AuthorisationServiceImpl();
        try {
            authorisationServiceImpl.fromMain();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }


    public static void main(String[] args) throws InterruptedException {
        System.out.println("Starting Client Application");
        AbstractApplicationContext context = new FileSystemXmlApplicationContext("resources/applicationContext.xml");
        System.out.println("Spring context loaded.");
        context.registerShutdownHook();
        System.out.println("ShutdownHook registered.");

        MainTestClient mainTestClient = new MainTestClient();
        mainTestClient.start();



    }

我在另一个班级打电话的方法是

package aero.sita.uatp.client;

import javax.jms.BytesMessage;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Queue;
import javax.jms.Session;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;

import aero.sita.uatp.client.utilities.ConfigProperties;

/**
 * AuthorisationServiceImpl
 * @author Sunil.Gogula
 */

public class AuthorisationServiceImpl {

    @Autowired
    private MessageSender messageSender;


    private MessageReceiver messageReceiver;

    private JmsTemplate jmsTemplate;
    private Queue queue;


    public JmsTemplate getJmsTemplate() {
        return jmsTemplate;
    }



    public void setJmsTemplate(JmsTemplate jmsTemplate) {
        this.jmsTemplate = jmsTemplate;
    }



    public Queue getQueue() {
        return queue;
    }



    public void setQueue(Queue queue) {
        this.queue = queue;
    }



    public MessageReceiver getMessageReceiver() {
        return messageReceiver;
    }



    public void setMessageReceiver(MessageReceiver messageReceiver) {
        this.messageReceiver = messageReceiver;
    }

    private ConfigProperties configProperties;


    public void fromMain() throws InterruptedException {
        System.out.println("Init method called");
        String message = "AAA-MM-CCC";
        long count = new Long("000001").longValue();
        while (true)
        {
            //container.start();
            StringBuffer corelationId = new StringBuffer();

            if (count == 1000000) {
                count = new Long("000001").longValue();
            }

            corelationId.append(message);
            corelationId.append(String.format("%6s", String.valueOf(count)).replace(' ', '0'));
            byte[] myvar = "Message".getBytes();
            System.out.println("Writing message having correlationId: " + corelationId.toString() + " to the queue.");
            sendMessage(corelationId.toString(),myvar);
            count++;
            Thread.sleep(5000);
        }


    }



    /*public boolean sendMessage(String correlationId) throws ServiceException {
        byte[] myvar = "Message".getBytes();
        boolean response = false;
        try {
            MessageSender messageSenderVar = new MessageSender();
            System.out.println("Writing message having correlationId: " + correlationId + " to the queue.");
            // writing message to the request queue. 
            sendMessage(correlationId,myvar);
            //messageReceiver.getMessage();

        }catch(Exception e) {

            throw new ServiceException("Exception:",e);
        }
        return response;
    }
    */
    public void sendMessage(final String correlationId, final byte[] bytes) {
        this.jmsTemplate.send(this.queue, new MessageCreator() {
            public Message createMessage(Session session) throws JMSException {
                BytesMessage bytesMessage = session.createBytesMessage();
                bytesMessage.setJMSCorrelationID(configProperties.getPREFIX_VALUE() + correlationId);

                // message will follow expiration time as configured in properties
                bytesMessage.writeBytes(bytes);
                return bytesMessage;
            }
        });
        System.out.println("Message " + configProperties.getPREFIX_VALUE() + correlationId + " with correlation id: " + configProperties.getPREFIX_VALUE() + correlationId + " written to the queue.");
    }



    public MessageSender getMessageSender() {
        return messageSender;
    }

    public void setMessageSender(MessageSender messageSender) {
        this.messageSender = messageSender;
    }



    public ConfigProperties getConfigProperties() {
        return configProperties;
    }

    public void setConfigProperties(ConfigProperties configProperties) {
        this.configProperties = configProperties;
    }

}

调用sendMessage方法时,我得到Null Pointer Exception。从静态方法调用非静态方法有什么问题吗?

Starting Client Application
Nov 23, 2015 12:49:53 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.FileSystemXmlApplicationContext@5ba28182: startup date [Mon Nov 23 12:49:53 UTC 2015]; root of context hierarchy
Nov 23, 2015 12:49:53 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from file [/app/dev-data/node1/support/tactical_tools/gwatest/client1/resources/applicationContext.xml]
Nov 23, 2015 12:49:54 PM org.springframework.core.io.support.PropertiesLoaderSupport loadProperties
INFO: Loading properties file from URL [file:resources/config.properties]
Nov 23, 2015 12:49:54 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@6b915330: defining beans [propertyConfigurer,configProperties,jndiTemplate,connectionFactory,paymentRequestQueue,paymentResponseQueue,jmsTemplate,messageSender,authorisationResponseHandler,authorisationServiceImpl,jmsContainer]; root of factory hierarchy
Nov 23, 2015 12:49:55 PM org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup start
INFO: Starting beans in phase 2147483647
Spring context loaded.
ShutdownHook registered.
Init method called
Writing message having correlationId: AAA-MM-CCC000001 to the queue.
Exception in thread "main" java.lang.NullPointerException
        at aero.sita.uatp.client.AuthorisationServiceImpl.sendMessage(AuthorisationServiceImpl.java:114)
        at aero.sita.uatp.client.AuthorisationServiceImpl.fromMain(AuthorisationServiceImpl.java:86)
        at aero.sita.uatp.client.MainTestClient.start(MainTestClient.java:15)
        at aero.sita.uatp.client.MainTestClient.main(MainTestClient.java:31)

当我通常在没有主方法的情况下调用sendMessage时,我能够成功连接。

0 个答案:

没有答案