当前位置: 首页 > 知识库问答 >
问题:

什么会导致Spring IoC每个WebApp实例化多个单例bean实例?

柯英奕
2023-03-14

我有一个基于Spring的WebApp。在我的应用程序上下文中,我定义了这个bean:

<bean id="someSingleton" class="com.fake.SomeSingleton" scope="singleton"/>

我有一个Spring调度servlet定义和一个具有@Controller注释的类,我自动连接了这个bean,期望Spring只实例化这个类一次。但是,根据以下调试代码,Spring不止一次实例化这个类:

private static final Semaphore SANITY_CHECK = new Semaphore(1);

public FakeSingleton(){
    if(!SANITY_CHECK.tryAcquire()){
      log.error("why?");
      System.exit(-1);
    else{
      log.error("OK");
    }
}

原因可能是什么?

注意:我使用spring 3.1.2.RELEASE

编辑:多亏了给我的提示,我找到了罪魁祸首。
除了DispatcherServlet,我的web.xml.中还有一个ContextLoaderListener删除它后,一些Singleton只实例化了一次。

<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<servlet>
    <servlet-name>FakeService</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>1</load-on-startup>
</servlet>

共有2个答案

上官凯歌
2023-03-14

单例是每个上下文一次,而不是每个宇宙热死一次。

打开日志记录,查看为什么/是否多次创建整个应用程序上下文。

南门飞扬
2023-03-14

有几个可能的原因:

>

  • 您的类由一些CGLIB代理包装,这会导致构造函数运行两次(而不是<code>@PostConstruct

    更有可能的是,你的豆子被两个上下文拾取:主要一个和SpringMVC一个。这是一种糟糕的做法,你应该避免它。检查您的某些单一类是否未被 MVC 调度程序 servlet 上下文通过某些类路径扫描拾取。

    顺便说一下,在这样的代码中,使用简单的< code>AtomicInteger而不是< code>Semaphore是安全的。

  •  类似资料:
    • 我不知道这里发生了什么事。我有一个包含列表的单例bean。当我向列表中添加项目时,内容总是一致的。然而,当我从另一个服务调用该列表上的get时,它返回一个具有不同java id的空列表。 下面是类的定义方式: 两者的区别是: add方法是从侦听新消息并调用相应处理程序的bean调用的。get是从另一个bean调用的,该bean在事件发生后处理数据。当我一个接一个地调用这两个对象时,列表具有不同的I

    • 当使用Spring Framework时,我怀疑在下面提到的场景中会创建多少实例: bean配置如下 默认情况下,bean“a”具有。因此,有一个单例bean引用了一个具有会话范围或原型范围的bean。 在这种情况下,如果有2个对应用程序的同时请求,那么将创建多少个A实例和多少个B实例? 如果有人能解释这是如何工作的,那将是非常有帮助的。 谢了达薇亚

    • 我们有一个Spring Boot Restful API,它需要从两个不同的Elasticsearch实例(在不同的服务器上)获取数据,一个用于“共享”数据(上面有大约5个不同的索引),一个用于“私有”数据(有大约3个不同的索引)。目前只针对“私有”数据实例运行,一切都很好。但我们现在需要获取“共享”数据。 在我们的Spring Boot应用程序中,我们启用了如下Elasticsearch存储库

    • 有人能解释一下下面的代码是如何毫无例外地工作的吗。我在想,当为星期天创建新实例时,它也会为星期一(星期天内)创建一个新实例,然后再为星期天(星期一内)创建一个新实例,以此类推。。。类似递归的东西,因为它们都是课程周的一部分。但我的理解是错误的,因为下面的代码运行良好。 我有这个疑问,当我读到java枚举。

    • 我正在我的Java SSE(Java Flex)应用程序中使用Quartz Scheduler 2.2.0。我设定了一个时间表,每天上午10点运行,并执行一些工作。我没有关闭Quartz调度程序,因为我想让它每天运行。 但无论如何,我知道Quartz调度程序已经在运行,因为如果我在用户打开Java Flex应用程序时启动它,那么就会有多个实例存在。 Quartz.Properties 这就是我安排

    • 问题内容: 我有一个自动相互连接的Spring bean图。大大简化了图示: 所有这些bean都没有指定范围,这暗示它们是单例(使它们成为显式单例不会改变任何东西,我已经尝试过)。 问题在于,在实例化 单个应用程序上下文之后 ,的实例和包含的 不同 实例。怎么会这样 我试图为它创建public no args构造函数,并且调试已确认创建了多次。所有这些创建的堆栈跟踪都在这里。 我还尝试过为Spri