복붙노트

[SPRING] Spring - application 두 번 초기화 되었습니까?

SPRING

Spring - application 두 번 초기화 되었습니까?

내 봄 애플리케이션 인 My Tomcat을 실행하기 시작하면 ContextRefreshedEvent가 두 번 발생합니다. StackTrace를 참조하십시오.

Dec 20, 2013 6:07:56 PM org.apache.tomcat.util.digester.SetPropertiesRule begin
WARNING: [SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting property 'source' to 'org.eclipse.jst.j2ee.server:SpringValidations' did not find a matching property.
Dec 20, 2013 6:07:56 PM org.apache.catalina.core.AprLifecycleListener init
INFO: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: C:\Program Files\Java\jre6\bin;.;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS;C:/Program Files/Java/jre6/bin/client;C:/Program Files/Java/jre6/bin;C:/Program Files/Java/jre6/lib/i386;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\Program Files\Microsoft SQL Server\80\Tools\Binn\;C:\Program Files\Microsoft SQL Server\90\Tools\binn\;F:\sub\svn\bin;%DERBY_HOME%\bin;D:\Lal\Lab\SW\apache-maven-3.0.4/bin;C:\Program Files\TortoiseSVN\bin;C:\Program Files\Java\jdk1.6.0_25\bin;;F:\Eclipse\sts-2.9.2.RELEASE;
Dec 20, 2013 6:07:56 PM org.apache.coyote.http11.Http11Protocol init
INFO: Initializing Coyote HTTP/1.1 on http-8080
Dec 20, 2013 6:07:56 PM org.apache.catalina.startup.Catalina load
INFO: Initialization processed in 289 ms
Dec 20, 2013 6:07:56 PM org.apache.catalina.core.StandardService start
INFO: Starting service Catalina
Dec 20, 2013 6:07:56 PM org.apache.catalina.core.StandardEngine start
INFO: Starting Servlet Engine: Apache Tomcat/6.0.16
Dec 20, 2013 6:07:56 PM org.apache.catalina.loader.WebappClassLoader validateJarFile
INFO: validateJarFile(F:\anand\Spring_Training\.metadata\.plugins\org.eclipse.wst.server.core\tmp1\wtpwebapps\SpringValidations\WEB-INF\lib\servlet-api-2.5.jar) - jar not loaded. See Servlet Spec 2.3, section 9.7.2. Offending class: javax/servlet/Servlet.class
Dec 20, 2013 6:07:56 PM org.apache.catalina.core.StandardContext addApplicationListener
INFO: The listener "org.springframework.web.context.ContextLoaderListener" is already configured for this context. The duplicate definition has been ignored.
Dec 20, 2013 6:07:56 PM org.apache.catalina.core.StandardContext addApplicationListener
INFO: The listener "org.springframework.web.util.Log4jConfigListener" is already configured for this context. The duplicate definition has been ignored.
Dec 20, 2013 6:07:56 PM org.apache.catalina.core.StandardContext addApplicationListener
INFO: The listener "org.springframework.web.context.ContextLoaderListener" is already configured for this context. The duplicate definition has been ignored.
Dec 20, 2013 6:07:56 PM org.apache.catalina.core.StandardContext addApplicationListener
INFO: The listener "org.springframework.web.context.ContextLoaderListener" is already configured for this context. The duplicate definition has been ignored.
log4j:WARN Continuable parsing error 108 and column 11
log4j:WARN The content of element type "logger" must match "(param*,level?,appender-ref*)".
log4j:WARN Continuable parsing error 114 and column 11
log4j:WARN The content of element type "logger" must match "(param*,level?,appender-ref*)".
Dec 20, 2013 6:07:57 PM org.apache.catalina.core.ApplicationContext log
INFO: Initializing Spring root WebApplicationContext
log4j:WARN No appenders could be found for logger (org.springframework.web.context.ContextLoader).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.

--------------- Context Refreshed -----------------
:::::::::::::::::::::::: Now you can Start the Server Initialization ! :::::::::::::::::::::::::::::

Dec 20, 2013 6:07:57 PM org.apache.catalina.core.ApplicationContext log
INFO: Set web app root system property: 'webapp.root' = [F:\anand\Spring_Training\.metadata\.plugins\org.eclipse.wst.server.core\tmp1\wtpwebapps\SpringValidations\]
Dec 20, 2013 6:07:57 PM org.apache.catalina.core.ApplicationContext log
INFO: Initializing log4j from [F:\anand\Spring_Training\.metadata\.plugins\org.eclipse.wst.server.core\tmp1\wtpwebapps\SpringValidations\WEB-INF\classes\log4j.xml]
log4j:WARN Continuable parsing error 108 and column 11
log4j:WARN The content of element type "logger" must match "(param*,level?,appender-ref*)".
log4j:WARN Continuable parsing error 114 and column 11
log4j:WARN The content of element type "logger" must match "(param*,level?,appender-ref*)".
Dec 20, 2013 6:07:57 PM org.apache.catalina.core.ApplicationContext log
INFO: Initializing Spring FrameworkServlet 'dispatcher'

--------------- Context Refreshed -----------------
:::::::::::::::::::::::: Now you can Start the Server Initialization ! :::::::::::::::::::::::::::::

Dec 20, 2013 6:07:58 PM org.apache.coyote.http11.Http11Protocol start
INFO: Starting Coyote HTTP/1.1 on http-8080
Dec 20, 2013 6:07:58 PM org.apache.jk.common.ChannelSocket init
INFO: JK: ajp13 listening on /0.0.0.0:8009
Dec 20, 2013 6:07:58 PM org.apache.jk.server.JkMain start
INFO: Jk running ID=0 time=0/16  config=null
Dec 20, 2013 6:07:58 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 1659 ms

내 Initializer 클래스는 as,

public class ApplicationListenerBean implements ApplicationListener<ContextRefreshedEvent> {

    private String message;

    public void onApplicationEvent(ContextRefreshedEvent event) {
        System.out.println("--------------- Context Refreshed -----------------");
        System.out.println( ":::::::::::::::::::::::: " +message+ " :::::::::::::::::::::::::::::");

       // Other stuff like logger Initialization , Server Initailization etc..
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

}

내 applicationContext.xml은

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org./dtd/spring-beans.dtd">

<beans>

    <bean id="test" class="com.pointel.applicationListener.ApplicationListenerBean">
        <property name="message"
            value="Now you can Start the Server Initialization !">
        </property>
    </bean>

</beans>

내 web.xml은

<?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>
        <load-on-startup>1</load-on-startup>
    </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>

내 디스패처 서블릿은

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">


    <!-- Application Message Bundle -->
    <bean id="messageSource"
        class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <!-- <property name="basename" value="/WEB-INF/messages/messages.properties" /> -->
        <property name="basenames">
            <list>
                <value>/WEB-INF/messages/messages.properties</value>
                <value>/WEB-INF/messages/mymessages.properties</value>
            </list>
        </property>
        <property name="cacheSeconds" value="3000" />
    </bean> 

    <!-- Scans the classpath of this application for @Components to deploy as beans -->
    <context:component-scan base-package="com.pointel.controllers" />

    <!-- Configures the @Controller programming model -->
    <mvc:annotation-driven />

    <!-- <context:annotation-config /> -->

    <!-- Resolves view names to protected .jsp resources within the /WEB-INF/views 
        directory -->
    <bean id="viewResolver"
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp" />
    </bean>

</beans>

내가 알기로는, 왜 --------------- Context Refreshed ----------------- 메시지가 두 번 오는가?

편집 : 나는 스프링 애플 리케이션을 초기화하는 많은 방법이 있다는 것을 알고있다. 하지만 로거 (Logger), 도메인 서버 시작과 같은 스프링 애플리케이션을 초기화하여 프로토콜 연결을 얻고, 쓰래드 (thread) 등을 명시하는 가장 효과적이고 효율적인 방법은 무엇입니까?

희망, 모두 내 질문을 이해할 수 있습니다.

해결법

  1. ==============================

    1.Dispatcher 및 Application의 각 컨텍스트에 맞게 새로 고쳐집니다. 이 테스트를 실행 해보십시오.

    Dispatcher 및 Application의 각 컨텍스트에 맞게 새로 고쳐집니다. 이 테스트를 실행 해보십시오.

       public void onApplicationEvent(ContextRefreshedEvent event) {
            ApplicationContext context = event.getApplicationContext();
            System.out.println(context.getDisplayName());
        }
    
  2. ==============================

    2.이것은 Spring MVC 애플리케이션이 일반적으로 적어도 두 개의 컨텍스트를 가지고 있기 때문에 정상적인 것처럼 보입니다.이 대답을보십시오.

    이것은 Spring MVC 애플리케이션이 일반적으로 적어도 두 개의 컨텍스트를 가지고 있기 때문에 정상적인 것처럼 보입니다.이 대답을보십시오.

    이 경우이 애플리케이션에는 다른 용도로 사용되는 두 가지 컨텍스트가 있습니다.

    Spring MVC 애플리케이션은 여러 개의 디스패처를 가질 수있다. 각각의 컨텍스트는 고유 한 애플리케이션 컨텍스트 빈을 가진 부모 컨텍스트를 공유한다.

    각 발송자 컨텍스트에는 다른 컨텍스트에 삽입 할 수 없으며 상위 컨텍스트에 삽입 할 수없는 발송자 고유의 bean (예 : @Controller로 주석 된 모든 bean)이 있습니다.

    이렇게하면 모든 컨트롤러에서 공통 컨텍스트에 정의 된 서비스 및 DAO 빈을 주입 할 수 있지만 서비스에 컨트롤러를 삽입하거나 한 디스패처에서 다른 디스패처로 컨트롤러 / 빈을 주입하여 디스패처를 격리하지 못하게 할 수 있습니다.

    로그에 따르면 초기화 된 첫 번째 컨텍스트는 루트 컨텍스트이고 두 번째 컨텍스트는 정상적인 디스패처 컨텍스트입니다.

  3. ==============================

    3.그건 아주 정상입니다. 컨텍스트를로드하는 응용 프로그램 수신기가 있고 시작할 때로드되고 컨텍스트도로드하는 서블릿이 있습니다. web.xml의 서블릿 선언에서 시작시로드를 제거합니다. web.xml은 다음과 같이됩니다.

    그건 아주 정상입니다. 컨텍스트를로드하는 응용 프로그램 수신기가 있고 시작할 때로드되고 컨텍스트도로드하는 서블릿이 있습니다. web.xml의 서블릿 선언에서 시작시로드를 제거합니다. web.xml은 다음과 같이됩니다.

    <?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>
    
  4. ==============================

    4.web.xml에 두 개의 가 선언 된 것 같습니다. 이 중 하나를 제거하십시오.

    web.xml에 두 개의 가 선언 된 것 같습니다. 이 중 하나를 제거하십시오.

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    
  5. ==============================

    5.나는 당신이 ApplicationListener를 오해 한 것으로 믿습니다. 웹 응용 프로그램 초기화 / 삭제 이벤트가 아닌 각 응용 프로그램 컨텍스트 이벤트를 수신하는 데 사용됩니다. 대신 ServletContextListener를 사용해보십시오.

    나는 당신이 ApplicationListener를 오해 한 것으로 믿습니다. 웹 응용 프로그램 초기화 / 삭제 이벤트가 아닌 각 응용 프로그램 컨텍스트 이벤트를 수신하는 데 사용됩니다. 대신 ServletContextListener를 사용해보십시오.

    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
    }
    
  6. from https://stackoverflow.com/questions/20704086/spring-application-initialized-twice by cc-by-sa and MIT license