Spring Bean的五个作用域

时间:2021-06-02 01:02:12


 Spring支持五个作用域:singleton、prototype、request、session、global session

1.singleton:默认作用域Spring IOC容器仅存在一个Bean实例,Bean以​​单例​​方式存在,在创建容器时就同时自动创建了一个Bean对象。作用域范围是ApplicationContext中。

2.prototype:每次从容器中调用Bean时,都会返回一个新的实例,即每次调用getBean时。作用域返回是getBean方法调用直至方法结束。

相当于执行newXxxBean().Prototype是原型类型,再我们创建容器的时候并没有实例化,而是当我们获取Bean的时候才会去创建一个对象,而且我们每次获取到的对象都不是同一个对象。

3.request:每次HTTP请求都会创建一个新的Bean,作用域范围是每次发起http请求直至拿到相应结果。该作用域仅适用于WebApplicationContext环境。

4.session:首次http请求创建一个实例,作用域是浏览器首次访问直至浏览器关闭。

同一个HTTP ​​Session共享​​一个Bean,不同Session使用不通的Bean,仅适用于WebApplicationContext环境。

5.global-session:作用域范围是WebApplicationContext中。一般用于Portlet应用环境,该运用域仅适用于WebApplicationContext环境。

 

作用域范围比较:

prototype < request < session < global-session < singleton

为什么要定义作用域:

可以通过Spring配置的方式限定Spring Bean的作用范围,可以起到对Bean使用安全的保护作用

 

request请求作用域
考虑如下的bean定义:

<bean  class="com.example.LoginController" scope="request"/>

Spring Bean的五个作用域

Spring Bean的五个作用域

@Scope("request")
@Controller
public class LoginController{
private int flag = 0;

@RequestMapping("/login")
public int login(){
return flag++;
}
}

Spring Bean的五个作用域

@RestController
@RequestScope
public class LoginController {

private int flag = 0;

@RequestMapping("/login")
public int login(){
return flag++;
}
}

Spring Bean的五个作用域

Spring Bean的五个作用域

 

对于每个http请求,Spring容器会创建一个 LoginController Bean 的新实例。也就是说,LoginController Bean 的作用域限于 HTTP 请求范围。 你可以在请求内随意修改这个Bean实例的状态,因为其他 LoginController Bean实例看不到这些变化,Bean实例是与特定的请求相关的。 当请求处理完毕,对应的Bean实例也就销毁(被回收)了。

 

session会话作用域
考虑如下的Bean定义:

<bean  class="com.example.UserController" scope="session"/>

Spring Bean的五个作用域

 

@RestController
@Scope("session")
public class UserController {
private int flag = 0;

@RequestMapping("/getUser")
public int getUser(){
return flag++;
}

}

 

@RestController
@SessionScope
public class UserController {
private int flag = 0;

@RequestMapping("/getUser")
public int getUser(){
return flag++;
}

}

Spring Bean的五个作用域

Spring Bean的五个作用域

 

在每个HTTP Session的生命周期内,Spring容器会根据id为 UserController 的Bean定义创建一个 UserController Bean的新实例。 也就是说,UserController Bean的作用域限于 HTTP Session范围。和请求作用域 request-scoped Bean 类似, 因为每个会话域 session-scoped Bean的范围限于特定的 HTTP Session 内部,所以一个 Session 内的 UserController Bean也是可以被随意修改, 而不会影响到其他 Session 中的 UserController Bean。当一个HTTP Session 最终用完被JVM回收时,相关的会话域 session-scoped Bean也被一起回收。