文章目录
- 前言
- Bean的作用域概念
- Bean作用域类型
- 1. singleton:单例作⽤域
- 2. prototype:原型作⽤域(多例作⽤域)
- 3. request:请求作⽤域
- 4. session:回话作⽤域
- 5. application:全局作⽤域
- 6. websocket:HTTP WebSocket 作⽤域
- 总结
- 使用作用域
- Spring的执行流程
- Bean ⽣命周期
前言
上文讲了, Spring有关注解的一些处理方式, 那这篇博客将注重讲述 ,Spring中 , Bean对象的生命周期与作用域
Bean的作用域概念
首先, 要明白一个基础概念 ,单例模式
单例模式 :单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象
总结 : 单例模式可以理解为在整个程序运行期间,对这个类进行修改, 将会改变整体这个类的值, 以后访问这个类的值也变了.
而Bean对象在默认情况下就是单例模式 , 单例模式有个好处就是可以提高性能 ,所以在Spring中默认情况下就是单例模式!
Bean 的作⽤域是指 Bean 在 Spring 整个框架中的某种⾏为模式,⽐如 singleton 单例作⽤域,就表示 Bean 在整个 Spring 中只有⼀份,它是全局共享的,那么当其他⼈修改了这个值之后,那么另⼀个⼈读取到的就是被修改的值。
Bean作用域类型
Spring有 6 种作⽤域,最后四种是基于 Spring MVC ⽣效的:在普通的 Spring 项⽬中只有前两种
1. singleton:单例作⽤域
应用场景:Bean对象的属性状态不需要更新
注:Spring默认选择该作⽤域
作用: 该作⽤域下的Bean在IoC容器中只存在⼀个实例:获取Bean(即通过applicationContext.getBean等⽅法获取)及装配Bean(即通过@Autowired注⼊)都是同⼀个对
象
2. prototype:原型作⽤域(多例作⽤域)
使用场景 : 当Bean对象的属性状态需要更新时
作用 : 每次对该作用域下的Bean对象进行操作的时候 , 都会请求创建一个新的实例, 获取Bean(即通过applicationContext.getBean等⽅法获取)及装配Bean(即通过@Autowired注⼊)都是新的对象
实例
3. request:请求作⽤域
应用场景:⼀次http的请求和响应的共享Bean
描述:每次http请求会创建新的Bean实例,类似于prototype
注:限定SpringMVC中使⽤
4. session:回话作⽤域
场景:⽤户回话的共享Bean, ⽐如:记录⼀个⽤户的登陆信息
描述:在⼀个http session中,共享⼀个Bean实例
注:限定SpringMVC中使⽤
5. application:全局作⽤域
场景:Web应⽤的上下⽂信息,⽐如:记录⼀个应⽤的共享信息
描述:在⼀个http servlet Context中,定义⼀个Bean实例
注:限定SpringMVC中使⽤
6. websocket:HTTP WebSocket 作⽤域
场景:WebSocket的每次会话中,保存了⼀个Map结构的头信息,将⽤来包裹客户端消息头。第⼀
次初始化后,直到WebSocket结束都是同⼀个Bean。
描述:在⼀个HTTP WebSocket的⽣命周期中,定义⼀个Bean实例
注:限定Spring WebSocket中使⽤
总结
上面, 可以看到作用域的范围是越来越大的 ,而单例模式的作用域 看起来和全局作用域很像 ,那他俩的区别在哪里?
①singleton 是 Spring 的作⽤域;application 是 Spring Web 中的作⽤域;
②singleton 作⽤于 IoC 的容器,⽽ application 作⽤于 Servlet 容器。
使用作用域
使⽤ @Scope 标签就可以⽤来声明 Bean 的作⽤域,⽐如设置 Bean 的作⽤域,如下代码所示
@Scope 标签既可以修饰⽅法也可以修饰类,@Scope 有两种设置⽅式:
- 直接设置值:
@Scope(“prototype”)
- 使⽤枚举设置:
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component
public class Users {
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Bean(name = "u1")
public User user1() {
User user = new User();
user.setId(1);
user.setName("Java"); // 【重点:名称是 Java】
return user;
}
}
Spring的执行流程
① 启动容器 , 加载配置文件(类加载下面的XML文件)
②根据配置完成初始化
③ 扫描给定的包路径中的类(添加了五大类注解的)
④ 将扫描到的对象注入到容器中
⑤装配Bean的属性 - 通过@Autowired 与@Resource
Bean ⽣命周期
所谓的⽣命周期指的是⼀个对象从诞⽣到销毁的整个⽣命过程,我们把这个过程就叫做⼀个对象的⽣命周期
而Bean的生命周期 ,大体上可以分为这5个部分
1.实例化 Bean(为 Bean 分配内存空间)
2.设置属性(Bean 注⼊和装配 ,@Autowired等)
3.Bean 初始化(实现各种通知方法)
4.使⽤ Bean
5.销毁 Bean
这里简单说一下 实例化和初始化的区别
实例化 : 就是将一个对象创造出来 ,初始化就是给这个对象附上各种属性值
这里在说明一下 , 生命周期 2 ,3 步骤不能相换 , 原因是: 使用依赖注入是动态的 , 也就是说执行了步骤2 之后 ,在执行步骤3, 一定是可以避免空指针异常的 , 但是如果先执行步骤3的话,就很可能出现空指针异常, 因为属性你并没有给他赋值, 而是使用系统的默认值