问题描述:
在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")
参考文章: