Bean的作用域和声明周期
创始人
2024-01-21 09:31:47
0

Bean的作用域和声明周期

  • Bean的作用域
    • Bean作用域的定义
    • Bean作用域的分类
      • 【singleton 单例作用域】
      • 【prototype 多例作用域】
      • 【request请求作用域】
      • 【session会话作用域】
      • 【application全局作用域(了解)】
      • 【websocket HTTP WebSocket 作⽤域(了解)】
    • 如何设置Bean对象中的作用域
  • Spring的主要执行流程
  • Bean对象的生命周期
    • 生命周期代码演示

Bean的作用域

Bean作用域的定义

Bean 的作⽤域是指 Bean 在 Spring 整个框架中的某种⾏为模式,⽐如 singleton 单例作⽤域,就

表示 Bean 在整个 Spring 中只有⼀份,它是全局共享的,那么当其他⼈修改了这个值之后,那么另⼀个⼈读取到的就是被修改的值

Bean作用域的分类

  1. singleton:单例作⽤域

  2. prototype:原型作⽤域(多例作⽤域)

  3. request:请求作⽤域

  4. session:回话作⽤域

  5. application:全局作⽤域

  6. websocket:HTTP WebSocket 作⽤域

【singleton 单例作用域】

描述:该作⽤域下的Bean在***IoC容器***中只存在⼀个实例:获取Bean(即通过applicationContext.getBean等⽅法获取)及装配Bean(即通过@Autowired注⼊)都是同⼀个对象。

场景:通常⽆状态的Bean使⽤该作⽤域。⽆状态表示Bean对象的属性状态不需要更新

备注:Spring默认选择该作⽤域

【prototype 多例作用域】

描述:每次对该作⽤域下的Bean的请求都会创建新的实例:获取Bean(即通过applicationContext.getBean等⽅法获取)及装配Bean(即通过@Autowired注⼊)都是新的对象实例

场景:通常有状态的Bean使⽤该作⽤域。有状态表示Bean对象的属性需要更新

【request请求作用域】

描述:每次http请求会创建新的Bean实例,类似于prototype

场景:⼀次http的请求和响应的共享Bean

备注:限定SpringMVC中使⽤

【session会话作用域】

描述:在⼀个http session中,定义⼀个Bean实例

场景:⽤户回话的共享Bean, ⽐如:记录⼀个⽤户的登陆信息

备注:限定SpringMVC中使⽤

【application全局作用域(了解)】

描述:在⼀个http servlet Context中,定义⼀个Bean实例

场景:Web应⽤的上下⽂信息,⽐如:记录⼀个应⽤的共享信息

备注:限定SpringMVC中使⽤

【websocket HTTP WebSocket 作⽤域(了解)】

描述:在⼀个HTTP WebSocket的⽣命周期中,定义⼀个Bean实例

场景:WebSocket的每次会话中,保存了⼀个Map结构的头信息,将⽤来包裹客户端消息头。第⼀次初始化后,直到WebSocket结束都是同⼀个Bean
备注:限定Spring WebSocket中使用

如何设置Bean对象中的作用域

使⽤ @Scope 标签就可以⽤来声明 Bean 的作⽤域, @Scope 标签既可以修饰⽅法也可以修饰类,@Scope设置方法:

1.直接设置作用域的具体值,如:@Scope(“prototype”);

2.设置 ConfigurableBeanFactory 和 WebApplicationContext 提供的 SCOPE_XXX 变量,如 @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)。

注意:无论我们是使用类注解还是方法注解来将对象保存到Spring容器中,要改变该bean对象的作用域,只有在添加一个@Scope进行设置就行

使用方法注解:

@Component
public class UserBeans {@Scope("prototype")@Bean("userService_1")public UserService getUserService() {return new UserService();}
}

使用类注解:

@Controller
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class UserController {public void doUserController() {System.out.println("do UserController.");}
}

Spring的主要执行流程

  1. 启动容器

  2. Bean的初始化

  3. 将bean对象注册到Spring容器中(给bean对象开辟内存空间)

    配置文件中的bean、配置了加载文件路径的类的扫描(看看有没使用类注解或者方法注解)

  4. 将bean对象注册到Spring 容器中

  5. 装配bean对象的属性(对象注入)

  6. 使用bean对象

  7. Spring销毁

Bean对象的生命周期

所谓的生命周期就是,一个对象从创建到销毁的过程

Bean对象的生命周期分为5大部分:

  1. 实例化bean对象(不是初始化bean对象,就是给bean对象分配内存空间)

  2. 设置bean属性(对象注入)

  3. 初始化bean

    1. 执行各种通知,如 BeanNameAware、BeanFactoryAware、

      ApplicationContextAware 的接⼝⽅法;

    2. 初始化的前置方法(xml配置文件bean标签有init-method属性来设置前置方法,@PostConstruct注解也能解决这问题,只有在方法前加上这个注解就行)

    3. 初始化方法

    4. 初始化的后置方法

  4. 使用bean对象

  5. 销毁bean对象(xml配置文件bean标签里有destroy-method属性来指定bean对象在销毁时使用哪个方法,@PreDestroy注解也能解决这个问题,在哪个方法前加上这个就行了)

生命周期代码演示

@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class UserController implements BeanNameAware {@Autowiredpublic UserService userService;public UserController() {System.out.println("无参构造方法:UserController()");}public void init() {System.out.println("通过xml配置文件来设置前置方法:UserController.init()");}@PostConstructpublic void before() {System.out.println("通过注解来设置化前置⽅法:UserController.before()");}public void doUserController() {System.out.println("bean对象的使用");}@Overridepublic void setBeanName(String s) {System.out.println("Aware 通知:"+s);}@PreDestroypublic void destroy() {System.out.println("bean对象的销毁:UserController.destroy()");}
}
@Service
public class UserService implements BeanNameAware {public UserService() {System.out.println("无参构造方法:UserService()");}@PostConstructpublic void before() {System.out.println("通过注解来设置化前置⽅法:UserService.before()");}@PreDestroypublic void destroy() {System.out.println("bean对象的销毁:UserService.destroy()");}public void doUserService() {System.out.println("do UserService.");}@Overridepublic void setBeanName(String s) {System.out.println("Aware 通知:"+s);}
}

xml配置:




相关内容

热门资讯

前端-session、jwt 目录:   (1)session (2&#x...
linux入门---制作进度条 了解缓冲区 我们首先来看看下面的操作: 我们首先创建了一个文件并在这个文件里面添加了...
关于测试,我发现了哪些新大陆 关于测试 平常也只是听说过一些关于测试的术语,但并没有使用过测试工具。偶然看到编程老师...
前缀和与对数器与二分法 1. 前缀和 假设有一个数组,我们想大量频繁的去访问L到R这个区间的和,...
nodejs:本地安装nvm实... 一、背景-使用不同版本node的原因 vue3+ts、nuxt3版本,node...
JAVA集合知识整理 Java集合知识整理 HashMap相关 HashMap的底层数据结构:jdk1.8之...
无刷直流电机介绍及单片机控制实... 无刷直流电机介绍及单片机控制实例前言基本概念优势与劣势使用寿命基本结构使用单片机控制实例电子调速器&...
fwdiary(2) dp2 1.传纸条  AcWing 275. 传纸条 - AcWing 走两条路,走一条最大的...
常用的DOS命令 常用的DOS命令 DOS(Disk Operating System,磁...
<C++> 类和对象(下) 1.const成员函数将const修饰的“成员函数”称之为const成员函数,cons...