有人可以解释一下Spring bean中的范围是什么我一直只是使用'原型'但是我可以用其他参数代替吗?
我正在谈论的例子
<bean id="customerInfoController" class="com.action.customer.Controller" scope="prototype">
<property name="accountDao" ref="accountDao"/>
<property name="utilityDao" ref="utilityDao"/>
<property name="account_usageDao" ref="account_usageDao"/>
</bean>
答案 0 :(得分:77)
从spring specs开始,支持五种类型的bean范围:
<强> 1。单(默认*)强>
将每个Spring的单个bean定义范围限定为单个对象实例 IoC容器。
<强> 2。原型强>
将单个bean定义范围限定为任意数量的对象实例。
第3。请求强>
将单个bean定义范围限定为单个HTTP的生命周期 请求;这就是每个HTTP请求都有自己的 在单个bean定义的后面创建的bean实例。 仅在Web感知Spring ApplicationContext的上下文中有效。
<强> 4。会话强>
将单个bean定义范围限定为HTTP会话的生命周期。 仅在Web感知Spring ApplicationContext的上下文中有效。
<强> 5。全球会议
将单个bean定义范围限定为全局HTTP的生命周期 会话。通常仅在portlet上下文中使用时有效。只要 在Web感知的Spring ApplicationContext的上下文中有效。
* default表示<bean />
标记中未明确提供范围的情况。
在这里阅读更多相关信息:http://static.springsource.org/spring/docs/3.0.0.M3/reference/html/ch04s04.html
答案 1 :(得分:19)
在Spring中,bean作用域用于决定应该将哪个类型的bean实例从Spring容器返回给调用者。
支持5种类型的bean作用域:
Singleton:它为每个Spring IoC容器返回一个bean实例。这个单实例存储在这样的单例bean的缓存中,并且该命名bean的所有后续请求和引用都返回缓存的对象。如果bean配置文件中没有指定bean范围,默认指定为单例。
原型:每次请求时都返回一个新的bean实例。它不存储像singleton这样的任何缓存版本。
请求:每个HTTP请求返回一个bean实例。
会话:每个HTTP会话返回一个bean实例(用户级会话)。
GlobalSession :每个全局HTTP会话返回一个bean实例。它仅在Web感知的Spring ApplicationContext(应用程序级别会话)的上下文中有效。
在大多数情况下,您可能只处理Spring的核心范围 - singleton 和 prototype ,默认范围是 singleton 。< / p>
答案 2 :(得分:7)
只想更新,就像在Spring docs中提到的那样,在Spring 5中,Spring支持6个范围,只有在使用支持Web的ApplicationContext时才有4个范围可用。
singleton (默认)将每个Spring IoC容器的单个bean定义范围限定为单个对象实例。
<强>原型强> 将单个bean定义范围限定为任意数量的对象实例。
请求强> 将单个bean定义范围限定为单个HTTP请求的生命周期;也就是说,每个HTTP请求都有自己的bean实例,它是在单个bean定义的后面创建的。仅在Web感知Spring ApplicationContext的上下文中有效。
<强>会话强> 将单个bean定义范围限定为HTTP会话的生命周期。仅在Web感知Spring ApplicationContext的上下文中有效。
<强>应用强> 将单个bean定义范围限定为ServletContext的生命周期。仅在Web感知Spring ApplicationContext的上下文中有效。
<强>的WebSocket 强> 将单个bean定义范围限定为WebSocket的生命周期。仅在Web感知Spring ApplicationContext的上下文中有效。
答案 3 :(得分:5)
Spring文档描述了following standard scopes:
singleton :(默认)将每个Spring IoC容器的单个bean定义范围限定为单个对象实例。
prototype :将单个bean定义范围限定为任意数量的对象实例。
request :将单个bean定义范围限定为单个HTTP请求的生命周期;也就是说,每个HTTP请求都有自己的bean实例,它是在单个bean定义的后面创建的。仅在Web感知Spring ApplicationContext的上下文中有效。
会话:将单个bean定义范围限定为HTTP会话的生命周期。仅在Web感知Spring ApplicationContext的上下文中有效。
全局会话:将单个bean定义范围限定为全局HTTP会话的生命周期。通常仅在portlet上下文中使用时有效。仅在Web感知Spring ApplicationContext的上下文中有效。
还可以使用CustomScopeConfigurer
创建和配置其他自定义范围。一个例子是Spring Webflow添加的flow
范围。
顺便说一句,你认为你总是使用prototype
我觉得奇怪的东西。标准范围是singleton
,在我开发的应用程序中,我很少需要原型范围。你应该看看这个。
答案 4 :(得分:5)
每个范围的详细说明可在Spring bean scopes中找到。以下是摘要
Singleton - (默认)将每个Spring IoC容器的单个bean定义范围限定为单个对象实例。
prototype - 将单个bean定义范围限定为任意数量的对象实例。
request - 将单个bean定义范围限定为单个HTTP请求的生命周期;也就是说,每个HTTP请求都有自己的bean实例,它是在单个bean定义的后面创建的。仅在Web感知Spring ApplicationContext的上下文中有效。
session - 将单个bean定义范围限定为HTTP会话的生命周期。仅在Web感知Spring ApplicationContext的上下文中有效。
全局会话 - 将单个bean定义范围限定为全局HTTP会话的生命周期。通常仅在portlet上下文中使用时有效。仅在Web感知Spring ApplicationContext的上下文中有效。
答案 5 :(得分:0)
关于原型豆:
客户端代码必须清理原型范围的对象并释放 原型bean持有的昂贵资源。得到的 Spring容器释放由原型范围的bean持有的资源, 尝试使用自定义bean后处理器,它包含一个引用 需要清理的豆子。
答案 6 :(得分:0)
根据Spring-Cloud-Config
的{{3}},在现有五个范围的旁边有一个额外的范围。是@RefreshScope
。
这是RefreshScope
的简短描述:
进行配置更改时,标记为 @RefreshScope得到特殊处理。此功能解决了 仅注入其配置的有状态bean问题 当它们初始化时。例如,如果数据源已打开 通过环境更改数据库URL时的连接,您 可能希望这些连接的持有人能够完成 他们在做什么。然后,下次有东西借用 从池中进行连接,它将获得一个带有新URL的地址。
有时,甚至可能必须应用@RefreshScope 某些bean上的注释只能被初始化一次。如果是豆 是“不可变的”,您将必须使用 @RefreshScope或在属性键下指定类名 spring.cloud.refresh.extra-refreshable。
刷新作用域bean是惰性代理,它们在初始化时会初始化 使用(即调用方法时),并且作用域充当缓存 初始化值。强制Bean在下一个重新初始化 方法调用,必须使它的缓存条目无效。
RefreshScope在上下文中是一个bean,并且具有公共 refreshAll()方法通过清除 目标缓存。 / refresh端点公开了此功能(通过 HTTP或JMX)。要通过名称刷新单个bean,还有一个 refresh(String)方法。
答案 7 :(得分:0)
一个简短的示例@Scope("singleton")
(默认)和@Scope("prototype")
之间有什么区别:
DAO类:
package com.example.demo;
public class Manager {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
配置:
@Configuration
public class AppConfiguration {
@Bean
@Scope("singleton")
public Manager getManager(){
return new Manager();
}
}
和MainApp:
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.scan("com.example.demo");
context.refresh();
Manager firstManager = context.getBean(Manager.class);
firstManager.setName("Karol");
Manager secondManager = context.getBean(Manager.class);
System.out.println(secondManager.getName());
}
}
在此示例中,即使我们仅为Karol
对象设置此名称,结果也将是:firstManager
。这是因为Spring IoC容器创建了一个对象实例。但是,当我们在Configuration类中将范围更改为@Scope("prototype")
时,结果为:null
,因为当请求该bean时,Spring IoC容器会创建该对象的新bean实例。
答案 8 :(得分:0)
还添加了websocket范围:
将单个bean定义的作用域限定为WebSocket的生命周期。仅在可感知网络的Spring ApplicationContext上下文中有效。
根据文档的内容,还有线程范围,默认情况下未注册。