消息监听器无法注入bean

问题描述:

在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")

参考文章:

http://blog.csdn.net/gaoshili001/article/details/77776863

原文地址:https://www.cnblogs.com/xyhero/p/77fb56ab8abcb918411d57e805c1c8b4.html