0

I want to execute a method on start up for that I used @PostConstruct annotation. On completion of method execution I print some text (starts with ****) on console. Now when I start the server it is showing me that text twice. Let me know what is the issue.

Web.xml

<web-app id="WebApp_ID" version="2.4"
    xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <welcome-file-list>
        <welcome-file>login.jsp</welcome-file>
    </welcome-file-list>
    <display-name>Spring MVC Application</display-name>

    <!-- Spring MVC -->
    <servlet>
        <servlet-name>mvc-dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>mvc-dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <listener>
        <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
    </listener>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/mvc-dispatcher-servlet.xml,
            /WEB-INF/spring-security.xml,
        </param-value>
    </context-param>

    <!-- Spring Security -->
    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <context-param>
        <param-name>avoidURL</param-name>
        <param-value>/login,/logout</param-value>
    </context-param>

    <session-config>
    <session-timeout>2</session-timeout>
    </session-config>

</web-app>

Spring Config File:

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

    <beans:bean id="sessionExpirationFilter"
        class="com.springSecurity.common.utils.SessionExpirationFilter">
        <beans:constructor-arg ref="httpSessionSecurityContextRepository" />
        <beans:property name="invalidSessionUrl" value="/login" />
        <beans:property name="sessionExpiredUrl" value="/login" />
    </beans:bean>

    <beans:bean id="httpSessionSecurityContextRepository"
        class="org.springframework.security.web.context.HttpSessionSecurityContextRepository" />


     <http auto-config="false" use-expressions="true">
        <intercept-url pattern="/admin**" access="hasAnyRole('SuperAdmin')" />

        <access-denied-handler error-page="/403" />
        <form-login 
            login-page="/login" 
            default-target-url="/innerOne" 
            authentication-failure-url="/loginfailed"  />
            <!-- username-parameter="username"
            password-parameter="password" -->
        <custom-filter ref="sessionExpirationFilter" after="FILTER_SECURITY_INTERCEPTOR" />
        <session-management invalid-session-url="/login" />
        <logout logout-success-url="/logout"  />
        <!-- <csrf/> -->
    </http>

    <authentication-manager>
        <authentication-provider>
            <password-encoder ref="passwordEncoder" />
            <jdbc-user-service data-source-ref="dataSource"
                users-by-username-query=
                    "select username,password, enabled from user where username=?"
                authorities-by-username-query=
                    "select username, role from user where username=?" />
        </authentication-provider>
    </authentication-manager> 

    <beans:bean
        id="passwordEncoder"
        class="org.springframework.security.authentication.encoding.Md5PasswordEncoder" />  

</beans:beans>

Log:

Nov 26, 2014 8:47:20 PM org.apache.catalina.loader.WebappClassLoader validateJarFile
INFO: validateJarFile(D:\_workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp1\wtpwebapps\SpringSecurityApp\WEB-INF\lib\javax.servlet-api.jar) - jar not loaded. See Servlet Spec 3.0, section 10.7.2. Offending class: javax/servlet/Servlet.class
Nov 26, 2014 8:47:22 PM org.apache.catalina.core.ApplicationContext log
INFO: No Spring WebApplicationInitializer types detected on classpath
Nov 26, 2014 8:47:22 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.
************Run:LRUCache [cacheMap={}]
Nov 26, 2014 8:47:36 PM org.apache.catalina.core.ApplicationContext log
INFO: Set web app root system property: 'webapp.root' = [D:\_workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp1\wtpwebapps\SpringSecurityApp\]
Nov 26, 2014 8:47:36 PM org.apache.catalina.core.ApplicationContext log
INFO: Initializing Spring FrameworkServlet 'mvc-dispatcher'
************Run:LRUCache [cacheMap={}]
Nov 26, 2014 8:47:49 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-bio-8084"]
Nov 26, 2014 8:47:49 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["ajp-bio-8009"]
Nov 26, 2014 8:47:49 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 29338 ms
Prashant
  • 692
  • 2
  • 11
  • 26

2 Answers2

0

It means that you create 2 bean instances of this class.

Possibly, you create one instance through XML, and another one through @ComponentScan - it's a common mistake, but not necessarily it happens in your case.

Maciej Walkowiak
  • 12,372
  • 59
  • 63
  • I used Component annotaion at class level and use Autowired annotaion once in other class to access it. I think with this it should not create two instance. – Prashant Nov 26 '14 at 15:36
0

In a spring web application there are two contexts. The servlet context (or web application context), and the root context. The ContextLoaderListener you have configured in your web.xml is the one that loads the root context. The dispatcherServlet is the one loading the servlet context.

  • By default, the dispatcherServlet loads the servlet context from a file named by the servlet name, followed by "-servlet.xml". In your case the name of the servlet is "mvc-dispatcher" therefore the servlet context will be loaded from mvc-dispatcher-servlet.xml.

  • By default, the ContextLoaderListener loads the root context from a file named "applicationContext. xml". In your case however, using the <context-param> attribute you have specified the root context to be loaded from the files "mvc-dispatcher-servlet.xml" and "spring-security.xml".

Result of the above two, is that the contents of the mvc-dispatcher-servlet.xml are included in both root and the servlet context, and thus every bean inside that file is created twice.

The appropriate thing to do is to have the spring security beans inside the root context like you do, and then separate all the other beans according to whether they are servlet specific related or not. For example any controller beans should be defined in the servlet context. Back-end beans like services and daos, although they can be defined in the servlet context too, they better suit at the root context (you can create a applicationContext.xml and put them there. Then use that from your ContextLoaderListener instead of the mvc-dispatcher-servlet.xml). That way, if you create someday a second servlet, it will access those beans too, because every bean inside the root context is accessible from the servlet context. The other way around does not work, i.e. beans inside the servlet context cannot be accessed from the root context.

You may also take a look at this post which describes the contexts differences What is the difference between ApplicationContext and WebApplicationContext in Spring MVC?

Community
  • 1
  • 1
Marios
  • 1,947
  • 1
  • 15
  • 24