如何在解决应用程序上下文之前启动tomcat

时间:2015-12-11 16:09:46

标签: spring spring-boot

我们有一个现有的Web应用程序,可以在spring上下文初始化期间计算ServletContext.contextPath

我进行了一些修改,因此应用程序现在使用弹簧启动,并且在正常的tomcat中它按设计工作。

如果我从命令行启动应用程序,那么计算ServletContext的bean将在现在可用的servlet上下文的时候进行处理。即使没有onStartup(ServletContext)事件,bean也已“准备就绪”。

这就是:

  1. Bean x实现FactoryBean,ServletContextAware
  2. bean由spring创建,并由另一个bean y(getObject)使用。
  3. getObject返回null,因为尚未调用setServletContext。
  4. 我尝试将(web)应用程序上下文注入x工作。但是在使用bean时,webapplication上下文中的servlet上下文尚未设置......

    出于调试原因,我提供了一个虚拟servlet上下文来查看接下来会发生什么。事实证明,只有在bean x和bean y“准备好”并启动后才会启动整个tomcat。

    起初我有

    - Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@3972a855: startup date [Fri Dec 11 16:56:33 CET 2015]; root of context hierarchy
    

    有些时候我在日志文件中看到以下条目:

     Tomcat initialized with port(s): 8080 (http)
    Dez 11, 2015 4:56:42 PM org.apache.catalina.core.StandardService startInternal
    INFORMATION: Starting service Tomcat
    Dez 11, 2015 4:56:42 PM org.apache.catalina.core.StandardEngine startInternal
    INFORMATION: Starting Servlet Engine: Apache Tomcat/8.0.28
    Dez 11, 2015 4:56:42 PM org.apache.catalina.core.ApplicationContext log
    INFORMATION: Initializing Spring embedded WebApplicationContext
    

    那么,在完整的Web环境启动后,如何声明我的bean才准备就绪? ServletContextAwareWebApplicationInitializer都没有做到这一点。

    到目前为止,我可以使用带有外部tomcat的spring boot,但不能用作可执行jar,因为在满足所有要求之前,我的bean被标记为“ready”。

    这是我得到的堆栈跟踪:

        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1578)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
        at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:154)
        at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:677)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:519)
        at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752)
        at org.springframework.boot.SpringApplication.doRun(SpringApplication.java:347)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:295)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1112)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1101)
        at com.db.opra.boot.Starter.main(Starter.java:34)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:497)
        at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
    Caused by: java.lang.NullPointerException
        at myClass.servletContext.getContextPath(WebContextNameResolverFactory.java:69)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1637)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574)
    

1 个答案:

答案 0 :(得分:0)

您可以让您的bean听取ContextRefreshed event。这很容易,您需要添加使用@EventListener注释的方法,该方法将ContextRefreshedEvent作为参数:

 @EventListener
    public void handleContextRefresh(ContextRefreshedEvent event) {
        ...
    }