2011-01-20 121 views
25

我想注入一个依赖项到ServletContextListener。但是,我的方法不起作用。我可以看到Spring正在调用我的setter方法,但后来调用contextInitialized时,该属性为nullSpring - 向ServletContextListener注入依赖项

这里是我的设置:

了ServletContextListener:

public class MyListener implements ServletContextListener{ 

    private String prop; 

    /* (non-Javadoc) 
    * @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent) 
    */ 
    @Override 
    public void contextInitialized(ServletContextEvent event) { 
     System.out.println("Initialising listener..."); 
     System.out.println(prop); 
    } 

    @Override 
    public void contextDestroyed(ServletContextEvent event) { 
    } 

    public void setProp(String val) { 
     System.out.println("set prop to " + prop); 
     prop = val; 
    } 
} 

web.xml文件:(这是文件中的最后一个侦听)

<listener> 
    <listener-class>MyListener</listener-class> 
</listener> 

applicationContext.xml:

<bean id="listener" class="MyListener"> 
    <property name="prop" value="HELLO" /> 
</bean> 

输出:

set prop to HELLO 
Initialising listener... 
null 

什么是实现这一目标的正确方法是什么?

回答

17

我通过移除监听器bean,并创造了我的属性的新豆解决了这个。然后我用我的听众以下,以获得性能豆:

@Override 
public void contextInitialized(ServletContextEvent event) { 

    final WebApplicationContext springContext = WebApplicationContextUtils.getWebApplicationContext(event.getServletContext()); 
    final Properties props = (Properties)springContext.getBean("myProps"); 
} 
-1

ServletContextListener由服务器创建,而不是由Spring创建。

编辑:AFAIK,你不能实现你想要什么,你想在侦听器中设置实例变量的原因是什么?

+0

@dogbane你在做什么? ServletContextListener用于监视Web应用程序的生命周期。 – saugata 2011-01-20 10:48:22

5

如前所述,ServletContextListener是由服务器创建的,因此它不是由Spring管理的。

如果您希望被通知ServletContext中,你可以实现该接口:

org.springframework.web.context.ServletContextAware 
+0

对不起,我不明白为什么我需要实现`ServletContextAware`?我的监听器已经有了对`ServletContext`的引用,因为它存在于`ServletContextEvent`中。 – dogbane 2011-01-20 12:16:01

+0

如果你使用监听器,你不能注入弹簧依赖项,所以ServletContextAware是另一种选择 – 2011-01-20 15:18:31

1

你不能有春天要做到这一点,前面已经指出,由服务器创建的。 如果需要PARAMS传递给您的听众,你可以在你的Web XML作为的context-param

<context-param> 
     <param-name>parameterName</param-name> 
     <param-value>parameterValue</param-value> 
    </context-param> 

而且在听者可以检索它像下面定义它;

event.getServletContext().getInitParameter("parameterName") 

编辑1:

请参见下面的链接,另一种可能的解决方案:

How to inject dependencies into HttpSessionListener, using Spring?

+0

我想传入一个bean。而不是名称值。 – dogbane 2011-01-20 12:17:05

+0

@dogbane请参阅编辑的文章。添加了一个新的链接,可能对您的案例有用 – fmucar 2011-01-20 13:10:25

28

的罗布麻的答案(接受)的作品,但它使测试困难,因为道路豆被实例化。我赞成在这个建议的方法question

@Autowired private Properties props; 

@Override 
public void contextInitialized(ServletContextEvent sce) { 
    WebApplicationContextUtils 
     .getRequiredWebApplicationContext(sce.getServletContext()) 
     .getAutowireCapableBeanFactory() 
     .autowireBean(this); 

    //Do something with props 
    ... 
}