Listener中注入Service的方法和需要注意的地方。

本人在实习的过程中,一个项目功能需要在Listener中的handlerMessage(即Listener的监听响应方法)用到Service,但是出现了以下的问题:

如果使用Spring的@Autowired自动注入,会出现这个Service为空的异常。

即在这里使用Service的时候不可以使用注解注入的方式,究其原因,因为Listener是一个Servlet,而使用注解注入的必须是Spring的组件,故注解不能为Servlet中的对象注入,但是必须还需要使用到这个Service来调用dao对象来与数据库交互,于是查了一下资料,这里分享一个解决办法。

之前采用的注解注入的方式是这样的。(不论是@Autowired自动注入还是@Resource利用名称注入都不可以)

public class PosListener{
    @Autowired
    private PosService posService;

    public void handlerMessage(MessageVO message){......}
}

如果想要让Service不为空并且能够与Spring的组件交互,则需要使用Spring进行注入,但是还不能使用注解在Servlet的生命周期中我们知道,在项目启动的时候,会对Servlet进行一次初始化,我们可不可以在Servlet初始化的时候,利用Spring的配置文件进行注入?

所以修改后的代码如下:

public class PosListener implements ServletContextListener{
    
    private PosService posService;

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        cvsPosService = WebApplicationContextUtils
                .getWebApplicationContext(sce.getServletContext())
                .getBean(PosServiceImpl.class);
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {

    }

    public void handlerMessage(MessageVO message){......}
}

​

这种方式,需要实现ServletContextListener,进而实现它的两个方法,contextInitialized和contextDestroyed,在contextInitialized中使用Spring的配置文件进行注入,这种方式,可以保证Service对象只被注入1次,而不会重复加载配置文件,除此之外,还需要在web.xml中将这个(PosListener)配置上。

但是,在handlerMessage中使用这个Service对象时,依然出现了空指针异常,这就有点不科学了,于是我接着排查,通过从头思考handlerMessage的工作流程,我发现,handlerMessage这个监听方法(即listener的event方法),每次从message queue中取得一个消息message,就会调用这个方法,因此,如果我们想要在事件监听方法event中使用Service方法,我们需要将想使用到的Service定义为static,才可以正常运行。

猜你喜欢

转载自blog.csdn.net/kevindyzs/article/details/81169338
今日推荐