简体   繁体   中英

Spring ApplicationContext beans loaded twice

My Spring ApplicationContext file is being loaded twice. This is using a standard maven webapp structure, with one web.xml. There is only one context file, and only one servlet defined. There is NO context-loader-listener.

I have attempted the following to fix the issue

  • Standard Naming Conventions ('test-servlet.xml')
  • Defining a ContextLoaderListener with a different Context file - without any bean definitions
  • Component Scan
  • Manual Bean definitions
  • Singleton getInstance type methods ("public static Test getInstance()") and private Constructor

The Web.XML

<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="testApp" version="2.5">

    <servlet>
        <servlet-name>test</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/beans.test.xml</param-value>
        </init-param>
    </servlet>
</web-app>

The beans file

<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:mvc="http://www.springframework.org/schema/mvc"
   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <mvc:annotation-driven />
    <bean id="testController" class="Test" />
</beans>

The Java Class

public class Test {
    private static Logger logger = Logger.getLogger(Test.class);
    public Test() {
        logger.debug("IN INIT");
    }
}

All of this results in the following lines

2014-08-12 15:56:32,427 - INFO : [beans.factory.xml.XmlBeanDefinitionReader-loadBeanDefinitions] - Loading XML bean definitions from ServletContext resource [/WEB-INF/beans.test.xml]
2014-08-12 15:56:32,427 - INFO : [beans.factory.xml.XmlBeanDefinitionReader-loadBeanDefinitions] - Loading XML bean definitions from ServletContext resource [/WEB-INF/beans.test.xml]
2014-08-12 15:56:33,015 - DEBUG: [Test-<init>] - IN INIT
2014-08-12 15:56:33,015 - DEBUG: [Test-<init>] - IN INIT

So far....Nothing has seemed to work.

Edit:

The app uses Log4j (version 1.2.17) with a log4j.xml file under /src/main/resources, with the following structure

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

     <appender name="console" class="org.apache.log4j.ConsoleAppender">
         <param name="Target" value="System.out" />
         <layout class="org.apache.log4j.PatternLayout">
             <param name="ConversionPattern" value="%d - %-5p: [%c{4}-%M] - %m%n" />
         </layout>
     </appender>
     <logger name="org.springframework.beans.factory">
         <level value="INFO" />
         <appender-ref ref="console" />
     </logger>
     <logger name="Test">
         <level value="DEBUG" />
         <appender-ref ref="console" />
     </logger>
     <root>
         <level value="ERROR" />
         <appender-ref ref="console" />
     </root>
</log4j:configuration>

This looks to me like your Logger is incorrectly (or, rather, unexpectedly) configured. You seem to have a root logger and an extra spring/custom logger where you haven't set the additivity flag to false (it's true by default). In this case, when you send a log event, the child logger will log the message, then its parent will be looked up and log it as well.

Set the child's additivity to false to disable any parents logging the event as well.

From the docs

Appender Additivity

  • The output of a log statement of logger C will go to all the appenders in C and its ancestors. This is the meaning of the term "appender additivity".
  • However, if an ancestor of logger C, say P, has the additivity flag set to false, then C's output will be directed to all the appenders in C and its ancestors upto and including P but not the appenders in any of the ancestors of P.
  • Loggers have their additivity flag set to true by default.

Change

<logger name="Test" additivity="false">
     <level value="DEBUG" />
     <appender-ref ref="console" />
</logger>

similarly for the Spring logger.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM