我在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;
}
}
这里没有什么特别的,一些Strings,一个Int和getter and setters。 然后我创建了这个上下文文件:
<?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对象的值时,它也已经更新了产品2.在我看来这是一种奇怪的行为,不是吗?
答案 0 :(得分:6)
您对原型范围的理解是正确的。来自文档:
bean的非单例原型范围部署导致每次发出对该特定bean的请求时创建一个新的bean实例(也就是说,它被注入到另一个bean中,或者通过程序化请求它{ {1}}方法调用容器)。
那就是说,我无法重现你观察到的行为(我正在运行你提供的代码)。这就是我getBean()
所得到的:
70.0 Let's change the price of this incredible game : Price for product1 object 80.0 Price Product 2 : 70.0
我没有尝试所有版本的Spring,但你可能会使用一个有缺陷的版本(虽然非常不太可能),或者某个地方还有其他问题(更有可能)。
答案 1 :(得分:1)
bean部署的原型模式导致每次完成对特定bean的请求时都会创建一个新的bean实例。
所以你是对的,每个电话都应该给出一个新的实例。
答案 2 :(得分:0)
无法重现:
70.0
Let's change the price of this incredible game :
Price for product1 object
80.0
Price Product 2 :
70.0
您是否正在使用它并且正在查看相同的XML文件?
答案 3 :(得分:0)
我只有这个上下文文件。但我认为这是IntelliJ的一个问题。很高兴我理解了这个原型的概念,这使我在这个上下文中的变化完全被忽略了。我看到当我在里面有一个豆子时,Spring说在尝试实现它时没有这个名字的豆子...奇怪!
谢谢你们!