簡體   English   中英

如何從Web應用程序使用Spring注入啟動守護程序

[英]How to start a daemon using Spring injection from a webapp

部署戰爭時,我需要啟動一個守護程序。 守護程序本身使用應隨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的內容了。

我的兩個問題:

  • 當我能夠使用完全相同的路徑顯示文件內容時,如何獲得“類路徑資源[src / main / webapp / WEB-INF / springapp-servlet.xml]無法打開,因為它不存在”同樣的方法?
  • 無論如何,我是否有正確的方法來啟動具有已注入依賴項的守護程序?

PS:我使用Tomcat。

您正在啟動兩個不同的spring應用程序上下文。 第一個是內置的ContextLoaderListener ,可能是從默認位置獲取springapp-servlet.xml配置。 (您未指定是否要指定contextConfigLocation。)

然后,在自定義偵聽器中,使用帶有顯式路徑的ClassPathXmlApplicationContext構造新的應用程序上下文。 在顯示的三行中,只有帶有“” WEB-INF / springapp-servlet.xml“的行看起來可能是類路徑解析的候選者,盡管它實際上取決於您如何配置和啟動Tomcat實例。 (即從Tomcat的角度來看,類路徑是什么?)

無論如何,都有更好的方法將Spring應用程序上下文放入servlet /偵聽器。 一種直接的方法是使用ContextLoaderListener,然后在自定義servlet /偵聽器中使用Spring的WebApplicationContextUtils.getWebApplicationContext

Spring也直接支持servlet,包括通過注釋, HttpServletBean類甚至直接使用FrameworkServlet進行配置。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM