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 id="loginController" class="com.example.LoginController" scope="request"/>
@Scope("request")
@Controller
public class LoginController{
private int flag = 0;
@RequestMapping("/login")
public int login(){
return flag++;
}
}
@RestController
@RequestScope
public class LoginController {
private int flag = 0;
@RequestMapping("/login")
public int login(){
return flag++;
}
}
对于每个http请求,Spring容器会创建一个 LoginController Bean 的新实例。也就是说,LoginController Bean 的作用域限于 HTTP 请求范围。 你可以在请求内随意修改这个Bean实例的状态,因为其他 LoginController Bean实例看不到这些变化,Bean实例是与特定的请求相关的。 当请求处理完毕,对应的Bean实例也就销毁(被回收)了。
session会话作用域
考虑如下的Bean定义:
<bean id="userController" class="com.example.UserController" scope="session"/>
@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++;
}
}
在每个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也被一起回收。