問題描述:
在activemq的監聽器中,通過注解@Autowired或@Resource注入bean時,獲取到的bean為null。調用該bean的方法時會報空指針異常。
問題原因:
當調用bean內方法時,spring容器中還沒有完成對注解bean的掃描,dispatcher.xml中配置的注解bean的優先級沒有框架中的contextListener的優先級高,所以contextListener初始化的時候根據@Autowired掃描,肯定是null的。
解決辦法:
在web.xml文件中增加一個監聽器類,該類實現ServletContextListener,ApplicationContextAware這兩個接口。
<listener>
<listener-
class
>com.activemq.common.InitComponent</listener-
class
>
</listener>
當容器啟動的時候,會執行該類中的contextInitialized(ServletContextEvent servletContextEvent)方法。
我們要做的,就是在該類中新增獲取bean的方法。
package com.activemq.common; import javax.jms.Connection; import javax.jms.ConnectionFactory; import javax.jms.Destination; import javax.jms.JMSException; import javax.jms.MessageConsumer; import javax.jms.Session; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import org.apache.activemq.ActiveMQConnectionFactory; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; @Component public class InitComponent implements ServletContextListener,ApplicationContextAware{ private static ApplicationContext applicationContext; public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { InitComponent.applicationContext=applicationContext; } /** * 程序運行時即初始化activemq消費組件 */ public void contextInitialized(ServletContextEvent servletContextEvent) { ConnectionFactory factory = new ActiveMQConnectionFactory("tcp://132.252.3.22:61616"); // ConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616"); Connection connection; Session session; Destination destination; MessageConsumer messageConsumer; try { connection = factory.createConnection(); connection.start(); session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE); destination = session.createTopic("ZHXJ_QUEUE"); // 創建連接的消息隊列 messageConsumer = session.createConsumer(destination);// 創建消息消費者 messageConsumer.setMessageListener(new StaffMsgListener()); } catch (JMSException e) { e.printStackTrace(); } } @SuppressWarnings("unchecked") public static <T> T getBean(String name) { checkApplicationContext(); return (T) applicationContext.getBean(name); } private static void checkApplicationContext() { if (applicationContext == null) { throw new IllegalStateException("applicaitonContext未注入"); } } public void contextDestroyed(ServletContextEvent sce) { } }
此時,獲取bean的方式就變為:
ConsumerDao consumerDao = InitComponent.getBean(
"ConsumerDao"
);
consumerDao.saveMessage(param);
注意:
ConsumerDao接口上需要加上注解:@Repository("ConsumerDao")
參考文章: