spring 原型范围
示例
在Spring容器启动时未预先创建原型范围的Bean。取而代之的是,每次将检索此bean的请求发送到容器时,都会创建一个新的新实例。对于有状态对象,建议使用此范围,因为它的状态不会被其他组件共享。
为了定义原型作用域的bean,我们需要添加@Scope批注,指定所需的作用域类型。
给定以下MyBean类:
public class MyBean {
private static final Logger LOGGER = LoggerFactory.getLogger(MyBean.class);
private String property;
public MyBean(String property) {
this.property= property;
LOGGER.info("Initializing {} bean...", property);
}
public String getProperty() {
return this.property;
}
public void setProperty(String property) {
this.property= property;
}
}我们定义一个bean定义,将其范围声明为原型:
@Configuration
public class PrototypeConfiguration {
@Bean
@Scope("prototype")
public MyBean prototypeBean() {
return new MyBean("prototype");
}
}为了了解它是如何工作的,我们从Spring容器中检索bean,并为其属性字段设置一个不同的值。接下来,我们将再次从容器中检索bean并查找其值:
MyBean prototypeBean1 = context.getBean("prototypeBean", MyBean.class);
prototypeBean1.setProperty("changed property");
MyBean prototypeBean2 = context.getBean("prototypeBean", MyBean.class);
logger.info("原型bean1属性: " + prototypeBean1.getProperty());
logger.info("原型bean2属性: " + prototypeBean2.getProperty());查看以下结果,我们可以看到如何在每个bean请求上创建一个新实例:
Initializing prototype bean... Initializing prototype bean... 原型bean1属性: changed property 原型bean2属性: prototype
一个常见的错误是假定每次调用或每个线程都重新创建了bean,事实并非如此。而是根据PERINJECTION(或从上下文中检索)创建实例。如果仅将Prototype范围的Bean注入到单个SingletonBean中,则将永远只有该Prototype范围的Bean的一个实例。
Spring不能管理原型bean的完整生命周期:容器实例化,配置,修饰和以其他方式组装原型对象,将其交给客户端,然后对该原型实例不再有任何了解。