Spring:IOC技术、Bean、DI
前言
Spring是一个开源的项目,并不是单单的一个技术,发展至今已形成一种开发生态圈。也就是说我们可以完全使用Spring技术完成整个项目的构建、设计与开发。Spring是一个基于IOC和AOP的架构多层j2ee系统的架构。
SpringFramework:Spring框架,是Spring中最早最核心的技术,也是所有其他技术的基础。
Spring系统架构图
核心层:
-
Core Container:核心容器,这个模块是Spring最核心的模块,其他的都需要依赖该模块
AOP层:
-
AOP:面向切面编程,它依赖核心层容器,目的是->在不改变原有代码的前提下对其进行功能增强
-
Aspects:AOP是思想,Aspects是对AOP思想的具体实现
数据层:
-
Data Access:数据访问,Spring全家桶中有对数据访问的具体实现技术
-
Data Integration:数据集成,Spring支持整合其他的数据层解决方案,比如Mybatis
-
Transactions:事务,Spring中事务管理是Spring AOP的一个具体实现
Web层:
- SpringMVC
Test层:
-
Spring主要整合了Junit来完成单元测试和集成测试
1.IOC
①Inversion of Control:控制反转
- 在使用对象时,由主动new产生对象转换为由“外部”提供对象,此过程中对象创建控制权由程序转为外部,此思想就是控制反转
②Spring和IOC之间的关系
- Spring技术对IOC思想进行了实现
- Spring提供了一个容器-->>“IOC容器”,用来充当IOC思想中的“外部”
- Spring容器中放的就是一个个的Bean对象
③IOC容器的作用以及内部存放的是什么
-
IOC容器负责对象的创建、初始化等一系列工作,其中包含了数据层和业务层的类对象
-
被创建或被管理的对象在IOC容器中统称为“Bean”
-
IOC容器中放的就是一个个的Bean对象
④将IOC中的对象相互绑定-->>DI
- DI(Dependency Injection)依赖注入
- 依赖注入:在容器中建立bean与备案、之间的依赖关系的整个过程
1.1IOC入门案例
①Spring使用容器管理bean,bean又是一个个对象,所以Spring管理的其实就是项目中所使用到的类对象(比如:Service、Dao);
创建BookService,BookServiceImpl,BookDao和BookDaoImpl四个类
public interface BookDao {public void save(); } public class BookDaoImpl implements BookDao {public void save() {System.out.println("book dao save ...");} } public interface BookService {public void save(); } public class BookServiceImpl implements BookService {private BookDao bookDao = new BookDaoImpl();public void save() {System.out.println("book service save ...");bookDao.save();} }
②使用配置文件告知IOC容器中管理着那些bean
resources下添加spring配置文件applicationContext.xml,并完成bean的配置
<!--bean标签标示配置beanid属性标示给bean起名字class属性表示给bean定义类型 --> <bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/> <bean id="bookService" class="com.itheima.service.impl.BookServiceImpl"/>
注意事项:bean定义时id属性在同一个上下文中(配置文件)不能重复
③用Spring框架提供的接口获取IOC容器,在调用接口中对应的方法获取bean
使用Spring提供的接口完成IOC容器的创建,创建App类,编写main方法
public class App {public static void main(String[] args) {//获取IOC容器ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); } }
从容器中获取对象进行方法调用
public class App {public static void main(String[] args) {//获取IOC容器ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); // BookDao bookDao = (BookDao) ctx.getBean("bookDao"); // bookDao.save();BookService bookService = (BookService) ctx.getBean("bookService");bookService.save();} }
1.2DI入门案例
①DI的实现需依赖于IOC管理bean
②删除掉Service中使用new创建Dao对象的形式
③在Service中提供方法,让Spring的IOC容器通过该方法传入所需要的Dao对象(bean)
public class BookServiceImpl implements BookService {//删除业务层中使用new的方式创建的dao对象private BookDao bookDao;public void save() {System.out.println("book service save ...");bookDao.save();}//提供对应的set方法public void setBookDao(BookDao bookDao) {this.bookDao = bookDao;} }
④用配置文件建立Service与Dao之间的关系
class="com.itheima.dao.impl.BookDaoImpl"/><bean id="bookService" class="com.itheima.service.impl.BookServiceImpl"><!--配置server与dao的关系--><!--property标签表示配置当前bean的属性name属性表示配置哪一个具体的属性ref属性表示参照哪一个bean--><property name="bookDao" ref="bookDao"/><bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/> </bean>
name="bookDao"中
bookDao
的作用是让Spring的IOC容器在获取到名称后,将首字母大写,前面加set找对应的setBookDao()
方法进行对象注入ref="bookDao"中
bookDao
的作用是让Spring能在IOC容器中找到id为bookDao
的Bean对象给bookService
进行注入
2.bean的配置
①bean的基础配置
bean的name属性
配置bean的别名
<bean id="bookService" name="service service4 bookEbi" class="com.itheima.service.impl.BookServiceImpl"> <property name="bookDao" ref="bookDao"/> </bean><!--scope:为bean设置作用范围,可选值为单例singloton,非单例prototype--> <bean id="bookDao" name="dao" class="com.itheima.dao.impl.BookDaoImpl"/>
根据容器这种的名称获取bean对象
public class AppForName {public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");//此处根据bean标签的id属性和name属性的任意一个值来获取bean对象BookService bookService = (BookService) ctx.getBean("service4");bookService.save();} }
当通过id或是name无法获取到bean时,会抛出NoSuchBeanDefinitionException异常
bean作用范围scope配置
小结:
bean默认为单例的原因:
-
bean为单例的意思是在Spring的IOC容器中只会有该类的一个对象
-
bean对象只有一个就避免了对象的频繁创建与销毁,达到了bean对象的复用,性能高
bean在容器中是单例的,是否会产生线程安全问题:
-
如果对象是有状态对象,即该对象有成员变量可以用来存储数据的,
-
因为所有请求线程共用一个bean对象,所以会存在线程安全问题。
-
如果对象是无状态对象,即该对象没有成员变量没有进行数据存储的,
-
因方法中的局部变量在方法调用完成后会被销毁,所以不会存在线程安全问题。
适合交给容器管理的bean对象:表现层对象、业务层对象、数据层对象、工具对象
注意:封装实例的域对象,因为会引发线程安全问题,所以不适合交由容器管理。
2.1bean的实例化
2.1.1构造方法
①准备一个BookDao和BookDaoImpl类
public interface BookDao {public void save();
}public class BookDaoImpl implements BookDao {public void save() {System.out.println("book dao save ...");}}
②将类配置到Spring容器中
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
③编写运行程序
public class AppForInstanceBook {public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");BookDao bookDao = (BookDao) ctx.getBean("bookDao");bookDao.save();}
}
④类中提供构造函数测试
public class BookDaoImpl implements BookDao {public BookDaoImpl() {System.out.println("book dao constructor is running ....");}public void save() {System.out.println("book dao save ...");}}
- 通过控制台的输出可以说明Spring容器在创建对象时走的是构造函数
将构造函数改为private进行测试:
- 从上图中可以看出Spring能访问到类中的私有构造方法,所以Spring的底层用的是反射
在构造函数中添加一个参数进行测试:
- 程序报错,则Spring底层使用的是无参构造
2.1.2实例工厂实例化
搭建实例工厂
①准备UserDao接口和UserDaoImpl实现类
public interface UserDao {public void save(); }public class UserDaoImpl implements UserDao {public void save() {System.out.println("user dao save ...");} }
②创建工厂类OrderDaoFactory并提供一个普通方法
public class UserDaoFactory {public UserDao getUserDao(){return new UserDaoImpl();} }
③编写AppForInstanceUser运行类,在类中通过工厂获取对象
public class AppForInstanceUser {public static void main(String[] args) {//创建实例工厂对象UserDaoFactory userDaoFactory = new UserDaoFactory();//通过实例工厂对象创建对象UserDao userDao = userDaoFactory.getUserDao();userDao.save(); }
将实例工厂创建对象的方式交友Spring管理
①编写配置文件
<bean id="userFactory" class="com.itheima.factory.UserDaoFactory"/> <bean id="userDao" factory-method="getUserDao" factory-bean="userFactory"/>
实例化工厂运行的顺序:
- 创建实例化工厂对象,对应的是上述第一行的配置
- 调用对象中的方法来创建bean,对应上述第二条配置
- factory-bean:工厂的实例对象
- factory-method:工厂对象中具体常见对象的方法名
②在AppForInstanceUser运行类,使用从IOC容器中获取bean的方法进行运行测试
public class AppForInstanceUser {public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");UserDao userDao = (UserDao) ctx.getBean("userDao");userDao.save();} }
运行后,控制台如下图所示:
2.1.3使用Spring提供的FactoryBean简化实例工厂实例化的配置
(1)创建一个UserDaoFactoryBean的类,实现FactoryBean接口,重写接口的方法
public class UserDaoFactoryBean implements FactoryBean<UserDao> {//代替原始实例工厂中创建对象的方法public UserDao getObject() throws Exception {return new UserDaoImpl();}//返回所创建类的Class对象public Class<?> getObjectType() {return UserDao.class;}
}
(2)在Spring的配置文件中进行配置
<bean id="userDao" class="com.itheima.factory.UserDaoFactoryBean"/>
(3)上述的AppForInstanceUser运行类不用做任何修改,直接运行
2.2bean的生命周期
(1)关于Spring中对bean生命周期控制提供了两种方式:
-
在配置文件中的bean标签中添加
init-method
和destroy-method
属性 -
类实现
InitializingBean
与DisposableBean
接口。
(2)对于bean的生命周期控制在bean的整个生命周期中所处的位置如下:
-
初始化容器
-
1.创建对象(内存分配)
-
2.执行构造方法
-
3.执行属性注入(set操作)
-
==4.执行bean初始化方法==
-
-
使用bean
-
1.执行业务操作
-
-
关闭/销毁容器
-
==1.执行bean销毁方法==
-
(3)关闭容器的两种方式:
-
ConfigurableApplicationContext是ApplicationContext的子类
-
close()方法
-
registerShutdownHook()方法
-
3.DI(Dependency Injection)依赖注入
Spring提供的两种依赖注入方式
-
setter注入
-
简单类型
-
<bean ...>
<property name="" value=""/>
</bean>
-
-
引用类型
-
<bean ...>
<property name="" ref=""/>
</bean>
-
-
-
构造器注入
-
简单类型
-
<bean ...>
<constructor-arg name="" index="" type="" value=""/>
</bean>
-
-
引用类型
-
<bean ...>
<constructor-arg name="" index="" type="" ref=""/>
</bean>
-
-
相关文章:

Spring:IOC技术、Bean、DI
前言 Spring是一个开源的项目,并不是单单的一个技术,发展至今已形成一种开发生态圈。也就是说我们可以完全使用Spring技术完成整个项目的构建、设计与开发。Spring是一个基于IOC和AOP的架构多层j2ee系统的架构。 SpringFramework:Spring框架…...

目标检测与跟踪 (2)- YOLO V8配置与测试
系列文章目录 第一章 目标检测与跟踪 (1)- 机器人视觉与YOLO V8 目标检测与跟踪 (1)- 机器人视觉与YOLO V8_Techblog of HaoWANG的博客-CSDN博客3D物体实时检测、三维目标识别、6D位姿估计一直是机器人视觉领域的核心研究课题&a…...
【Leetcode】56.合并区间
一、题目 1、题目描述 以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [ s t a r t i start_i start...

设置系统编码 Beta
在yolov5环境搭建过程中会遇到如下的编码错误警告: 这时,按住“ctrlc”中止进程,然后设置系统编码: 电脑右键属性打开: 重启之后等安装好了,记得回去把bae键取消。...
phpunit
composer地址:phpunit/phpunit - Packagist 官方文档:PHPUnit文档 – PHP测试框架 PHPUnit是一个框架,最为hyperf学习的补充学习,就不写这么细了。 估计写下安装和使用,具体学习内容看文档。 一、安装 需安装扩展:…...

html学习9(脚本)
1、<script>标签用于定义客户端脚本,比如JavaScript,既可包含脚本语句,也可通过src属性指向外部文件。 2、JavaScript最常用于图片操作、表单验证及内容动图更新。 3、<noscript>标签用于在浏览器禁用脚本或浏览器不支持脚本&a…...

SpringBoot整合Caffeine
一、Caffeine介绍 1、缓存介绍 缓存(Cache)在代码世界中无处不在。从底层的CPU多级缓存,到客户端的页面缓存,处处都存在着缓存的身影。缓存从本质上来说,是一种空间换时间的手段,通过对数据进行一定的空间安排,使得下…...

元宇宙虚拟展厅的特点是什么呢?优势有哪些?
元宇宙是一个很广阔的虚拟世界,它可以创造出更为丰富、沉浸式的体验,这种全新的体验为展览和艺术领域带来了更多的可能性,元宇宙虚拟展厅以其多样化、互动性、沉浸式展示的特点,带领大家进入一个虚拟现实的全新世界。 元宇宙虚拟展…...

Day11-Webpack前端工程化开发
Webpack 一 webpack基本概念 遇到问题 开发中希望将文件分开来编写,比如CSS代码,可以分为头部尾部内容,公共的样式。 JS代码也希望拆分为多个文件,分别引入,以后代码比较好维护。 本地图片,希望可以实现小图片不用访问后端,保存在前端代码中就可以了 运行程序时我…...
什么是函数式编程,应用场景是什么
什么是函数式编程,应用场景是什么 函数式编程和面向对象编程一样,是一种编程规范。强调执行的过程而非结果,通过一系列的嵌套的函数调用,完成一个运算过程。它主要有以下几个特点: 1.函数是"一等公民"&…...
Vue3之路由认识
回顾: 原来的vue2路由是通过this. r o u t e 和 t h i s . route和this. route和this.router来控制的。现在vue3有所变化,useRoute相当于以前的this. r o u t e ,而 u s e R o u t e r 相当于 t h i s . route,而useRouter相当于t…...

P1775 石子合并(弱化版)(内附封面)
石子合并(弱化版) 题目描述 设有 N ( N ≤ 300 ) N(N \le 300) N(N≤300) 堆石子排成一排,其编号为 1 , 2 , 3 , ⋯ , N 1,2,3,\cdots,N 1,2,3,⋯,N。每堆石子有一定的质量 m i ( m i ≤ 1000 ) m_i\ (m_i \le 1000) mi (mi≤1000)。…...

jmeter之接口测试(http接口测试)
基础知识储备 一、了解jmeter接口测试请求接口的原理 客户端--发送一个请求动作--服务器响应--返回客户端 客户端--发送一个请求动作--jmeter代理服务器---服务器--jmeter代理服务器--服务器 二、了解基础接口知识: 1、什么是接口:前端与后台之间的…...

webpack基础知识二:说说webpack的构建流程?
一、运行流程 webpack 的运行流程是一个串行的过程,它的工作流程就是将各个插件串联起来 在运行过程中会广播事件,插件只需要监听它所关心的事件,就能加入到这条webpack机制中,去改变webpack的运作,使得整个系统扩展…...

PHP使用PhpSpreadsheet实现导出Excel时带下拉框列表 (可支持三级联动)
因项目需要导出Excel表 需要支持下拉 且 还需要支持三级联动功能 目前应为PHPExcel 不在维护,固采用 PhpSpreadsheet 效果如图: 第一步:首先 使用composer 获取PhpSpreadsheet 我这里PHP 版本 7.4 命令如下: composer r…...

Openssh高危漏洞CVE-2023-38408修复方案
0x01 漏洞简述 2023年07月21日,360CERT监测发现OpenSSH发布了OpenSSH的风险通告,漏洞编号为CVE-2023-38408,漏洞等级:高危,漏洞评分:8.1。 OpenSSH 是 Secure Shell (SSH) 协议的开源实现,提供…...
Android中的ContentProvider
Android中的ContentProvider 在Android中,ContentProvider是四大组件之一,用于在不同应用程序之间共享和管理数据。它提供了一种标准化的方式来访问和管理应用程序的数据,使得多个应用程序可以安全地共享数据,而无需直接访问彼此…...
if device is None and isinstance(net, torch.nn.Module):的含义?
这段代码的含义是,如果变量 device 为 None 并且 net 是 torch.nn.Module 的实例,那么执行后续的代码块。 解释一下其中的几个部分: device:这是一个代表设备的变量,通常用于指定在哪个设备上执行模型的计算ÿ…...

C++如何用OpenCV中实现图像的边缘检测和轮廓提取?
最近有个项目需要做细孔定位和孔距测量,需要做边缘检测和轮廓提取,先看初步效果图: 主要实现代码: int MainWindow::Test() {// 2.9 单个像素长度um 5倍double dbUnit 2.9/(1000*5);// 定义显示窗口namedWindow("src"…...

智慧水务和物联网智能水表在农村供水工程中的应用
摘 要:随着社会的进步和各项事业的飞速发展,人民生活水平的逐步提升,国家对农村饮水安全有了更高的要求,为了进一步提升农村供水服务的质量,利用现代化、信息化科学技术提升农村供水服务质量,提高用水管理效…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

汽车生产虚拟实训中的技能提升与生产优化
在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...

定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...

对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...

2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比
在机器学习的回归分析中,损失函数的选择对模型性能具有决定性影响。均方误差(MSE)作为经典的损失函数,在处理干净数据时表现优异,但在面对包含异常值的噪声数据时,其对大误差的二次惩罚机制往往导致模型参数…...

uniapp手机号一键登录保姆级教程(包含前端和后端)
目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号(第三种)后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...

系统掌握PyTorch:图解张量、Autograd、DataLoader、nn.Module与实战模型
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文通过代码驱动的方式,系统讲解PyTorch核心概念和实战技巧,涵盖张量操作、自动微分、数据加载、模型构建和训练全流程&#…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...