Spring Bean Scope

1,230 阅读2分钟

ScopeSpring Bean 的作用域, 在创建 Bean 的时候可以带上 Scope 属性来声明该 Bean 的作用域

Scope 的类型

Spring 最初提供了两种 Scope

  • singleton
  • prototype

但发布 2.0 以后,又引入了另外三种 Scope

  • request
  • session
  • global session

这三种只能在 web 应用中才可以使用

image.png

singleton

singletonSpring Bean 默认的 Scope!表示同一个Bean ,Spring IoC 容器只会创建一个实例,并且会将该实例在 Spring IoC 容器中缓存起来,之后需要时,不再创建,直接在 IoC 容器中获取。

singleton 作用域下,所有依赖这个对象的 Bean 都共享该实例,这也就是设计模式中单例模式的形式。

使用场景:无状态的 Spring Bean 都建议使用singleton 作用域

prototype

每次获取 Bean 的时候,都创建新的实例

用场景:有状态的 Spring Bean 才会考虑使用 prototype 作用域

request

每个 http 请求都会创建有各自的 bean 实例,也就是说每个 request 作用域内同一个bean 只会创建一个实例

session

在一个 http session 中,一个 bean 对应一个实例,也就是说每个 session 作用域内同一个bean 只创建一个实例

global session

在一个全局的 http session 中,一个 bean 对应一个实例

但是,global session 只在 portletweb 应用程序中才有意义,它映射到 portletglobal 范围的 session,如果普通的 web 应用使用了这个 scope,容器会把它当做普通的 session 作用域

使用方法

在上面这些 Scope 中,最常用的就只有 singletonprototype,而 singleton 又是 Scope 的默认值,所以,这里只说一下如何指定一个 prototype 作用域的 Bean

例如,设置 BService 依赖的作用域为 prototype

@Controller
public class AController {

    private BService b;

    @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    @Resource
    public void setB(BService b) {
        this.b = b;
    }
}

@Scope 注解只能作用在非构造方法上和类上

实例化时机

singleton 作用域的 Bean,会在容器启动后进行实例化,也可以通过 @Lazy 注解推迟到使用时才进行实例化

singleton 作用域的 Bean 会等到 Bean 被使用时才进行实例化