0

戦争を展開するときにデーモンを開始する必要があります。デーモン自体は、Spring で注入する必要があるオブジェクトを使用します。私は次のことをしました:

web.xml 内

...
<context-param>
   <param-name>contextConfigLocation</param-name>
   <param-value>/WEB-INF/springapp-servlet.xml</param-value>
</context-param>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
    <listener-class>example.AppListener</listener-class>
</listener>

AppListener.java

public class AppListener implements ServletContextListener {
...
  @Override
  public void contextInitialized(final ServletContextEvent sce) {
      log.info("======================= Begin context init =======================");
      try {
        // final ApplicationContext context = new ClassPathXmlApplicationContext("WEB-INF/springapp-servlet.xml");
        final ApplicationContext context = new ClassPathXmlApplicationContext("src/main/webapp/WEB-INF/springapp-servlet.xml");
      //final ApplicationContext context = new ClassPathXmlApplicationContext("//Users/.../WEB-INF/springapp-servlet.xml");

      final SessionServiceDaemon sessionServiceDaemon = context.getBean(SessionServiceDaemon.class);
      sessionServiceDaemon.start();
    } catch (final Exception e) {
      log.error("Was not able to start daemon",e);
    }
}

SessionServiceDaemon.java

@Service
@Singleton
public class SessionServiceDaemon {

  private final static Logger log = LoggerFactory.getLogger(SessionServiceDaemon.class);

  private final SessionServiceHandler handler;

  @Inject
  public SessionServiceDaemon(final SessionServiceHandler handler) {
    log.info("+++++++++++++++++++++++++++++++ SessionServiceDaemon injected");
    this.handler = handler;
  }

私の springapp-servlet.xml には、インジェクションに必要なパッケージが含まれています。

<?xml version="1.0" encoding="UTF-8"?>
<beans ...

  <context:component-scan base-package="example" />
    <mvc:annotation-driven />

</beans>

起動ログには、期待どおりに表示されます。

+++++++++++++++++++++++++++++++ SessionServiceDaemon injected

に続く

======================= Begin context init =======================

問題は次のとおりです。springapp-servlet.xml を指すために使用するパスに関係なく、ファイルが存在しないという例外が発生します。

org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from class path resource [src/main/webapp/WEB-INF/springapp-servlet.xml]; nested exception is java.io.FileNotFoundException: class path resource [src/main/webapp/WEB-INF/springapp-servlet.xml] cannot be opened because it does not exist

さまざまな相対パスと絶対パスを試しましたが、成功しませんでした。上記のコードを編集して、コンテキストをロードしようとする試みのすぐ上に次のコードを追加しました。

  try {
    log.info(org.apache.commons.io.FileUtils.readFileToString(new File("src/main/webapp/WEB-INF/springapp-servlet.xml")));
  } catch (final Exception e) {
    log.error("Unable to find file",e);
  }

そして、springapp-servlet.xml の内容を問題なく出力しました。

私の2つの質問:

  • からのまったく同じパスを使用してファイルコンテンツを表示できるときに、「クラスパスリソース [src/main/webapp/WEB-INF/springapp-servlet.xml] が存在しないため開くことができません」というメッセージを取得するにはどうすればよいですか?同じ方法?
  • とにかく、注入された依存関係を持つデーモンを開始するための正しいアプローチがありますか?

PS: Tomcat を使用しています。

4

1 に答える 1

1

2 つの異なる Spring アプリケーション コンテキストを開始しています。最初の組み込みのContextLoaderListener は、デフォルトの場所からspringapp -servlet.xml 構成を取得する可能性があります。(contextConfigLocation を指定しているかどうかは言いませんでした。)

次に、カスタム リスナーで、ClassPathXmlApplicationContext を明示的なパスとともに使用して、新しいアプリケーション コンテキストを構築します。表示した 3 行のうち、""WEB-INF/springapp-servlet.xml" を含む行のみがクラスパス解決の候補のように見えますが、Tomcat インスタンスの構成方法と起動方法に大きく依存します。 (つまり、Tomcat の観点から見たクラスパスは何ですか?)

とにかく、Spring アプリケーションのコンテキストをサーブレット/リスナーに取得するためのより良い方法があります。直接的なアプローチは、これまで行ったように ContextLoaderListener を使用することですが、カスタム サーブレット/リスナーでは、Spring のWebApplicationContextUtils.getWebApplicationContextを使用します。

Spring は、アノテーション、 HttpServletBeanクラス、またはFrameworkServletを直接使用することによる構成など、サーブレットも直接サポートしています。

于 2013-01-14T18:03:28.013 に答える