Spring Bean 的作用域

在面向对象程序设计中作用域一般指对象或变量之间的可见范围,而在Spring容器中是指其创建的Bean对象相对于其他Bean对象的请求可见范围。

在Spring容器当中,一共提供了5种作用域类型,在配置文件中,通过属性scope来设置bean的作用域范围。在Spring 2.0中,Spring的Bean作用域是可以扩展的,你可以定义自己的作用域,也可以重定义现有的作用域(但不建议这样做,因为不能覆盖内置的singleton和prototype作用域)

  1. 实现自定义Scope类:
1
org.springframework.beans.factory.config.Scope
  1. 注册自定义Scope类:
1
ConfigurableBeanFactory.registerScope(String scopeName, Scope scope)
  1. 使用自定义的Scope:
1
2
3
Scope customScope = new ThreadScope();
beanFactory.registerScope(“thread”, customeScope);
<bean id=“***” class=“***” scope=“scopeName” />

当然,这些你可以用不到,因为一般用内置的就可以了。

作用域 描述
singleton 该作用域将 bean 的定义的限制在每一个 Spring IoC 容器中的一个单一实例(默认)。
prototype 该作用域将单一 bean 的定义限制在任意数量的对象实例。
ike 该作用域将 bean 的定义限制为 HTTP 请求。只在 web-aware Spring ApplicationContext 的上下文中有效。
request 该作用域将 bean 的定义限制为 HTTP 请求。只在 web-aware Spring ApplicationContext 的上下文中有效。
session 该作用域将 bean 的定义限制为 HTTP 会话。 只在web-aware Spring ApplicationContext的上下文中有效。
global-session 该作用域将 bean 的定义限制为全局 HTTP 会话。只在 web-aware Spring ApplicationContext 的上下文中有效。

下面创建一个实例,详细介绍前二个范围。
分别创建Boss类和Car类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package me.ipz.spring.chapter02;

public class Boss {
private String name;
private Car car;
public Boss() {
}
public Car getCar() {
return car;
}
public void setCar(Car car) {
this.car = car;
}
@Override
public String toString() {
return "Boss [name=" + name + ", car=" + car + "]";
}


}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package me.ipz.spring.chapter02;

public class Car {
private String color;
private String brand;
private double price;

public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}


}

Main主方法依旧类似

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package me.ipz.spring.chapter02;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

public static void main(String[] args) {
BeanFactory beanFactory = new ClassPathXmlApplicationContext("conf-scope.xml");
Boss boss1 = beanFactory.getBean("Boss1",Boss.class);
Boss boss2 = beanFactory.getBean("Boss2",Boss.class);
Boss boss3 = beanFactory.getBean("Boss2",Boss.class);
System.out.println(boss1.getCar());
System.out.println(boss2.getCar());
System.out.println(boss3.getCar());

}

}

再创建一个conf-scope.xml配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">

<bean id="car" class="me.ipz.spring.chapter02.Car" scope="singleton" />
<bean id="Boss1" class="me.ipz.spring.chapter02.Boss" p:car-ref="car" />
<bean id="Boss2" class="me.ipz.spring.chapter02.Boss" p:car-ref="car" />
<bean id="Boss3" class="me.ipz.spring.chapter02.Boss" p:car-ref="car" />

</beans>

注意,这里需要使用命名空间p,在配置文件添加这一行就可以了

1
xmlns:p="http://www.springframework.org/schema/p"

如配置文件所示,singleton作用域是指Spring loC容器中仅存在一个Bean的示例,Bean以单示例的方式存在。单实例是重要的设计模式之一,在Spring中实现了超越,可以对那些非线程安全的对象采取单实例模式。
在默认的情况下Spring的ApplicationContext容器在启动的时候,自动实例化所有的singleton的bean并缓存于容器当中。
所以Boss1/2/3都指向了同一个Bean

而prototype作用域是指每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()时,相当于执行new Bean()操作。
在默认情况下,Spring容器在启动时不实例化prototype的Bean。
剩下的三个作用域简单介绍一下
request作用域:每次请求需要容器创建一个全新的Bean,在请求处理完成之后还要销毁释放这些数据Bean

session作用域:表示每个会话请求都需要容器创建一个全新的Bean,Session(会话)结束后就销毁这个Bean

globalSession作用域:和session作用域类似,只用于portlet环境的Web应用。如果非protlet环境将视为session作用域

Portlet规范定义了全局session的概念。请求的bean被组成所有portlet的自portlet所共享。
如果不是在portlet这种应用下,globalSession则等价于session作用域

广而告之,不为钱财,只是好看。


0%