java 如何在listener(监听器) 中使用Spring容器管理bean

本文解释了为何在Listener监听器中不能直接使用Spring的注解注入Bean,并提供了解决方案,即通过WebApplicationContextUtils工具类获取Spring容器中的Bean实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题来源:在Listener监听器中无法使用Spring容器的@Resource或者@Autowired 注解的方法注入bean,因为,在web Server容器中,无论是Servlet,Filter,还是Listener都不是Spring容器管理的,因此我们都无法在这些类中直接使用Spring注解的方式来注入我们需要的对象。

在这里,Servlet的整个生命周期都是由Servlet容器来处理的。如果把它硬放到Spring容器中去创建,Servlet对象是可被Spring容器建出来,但Servlet容器可能跟本就不知此Servlet存在,因不在它的容器中。所以,servlet交给web server来管理,不要交给spring管理。


我们在Java web 应用中会使用到监听器来完成一些操作,比如说使用Session监听器来监听Session的变化,通常情况下我们会用javaee规范中的Listener去实现,例如

public class TestListener implements HttpSessionAttributeListener,ServletContextListener
{

    @Override
    public void attributeAdded(HttpSessionBindingEvent arg0)
    {
        // TODO Auto-generated method stub  
    }

    @Override
    public void attributeRemoved(HttpSessionBindingEvent arg0)
    {
        // TODO Auto-generated method stub  
    }

    @Override
    public void attributeReplaced(HttpSessionBindingEvent arg0)
    {
        // TODO Auto-generated method stub  
    }

    @Override
    public void contextDestroyed(ServletContextEvent arg0)
    {
        // TODO Auto-generated method stub  
    }

    @Override
    public void contextInitialized(ServletContextEvent arg0)
    {
        // TODO Auto-generated method stub  
    }

}

现在,我们想在这个监听器里面注入bean,如果使用Spring注解的方式注入bean如下面这样:

@Resource
private AdvertisementServiceImpl advertisementServiceImpl;

然而以上代码会在项目启动时抛出空指针异常!AdvertisementServiceImpl的实例并没有成功注入。这是为什么呢?要理解这个问题,首先要区分Listener的生命周期和spring管理的bean的生命周期。

(1)Listener的生命周期是由servlet容器(例如tomcat)管理的,项目启动时上例中的TestListener是由servlet容器实例化并调用其contextInitialized方法,而servlet容器并不认得@Resource注解,因此导致AdvertisementServiceImpl实例注入失败。

(2)而spring容器中的bean的生命周期是由spring容器管理的。

那么该如何在spring容器外面获取到spring容器bean实例的引用呢?这就需要用到spring为我们提供的WebApplicationContextUtils工具类,该工具类的作用是获取到spring容器的引用,进而获取到我们需要的bean实例。代码如下

@Override
public void contextInitialized(ServletContextEvent sce) {    
    WebApplicationContext applicationContext =    WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext());    
    this.advertisementServiceImpl=(AdvertisementServiceImpl)applicationContext.getBean("advertisementServiceImpl");     
}  
然后在spring配置:

 <bean id="xxxService">xxx.xxx.xxx.xxxService</bean>





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值