当前位置: 首页 > news >正文

Spring Bean作用域与生命周期全解析

Bean 作用域

概念

我们在之前的 Ioc & DI 说过 spring  是如何管理我们的对象的

发现输出的 bean 对象地址值是一样的,说明每次从 Spring 容器中取出来的对象都是同一个

默认情况下,Spring容器中的bean都是单例的,这种行为模式,我们就称之为Bean的作用域

Bean 的作用域是指 Bean 在 Spring 框架中的某种行为模式

比如单例作用域:表示 Bean 在整个Spring中只有一份,它是全局共享的,当其他人修改了这个值之后,接下来读到的就都是被修改的值

我们发现 dog1 和 dog2 为同一个对象,dog2 拿到了 dog1 设置的值

那么能不能让他 bean 对象设置为非单例的

请看接下来所说的

Bean 的作用域

在 Spring 中支持 6 种作用域,后 4 种在 Spring Mvc 下才能生效

singleton: 单例作用域
prototype: 原型作用域( 每次使用该 bean 时会创建新的实例)
request: 请求作用域
session: 会话作用域
Application: 全局作用域
websocket: HTTP WebSocket 作用域

我们来简单进行测试一下

DogBeanConfig

DogController

我们来观察一下

单例作用域

多例作用域

每次获取的对象都不一样,但对于 Autowired注入的 ,因为注入的对象在 Spring 容器是,就已经注入了,所以多次请求都不会变化用域

请求作用域

在一次请求中他俩是同一个对象,但是再次发起一个请求的话,就会重新创建对象

会话作用域

同一个Session 多次请求获得到的对象都是同一个

当我们换了一个浏览器访问时,它会重新创建一个对象

Application 作用域

在一个应用中,多次访问都是同一个对象,不管是重新发起请求,还是换一个浏览器

Bean 的生命周期

生命周期指的是一个对象从诞生到销毁的整个生命过程,我们把这个过程就叫做一个对象的生命周期

Bean 生命周期分为 5 个部分

1.实例化(为 Bean 分配空间)

2.属性赋值(Bean 注入和装配)

3.初始化

        3.1  执行各种同时
        3.2  执行初始化方法
              xml 定义 init - method
              使用注解的方式 @PostConstruct
              执行初始化后置方法(BeanPostProcessor)

4.使用 Bean

5.销毁 Bean

这就像是往杯子倒水一样

1.买个杯子

2.可以对杯子进行染色等的一些属性操作

3. 可以往杯子里放东西了

4.接下来就是使用杯子了

5.用完杯子我可以把它扔了或者卖了

我们来看看源码

创建Bean的代码入口在 

AbstractAutowireCapableBeanFactory

我们找到 createBean

在这里创建 Bean,方法中包含了实例化,属性赋值,初始化过程

我们进去看看

doCreateBean

实例化 Bean

根据bean definition 完成 bean 属性赋值,然后执行 bean 初始化

这三个方法分别对应:
createBeanInstance  实例化
populateBean     属性赋值
initializeBean   初始化

Spring Boot 自动配置

Spring Boot 的自动配置就是当 Spring 容器启动后,一些配置类,bean 对象等就自动存入到 IoC 容器中,不需要我们手动去声明,从而简化了开发,省去了繁琐的配置操作

SpringBoot 自动配置,就是指 SpringBoot 是如何将依赖 jar 包中的配置类以及 Bean 加载到 Spring IoC 容器中的

Spring 加载 Bean

使用 Spring 管理第三方的 jar 包的配置

数据准备

创建项目 SpringAutoconfig,当前项目目录为 com.example.springautoconfig
模拟第三方代码文件在 com.example.autoconfig 目录下

第三方文件

获取 AutoConfig 这个 Bean

运行程序

它说没有  com.example.autoconfig.AutoConfig 这个类型的 Bean

原因分析

Spring 通过五大注解和@Bean 注解可以帮助我们把Bean加载到 SpringIoC 容器中,但是有一个前提就是 这些注解类需要和 SpringBoot 启动类在同一个目录下

当我们引入第三方的 Jar 包时,第三方的 Jar 代码目录肯定不在启动类的目录下,如何告诉 Spring 帮我们管理这些 Bean?

解决方案

我们需要指定 路径或者引入的文件,告诉Spring,让 Spring 进行扫描

常见的解决方案有两种:
1.@ComponentScan 组件扫描
2.@Import 导入

使用 @import 导入的类会被 Spring 加载到 IoC 容器中

@ComponentScan

Spring 和 SpringBoot 都没有采用这种方式,因为会比较繁琐

@Import
@Import 导入主要有两种方式:

1.导入类

2.导入 ImportSelector 接口实现类

很显然这跟上面那位都很繁琐,所以 SpringBoot 也没有采纳

导入 ImportSelector 接口实现类
ImportSelector 接口实现类

启动类:

运行程序:

问题:

他们都有一个明显的问题,就是使用者需要知道第三方依赖中有哪些 Bean 对象或 配置类,如果漏掉一些Bean的话,就完了

这对我们很不友好

依赖中有哪些 Bean,使用是需要配置哪些 Bean,第三方依赖最清楚,我们是否可以把这件事交给第三方依赖呢?

一般就是第三方依赖给我们提供一个注解,这个注解一般都以 @Enablexxx 开头的,注解中封装的就是 @Import 注解

第三方依赖提供注解

在启动类上使用第三方提供的注解

SpringBoot 源码分析

源码阅读

SpringBoot 如何帮我们做的,都要先从 SpringBoot 启动类开始

@SpringBootApplication 是 SpringBoot 实现自动配置的核心

它是一个组合注解,包含了
1.元注解
元注解名称作用说明
@Target描述注解的使用范围
@Retention描述注解保留的时间范围
@Documented描述在使用 javadoc 工具为类生成帮助文档时是否要保留其注解信息
@Inherited使被它修饰的注解具有继承性

这四个是 JDK 提供的标准元注解,用于对 “注解类型” 本身进行注解,从而定义自定义注解的行为规则(如作用范围、保留时机、文档生成、继承性等)。

2.@SpringBootConfiguration
内容要点说明
@Configuration标注当前类为配置类,是对底层机制的封装重命名
@Indexed用于加速应用启动
3.@EnableAutoConfiguration(开启自动配置)

Spring 自动配置的核心注解

4.@ComponetScan(包扫描)

可以用 basePackageClasses / basePackages 来定义要扫描的特定包

basePackageClasses / basePackages用于定义要扫描的特定包;若未定义,将从声明该注解的类的包开始扫描,这也是 Spring Boot 项目注解类需在启动类目录下的原因
excludeFilters自定义过滤器,通常用于排除一些类、注解等

@EnableAutoConfiguration

这个注解包含两个部分:

@Import(AutoConfigurationImportSelector.class)

使用 @Import 注解,导入实现 ImportSelector 接口的实现类

selectImport()方法底层调用  getAutoConfigurationEntry()方法,获取可自动配置的配置类信息集合

getAutoConfigurationEntry()方法通过调用 getCandidateConfigurations(annotationMetadata, attributes) 方法获取在配置文件中配置的所有自动配置类的集合

@AutoConfigurationPackage

这个注解主要是导入一个配置文件 AutoConfigurationPackages.Registrar.class

 Registrar 实现了 ImportBeanDefinitionRegistrar 类,可被 @Import 注解导入到 Spring 容器里。

(String[])(new PackageImports(metadata)).getPackageNames().toArray(new String[0]) 表示当前启动类所在的包名。

@AutoConfigurationPackage 的作用是将启动类所在包下的所有组件扫描并注册到 Spring 容器中。

http://www.dtcms.com/a/550980.html

相关文章:

  • 选择邯郸网站制作南昌网站建设策划
  • 邢台市政建设集团网站上传照片的网站赚钱
  • 扩展阅读:数据标注的两种类型 - 矩形框标注 和 关键点标注
  • 小杰-大模型(one)——大模型的概念与历程。
  • 为什么用开源建站第三方商城网站开发
  • 政务移动门户网站建设方案php开源cms
  • 重庆建设教育网站昭通网站建设
  • 企业申请网站建设请示3秒钟自动跳转网页
  • 加强网站建设的措施网站营销推广应该怎么做
  • 做网站看网页效果999网站免费
  • TypeScript 中的 args 详解,和 arguments 有什么不同?
  • 鞍山网站设计公司免费刷推广链接的软件
  • 做网站用什么语言简单制作动画的网站
  • 三坐标同轴度测量方法
  • 汕头多语种网站制作俄罗斯做牙网站
  • 仿织梦小说网站源码浙江网
  • 做教程网站如何查用户搜索深圳福田区十强企业
  • 二叉搜索树学习笔记
  • 建设部安全员证书查询网站妇科在线医生免费咨询
  • 网站建设zrhskjseo如何优化排名
  • 河北建设执业资格注册中心网站中国十大杰出建筑师
  • 【Rust编程】ORM框架Diesel
  • 呢图网站场建设封面桔子摄影
  • 设计网站大全湖南岚鸿网站大全网站大事记时间轴折叠
  • Redis的内存淘汰策略
  • 网站 制作 工具个人网站 备案 类型
  • 网站建设公司排名打不开wordpress网址
  • 装修公司免费网站模版吴江建设工程招标中心网站
  • 影石开奖,有点香
  • 苏宁推客如何做网站东莞互联网营销网站建设