Spring singleton being called twice
Asked Answered
V

2

10

getting some problem into my spring application.

I have very fairly simple spring beans, they are injected into various other spring beans. While debugging I found, they are being called twice, Constructor & @PostConstruct both called two times.

My application have no front end technology. Its simply for backend task related.

Spring Configuration

<?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:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:lang="http://www.springframework.org/schema/lang" xmlns:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-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/lang http://www.springframework.org/schema/lang/spring-lang.xsd">


    <context:component-scan base-package="com.green.integration" />

    <!-- ######################################################## -->
    <!-- EXPOSING SPRING BEAN VIA HTTPINVOKER SPRING REMOTING -->
    <!-- ######################################################## -->

    <bean name="/switch"
        class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
        <property name="service" ref="SwitchController" />
        <property name="serviceInterface"
            value="com.green.ISwitchController" />
    </bean>

    <!-- Load in application properties reference -->
    <bean id="applicationProperties"
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location" value="classpath:application.properties" />
    </bean>


    <bean id="mongo" class="com.mongodb.Mongo">
        <constructor-arg value="${mongo.server}" />
        <constructor-arg value="${mongo.port}" />
    </bean>

    <bean id="morphia" class="com.google.code.morphia.Morphia">
    </bean>


</beans>

Spring Bean Class

@Repository
public class TransactionDAO extends BasicDAO<Transaction, ObjectId>  {
    private Datastore datastore;

    @Autowired
    public TransactionDAO(Mongo mongo, Morphia morphia) {
        super(mongo, morphia, "itransact");
        morphia.map(Transaction.class);
        // TO USE MONGO WITHOUT SECURITY
        this.datastore = morphia.createDatastore(mongo, "itransact");
        logger.debug("***** CONNECTED TO MONGODB SUCCESSFULLY *****");
        this.datastore.ensureIndexes();
        // this.datastore.ensureCaps();
    }
}

Constructor "TransactionDAO" is being called twice.

I tried to watch call stack trace by

Throwable t = new Throwable();
System.out.println(t.getStackTrace()[1].toString());

and each time it showed the following

sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
Vereen answered 28/5, 2012 at 20:29 Comment(12)
Are you absolutely sure @PostConstruct is called twice as well? Constructor being called twice can be easily explained, but not @PostConstruct.Touchmenot
Do you have a dispatcher servlet configuration?Banta
Maybe you have your application context xml imported from another context's xml configuration file via <import ..>?Rowel
Your spring configuration doesn't include the DAO class you listed. There is missing information here.Shallot
@JuanAlbertoLópezCavallotti Yeah, I do have a dispatcher servlet for spring httpinvoker. Is it causing the problem?Vereen
@BorisTreukhov Boris, I was having multiple spilt spring config files & importing into one main spring config file. Then I removed all imports and put all config into the main spring file, but it did not make any difference.Vereen
@JuanAlbertoLópezCavallotti Juan, I verified by removing the dispatcher servlet and beans are once initialized. Its the dispatcher that causing twice initialization. So what's the fix, please?Vereen
What is your environment? Are you sure that your classes are managed by spring only https://mcmap.net/q/640243/-postconstruct-method-called-twice-for-the-same-requestRowel
@BorisTreukhov Yeah, all classes are being managed by spring container.Vereen
@FaisalBasra if your dispatcher is scanning the packages then you may be scanning the same beans in two different contexts!Banta
@FaisalBasra I'll add it as an answer if it solved the problemBanta
@TomaszNurkiewicz Constructor being called twice can be easily explained, but not @PostConstruct ...if called from different contexts in the same JVM, PostConstruct is called each time after the constructor; what was the rational behind your comment?Acaricide
V
17

I just figured out the problem and special thanks to @Juan Alberto who give me hint to the problem.

Description: Actually I was giving the one applicationContext.xml file for both contextListner and dispatcher servlet. So 1st bean was initializing for spring core and 2nd time for spring dispatcher.

I spilt the configuration now, into applicationContext.xml and applicationContext-dispatcher.xml which have only their relevant configurations and my beans are initializing once properly.

Problematic Configs

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>


<servlet>
    <servlet-name>remoting</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext.xml</param-value>
    </init-param>
    <load-on-startup>0</load-on-startup>
</servlet>

Solved Configs

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>


<servlet>
    <servlet-name>remoting</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext-dispatcher.xml</param-value>
    </init-param>
    <load-on-startup>0</load-on-startup>
</servlet>
Vereen answered 29/5, 2012 at 8:56 Comment(1)
I don't understand the what contain we should put in applicationContext-dispatcher.xml and what should be put in applicationContext.xmlKaree
T
5

Actually your issue is that you may be defining the beans in the dispatcher servlet and also your spring context, the dispatcher provides a different context but It (a sub context I think) of the main context so the right way to do things is having your main context scan your "model classes" and the dispatcher just only scan for the controllers.

I hope this helps you.

Toomay answered 29/5, 2012 at 14:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.