java Spring单例被调用两次

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10790120/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 02:35:21  来源:igfitidea点击:

Spring singleton being called twice

javaspringsingletonpostconstruct

提问by Faisal Basra

getting some problem into my spring application.

在我的 spring 应用程序中遇到了一些问题。

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.

我有非常简单的春豆,它们被注入到其他各种春豆中。在调试时我发现,它们被调用了两次,Constructor 和 @PostConstruct 都被调用了两次。

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.

构造函数“TransactionDAO”被调用两次。

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)

回答by Faisal Basra

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

我刚刚解决了这个问题,特别感谢@Juan Alberto,他给了我这个问题的提示。

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.

描述:实际上,我为 contextListner 和调度程序 servlet 提供了一个 applicationContext.xml 文件。所以第一个 bean 为 spring 核心初始化,第二次为 spring 调度程序初始化。

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.

我现在将配置溢出到 applicationContext.xml 和 applicationContext-dispatcher.xml 中,它们只有它们的相关配置,并且我的 bean 正在正确初始化一次。

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>

回答by Juan Alberto López Cavallotti

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.

实际上,您的问题是您可能在调度程序 servlet 和 spring 上下文中定义了 bean,调度程序提供了不同的上下文,但是它(我认为是一个子上下文)是主上下文,因此正确的做事方法是让您的主上下文扫描您的“模型类”,调度程序只扫描控制器。

I hope this helps you.

我希望这可以帮助你。