Spring - application Initialized twice?

前端 未结 5 857
别那么骄傲
别那么骄傲 2020-12-09 19:57

When I starts to run my spring application my tomcat , the ContextRefreshedEvent fires twice. Please see the StackTrace.

Dec 20, 2013 6:07:56 PM         


        
相关标签:
5条回答
  • 2020-12-09 20:29

    That's very normal. You have an application listener that loads a the context, and you have a servlet that loads on startup and loads the context also. Remove load on startup from the servlet declaration in web.xml. You web.xml will become tike this :

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
        id="WebApp_ID" version="2.5">
        <display-name>SpringValidations</display-name>
    
        <welcome-file-list>
            <welcome-file>index.jsp</welcome-file>
        </welcome-file-list>
    
        <servlet>
            <servlet-name>dispatcher</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
            </init-param>
    
        </servlet>
    
        <servlet-mapping>
            <servlet-name>dispatcher</servlet-name>
            <url-pattern>*.html</url-pattern>
        </servlet-mapping>
    
    
        <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/applicationContext.xml</param-value>
        </context-param>
    
        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
    
        <context-param>
            <param-name>log4jConfigLocation</param-name>
            <param-value>/WEB-INF/classes/log4j.xml</param-value>
        </context-param>
    
        <listener>
            <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
        </listener>
    
    </web-app>
    
    0 讨论(0)
  • 2020-12-09 20:39

    I believe you misunderstood ApplicationListener. It is used to listen for each application context events not web app initialization/destruction events. Try using ServletContextListener instead.

    In web.xml

    <listener>
    <listener-class>com.blablah.StartupListener</listener-class>
    </listener>
    

    StartupListener.java

    public class StartupListener implements ServletContextListener {
        @Override
        public void contextInitialized(ServletContextEvent event) {
            System.out.println("--------------- Context Initialized -----------------");
            // If want to get a bean
            ServletContext context = event.getServletContext();
            ApplicationContext ctx = (ApplicationContext) WebApplicationContextUtils.getRequiredWebApplicationContext(context);
            MyBean bean = (MyBean) ctx.getBean("myBean");
        }
        // Omitted for brevity
    }
    
    0 讨论(0)
  • 2020-12-09 20:44

    This seems normal as Spring MVC application have usually at least two contexts, see this answer.

    In this case this application has two different contexts that serve different purposes:

    • a global Spring context common to the whole application

    • a servlet-level spring context, which contains all the beans associated to a given dispatcher servlet.

    A Spring MVC application can have multiple dispatchers, each with it's own context and all sharing a parent context with common application-wide beans.

    In each dispatcher context there are beans specific of the dispatcher that cannot be injected in other contexts and neither on the parent context, for example all beans annotated with @Controller.

    This ensures that we can inject service and DAO beans defined in the common context in any controller, but we can never inject a controller into a service, or controllers/beans from one dispatcher into another dispatcher, keeping the dispatchers isolated.

    According to the log, the first context initialised is the root context, and the second context is the dispatcher context, which is OK.

    0 讨论(0)
  • 2020-12-09 20:50

    Its getting refreshed for each context, Dispatcher and Application. Try running this test:

       public void onApplicationEvent(ContextRefreshedEvent event) {
            ApplicationContext context = event.getApplicationContext();
            System.out.println(context.getDisplayName());
        }
    
    0 讨论(0)
  • 2020-12-09 20:50

    You seem to have two <ContextLoaderListener>s declared in your web.xml? Try removing one of these.

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    
    0 讨论(0)
提交回复
热议问题