(四)Spring Bean 作用域

本文内容纲要:

- 1、Bean 的作用域

- 2.1、singleton

- 2.2、prototype

(四)Spring Bean 作用域

1、Bean 的作用域

当在 Spring 中定义一个 bean 时,你必须声明该 bean 的作用域的选项。例如,为了强制 Spring 在每次需要时都产生一个新的 bean 实例,你应该声明 bean 的作用域的属性为 prototype。同理,如果你想让 Spring 在每次需要时都返回同一个bean实例,你应该声明 bean 的作用域的属性为 singleton。

Spring 框架支持以下五个作用域,分别为 singleton、prototype、request、session 和 global session,5种作用域说明如下所示,

注意,如果你使用 web-aware ApplicationContext 时,其中三个是可用的。

作用域描述
singleton

在spring IoC容器仅存在一个Bean实例,Bean以单例方式存在,默认值

prototype每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()时,相当于执行newXxxBean()
request每次HTTP请求都会创建一个新的Bean,该作用域仅适用于WebApplicationContext环境
session同一个HTTP Session共享一个Bean,不同Session使用不同的Bean,仅适用于WebApplicationContext环境
global-session一般用于Portlet应用环境,该作用域仅适用于WebApplicationContext环境

application

同一个 Web 应用共享一个 Bean 实例,该作用域在当前 ServletContext 内有效。

类似于 singleton,不同的是,singleton 表示每个 IoC 容器中仅有一个 Bean 实例,而同一个 Web 应用中可能会有多个 IoC 容器,但一个 Web 应用只会有一个 ServletContext,也可以说 application 才是 Web 应用中货真价实的单例模式。 

注意: Spring 5 版本之前还支持 global Session,该值表示在一个全局的 HTTP Session 中,容器会返回该 Bean 的同一个实例。一般用于 Portlet 应用环境。Spring 5.2.0 版本中已经将该值移除了。

request、session、application 和 global Session 作用域只能在 Web 环境下使用,如果使用 ClassPathXmlApplicationContext 加载这些作用域中的任意一个的 Bean,就会抛出以下异常。

java.lang.IllegalStateException: No Scope registered for scope name 'xxx'

2、下面我们详细讲解常用的两个作用域:singleton 和 prototype。

2.1、singleton

singleton 是 Spring 容器默认的作用域。当 Bean 的作用域为 singleton 时,Spring 容器中只会存在一个共享的 Bean 实例。该 Bean 实例将存储在高速缓存中,并且所有对 Bean 的请求,只要 id 与该 Bean 定义相匹配,都会返回该缓存对象。

通常情况下,这种单例模式对于无会话状态的 Bean(如 DAO 层、Service 层)来说,是最理想的选择。

在 Spring 配置文件中,可以使用 元素的 scope 属性,将 Bean 的作用域定义成 singleton,其配置方式如下所示:

<bean id="..." class="..." scope="singleton"/>

下面举例说明 SpringBean 默认是单例的

HelloWorld 类代码如下:

public class HelloWorld {

private String message;

public void setMessage(String message) {

this.message = message;

}

public void getMessage() {

System.out.println("message : " + message);

}

}

MainApp 类如下:

public class MainApp {

public static void main(String[] args) {

ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");

HelloWorld objA = (HelloWorld) context.getBean("helloWorld");

objA.setMessage("对象A");

objA.getMessage();

HelloWorld objB = (HelloWorld) context.getBean("helloWorld");

objB.getMessage();

}

}

Beans.xml 文件内容如下:

<?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-3.0.xsd">

<bean id="helloWorld" class="com.dw.study.HelloWorld"/>

</beans>

运行结果如下:

message : 对象A

message : 对象A

从运行结果可以看出,两次输出内容相同,这说明 Spring 容器只创建了一个 HelloWorld 类的实例。 Spring 容器默认作用域是 singleton

2.2、prototype

对于 prototype 作用域的 Bean,Spring 容器会在每次请求该 Bean 时都创建一个新的 Bean 实例。

在 Spring 配置文件中,可以使用 元素的 scope 属性,将 Bean 的作用域定义成 prototype,其配置方式如下所示:

<bean id="..." class="..." scope="prototype"/>

修改上面例子的Beans.xml

<?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-3.0.xsd">

<bean id="helloWorld" class="com.dw.study.HelloWorld" scope="prototype"/>

</beans>

运行结果如下:

message : 对象A

message : null

从运行结果可以看出,两次输出的内容并不相同,这说明在 prototype 作用域下,Spring 容器创建了两个不同的 HelloWorld 实例。

本文内容总结:1、Bean 的作用域,2.1、singleton,2.2、prototype,

原文链接:https://www.cnblogs.com/dw3306/p/15068271.html

以上是 (四)Spring Bean 作用域 的全部内容, 来源链接: utcz.com/z/362429.html

回到顶部