提问者:小点点

何时使用Spring原型范围?


我想知道什么时候应该确切地使用Spring中的原型范围?我已经理解单例如果请求bean,则返回相同的对象实例。

那我们为什么要考虑原型

用例子进行解释将有助于理解它的必要性。


共3个答案

匿名用户

明确简单的定义:

>

  • 原型范围=每次注入/查找时都会创建一个新对象。它每次都将使用new有Bean()

    Singleton scope=每次注入/查找时都会返回相同的对象。这里它将实例化一个有Bean的实例,然后每次都返回它。

    原型bean是在使用时创建的。因此,当您想要有状态bean时,有时非常需要有原型范围,或者当您不想在bean中缓存任何值时。原型bean可以与一个会话或一些调用相关联。

    示例:

    数据访问对象(DAO)通常不配置为原型,因为典型的DAO不持有任何会话状态;作者更容易重用单例图的核心。

  • 匿名用户

    通过使用范围原型,您将构建更好且可靠的应用程序设计/架构,例如实时系统,有一些有趣的用例。

    想象一下,你必须建立一个车辆跟踪的实时系统,你将有2.000.000辆汽车共享信息每5秒,在服务器端,你将使用两个或更多不同的配置组,一个用于汽车,另一个用于卡车。

    基于这个简单的示例,如果您将应用程序设计为通过原型模式使用内存中的不同配置组,您将获得更好的性能。

    因此,在这种情况下,每当服务器收到来自Truck的新消息时,例如,服务器将从车辆GrupConfiguration实例的hashmap中获取内存中的配置实例,然后应用此消息必须具有的配置行为,例如:超时、重试等。

    我想强调,有很多方法可以实现这种情况,但是这个例子表明原型模式在性能和设计模式方面非常强大。

    匿名用户

    正如留档所说,创建具有原型范围的bean Foo与调用相同:

    Foo foo = new Foo(dependency1, dependency2, ...);
    foo.initialize(dependency7, dependency8...);
    

    使用原型范围bean而不是new的唯一好理由是,用于创建和初始化实例的依赖项应该保留在需要新实例的代码之外。

    举个例子:

    // need to explicitly mention dependencies here
    public void createdWithNew(Dependency dependency1, Dependency dependency2) {
      Foo foo = new Foo(dependency1, dependency2, ...);
      foo.doSomething();
    }
    
    // Dependencies managed in class Foo by Spring
    public void createdWithSpring(Foo foo) {
      foo.doSomething();
    }
    
    

    例如,如果您想编写类似于EJB2Java实体bean的持久性代码,例如

    Person p = ...
    p.setName("John Doe");
    p.save(); // write to DB
    

    而不是使用JPA方式

    Person p = new Person();
    p.setName("John Doe");
    personService.save(p); // write to DB
    

    在实体bean代码风格中,人实例需要知道应该如何持久化,因此需要注入编写人的代码不应该知道的持久化细节。

    另一个例子:如果你想在应用程序的许多地方使用非线程安全的SimpleDateFormatJava类,并从配置文件中使用格式模式(可能根据其他条件使用不同的格式)。你可以使用原型范围每次都获得一个新的实例,而不是在所有这些地方创建一个新的格式实例,同时从文件(或Spring属性)加载格式化字符串。设置通用格式的细节在一个地方。