Bean的作用域和声明周期
Bean的六种作用域
也就是Bean实例在容器中存在的时间,
Spring中有六种作用域,其作用范围从小到大依次为:
- Singleton:单例模式,整个Bean容器中只有一个Bean实例。默认的Bean作用域就是SingleTon。
- prototype:多例模式,每次通过getBean()获取的都是一个全新的Bean。
- request:Web应用中,每个请求都会创建一个Request Bean,请求结束后,Request Bean就会被销毁。
- session:表示每个会话都会有一个Bean实例,会话结束后Bean实例销毁。
- global-session:在Web应用中,仅适合于Portal类型的Web应用,它表示全局会话,Bean的生命周期跟随全局会话的创建和销毁而创建和销毁。
- websocket:WebSocket类型的Web应用Bean实例的生命周期跟随WebSocket连接的创建和销毁。 注:singleton和prototype是 spring 核⼼作⽤域, 4 种是 spring mvc 中的作⽤域。
作用域 | 描述 |
---|---|
singleton | 单例作用域 (默认作用域),整个应用中只有一个Bean实例 |
prototype | 原型作用域(多例作用域),每次通过getBean()获取的都是一个全新的Bean |
request | 请求作用域,每个HTTP请求都会创建一个新的实例 |
session | 会话作用域,每个HTTP会话中只会创建一个实例,场景:⽤户回话的共享Bean, ⽐如:记录⼀个⽤户的登陆信息 |
application | 全局作用域,限定SpringMVC中使⽤ |
websocket | HTTP WebSocket作用域,每个WebSocket会话只会创建一个实例 |
单例作用域VS全局作用域
singleton 是 Spring Core 的作⽤域;application 是 Spring Web 中的作⽤域;
singleton 作⽤于 IoC 的容器,⽽ application 作⽤于 Servlet 容器。
设置作用域
在Spring的XML或JavaConfig中,可以通过注解@Scope来标记Bean的作用域类型。例如:
@Scope(value = "prototype")
public class MyBean {...}
或者使用ConfigurableBeanFactory的参数,例如:
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class MyBean {...}
Bean生命周期的各个阶段
- 实例化:使用构造器创建一个Bean实例,先实例化Bean的类,然后再注入Bean的依赖项。
- 属性赋值:在Bean的类上声明setter方法,并在Bean的配置文件中或其他地方定义Bean的属性的值。
- 初始化:在Bean所有属性被设置后,Spring会查找实现了BeanPostProcessor接口的类,然后执行其中的回调方法。执行完毕后,执行自定义的初始化方法,例如:@PostConstruct注解的方法或者默认指定的初始化方法。然后再次执行BeanPostProcessor回调方法。
- 使用:当Bean已经初始化完成后,可以被容器及其他Bean调用。
- 销毁:容器调用Bean的destroy方法销毁Bean实例,或者使用@PreDestroy注解指定的销毁方法。
巧记生命流程:
Bean的声明周期可以用生活上的例子来理解记忆
①实例化
(对应 JVM的“加载”
)【从无到有,将字节码转换成内存中的对象,只是分配了内存】 --》(买了一个毛坯房)
②设置属性
(Bean的注入和装配)–》购买装修材料(引入外部资源)③ 初始化
(房子装修)
a)各种通知 --》打电话给各个装修师傅施工
b)初始化的前置工作–》 师傅到达现场,先勘探环境,指定装修方案【前置工作】
c)进行初始化工作【使用注解@PostConstruct 初始化、使用(xml) init-method 初始化】–》两类师傅进行装修,技术好的,技术一般的
d) 初始化的后置工作 --》装修之后的清理工作
④使用Bean
--》可以入住
⑤销毁Bena
--》 卖掉这套房子