Spring Bean 作用域
定义 <bean> 时,可以选择声明该 bean 的作用域。 例如,要强制 Spring 在每次需要时生成一个新的 bean 实例,应该将 bean 的 scope 属性声明为 prototype。 类似地,如果希望 Spring 在每次需要时返回相同的 bean 实例,应该将 bean 的 scope 属性声明为 singleton。
Spring Framework 支持以下五个作用域,如果你使用 web-aware ApplicationContext 时,其中三个是可用的。
序号 | 作用域 | 描述 |
---|---|---|
1 | singleton | 在spring IoC容器仅存在一个Bean实例,Bean以单例方式存在(默认值) |
2 | prototype | 每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()时,相当于执行newXxxBean() |
3 | request | 每次HTTP请求都会创建一个新的Bean,该作用域仅适用于WebApplicationContext环境 |
4 | session | 同一个HTTP Session共享一个Bean,不同Session使用不同的Bean,仅适用于WebApplicationContext环境 |
5 | global-session | 一般用于Portlet应用环境,该作用域仅适用于WebApplicationContext环境 |
在本章中,我们将讨论前两个作用域,其余三个将在讨论 web-aware ApplicationContext 时讨论。
singleton 作用域
singleton 是默认的作用域,也就是说,当定义 Bean 时,如果没有指定作用域配置项,则 Bean 的作用域被默认为 singleton。
当一个bean的作用域为 Singleton,那么 Spring IoC 容器中只会存在一个共享的 bean 实例,并且所有对 bean 的请求,只要 id 与该 bean 定义相匹配,则只会返回 bean 的同一实例。
也就是说,当将一个 bean 定义设置为 singleton 作用域的时候,Spring IoC 容器只会创建该 bean 定义的唯一实例。
Singleton 是单例类型,就是在创建起容器时就同时自动创建了一个 bean 的对象,不管你是否使用,他都存在了,每次获取到的对象都是同一个对象。注意,Singleton 作用域是 Spring 中的缺省作用域。你可以在 bean 的配置文件中设置作用域的属性为 singleton,如下所示:
<!-- A bean definition with singleton scope -->
<bean id = "..." class = "..." scope = "singleton">
<!-- collaborators and configuration for this bean go here -->
</bean>
示例
假设我们已经安装 IDEA,按照下面的步骤,我们可以创建一个 Spring 应用程序。
步骤 | 描述 |
---|---|
1 | 创建一个名为 SpringExample 的工程并在 src 文件夹下新建一个名为 com.jiyik 文件夹。 |
2 | 在 com.jiyik 文件夹下创建 HelloWorld.java 和 MainApp.java 两个类文件。 |
3 | 在 src 文件夹下创建 Bean 的配置文件 Beans.xml |
4 | 最后的步骤是创建所有 Java 文件和 Bean 的配置文件的内容,按照如下所示步骤运行应用程序。 |
下面是文件 HelloWorld.java 的内容:
HelloWorld.java
package com.jiyik; public class HelloWorld { private String message; public void setMessage(String message){ this.message = message; } public void getMessage(){ System.out.println("Your Message : " + message); } }
下面是文件 MainApp.java 的内容:
MainApp.java
package com.jiyik; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MainApp { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml"); HelloWorld objA = (HelloWorld) context.getBean("helloWorld"); objA.setMessage("I'm object A"); objA.getMessage(); HelloWorld objB = (HelloWorld) context.getBean("helloWorld"); objB.getMessage(); } }
以下是 singleton 作用域所需的配置文件 Beans.xml
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.jiyik.HelloWorld" scope = "singleton"> </bean> </beans>
创建完源和 bean 配置文件后,让我们运行应用程序。 如果您的应用程序一切正常,它将打印以下消息
Your Message : I'm object A
Your Message : I'm object A
prototype 作用域
如果作用域设置为 prototype,则每次对特定 bean 发出请求时,Spring IoC 容器都会创建对象的新 bean 实例。 通常,对所有状态完整的 bean 使用 prototype 作用域,对无状态 bean 使用 singleton 作用域。
要定义 prototype 作用域,可以在 bean 配置文件中将作用域属性设置为 prototype,如下代码片段所示
<!-- A bean definition with prototype scope -->
<bean id = "..." class = "..." scope = "prototype">
<!-- collaborators and configuration for this bean go here -->
</bean>
示例
假设我们已经安装 IDEA,按照下面的步骤,我们可以创建一个 Spring 应用程序。
步骤 | 描述 |
---|---|
1 | 创建一个名为 SpringExample 的工程并在 src 文件夹下新建一个名为 com.jiyik 文件夹。 |
2 | 在 com.jiyik 文件夹下创建 HelloWorld.java 和 MainApp.java 两个类文件。 |
3 | 在 src 文件夹下创建 Bean 的配置文件 Beans.xml |
4 | 最后的步骤是创建所有 Java 文件和 Bean 的配置文件的内容,按照如下所示步骤运行应用程序。 |
下面是文件 HelloWorld.java 的内容:
HelloWorld.java
package com.jiyik; public class HelloWorld { private String message; public void setMessage(String message){ this.message = message; } public void getMessage(){ System.out.println("Your Message : " + message); } }
下面是文件 MainApp.java 的内容:
MainApp.java
package com.jiyik; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MainApp { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml"); HelloWorld objA = (HelloWorld) context.getBean("helloWorld"); objA.setMessage("I'm object A"); objA.getMessage(); HelloWorld objB = (HelloWorld) context.getBean("helloWorld"); objB.getMessage(); } }
以下是 prototype 作用域所需的配置文件 Beans.xml
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.jiyik.HelloWorld" scope = "prototype"> </bean> </beans>
创建完源和 bean 配置文件后,让我们运行应用程序。 如果您的应用程序一切正常,它将打印以下消息
Your Message : I'm object A
Your Message : null