[英]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的內容了。
我的兩個問題:
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.