spring 单例范围
示例
如果使用单例作用域定义了bean,则Spring容器中将仅初始化一个对象实例。对此bean的所有请求都将返回相同的共享实例。这是定义bean时的默认范围。
给定以下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批注定义一个单例bean:
@Configuration
public class SingletonConfiguration {
@Bean
public MyBean singletonBean() {
return new MyBean("singleton");
}
}以下示例从Spring上下文两次检索同一bean:
MyBean singletonBean1 = context.getBean("singletonBean", MyBean.class);
singletonBean1.setProperty("changed property");
MyBean singletonBean2 = context.getBean("singletonBean", MyBean.class);记录singletonBean2属性时,将显示消息“已更改属性”,因为我们刚刚检索了相同的共享实例。
由于实例是在不同组件之间共享的,因此建议为无状态对象定义单例作用域。
懒惰的单例豆
默认情况下,单例bean是预先实例化的。因此,将在创建Spring容器时创建共享库实例。如果启动应用程序,将显示“正在初始化单例bean...”消息。
如果我们不想预先实例化该bean,则可以将@Lazy批注添加到bean定义中。这将阻止在第一次请求之前创建该bean。
@Bean
@Lazy
public MyBean lazySingletonBean() {
return new MyBean("lazy singleton");
}现在,如果我们启动Spring容器,将不会出现“正在初始化惰性单例bean...”消息。在第一次请求之前,不会创建该bean:
logger.info("检索懒惰的单例豆...");
context.getBean("lazySingletonBean");如果我们同时定义了Singleton和LazySingletonBean运行该应用程序,它将产生以下消息:
初始化单例bean... 检索懒惰的单例豆... 初始化惰性单例豆...