小豆角

有人能解释一下 Spring bean 中的作用域是什么吗? 我一直使用的是“原型”,但是有没有其他参数可以代替它呢?

我所说的例子

<bean id="customerInfoController" class="com.action.Controller" scope="prototype">
<property name="accountDao" ref="accountDao"/>
<property name="utilityDao" ref="utilityDao"/>
<property name="account_usageDao" ref="account_usageDao"/>
</bean>
137827 次浏览

弹簧规格支持五种类型的 bean 作用域:

1. singleton (默认 *)

每个 Spring 将单个 bean 定义作用域设置为单个对象实例 物联网集装箱。

2. 原型

将单个 bean 定义的范围扩展到任意数量的对象实例。

3. 请求

将单个 bean 定义作用于单个 HTTP 的生命周期 也就是说,每个 HTTP 请求都有自己的 在单个 bean 定义的后面创建的 bean 的实例。 只有在支持 Web 的 SpringApplicationContext 上下文中才有效。

4. 会议

将单个 bean 定义作用于 HTTP 会话的生命周期。 只有在支持 Web 的 SpringApplicationContext 上下文中才有效。

5. 全球会议

将单个 bean 定义作用于全局 HTTP 的生命周期 通常只有在 Portlet 上下文中使用时才有效 在支持 Web 的 SpringApplicationContext 上下文中有效。

* default 意味着在 <bean />标记中没有显式提供作用域。 点击这里阅读更多相关 http://static.springsource.org/spring/docs/3.0.0.m3/reference/html/ch04s04.html

Spring 文档描述了 以下标准范围:

Singleton : (默认)将单个 bean 定义作用于每个 Spring IoC 容器的单个对象实例。

原型 : 将单个 bean 定义作用于任意数量的对象实例。

Request : 将单个 bean 定义作用于单个 HTTP 请求的生命周期; 也就是说,每个 HTTP 请求都有自己的 bean 实例,该实例是在单个 bean 定义的后面创建的。只有在支持 Web 的 SpringApplicationContext 上下文中才有效。

Session : 将单个 bean 定义作用于 HTTP 会话的生命周期。只有在支持 Web 的 SpringApplicationContext 上下文中才有效。

Global Session : 将单个 bean 定义作用于全局 HTTP 会话的生命周期。通常只有在 Portlet 上下文中使用时才有效。只有在支持 Web 的 SpringApplicationContext 上下文中才有效。

还可以使用 CustomScopeConfigurer创建和配置其他自定义作用域。例如,SpringWebflow 添加的 flow作用域。

顺便说一下,你认为你总是使用 prototype我觉得奇怪。标准范围是 singleton,在我开发的应用程序中,我很少需要原型范围。你应该看看这个。

每个范围的详细说明可以在 春豆显微镜中找到

单身人士 (默认值)将单个 bean 定义作用域设置为每个 Spring IoC 容器的单个对象实例。

Model -将单个 bean 定义作用于任意数量的对象实例。

Request -将单个 bean 定义作用于单个 HTTP 请求的生命周期; 也就是说,每个 HTTP 请求都有自己的 bean 实例,该实例是在单个 bean 定义的后面创建的。只有在支持 Web 的 SpringApplicationContext 上下文中才有效。

Session -将单个 bean 定义作用于 HTTP 会话的生命周期。只有在支持 Web 的 SpringApplicationContext 上下文中才有效。

Global Session -将单个 bean 定义作用于全局 HTTP 会话的生命周期。通常只有在 Portlet 上下文中使用时才有效。只有在支持 Web 的 SpringApplicationContext 上下文中才有效。

在 Spring 中,bean 范围用于决定哪种类型的 bean 实例应该从 Spring 容器返回给调用者。

支持5种类型的 bean 范围:

  1. Singleton: 每个 Spring IoC 容器返回一个 bean 实例。这个单一实例存储在这种单一 bean 的缓存中,所有后续的请求和对这个命名 bean 的引用都返回缓存的对象。 enter image description here

  2. Prototype : 每次被请求时,它都返回一个新的 bean 实例。它不存储任何类似单例的缓存版本。 enter image description here

  3. Request : 每个 HTTP 请求返回一个 bean 实例。

    enter image description here

  4. Session : 每个 HTTP 会话(用户级会话)返回一个 bean 实例。

  5. GlobalSession : 每个全局 HTTP 会话返回一个 bean 实例。它只在支持 Web 的 SpringApplicationContext (应用程序级会话)的上下文中有效。

在大多数情况下,您可能只处理 Spring 的核心作用域 -单身原型机,并且默认作用域是 单身

只是想更新一下,在 Spring 5中,如 Spring Docs中所提到的,Spring 支持6个作用域,其中4个作用域只有在使用 Web 感知的 ApplicationContext 时才可用。

Singleton (默认值)将单个 bean 定义作用于每个 Spring IoC 容器的单个对象实例。

原型机 将单个 bean 定义的范围扩展到任意数量的对象实例。

请求 将单个 bean 定义作用于单个 HTTP 请求的生命周期; 也就是说,每个 HTTP 请求都有自己的 bean 实例,该实例是在单个 bean 定义的后面创建的。只有在支持 Web 的 SpringApplicationContext 上下文中才有效。

会议 将单个 bean 定义作用于 HTTP 会话的生命周期。只有在支持 Web 的 SpringApplicationContext 上下文中才有效。

申请 将单个 bean 定义作用于 ServletContext 的生命周期。只有在支持 Web 的 SpringApplicationContext 上下文中才有效。

网络插座 将单个 bean 定义作用于 WebSocket 的生命周期。只有在支持 Web 的 SpringApplicationContext 上下文中才有效。

关于原型 bean:

客户机代码必须清理原型范围的对象并发布 原型 bean 持有的昂贵资源 Spring 容器释放由原型范围内的 bean 持有的资源, 尝试使用自定义 bean 后处理程序,该后处理程序保存对 需要清理的豆子。

档号: https://docs.spring.io/spring/docs/3.0.0.M3/reference/html/ch04s04.html#beans-factory-scopes-prototype

根据 Spring-Cloud-Config文件,在现有的五个范围之外还有一个额外的范围,那就是 @RefreshScope

以下是 RefreshScope的简短描述:

当配置发生更改时,标记为 @ RefreshScope 得到特殊处理 只注入配置的有状态 bean 的问题 例如,如果 DataSource 已打开 当通过环境更改数据库 URL 时,可以使用 可能希望这些连接的持有者能够完成 他们正在做什么。然后,下一次借用一个 连接,它将得到一个带有新 URL 的。

有时,甚至可能必须应用@RefreshScope 对某些只能初始化一次的 bean 进行注释 是“不可变的”,则必须使用 @ RefreshScope 或在属性键下指定类名 Spring.cloud 清爽,超级清爽。

刷新范围 bean 是当它们被初始化时的惰性代理 使用(即调用方法时) ,作用域充当缓存 要强制一个 bean 在下一个 方法调用时,必须使其缓存条目无效。

RefreshScope 是上下文中的一个 bean,具有一个 public 方法刷新作用域中的所有 bean,方法是清除 /刷新端点公开此功能(在 要按名称刷新单个 bean,还有一个 Refresh (String)方法。

一个简短的例子,@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());
}


}

在这个例子中,即使我们只为 firstManager对象设置这个名称,结果也是: Karol。这是因为 Spring IoC 容器创建了一个对象实例。但是,当我们在 Configuration 类中将作用域更改为 @Scope("prototype")时,结果是: null,因为 Spring IoC 容器在对该 bean 发出请求时创建了该对象的新 bean 实例。

还增加了 网络插座范围:

将单个 bean 定义作用于 WebSocket 的生命周期。只有在支持 Web 的 SpringApplicationContext 上下文中才有效。

根据文档的内容,还有一个线程范围,默认情况下没有注册。