web-dev-qa-db-ja.com

Spring-依存関係をServletContextListenerに注入する

依存関係をServletContextListenerに挿入したいと思います。しかし、私のアプローチは機能していません。 Springがセッターメソッドを呼び出しているのがわかりますが、後でcontextInitializedが呼び出されると、プロパティはnullになります。

これが私のセットアップです:

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

これを達成する正しい方法は何ですか?

27
dogbane

これを解決するには、リスナーBeanを削除し、プロパティ用に新しいBeanを作成します。次に、プロパティーBeanを取得するために、リスナーで以下を使用しました。

@Override
public void contextInitialized(ServletContextEvent event) {

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

Dogbaneの答え(受け入れられた)は機能しますが、Beanのインスタンス化の方法が原因で、テストが困難になります。私はこれで提案されたアプローチを好む question

@Autowired private Properties props;

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

    //Do something with props
    ...
}    
30
a.b.d

前述のとおり、ServletContextListenerはサーバーによって作成されるため、Springによって管理されません。

ServletContextの通知を受け取りたい場合は、インターフェースを実装できます。

org.springframework.web.context.ServletContextAware
5
RicoZ

すでに述べたように、サーバーによって作成されます。 paramsをリスナーに渡す必要がある場合は、それをweb-xmlでcontext-paramとして定義できます。

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

リスナーでは、次のようにして取得できます。

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

編集1:

別の可能な解決策については、以下のリンクを参照してください:

Springを使用してHttpSessionListenerに依存関係を注入する方法

1
fmucar