Spring Boot找不到WebApplicationContext

5

我有一个简单的Spring Boot应用程序,正在尝试运行它。配置包括一个应用上下文(applicationContext.xml)的XML文件,其中包含许多bean。我有一个Spring应用程序类:

@SpringBootApplication
@Configuration
@ImportResource("classpath:applicationContext.xml")
public class WebCheckApplication {

    private static final Logger logger = Logger.getLogger(WebCheckApplication.class);

    public static void main(String[] args) {
        ApplicationContext ctx = SpringApplication.run(WebCheckApplication.class, args);

        if (logger.isDebugEnabled()) {
            logger.debug("Let's inspect the beans provided by Spring Boot:");

            String[] beanNames = ctx.getBeanDefinitionNames();
            Arrays.sort(beanNames);
            for (String beanName : beanNames) {
                logger.debug(beanName);
            }
        }
    }
}

我有一个@WebListener类,它从ServletContext中获取一些WebContext的bean:

@WebListener
public class SystemPropertiesContextInitializer extends SysPropsAlertsFetcher implements ServletContextListener {

    private static final Logger logger = Logger.getLogger(SystemPropertiesContextInitializer.class);

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        //remove the SystemProperties and alert types map object from context
        sce.getServletContext().removeAttribute(BaseAuthenticatedController.SYSPROPS_KEY);
        sce.getServletContext().removeAttribute(BaseAuthenticatedController.ALERT_TYPES_MAP_KEY);
    }

    @Override
    public void contextInitialized(ServletContextEvent sce) {

        SysPropsDataAccess = (SystemPropertiesDataAccess) WebApplicationContextUtils.getRequiredWebApplicationContext(sce.getServletContext()).getBean("SystemPropertiesDataAccess");
        AlertsDataAccess = (AlertDataAccess) WebApplicationContextUtils.getRequiredWebApplicationContext(sce.getServletContext()).getBean("AlertsDataAccess");
        fetchObjects(sce.getServletContext());
    }
}

当我尝试启动该应用程序时,出现以下错误:
SEVERE: Exception sending context initialized event to listener instance of class web.SystemPropertiesContextInitializer
java.lang.IllegalStateException: No WebApplicationContext found: no ContextLoaderListener registered?
    at org.springframework.web.context.support.WebApplicationContextUtils.getRequiredWebApplicationContext(WebApplicationContextUtils.java:83)
    at .web.SystemPropertiesContextInitializer.contextInitialized(SystemPropertiesContextInitializer.java:31)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4994)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5492)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)

这个错误出现在以下代码行:

SysPropsDataAccess = (SystemPropertiesDataAccess) WebApplicationContextUtils.getRequiredWebApplicationContext(sce.getServletContext()).getBean("SystemPropertiesDataAccess");

看起来Spring没有创建WebApplicationContext。


当您将 /@WebListener 移除并将其变为 /@Bean 注释的方法时,WebCheckApplication 会发生什么?请参考 http://docs.spring.io/spring-boot/docs/current/reference/html/howto-embedded-servlet-containers.html。 - Zergleb
顺便提一下,/@SpringBootApplication 已经包含 /@Configuration。https://github.com/spring-projects/spring-boot/blob/6193b640a4ba69ee0ca43faf440a6e34acf3dfaf/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/SpringBootApplication.java - Zergleb
这有点违背了我想要导入一个已经完全编写好的外部应用程序上下文XML的目的,对吧? - alessandro ferrucci
2个回答

1
大于或等于1.3.0.RC1使用@ServletComponentScan
@ServletComponentScan // <-- This scans for EJB @WebFilter, @WebListener and @WebServlet 
@SpringBootApplication
@ImportResource("classpath:applicationContext.xml")
public class WebCheckApplication {

小于或等于1.2.x版本使用@Component来扫描监听器。
@Component // <-- This allows the component to be found by @ComponentScan inside of @SpringBootApplication
@WebListener
public class MojoSystemPropertiesContextInitializer extends MojoSysPropsAlertsFetcher implements ServletContextListener {

扩展War部署需要继承SpringBootServletInitializer
public class WebCheckApplication extends SpringBootServletInitializer {

在1.3.0.RC1版本中添加了@ServletComponentScan,因此仅对主应用程序配置进行注释即可使这些内容被捕获。否则,将@Component添加到您的ServletContextListener应该可以正常工作。

此链接讨论了他们当前如何处理@WebFilter以及他们决定如何处理@WebFilter,还讨论了SpringBootServletInitializer,如果两者都被使用,则会重复处理每个项目。同时提供了实施新功能的提交链接。

https://github.com/spring-projects/spring-boot/issues/2290

如果您打算将应用程序部署为war文件,还可以让您的主配置扩展SpringBootServletInitializer。

http://docs.spring.io/spring-boot/docs/current/reference/html/howto-traditional-deployment.html


0
只需让Application类扩展SpringBootServletInitializer即可。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接