我想连接到Sonic Broker主题并侦听任何传入的XML消息。我做了下面的事情;
应用程序
@SpringBootApplication @ComponentScan({"com.mainpack", "com.msgpack.jms"}) @EnableJms public class Application extends SpringBootServletInitializer { @Autowired private JmsTopicListener jmsTopicListener; @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(Application.class); } @Override public void onStartup(final ServletContext servletContext) throws ServletException { try { LogService.info(Application.class.getName(), "Starting Service..."); super.onStartup(servletContext); jmsTopicListener.listenMessage(); LogService.info(Application.class.getName(), "Service Started"); } catch (Exception ex) { LogService.error(this.getClass().getName(), ex); } } public static void main(String[] args) { ApplicationContext context = SpringApplication.run(Application.class, args); LogService.info(Application.class.getName(), "Service Started..."); } }
JmsTopicListener.java
@Component public class JmsTopicListener { @Autowired private ApplicationProperties properties; @Autowired private MsgListener msgListener; public void listenMessage() { TopicConnectionFactory factory; TopicConnection connection = null; LogService.info(this.getClass().getName(), "Registering Broker Connection"); try { factory = new progress.message.jclient.TopicConnectionFactory(properties.getBrokerURL()); connection = factory.createTopicConnection(properties.getUserName(), properties.getPass()); javax.jms.TopicSession subSession = (TopicSession) connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); javax.jms.Topic topic = subSession.createTopic(properties.getTopicName()); MessageConsumer subscriber = subSession.createSubscriber(topic); subscriber.setMessageListener(msgListener); connection.start(); LogService.info(this.getClass().getName(), "Broker connected"); } catch (Exception ex) { LogService.error(this.getClass().getName(), ex); } } }
MsgListener.java
@Component public class MsgListener implements MessageListener { @Override public void onMessage(Message msg) { if (msg instanceof XMLMessage) { try { XMLMessage m = (XMLMessage) msg; if (m.getText().contains("Applications")) { LogService.info(this.getClass().getName(), "Recieved A Applications Message"); } else { LogService.info(this.getClass().getName(), "Recieved Message Does not contain Applications Tag"); } } catch (Exception ex) { LogService.info(this.getClass().getName(), "Exception: " + ex.getMessage()); } } } }
何时,我运行此代码,在行jmsTopicListener.listenMessage()中得到nullPointer Application.java。
jmsTopicListener.listenMessage()
Application.java
我在这里犯了什么错误?有没有办法可以改善这一点(我的意思是可以用更少的代码完成工作)?
注意:com.mainpack具有类Application.java,ApplicationProp.java com.msgpack.jms具有JmsTopicListener.java和MsgListner.java
ApplicationProp.java
MsgListner.java
来自记录器的错误:
ERROR [2015-07-14 14:34:52] [com.mainpack.Application] [localhost-startStop-1] - [Exception: ]java.lang.NullPointerException at com.mainpack.Application.onStartup(Application.java:33) at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:175) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5156) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:725) at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:701) at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:717) at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:945) at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1768) at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) at java.util.concurrent.FutureTask.run(Unknown Source) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source)
onStartup是在应用程序生命周期的早期由servlet容器调用的,并且是在由servlet容器而不是Spring Boot创建的类的实例上调用的。这就是为什么jmsTopicListener是null。
onStartup
jmsTopicListener
null
onStartup可以使用注解的方法代替覆盖@PostConstruct。一旦创建了实例Application 并 注入了任何依赖项,它将被Spring调用:
@PostConstruct
Application
@SpringBootApplication @ComponentScan({"com.mainpack", "com.msgpack.jms"}) @EnableJms public class Application extends SpringBootServletInitializer { @Autowired private JmsTopicListener jmsTopicListener; @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(Application.class); } @PostConstruct public void listen() { jmsTopicListener.listenMessage(); } public static void main(String[] args) { ApplicationContext context = SpringApplication.run(Application.class, args); LogService.info(Application.class.getName(), "Service Started..."); } }