上俩篇文章简单的介绍了存储Bean对象,此处将解答Bean对象的作用域与生命周期
限定程序中变量的可⽤范围叫做作⽤域,或者说在源代码中定义变量的某个区域就叫做作⽤域。
⽽ Bean 的作⽤域是指 Bean 在 Spring 整个框架中的某种⾏为模式,⽐如 singleton 单例作⽤域,就表示 Bean 在整个 Spring 中只有⼀份,它是全局共享的,那么当其他⼈修改了这个值之后,那么另⼀个⼈读取到的就是被修改的值
1.Bean对象的作用域
1.1理解作用域
我们将用以下代码来简单理解一下普通的Bean对象的作用域:
启动类启动~~
我们预期在B对象进行获取name属性的时候 还是原来的Mary,但是获取到的确实Lily,这就涉及到了Bean对象作用域的知识。
操作以上问题的原因是因为 Bean 默认情况下是单例状态(singleton),也就是所有⼈的使⽤的都是同⼀个对象,之前我们学单例模式的时候都知道,使⽤单例可以很⼤程度上提⾼性能,所以在 Spring 中Bean 的作⽤域默认也是 singleton 单例模式。
1.2 Spring Bean 作用域
1.(单例模式) singleton:单例作用域
这个和我们之前学过的单例模式是有相似之初的,就是说Spring为了性能考虑,将Bean对象设置成单例模式,要想获取Bean对象的时候,可以认为是从Spring复制一份,而这contoller类使用或者说是操纵Bean对象这个类使用的是是这个复制品而不是真正的Bean对象~~
官⽅说明:(Default) Scopes a single bean definition to a single object instance for each
Spring IoC container.
描述:该作⽤域下的Bean在IoC容器中只存在⼀个实例:获取Bean(即通过
applicationContext.getBean等⽅法获取)及装配Bean(即通过@Autowired注⼊)都是同⼀个对象。
场景:通常⽆状态的Bean使⽤该作⽤域。⽆状态表示Bean对象的属性状态不需要更新
备注:Spring默认选择该作⽤域
2.(原型模式)prototype:多例作用域
原本的形态就叫原型模式,也就是说在该作用域下Bean的每一此请求都是创建新的实例~~就不会出现一开始代码出现的情况咯。
官⽅说明:Scopes a single bean definition to any number of object instances.
描述:每次对该作⽤域下的Bean的请求都会创建新的实例:获取Bean(即通过
applicationContext.getBean等⽅法获取)及装配Bean(即通过@Autowired注⼊)都是新的对象实例。
场景:通常有状态的Bean使⽤该作⽤域
3. request:请求作⽤域
描述:每次http请求会创建新的Bean实例,类似于prototype(作用的对象不一样)
场景:⼀次http的请求和响应的共享Bean
备注:限定SpringMVC中使⽤
适用于Spring MVC/Spring Web
4. session:回话作⽤域
描述:在⼀个http session中,定义⼀个Bean实例(在一个session 共享一个Bean)
场景:⽤户回话的共享Bean, ⽐如:记录⼀个⽤户的登陆信息
备注:限定SpringMVC中使⽤
5. application:全局作⽤域
官⽅说明:Scopes a single bean definition to the lifecycle of a ServletContext. Only valid in
the context of a web-aware Spring ApplicationContext.
描述:在⼀个http servlet Context中,定义⼀个Bean实例
场景:Web应⽤的上下⽂信息,⽐如:记录⼀个应⽤的共享信息
备注:限定SpringMVC中使⽤
6. websocket:HTTP WebSocket 作⽤域
官⽅说明:Scopes a single bean definition to the lifecycle of a WebSocket. Only valid in the
context of a web-aware Spring ApplicationContext.
描述:在⼀个HTTP WebSocket的⽣命周期中,定义⼀个Bean实例
场景:WebSocket的每次会话中,保存了⼀个Map结构的头信息,将⽤来包裹客户端消息头。第⼀次初始化后,直到WebSocket结束都是同⼀个Bean。
备注:限定Spring WebSocket中使⽤
1.3 设置作用域
关于设置作用域如何设置也是非常简单的,利用这个注解的方式来实现具体有俩种方式:
@Scope 标签既可以修饰⽅法也可以修饰类,@Scope 有两种设置⽅式:
1. 直接设置值:@Scope("prototype")
2. 使⽤枚举设置:@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
我们就简单的用第一种方式来写一下代码:
2.Spring执行流程和Bean的生命周期
2.1Spring执行流程 
2.2 Bean的生命周期
1.实例化Bean对象 进行分配空间
2.设置属性 对Bean对象 进行注入和装配
3.初始化 (先进行设置属性是因为在初始化的时候可以会用到一些Bean对象的属性)就比如说:
3.1 执行各种通知
实现了各种 Aware 通知的⽅法,如 BeanNameAware、BeanFactoryAware、ApplicationContextAware 的接⼝⽅法;
3.2 执行 初始化前置方法
3.3执行初始化方法(设置了就执行,没有设置就不会有这一步)
1.@PostConstruct 注解的方式
2.xml的方式(init-method属性)
3.4 执行初始化后置方法
4.使用Bean
5.销毁Bean
用代码演示:
实现一个Bean类,该类包含了通知,注解构造,xml构造,普通方法,销毁方法,
package obj.com.bit.component;
import org.springframework.beans.factory.BeanNameAware;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
public class BeanComponent implements BeanNameAware {
@Override
public void setBeanName(String s) {
System.out.println("执行了通知");
System.out.println("BeanComponent Bean的名字是:"+s);
}
//这里的构造方法要与xml文件中保持一致
public void myInit(){
System.out.println("xml方式的初始化");
}
@PostConstruct
public void BeanComponent(){
System.out.println("注解方式的初始化");
}
public void sayHi(){
System.out.println("hi");
}
@PreDestroy
public void doPreDestroy(){
System.out.println("执行了销毁操作");
}
}