消息队列监听器无法注入bean的问题解决

来源:互联网 发布:外包软件开发公司 编辑:程序博客网 时间:2024/06/06 18:39

在使用ActiveMq或者其他消息队列的过程中,第一步对ActiveMq进行初始化的过程是放在ContextListener的初始化的时候的;

然而当mq接收到消息的时候触发getMqMsg方法的时候报错null,调试发现MqManageService根本没有获取到,我的想法是获取的方式不对,@Autowired这种方式获取bean不成功,但是bean肯定是已经存在于spring容器中的,如果对思维理解熟悉的人已经知道我的问题出在哪里了,没错,此时,spring容器中根本没有完成对注解bean的扫描,因为dispatcher.xml中配置的注解bean的优先级肯定没有框架中的contextListener的优先级高,contextListener初始化的时候根据@Autowired进行扫描的话,肯定是null的呀!

当我使用new对象的时候确实可以成功获取到这个MqmanageService,但是其调用的service(也是注解方式的)又获取不到了,原因是一样的。那么我可不可以在这里也new一个对象出来呢?可以是可以,但是没有意义,因为通过注解方式注册到容器中的bean本身就是单例模式,再new一个出来,违背初衷。还有一种方式就是可以通过ApplicationContextAware来getBean,这里的Bean的name就是@Service注解的类的小写全称。

下面给出我的代码例子:

SpringContextHolder
import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;public class SpringContextHolder implements ApplicationContextAware {    private static ApplicationContext applicationContext;    /**     * 实现ApplicationContextAware接口的context注入函数, 将其存入静态变量.     */    public void setApplicationContext(ApplicationContext applicationContext) {        SpringContextHolder.applicationContext = applicationContext; // NOSONAR    }    /**     * 取得存储在静态变量中的ApplicationContext.     */    public static ApplicationContext getApplicationContext() {        checkApplicationContext();        return applicationContext;    }    /**     * 从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型.     */    @SuppressWarnings("unchecked")    public static <T> T getBean(String name) {        checkApplicationContext();        return (T) applicationContext.getBean(name);    }    /**     * 从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型.     */    @SuppressWarnings("unchecked")    public static <T> T getBean(Class<T> clazz) {        checkApplicationContext();        return (T) applicationContext.getBeansOfType(clazz);    }    /**     * 清除applicationContext静态变量.     */    public static void cleanApplicationContext() {        applicationContext = null;    }    private static void checkApplicationContext() {        if (applicationContext == null) {            throw new IllegalStateException("applicaitonContext未注入,请在applicationContext.xml中定义SpringContextHolder");        }    }}
messageListener里面调用
SpringContextHolder.getBean("messageDistribute");

public class WebMessageListener implements MessageListener {    private static final Logger logger = LoggerFactory.getLogger(WebMessageListener.class);    private static long callCount = 0;//    @Autowired//    private MessageDistribute messageDistribute;    public Action consume(Message message, ConsumeContext context) {        logger.info("consume: " + message);        String topic = "";        try {            //do something..            topic = message.getTopic();            String content = new String(message.getBody(), "UTF-8");            //            Thread.sleep(1000);            JSONObject resultjson = JSONObject.fromObject(content);            //PushInfoBeanEx info = JSON.parseObject(content, PushInfoBeanEx.class);            //PushServiceExImpl.getgPushFactory().sendMessageByMQ(info);            //接收消息            //接收并处理消息            MessageDistribute mMessageDistribute =  SpringContextHolder.getBean("messageDistribute");            mMessageDistribute.socketSendCallBack(Integer.parseInt(pushid),code,new Date());            return Action.CommitMessage;        } catch (Exception e) {            //消费失败            return Action.CommitMessage;// 处理失败, 也不重新处理        }    }