我正在使用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时,我能够成功连接。