JavaEE进阶第四课:Bean 作用域和生命周期
创始人
2024-05-24 06:25:24
0

上篇文章介绍了Spring更简单的对象存储和取出,这篇文章我们将会介绍Bean 作用域和生命周期

目录

  • 1.作用域
    • 1.1引例
    • 1.2Bean的六种作用域
    • 1.3设置作用域
  • 2.生命周期
    • 2.1Spring 执行流程
    • 2.2Bean的生命周期
  • 结束语

1.作用域

1.1引例

首先这里的作用域和我们之前java学到变量的作用域可能有点不一样。我们之前学习的变量作用域指的是该变量的可使用范围,比如:

{{int a=0;}//2
}//1

a变量只在括号2中生效。但是Bean的作用域指的是:

  • Bean在Spring框架(项目)里面的某种行为模式

具体什么意思呢,我们先看例子:

有一个公共的Bean供A和B两个类使用,假设这个Bean里面有个属性为value=ikun,A第一次使用时拿到value=ikun,待B使用时他偷偷改成了value=只因,A下一次使用时就拿到了value=只因,但是预期value=ikun啊,从而导致了程序出现错误。
说好一起当ikun,你却偷偷开了团

用代码怎么演示呢?

@Controller
@Data
public class Ikun {private String name="ikun";
}@Controller
public class A {@Autowiredprivate Ikun ikun;public void show(){System.out.println(ikun.getName());//我是ikun}
}@Controller
public class B {@Autowiredprivate Ikun ikun;public void show(){ikun.setName("只因");//偷偷开团}
}public class App {public static void main(String[] args) {ApplicationContext context=new ClassPathXmlApplicationContext("spring-config.xml");A a=context.getBean("a",A.class);System.out.println("A第一次使用Ikun:");a.show();B b=context.getBean("b",B.class);System.out.println("B偷偷开团,修改Ikun");b.show();System.out.println("A第二次使用Ikun:");a.show();}
}

注意:这里使用了@Data注解,属于lombok插件,可以帮我们处理set,get等等方法,喜欢可以去了解以下

运行得到结果:
在这里插入图片描述
首先怎么处理这样的问题呢?我们需要先知道原因。
原因是Bean默认的作用域是单例状态,也就是所有类用的都是同一个对象。可能会有人问,为什么默认是单例模式呢?因为对于单例模式(以前学过懒汉,饿汉等等),我们知道可以提高代码的性能。那怎么修改Bean的模式呢?修改之前,我们要先知道有哪些模式。

1.2Bean的六种作用域

  1. singleton:单例作⽤域
  2. prototype:原型作⽤域(多例作⽤域)
  3. request:请求作⽤域
  4. session:回话作⽤域
  5. application:全局作⽤域
  6. websocket:HTTP WebSocket 作⽤域

后四种都属于SpringMVC里面的值,普通的Spring只有前两种,本文只说前两种。
第一种已经说明,着重解释第二种

prototype:原型作⽤域(多例作⽤域)
这个与单例作用域恰恰相反,每一次装配(即@AutoWired)都是新的对象实例,也就是一个类修改Bean不会影响另一个类的Bean。
那怎么修改上面例子的Bean为该模式呢?

1.3设置作用域

使用@Scope 标签就可以⽤来声明 Bean 的作⽤域
为Ikun类添加注解

//或者 @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Scope("prototype")
@Controller
@Data
public class Ikun {private String name="ikun";
}

得到结果:
在这里插入图片描述
很明显,开团失败了

小结:
@Scope 标签既可以修饰⽅法也可以修饰类(上面就是修饰类)
@Scope 有两种设置⽅式:

  1. 直接设置值:@Scope(“prototype”)//适合记得住单词
  2. 使⽤枚举设置:@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)//idea会有提示,更方便

2.生命周期

解释生命周期之前,必须要先了解Spring的执行流程

2.1Spring 执行流程

这个我JavaEE第二课就介绍过,这里我直接给出流程:

Bean 执行流程(Spring 执行流程):启动 Spring 容器 -> 实例化 Bean(读取配置文件,分配内存空间,初始化) -> Bean 注册到 Spring 中(存操作) -> 将 Bean 装配到需要的类中(取操作)

这里可能会出一道面试题:
在这里插入图片描述

2.2Bean的生命周期

生命周期指的是有个对象从诞生到销毁的整个生命过程,Bean的生命周期注意分为以下五部分:

  1. 实例化Bean(为Bean分配内存空间)ex:拿到毛坯房
  2. 设置属性(Bean注入和装配)ex:购买装修材料
  3. 进行初始化工作
    实现了各种 Aware 通知的方法,如 BeanNameAware、BeanFactoryAware、
    ApplicationContextAware 的接口方法;ex:通知装修工人
    执行 BeanPostProcessor 初始化前置方法;ex:工人制定装修方案
    执行 @PostConstruct 初始化方法,依赖注入操作之后被执行;
    执行自己指定的 init-method 方法(如果有指定的话);ex:开始装修
    执行 BeanPostProcessor 初始化后置方法;ex:处理装修后现场
  4. 使用Bean ex:住房
  5. 销毁Bean ex:拆迁,房子被击碎

个人而言,对于第二点设置属性(Bean注入和装配)如果有疑问的。看以下代码便知:

@Controller
public class B {@Autowired //这一步就是设置属性private Ikun ikun;public void show(){ikun.setName("只因");//偷偷开团}
}

看到这里我们可以思考一个问题:

上面五个部分中,2和3能不能颠倒顺序?
显然是不能的,因为可能第三步中会用到第二步的设置好的属性Bean,如果颠倒就会导致出现空指针异常,因为Bean还没有注入和装配。

结束语

那么今天的第四课就到这里,下节课会进入SpringBoot的学习,喜欢的话还请多多为我投票吧(doge)

在这里插入图片描述

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
【PdgCntEditor】解... 一、问题背景 大部分的图书对应的PDF,目录中的页码并非PDF中直接索引的页码...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
修复 爱普生 EPSON L4... L4151 L4153 L4156 L4158 L4163 L4165 L4166 L4168 L4...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...