简体   繁体   English

Spring singleton创建了多次

[英]Spring singleton created multiple times

I have a bean defined in my spring web application and I am expecting to have only one instance of this bean, here is my bean definition: 我在我的spring web应用程序中定义了一个bean,我希望只有一个这个bean的实例,这是我的bean定义:

<bean id="accessControl" class="my.spring.app.AccessControl" />

In the constructor of AccessControl, I assign an identifier to the object, something like this: 在AccessControl的构造函数中,我为对象分配一个标识符,如下所示:

public class AccessControl {
   private long id = 0;
   public AccessControl() {
        id = System.currentTimeMillis();
   }

   public long getAccessControlId() {
        return id;
   }
}

In a different class, I try to get hold of the instance of AccessControl, something like this: 在另一个类中,我尝试抓住AccessControl的实例,如下所示:

            ApplicationContext ctx =
                     new ClassPathXmlApplicationContext("acbean.xml");

            AccessControl ac = (AccessControl) ctx.getBean("accessControl");
            LOGGER_.info("AccessControl Identifier : " + ac.getAccessControlId());

I am expecting the "id" value to be the same because the value of "id" is set in the constructor and constructor should not get called again and again but that is exactly what is happening. 我期望“id”值是相同的,因为“id”的值在构造函数中设置,并且构造函数不应该一次又一次地被调用,但这正是发生的事情。 Infact, I added a log statement to the constructor and a new object is created everytime. 事实上,我在构造函数中添加了一个日志语句,每次都会创建一个新对象。

I have read: http://www.digizenstudio.com/blog/2006/09/14/a-spring-singleton-is-not-a-singleton/ but I don't think I am dealing with the same class defined twice with two different bean identifiers and the application context is the same. 我看过: http//www.digizenstudio.com/blog/2006/09/14/a-spring-singleton-is-not-a-singleton/但我不认为我正在处理相同的类定义两次使用两个不同的bean标识符,应用程序上下文是相同的。

Can anyone share what is wrong with the way I have defined the bean? 任何人都可以分享我定义bean的方式有什么问题吗?

I have also experimented with singleton="true" and scope="singleton" but they do not make any differece. 我还尝试过singleton =“true”和scope =“singleton”,但它们没有任何差异。

Thanks. 谢谢。

the singelton-ness in spring is per application context, every time you create a new instance of the application context (like the first line in your second code sample) all the singletons are instantiated. Spring中的singelton-ness是每个应用程序上下文,每次创建应用程序上下文的新实例时(如第二个代码示例中的第一行),所有单例都将被实例化。

You need to have a single application context and reuse it around in your application 您需要拥有单个应用程序上下文并在应用程序中重复使用它

You are creating a new application context with each call of: 您正在创建一个新的应用程序上下文,每次调用:

ApplicationContext ctx = new ClassPathXmlApplicationContext("acbean.xml");

So, you end up with a new spring container, which means that your beans are all re-created by the new container. 因此,您最终得到一个新的弹簧容器,这意味着您的bean都是由新容器重新创建的。

Also, you mentioned that you had this in a web application. 此外,您提到您在Web应用程序中有此功能。 If so, you need to allow the web application to load the spring context and to obtain and use that context as necessary. 如果是这样,您需要允许Web应用程序加载spring上下文并根据需要获取和使用该上下文。

Add to web.xml: 添加到web.xml:

<context-param>
    <description>Core Spring context.</description>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/classes/applicationContext.xml</param-value>
</context-param>
<listener>
    <description>Spring loader.</description>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

or something similar. 或类似的东西。 Obtain the web context via a servletcontext as needed. 根据需要通过servletcontext获取Web上下文。

One other note: one point of spring is to provide inversion of control, commonly with dependency injection. 另一个注意事项:弹簧的一个方面是提供控制反转,通常是依赖注入。 You should consider allowing spring to inject any dependencies for you rather than obtaining the context and pulling beans yourself. 你应该考虑允许spring为你注入任何依赖,而不是自己获取上下文和拉豆。

In a Spring app you should not be explicitly creating an application context of your own. 在Spring应用程序中,您不应该显式创建自己的应用程序上下文。

Ideally the singleton should be injected into your class, or you should be implementing ApplicationContextAware ( docs , and some notes ). 理想情况下,单例应该注入到您的类中,或者您应该实现ApplicationContextAwaredocs一些注释 )。 I prefer injection; 我更喜欢注射; easier. 更轻松。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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