【问题标题】:Spring and the scope attributeSpring 和范围属性
【发布时间】:2009-11-18 14:14:46
【问题描述】:

我在 Spring 学习中遇到问题,需要一些帮助。

我正在学习 bean 的 prototype 范围,这基本上意味着每次有人或其他 bean 需要这个 bean 时,Spring 将创建一个新 bean 而不是使用相同的一。

所以我尝试了这段代码,假设我有这个Product 类:

public class Product {

    private String categoryOfProduct;

    private String name;

    private String brand;

    private double price;

    public String getCategoryOfProduct() {
        return categoryOfProduct;
    }

    public void setCategoryOfProduct(String categoryOfProduct) {
        this.categoryOfProduct = categoryOfProduct;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    } 
}

这里没有什么特别的,一些字符串、一个 Int 以及 getter 和 setter。 然后我创建了这个上下文文件:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

    <bean id="product" class="com.springDiscovery.org.product.Product" scope="prototype">
        <property name="brand" value="Sega"/>
        <property name="categoryOfProduct" value="Video Games"/>
        <property name="name" value="Sonic the Hedgehog"/>
        <property name="price" value="70"/>
     </bean>
</beans>

然后我试着玩一下,看看我对原型作用域的理解是否正确,有这个类:

package com.springDiscovery.org.menu;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.springDiscovery.org.product.Product;


public class menu {

    public static void main(String[] args)
    {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml");
        Product product1 = (Product) context.getBean("product");
        Product product2 = (Product) context.getBean("product");

        System.out.println(product1.getPrice());
        System.out.println("Let's change the price of this incredible game : ");
        product1.setPrice(80);
        System.out.println("Price for product1 object");
        System.out.println(product1.getPrice());
        System.out.println("Price Product 2 : ");
        System.out.println(product2.getPrice());            
    }
}

让我惊讶的是答案是:

70.0
Let's change the price of this incredible game : 
Price for product1 object
80.0
Price Product 2 : 
80.0

所以看来,当我更新了 product1 对象的值时,它也为 product 2 更新了。在我看来,这似乎是一种奇怪的行为,不是吗?

【问题讨论】:

  • 如果将 product2 的实例化移动到 product1.setPrice(80) 之后会发生什么?

标签: java spring


【解决方案1】:

您对原型范围的理解是正确的。来自文档:

bean 部署的非单例原型范围导致每次对特定 bean 发出请求时都会创建一个新的 bean 实例(也就是说,它被注入另一个 bean 或通过编程 @ 987654321@容器上的方法调用)。

也就是说,我无法重现您观察到的行为(我正在运行您提供的代码)。这就是我通过spring-2.5.6.SEC01.jar 得到的:

70.0 让我们改变这个令人难以置信的游戏的价格: product1 对象的价格 80.0 价格产品 2: 70.0

我没有尝试所有版本的 Spring,但您可能使用了有问题的版本(虽然可能性很小),或者某个地方存在其他问题(更有可能)。

【讨论】:

  • 谢谢,我也在使用 Spring 2.5.6。我认为这是我在 IntelliJ 中的源文件夹的问题。我意识到包含这个上下文文件的文件夹在我的 IntelliJ 配置中不再被引用为源文件夹,所以我所做的任何更改都没有考虑在内,所以这个原型范围实际上没有写在 xml 中......
【解决方案2】:

bean 部署的原型模式会在每次完成对该特定 bean 的请求时创建一个新的 bean 实例。

所以你是对的,每次调用都应该给出一个新的实例。

【讨论】:

    【解决方案3】:

    无法重现:

    70.0
    Let's change the price of this incredible game : 
    Price for product1 object
    80.0
    Price Product 2 : 
    70.0
    

    你是否使用你,它正在查看同一个 XML 文件?

    【讨论】:

      【解决方案4】:

      好吧,我只有这个上下文文件。但我认为这是 IntelliJ 的问题。很高兴我正确理解了原型的这个概念,这使得我在这个上下文文件中的更改完全被忽略了。我看到当我有一个bean时,Spring在尝试实例化它时说没有这个名字的bean......奇怪!

      谢谢大家!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多