【Spring进阶系列丨第四篇】学习Spring中的Bean管理(基于xml配置)

前言

在之前的学习中我们知道,容器是一个空间的概念,一般理解为可盛放物体的地方。在Spring容器通常理解为BeanFactory或者ApplicationContext。我们知道spring的IOC容器能够帮我们创建对象,对象交给spring管理之后我们就不用手动去new对象。

那么Spring是如何管理Bean的呢?

在这里插入图片描述

文章目录

  • 前言
  • 一、概念
  • 二、创建Bean对象的三种方式
    • 2.1、使用默认构造函数创建方式
      • 2.1.1、定义Bean
      • 2.1.2、主配置文件中配置bean
      • 2.1.3、测试Bean
      • 2.1.4、注意点
    • 2.2、使用工厂中的实例方法创建方式
      • 2.2.1、定义工厂
      • 2.2.2、定义Bean
      • 2.2.3、主配置文件中配置Bean
      • 2.2.4、测试
    • 2.3、使用工厂中的静态方法创建方式
      • 2.3.1、定义工厂
      • 2.3.2、定义Bean
      • 2.3.3、主配置文件中配置Bean
      • 2.3.4、测试
  • 三、Bean对象的作用域
    • 3.1、说明
    • 3.2、作用域类型
    • 3.3、注意细节
    • 3.4、如何修改Bean的作用域
    • 3.5、测试
      • 3.5.1、测试singleton单例
      • 3.5.2、测试prototype多例
  • 四、Bean对象的生命周期
    • 4.1、单例对象
      • 4.1.1、说明
      • 4.1.2、测试
        • 4.1.2.1、定义Bean
        • 4.1.2.2、主配置文件中配置Bean
        • 4.1.2.3、测试
        • 4.1.2.4、测试结果
    • 4.2、多例对象
      • 4.2.1、说明
      • 4.2.2、测试
        • 4.2.2.1、定义Bean
        • 4.2.2.2、主配置文件中配置Bean
        • 4.2.2.3、测试1
        • 4.2.2.4、测试2
  • 五、总结

一、概念

简而言之,Spring bean是Spring框架在运行时管理的对象。Spring bean是任何Spring应用程序的基本构建块。你编写的大多数应用程序逻辑代码都将放在Spring bean中。

Spring bean的管理包括:

  • 创建一个对象
  • 提供依赖项(例如其他bean,配置属性)
  • 拦截对象方法调用以提供额外的框架功能
  • 销毁一个对象

Spring bean是框架的基本概念。作为Spring的用户,你应该对这个核心抽象有深刻的理解。


二、创建Bean对象的三种方式

2.1、使用默认构造函数创建方式

2.1.1、定义Bean

public class UserServiceImpl {
    
}

2.1.2、主配置文件中配置bean

<!-- 方式一:使用默认构造函数方式创建Bean   -->
<beans>
	<bean id="userService" class="cn.bdqn.UserServiceImpl"></bean>
</beans>

2.1.3、测试Bean

@Test
public void testUserService() throws Exception{
        // 1、读取主配置文件信息,获取核心容器对象
        ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");

        // 2、从容器中根据id获取对象(bean)
        UserServiceImpl userService = (UserServiceImpl) ac.getBean("userService");

        // 3、打印bean
        System.out.println(userService);
}

2.1.4、注意点

此种方式采用的就是通过默认构造函数的方式创建Bean,假设我们给UserServiceImpl添加了一个带参的构造方法,则运行会报错,原因在于当我们为某个类自定义构造方法的时候,Java编译器便不会为该类提供默认的不带参数的构造方法了。

2.2、使用工厂中的实例方法创建方式

2.2.1、定义工厂

// UserService的工厂,作用是创建UserServiceBean对象
public class UserServiceImplFactory {

    public UserServiceImpl createUserService(){
        return new UserServiceImpl();
    }
}

2.2.2、定义Bean

public class UserServiceImpl {
    
}

2.2.3、主配置文件中配置Bean

<beans>
  	<!-- 方式二:使用工厂中提供的实例方法创建Bean   -->
  
	<!-- 第一步:把该工厂定义出来   -->
    <bean id="userServiceFactory" class="cn.bdqn.UserServiceImplFactory"/>
    <!-- 第二步:定义Bean(通过userServiceFactory中提供的实例方法)-->
    <bean id="userService" factory-bean="userServiceFactory" 
 						   factory-method="createUserService"/>
</beans>

2.2.4、测试

@Test
public void testUserService() throws Exception{
        // 1、读取主配置文件信息,获取核心容器对象
        ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");

        // 2、从容器中根据id获取对象(bean)
        UserServiceImpl userService = (UserServiceImpl) ac.getBean("userService");

        // 3、打印bean
        System.out.println(userService);
}

2.3、使用工厂中的静态方法创建方式

2.3.1、定义工厂

// UserService的工厂,作用是创建UserServiceBean对象
public class UserServiceImplFactory {

    public static UserServiceImpl createUserService(){
        return new UserServiceImpl();
    }
}

2.3.2、定义Bean

public class UserServiceImpl {

}

2.3.3、主配置文件中配置Bean

<beans>
    <!-- 方式三:使用工厂中提供的静态方法创建Bean   -->

    <!-- 定义Bean(通过工厂类的静态方法创建)   -->
    <bean id="userService" class="cn.bdqn.UserServiceImplFactory" 
          				   factory-method="createUserService">
    </bean>
</beans>

2.3.4、测试

@Test
public void testUserService() throws Exception{
        // 1、读取主配置文件信息,获取核心容器对象
        ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");

        // 2、从容器中根据id获取对象(bean)
        UserServiceImpl userService = (UserServiceImpl) ac.getBean("userService");

        // 3、打印bean
        System.out.println(userService);
}

三、Bean对象的作用域

3.1、说明

​ Spring对Bean的默认的作用域(作用范围)是singleton【单例】

3.2、作用域类型

  • singleton:单例的(默认值),只会new一次。

  • prototype:多例的,用到一次就会new一次。

  • request:作用于web应用的请求范围,Spring创建这个类之后,将这个类存到request范围内。

  • session:应用于web项目的会话范围,Spring创建这个类之后,将这个类存到session范围内。

  • global-session:作用于集群环境的会话范围(全局会话范围),当不是集群环境时,它就是session。

3.3、注意细节

实际开发中用得最多的就是singletonprototype在整合struts2的时候使用prototype,在整合SpringMVC的时候使用singleton。

3.4、如何修改Bean的作用域

bean标签的scope属性,作用:指定bean的作用范围。

3.5、测试

3.5.1、测试singleton单例

public class UserServiceImpl {
    
}
<beans>
	<bean id="userService" class="cn.bdqn.UserServiceImpl" />
</beans>
@Test
public void testUserService() throws Exception{
        // 1、读取主配置文件信息,获取核心容器对象
        ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");

        // 2、从容器中根据id获取对象(bean)
        UserServiceImpl userService1 = (UserServiceImpl) ac.getBean("userService");
        UserServiceImpl userService2 = (UserServiceImpl) ac.getBean("userService");

        // 3、打印bean
        System.out.println(userService1 == userService2); // true
}

3.5.2、测试prototype多例

public class UserServiceImpl {
    
}
<bean id="userService" class="cn.bdqn.UserServiceImpl" scope="prototype"/>
 @Test
public void testUserService() throws Exception{
        // 1、读取主配置文件信息,获取核心容器对象
        ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");

        // 2、从容器中根据id获取对象(bean)
        UserServiceImpl userService1 = (UserServiceImpl) ac.getBean("userService");
        UserServiceImpl userService2 = (UserServiceImpl) ac.getBean("userService");

        // 3、打印bean
        System.out.println(userService1 == userService2); // false
}

四、Bean对象的生命周期

4.1、单例对象

4.1.1、说明

出生:当容器创建时对象出生
活着:只要容器还在,对象一直活着
死亡:容器销毁,对象消亡

4.1.2、测试

4.1.2.1、定义Bean
public class UserServiceImpl {
    
    public UserServiceImpl(){
        System.out.println("对象的构造方法执行了");
    }

    public void init(){
        System.out.println("对象初始化了");
    }
    
    public void destroy(){
        System.out.println("对象销毁了");        
    }
}
4.1.2.2、主配置文件中配置Bean
<beans>
	<bean id="userService" class="cn.bdqn.UserServiceImpl"
          scope="singleton" init-method="init" destroy-method="destroy"/>
</beans>
4.1.2.3、测试
@Test
public void testUserService() throws Exception{
    // 1、读取主配置文件信息,获取核心容器对象
    ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");

    ac.close();
}
// 结果:对于单例对象来说,只要容器创建了,那么对象就创建了。类似于立即加载。
4.1.2.4、测试结果

对象的构造方法执行了
对象初始化了
对象销毁了

总结:单例对象的生命周期和容器相同

4.2、多例对象

4.2.1、说明

出生:当我们使用对象时spring框架为我们创建
活着:对象只要是在使用过程中就一直活着。
死亡:当对象长时间不用,且没有别的对象引用时,由Java的垃圾回收器回收

4.2.2、测试

4.2.2.1、定义Bean
public class UserServiceImpl {
    
    public UserServiceImpl(){
        System.out.println("对象的构造方法执行了");
    }

    public void init(){
        System.out.println("对象初始化了");
    }
    
    public void destroy(){
        System.out.println("对象销毁了");        
    }
}
4.2.2.2、主配置文件中配置Bean
<beans>
	<bean id="userService" class="cn.bdqn.UserServiceImpl"
          scope="prototype" init-method="init" destroy-method="destroy"/>
</beans>
4.2.2.3、测试1
@Test
public void testUserService() throws Exception{
   	// 1、读取主配置文件信息,获取核心容器对象
    ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");

    ac.close();
}
// 结果:什么都不输出,说明容器启动的时候,对于多例对象来说并不会创建
4.2.2.4、测试2
@Test
public void testUserService() throws Exception{
   	// 1、读取主配置文件信息,获取核心容器对象
    ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");

    UserServiceImpl userService = (UserServiceImpl) ac.getBean("userService");
    System.out.println(userService);
        
    ac.close();
}
/**
	结果:
		对象的构造方法执行了
		对象初始化了
	说明:
		对于多例对象来说,只有等到真正使用到该对象的时候才会创建。类似于懒加载。
**/

对于多例的Bean,Spring框架是不负责管理的


五、总结

在这里插入图片描述


以上就是本篇文章的全部内容了,如果对你有帮助的话,可以点个免费的关注,如果能在下方三连一下就更好啦,你的支持就是我更新的动力!

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/183074.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

操作系统发展过程--单道批处理系统、多道批处理系统、分时系统、实时系统

一、单道批处理系统 计算机早期&#xff0c;为了能提高利用率&#xff0c;需要尽量保持系统的连续运行&#xff0c;即在处理完一个作业之后&#xff0c;紧接着处理下一个作业&#xff0c;以减少机器的空闲等待时间 1.单道批处理系统的处理过程 为了实现对作业的连续处理&…

EPT-Net:用于3D医学图像分割的边缘感知转换器

EPT-Net: Edge Perception Transformer for 3D Medical Image Segmentation EPT-Net&#xff1a;用于3D医学图像分割的边缘感知转换器背景贡献实验方法Dual Positional Transformer&#xff08;双位置Transformer&#xff09;Learnable Patch EmbeddingVoxel Spacial Positiona…

OpenCV实现图像噪声、去噪基本方法

一、噪声分类 1、高斯噪声 指服从高斯分布&#xff08;正态分布&#xff09;的一类噪声&#xff0c;其产生的主要原因是由于相机在拍摄时视场较暗且亮度不均匀造成的&#xff0c;同时相机长时间工作使得温度过高也会引起高斯噪声&#xff0c;另外电路元器件白身噪声和互相影响…

土地利用数据技术服务

一、背景介绍 土地是人类赖以生存与发展的重要资源和物质保障&#xff0c;在“人口&#xff0d;资源&#xff0d;环境&#xff0d;发展&#xff08;PRED&#xff09;”复合系统 中&#xff0c;土地资源处于基础地位。随着现代社会人口的不断增长以及工业化、城市化进程的加速&a…

nvm切换版本之后npm用不了

原因是 nvm只给你安了对应的node没给你安装对应的node版本的npm 解决办法如下 1找到你安装的node版本号 然后去官网下载对应的版本包 这个网址就是node官网的版本列表 Index of /download/release/ 2下载后解压 把根目录这俩复制到自己的nvm安装目录下 还有那个node_modul…

Vue学习之路------指令

Vue指令 vue会根据不同的指令&#xff0c;针对标签实现不同的功能 指令:带有v-前缀的特殊标签属性 1&#xff1a;v-html&#xff1a;指令 <div v-html"msg"></div> 2&#xff1a;v-show 作用&#xff1a;控制元素显示隐藏 语法&#xff1a;v-show&quo…

解决:javax.websocket.server.ServerContainer not available 报错问题

原因&#xff1a; 用于扫描带有 ServerEndpoint 的注解成为 websocket&#xff0c;该方法是 服务器端点出口&#xff0c;当进行 SpringBoot 单元测试时&#xff0c;并没有启动服务器&#xff0c;所以当加载到这个bean时会报错。 解决方法&#xff1a; 加上这个注解内容 Spr…

顺序表基本操作全面解析

文章目录 1.线性表2.顺序表分类2.1 静态顺序表2.2 动态顺序表 3. 顺序表各接口实现1. 定义结构体(Seqlist)2. 结构体初始化(SLInit)3.检查容量 (SLCheckCapacity)4.打印数据 (SLPrintf)5.插入操作5.1 从数据头部插入(SLPushFront)5.2 从数据尾部插入(SLPushBack)5.3 从任意下标…

ELK企业级日志分析平台——kibana数据可视化

部署 新建虚拟机server5&#xff0c;部署kibana [rootelk5 ~]# rpm -ivh kibana-7.6.1-x86_64.rpm [rootelk5 ~]# cd /etc/kibana/[rootelk5 kibana]# vim kibana.ymlserver.host: "0.0.0.0"elasticsearch.hosts: ["http://192.168.56.11:9200"]i18n.local…

项目管理套路:看这一篇绝对够用❤️

写论文必不可少的&#xff0c;就是创建代码并进行实验。好的项目管理可以让实验进行得更加顺利。本篇博客以一次项目实践为例&#xff0c;介绍项目管理的方法&#xff0c;以及可能遇到的问题&#xff0c;并提供一些可行的解决方案。 目录 项目管理工具开始第一步版本管理十分关…

ATFX汇市:11月美联储会议纪要提振美指,但中期跌势或将延续

ATFX汇市&#xff1a;11月21日公布的11月美联储利率决议会议纪要提到&#xff1a;过去一年通胀有所缓和&#xff0c;但目前通胀仍然高得令人无法接受&#xff0c;远高于委员会 2% 的长期目标&#xff1b;在消费者支出激增的推动下&#xff0c;第三季度实际 GDP 出人意料地强劲增…

【C++干货铺】适配器 | stack | queue

个人主页点击直达&#xff1a;小白不是程序媛 C系列学习专栏&#xff1a;C干货铺 代码仓库&#xff1a;Gitee 目录 stack的介绍和使用 stack的介绍 stack的使用 queue的介绍和使用 queue的介绍 queue的使用 容器适配器 什么是适配器 STL中stack和queue的底层结构 d…

Python 使用XlsxWriter操作Excel

在数据处理和报告生成的领域中&#xff0c;Excel 文件一直是广泛使用的标准格式。为了让 Python 开发者能够轻松创建和修改 Excel 文件&#xff0c;XlsxWriter 库应运而生。XlsxWriter 是一个功能强大的 Python 模块&#xff0c;专门用于生成 Microsoft Excel 2007及以上版本&a…

外部中断为什么会误触发?

今天在写外部中断的程序的时候&#xff0c;发现中断特别容易受到干扰&#xff0c;我把手放在对应的中断引脚上&#xff0c;中断就一直触发&#xff0c;没有停过。经过一天的学习&#xff0c;找到了几个解决方法&#xff0c;所以写了这篇笔记。如果你的中断也时不时会误触发&…

人工智能教程(一):基础知识

目录 前言 什么是人工智能&#xff1f; 教学环境搭建 向量和矩阵 前言 如果你是关注计算机领域最新趋势的学生或从业者&#xff0c;你应该听说过人工智能、数据科学、机器学习、深度学习等术语。作为人工智能系列文章的第一篇&#xff0c;本文将解释这些术语&#xff0c;并搭…

Spring事务的实现方式和实现原理;事务声明的方式,Spring的事务传播行为,spring事务的实现原理

Spring事务的实现方式和实现原理 Spring事务的本质其实就是数据库对事务的支持&#xff0c;没有数据库的事务支持&#xff0c;spring是无法提供事务功能的。真正的数据库层的事务提交和回滚是通过binlog或者redo log实现的。 什么是事务 数据库事务是指作为单个逻辑工作单元执…

Ubuntu安装CUDA驱动

Ubuntu安装CUDA驱动 前言官网安装确认安装版本安装CUDA Toolkit 前言 CUDA驱动一般指CUDA Toolkit&#xff0c;可通过Nvidia官网下载安装。本文介绍安装方法。 官网 CUDA Toolkit 最新版&#xff1a;CUDA Toolkit Downloads | NVIDIA Developer CUDA Toolkit 最新版文档&…

【【Linux系统下常用指令学习 之 二 】】

Linux系统下常用指令学习 之 二 文件查询和搜索 文件的查询和搜索也是最常用的操作&#xff0c;在嵌入式 Linux 开发中常常需要在 Linux 源码文件中查询某个文件是否存在&#xff0c;或者搜索哪些文件都调用了某个函数等等。 1、命令 find find 命令用于在目录结构中查找文件…

Dubbo3使用Zookeeper作为注册中心的方案讨论!详解DubboAdmin与PrettyZoo来监控服务的优劣!

文章目录 一&#xff1a;Dubbo注册中心的基本使用 二&#xff1a;Zookeeper注册中心的使用 1&#xff1a;依赖引入 2&#xff1a;实际开发 三&#xff1a;Zookeeper作为注册中心的使用展示 1&#xff1a;启动注册Zookeeper服务 2&#xff1a;引入注册中心 (一)&#xf…

Qt实现自定义IP地址输入控件(百分百还原Windows 10网络地址输入框)

在开发网络相关的程序时,我们经常需要输入IP地址,例如源地址和目标地址。Qt提供了一些基础的控件,如QLineEdit,但是它们并不能满足我们对IP地址输入的要求,例如限制输入的格式、自动跳转到下一个输入框、处理回车和退格键等。因此,我们需要自己编写一个自定义的IP地址输入…