【Spring】IoC容器 控制反转 与 DI依赖注入 XML实现版本 第二期
文章目录
- 基于 XML 配置方式组件管理
- 前置 准备项目
- 一、 组件(Bean)信息声明配置(IoC):
- 1.1 基于无参构造
- 1.2 基于静态 工厂方法实例化
- 1.3 基于非静态 工厂方法实例化
- 二、 组件(Bean)依赖注入配置(DI):
- 1. 1 基于构造函数的依赖注入(单个构造参数)
- 1.2 基于构造函数的依赖注入(多构造参数解析)
- * 1.3 基于Setter方法依赖注入
- 三、 IoC容器创建和使用:
- 1. 1 容器实例化
- 1.2 Bean对象读取
- 四、 高级特性: 组件(Bean)作用域和周期方法配置:
- 1. 1 组件周期
- 1.2 组件作用域
- 五、 高级特性:FactoryBean特性和使用:
- 1. 1 FactoryBean简介
- 1.2 FactoryBean应用
- 1.3 FactoryBean和BeanFactory区别
- 六、基于XML方式整合三层架构组件
- 1.1 需求分析
- 1.2 项目准备
- 1.3 配置文件
- 1.4 测试 数据库 增删改查
- 1.5 三层结构 搭建 开始
- 总结
- XMLIoC方式问题总结 :
基于 XML 配置方式组件管理
前置 准备项目
- 创建项目工程
- 导入springioc依赖
父模块 导入子都需要的依赖,子模块继承:
pom.xml
<dependencies><!--spring context依赖--><!--当你引入Spring Context依赖之后,表示将Spring的基础依赖引入了--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>6.0.6</version></dependency><!--junit5测试--><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-api</artifactId><version>5.3.1</version></dependency></dependencies>
一、 组件(Bean)信息声明配置(IoC):
1.1 基于无参构造
- 创建无参构造 类
- 创建spring配置文件
- 配置文件中 创建bean
- bean标签:通过配置bean标签告诉IOC容器需要创建对象的组件信息
- id属性:bean的唯一标识,方便后期获取Bean!
- class属性:组件类的全限定符!
- 注意:要求当前组件类必须包含无参数构造函数!
1.2 基于静态 工厂方法实例化
factory-method: 指定静态工厂方法,注意,该方法必须是static方法。
1.3 基于非静态 工厂方法实例化
<!-- 将工厂类进行ioc配置 --><bean id="notStaticMethod" class="com.doug.ClientService"></bean><!-- 根据工厂对象的实例工厂方法进行实例化组件对象 --><bean id="clientService" factory-bean="notStaticMethod" factory-method="createInstance"></bean>
- factory-bean属性:指定当前容器中工厂Bean 的名称。
- factory-method: 指定实例工厂方法名。注意,实例方法必须是非static的!
二、 组件(Bean)依赖注入配置(DI):
1. 1 基于构造函数的依赖注入(单个构造参数)
1.2 基于构造函数的依赖注入(多构造参数解析)
- constructor-arg标签:指定构造参数和对应的值
- constructor-arg标签:name属性指定参数名、index属性指定参数角标、value属性指定普通属性值
* 1.3 基于Setter方法依赖注入
- property标签: 可以给setter方法对应的属性赋值
- property 标签: name属性代表set方法标识、ref代表引用bean的标识id、value属性代表基本属性值
- name 本质是去找方法(set方法),去掉set的
三、 IoC容器创建和使用:
1. 1 容器实例化
读取配置文件,实例化Bean对象
// 方法一:
//参数:String...locations 传入一个或者多个配置文件
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-bean-01.xml","spring-bean-02.xml");//方法二:// 先实例化,再指定配置文件,最后刷新容器触发Bean实例化
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext();
//设置配置配置文件,方法参数为可变参数,可以设置一个或者多个配置
context.setConfigLocations("spring-bean-01.xml","spring-bean-02.xml");
//后配置的文件,需要调用refresh方法,触发刷新配置
context.refresh();
1.2 Bean对象读取
//方式1: 根据id获取
//没有指定类型,返回为Object,需要类型转化!
HappyComponent happyComponent = (HappyComponent) applicationContext.getBean("bean的id标识");//使用组件对象
happyComponent.doWork();//方式2: 根据类型获取
//根据类型获取,但是要求,同类型(当前类,或者之类,或者接口的实现类)只能有一个对象交给IoC容器管理
//配置两个或者以上出现: org.springframework.beans.factory.NoUniqueBeanDefinitionException 问题
HappyComponent happyComponent = applicationContext.getBean(HappyComponent.class);
happyComponent.doWork();//方式3: 根据id和类型获取 !
// getBean("bean的id标识",class)
HelloComponent helloComponent = applicationContext.getBean("helloComponent", HelloComponent.class);
helloComponent.doWork();
- 根据类型来获取
bean
时,在满足bean唯一性的前提下,其实只是看:- 『
对象 instanceof 指定的类型
』的返回结果,
- 『
- 只要返回的是true就可以认定为和类型匹配,能够获取到。
- 根据类型获取,同一个类型,在IoC容器中只能有一个bean
- 存在多个同类型bean 会报错 (见上代码!)
- IOC的配置一定是实现类,但可以根据接口类型获取值。
interfaceA happyComponent = applicationContext.getBean(interfaceA.class);
happyComponent.doWork();
- 根据实现类的父接口 调用它实现类的方法
四、 高级特性: 组件(Bean)作用域和周期方法配置:
1. 1 组件周期
IoC容器实例化和销毁组件对象
-
周期方法声明
-
周期方法配置bean
<bean id="beanPeriod" class="com.doug.BeanPeriod" init-method="Init" destroy-method="destroy"/>
- 测试
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-bean-01.xml");// 正常关闭 , 没调用这个方法,就只执行初始化,然后直接寄(非正常死亡)applicationContext.close();
1.2 组件作用域
默认就是单例模式,
多例模式:组件对象 getBean 一次就会创建一个组件对象
五、 高级特性:FactoryBean特性和使用:
1. 1 FactoryBean简介
- BeanFactory IoC容器最大的接口 IoC容器
- FactoryBean 标准化组件工厂的接口 组件
FactoryBean用于配置复杂的Bean对象,可以将创建过程存储在
FactoryBean
的getObject方法!
FactoryBean<T>
接口提供三种方法:
-
T getObject()
:返回此工厂创建的对象的实例。该返回值会被存储到IoC容器!
-
boolean isSingleton()
:如果此
FactoryBean
返回单例,则返回true
,否则返回false
。此方法的默认实现返回true
(注意,lombok插件使用,可能影响效果)。 -
Class<?> getObjectType()
: 返回getObject()
方法返回的对象类型,如果事先不知道类型,则返回null
。
1.2 FactoryBean应用
FactoryBean使用场景:
- 代理类的创建
- 第三方框架整合
- 复杂对象实例化等
- 准备FactoryBean的实现类
- 配置FactoryBean实现类
<!--id -> getObject方法返回的对象标识class -> factoryBean标准化工厂类--><bean id="javaBean" class="com.doug.ioc02.JavaBeanFactoryBean"><property name="value" value="道格维克"/></bean>
- 测试
1.3 FactoryBean和BeanFactory区别
FactoryBean
- 是 Spring 中一种特殊的 bean,可以在 getObject() 工厂方法自定义的逻辑创建Bean!
- 是一种能够生产其他 Bean 的 Bean
- FactoryBean 在容器启动时被创建,而在实际使用时则是通过调用 getObject() 方法来得到其所生产的 Bean
- FactoryBean 可以自定义任何所需的初始化逻辑,生产出一些定制化的 bean
- 一般情况下,整合第三方框架,都是通过定义FactoryBean实现
BeanFactory
- Spring 框架的基础,其作为一个顶级接口定义了容器的基本行为
- 例如管理 bean 的生命周期、配置文件的加载和解析、bean 的装配和依赖注入等
- BeanFactory 接口提供了访问 bean 的方式
总的来说 , FactoryBean 和 BeanFactory 的区别 :
- 主要在于FactoryBean 是用于创建 bean 的接口,它提供了更加灵活的初始化定制功能,
- 而 BeanFactory是用于管理 bean 的框架基础接口,提供了基本的容器功能和 bean 生命周期管理。
六、基于XML方式整合三层架构组件
1.1 需求分析
搭建一个三层架构案例,模拟查询全部学生(学生表)信息,持久层使用JdbcTemplate和Druid技术,使用XML方式进行组件管理!
1.2 项目准备
- 数据库:
create database studb;use studb;CREATE TABLE students (id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(50) NOT NULL,gender VARCHAR(10) NOT NULL,age INT,class VARCHAR(50)
);INSERT INTO students (id, name, gender, age, class)
VALUES(1, '张三', '男', 20, '高中一班'),(2, '李四', '男', 19, '高中二班'),(3, '王五', '女', 18, '高中一班'),(4, '赵六', '女', 20, '高中三班'),(5, '刘七', '男', 19, '高中二班'),(6, '陈八', '女', 18, '高中一班'),(7, '杨九', '男', 20, '高中三班'),(8, '吴十', '男', 19, '高中二班');
- 项目创建:
spring-ioc-xml-practice-02 - 依赖导入:
<dependencies><!--spring context依赖--><!--当你引入SpringContext依赖之后,表示将Spring的基础依赖引入了--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>6.0.6</version></dependency><!-- 数据库驱动和连接池--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.25</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.8</version></dependency><!-- spring-jdbc --><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>6.0.6</version></dependency></dependencies>
- 实体类准备:
package com.doug.ioc;public class Student {private Integer id;private String name;private String gender;private Integer age;private String classes;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getGender() {return gender;}public void setGender(String gender) {this.gender = gender;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public String getClasses() {return classes;}public void setClasses(String classes) {this.classes = classes;}@Overridepublic String toString() {return "Student{" +"id=" + id +", name='" + name + '\'' +", gender='" + gender + '\'' +", age=" + age +", classes='" + classes + '\'' +'}';}
}
1.3 配置文件
从JAVA写法 改成 bean创建对象
1.4 测试 数据库 增删改查
@Testpublic void testForIoC(){// 1. 创建IOC容器ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-ioc01.xml");// 2. 获取jdbc组件JdbcTemplate jdbcTemplate = applicationContext.getBean(JdbcTemplate.class);// 3. 进行数据库的crud操作// 3.1 插入 删除 修改 DML updateString sql = "insert into students(name,gender,age,class) values(?,?,?,?)";/** 参数一:sql语句* 参数二: 传入占位符?的值 按顺序* 返回值:int 影响行数* */int rows = jdbcTemplate.update(sql, "道格", "男", 25, "十年十班");System.out.println(rows);// 3.2 查询单条信息// 按照 ID 查询一条学生信息 返回实体对象sql = "select * from students where id = ?";/** 参数一:sql语句* 参数二:RowMapper 列名和属性名的映射器接口* 参数三:Object...param 占位符 (这里是id数字)* 返回值: rowMapper指定的对象 结果返回实体类* */Student queryStudent = jdbcTemplate.queryForObject(sql, (rs, rowNum) -> {// 返回的结果集对象// rs 结果集// rowNum 行数// rs 结果集中获取列的值 赋值给实体类对象即可Student student = new Student();student.setId(rs.getInt("id"));student.setName(rs.getString("name"));student.setGender(rs.getString("gender"));student.setAge(rs.getInt("age"));student.setClasses(rs.getString("class"));return student;}, 1);System.out.println(queryStudent);// 3.3 查询所有学生的信息sql = "select id,name,gender,age,class as classes from students";// BeanPropertyRowMapper 帮助我们自动映射列和属性值!要求列名和属性名一致!不一致需要起别名!List<Student> studentList = jdbcTemplate.query(sql, new BeanPropertyRowMapper<Student>(Student.class));System.out.println(studentList);
结果:
1.5 三层结构 搭建 开始
-
dao
-
service
- controller
- xml 配置文件
<context:property-placeholder location="classpath:jdbc.properties"/><bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="url" value="${doug.url}"/><property name="driverClassName" value="${doug.driver}"/><property name="username" value="${doug.username}"/><property name="password" value="${doug.password}"/></bean><bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="druidDataSource"/></bean><bean id="stuDao" class="com.doug.dao.impl.StuDaoImpl"><property name="jdbcTemplate" ref="jdbcTemplate"/></bean><bean id="stuService" class="com.doug.service.impl.StuServiceImpl"><property name="stuDao" ref="stuDao"/></bean><bean id="stuController" class="com.doug.controller.StuController"><property name="stuService" ref="stuService"/></bean>
- 测试
@Testpublic void testStuControllerMethod(){ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-02.xml");StuController stuController = applicationContext.getBean(StuController.class);stuController.findAllStu();}
总结
lambada
XMLIoC方式问题总结 :
- 注入的属性必须添加setter方法、代码结构乱!
- 配置文件和Java代码分离、编写不是很方便!
- XML配置文件解析效率低
相关文章:

【Spring】IoC容器 控制反转 与 DI依赖注入 XML实现版本 第二期
文章目录 基于 XML 配置方式组件管理前置 准备项目一、 组件(Bean)信息声明配置(IoC):1.1 基于无参构造1.2 基于静态 工厂方法实例化1.3 基于非静态 工厂方法实例化 二、 组件(Bean)依赖注入配置…...

神经网络系列---感知机(Neuron)
文章目录 感知机(Neuron)感知机(Neuron)的决策函数可以表示为:感知机(Neuron)的学习算法主要包括以下步骤:感知机可以实现逻辑运算中的AND、OR、NOT和异或(XOR)运算。 感知机(Neuron) 感知机(Neuron)是一种简单而有效的二分类算法,用于将输入…...

k8s(2)
目录 一.二进制部署k8s 常见的K8S安装部署方式: k8s部署 二进制与高可用的区别 二.部署k8s 初始化操作: 每台node安装docker: 在 master01 节点上操作; 准备cfssl证书生成工具:: 执行脚本文件: 拉入etcd压缩包…...

利用nginx内部访问特性实现静态资源授权访问
在nginx中,将静态资源设为internal;然后将前端的静态资源地址改为指向后端,在后端的响应头部中写上静态资源地址。 近期客户对我们项目做安全性测评,暴露出一些安全性问题,其中一个是有些静态页面(*.html&…...

fly-barrage 前端弹幕库(1):项目介绍
fly-barrage 是我写的一个前端弹幕库,由于经常在 Bilibili 上看视频,所以对网页的弹幕功能一直蛮感兴趣的,所以做了这个库,可以帮助前端快速的实现弹幕功能。 项目官网地址:https://fly-barrage.netlify.app/ÿ…...
jetcache如果一个主体涉及多个缓存时编辑或者删除时如何同时失效多个缓存
在实际使用过程中,可能会遇到这种情形:一个主体会有多个缓存,比如用户基础信息缓存、用户详情缓存,那么当删除用户信息后就需要同时失效多个缓存中该主体数据,那么jetcache支持这种应用场景么,答案是支持&a…...

uni-app 实现拍照后给照片加水印功能
遇到个需求需要实现,研究了一下后写了个demo 本质上就是把拍完照后的照片放到canvas里,然后加上水印样式然后再重新生成一张图片 代码如下,看注释即可~使用的话记得还是得优化下代码 <template><view class"content"&g…...

【ArcGIS】利用DEM进行水文分析:流向/流量等
利用DEM进行水文分析 ArcGIS实例参考 水文分析通过建立地表水文模型,研究与地表水流相关的各种自然现象,在城市和区域规划、农业及森林、交通道路等许多领域具有广泛的应用。 ArcGIS实例 某流域30m分辨率DEM如下: (1)…...

论文阅读笔记——PathAFL:Path-Coverage Assisted Fuzzing
文章目录 前言PathAFL:Path-Coverage Assisted Fuzzing1、解决的问题和目标2、技术路线2.1、如何识别 h − p a t h h-path h−path?2.2、如何减少 h − p a t h h-path h−path的数量?2.3、哪些h-path将被添加到种子队列?2.4、种…...
C语言中各种运算符用法
C语言中有许多不同的运算符,用于执行各种不同的操作。 以下是C语言中常见的运算符及其用法: 算术运算符: 加法运算符():用于将两个值相加。减法运算符(-):用于将一个值减…...

pythonJax小记(五):python: 使用Jax深度图像(正交投影和透视投影之间的转换)(持续更新,评论区可以补充)
python: 使用Jax深度图像(正交投影和透视投影之间的转换) 前言问题描述1. 透视投影2. 正交投影 直接上代码解释1. compute_projection_parameters 函数a. 参数解释b. 函数计算 2. ortho_to_persp 函数a. 计算投影参数:b. 生成像素坐标网格&am…...

web安全学习笔记【16】——信息打点(6)
信息打点-语言框架&开发组件&FastJson&Shiro&Log4j&SpringBoot等[1] #知识点: 1、业务资产-应用类型分类 2、Web单域名获取-接口查询 3、Web子域名获取-解析枚举 4、Web架构资产-平台指纹识别 ------------------------------------ 1、开源-C…...

145.二叉树的后序遍历
// 定义一个名为Solution的类,用于解决二叉树的后序遍历问题 class Solution { // 定义一个公共方法,输入是一个二叉树的根节点,返回一个包含后序遍历结果的整数列表 public List<Integer> postorderTraversal(TreeNode root) { /…...
ssh远程连接免密码访问
我们在远程登录的时候,经常需要输入密码,密码往往比较复杂,输入比较耗费时间,这种情况下可以使用ssh免密码登录。 一般的教程是需要生成ssh密钥后,然后把密钥复制到server端完成配置,这里提供一个简单的方…...
Vue-Json-Schema-Form: 如何基于模板定制前端页面
本人从事的是工业物联网, 面对工业设备的通讯难题是各大设备都有各自的通讯协议, 如果想要用一款硬件去和所有设备做通讯的话, 就得面对怎么把自己想要采集的配置下发给自己的采集器的问题, 以前都是采用各种模型去尝试构建配置项, 但是因为配置可能会有深层次嵌套, 而且…...
保存Json对象到数据库
文章目录 背景实现方式1. 直接以 Json 对象保存到数据库2. 以 String 类型保存到数据库 背景 项目过程中可能需要保存 Json 对象到数据库中。 实现方式 有两种实现方式,一种是直接保存 Json 对象到数据库,这种方式在创建实体类以及编写 Mapper XML 脚本…...

《Docker 简易速速上手小册》第3章 Dockerfile 与镜像构建(2024 最新版)
文章目录 3.1 编写 Dockerfile3.1.1 重点基础知识3.1.2 重点案例:创建简单 Python 应用的 Docker 镜像3.1.3 拓展案例 1:Dockerfile 优化3.1.4 拓展案例 2:多阶段构建 3.2 构建流程深入解析3.2.1 重点基础知识3.2.2 重点案例:构建…...

【Python笔记-设计模式】适配器模式
一、说明 适配器模式是一种结构型模式,它使接口不兼容的对象能够相互合作 (一) 解决问题 主要解决接口不兼容问题 (二) 使用场景 当系统需要使用现有的类,但类的接口不符合需求时当需要一个统一的输出接口,但输入类型不可预知时当需要创…...

二分算法(c++版)
二分的本质是什么? 很多人会认为单调性是二分的本质,但其实其本质并非单调性,只是说,有单调性的可以进行二分,但是有些题目没有单调性我们也可以进行二分。其本质其实是一个边界问题,给定一个条件…...

【C#】用于基于 UV DLP 的 3D 打印机的切片软件源码解析(一)DLP原理 GUI
0. 原理 基于 UV DLP 的 3D 打印机的工作原理是这样的: UV DLP 是一种使用数字光处理(Digital Light Processing)技术的 3D 打印方法,它利用紫外光(UV)来固化液态树脂,从而形成实体物体。UV DLP…...

XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...

大型活动交通拥堵治理的视觉算法应用
大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动(如演唱会、马拉松赛事、高考中考等)期间,城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例,暖城商圈曾因观众集中离场导致周边…...
生成 Git SSH 证书
🔑 1. 生成 SSH 密钥对 在终端(Windows 使用 Git Bash,Mac/Linux 使用 Terminal)执行命令: ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" 参数说明: -t rsa&#x…...
GitHub 趋势日报 (2025年06月08日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...

《信号与系统》第 6 章 信号与系统的时域和频域特性
目录 6.0 引言 6.1 傅里叶变换的模和相位表示 6.2 线性时不变系统频率响应的模和相位表示 6.2.1 线性与非线性相位 6.2.2 群时延 6.2.3 对数模和相位图 6.3 理想频率选择性滤波器的时域特性 6.4 非理想滤波器的时域和频域特性讨论 6.5 一阶与二阶连续时间系统 6.5.1 …...

高分辨率图像合成归一化流扩展
大家读完觉得有帮助记得关注和点赞!!! 1 摘要 我们提出了STARFlow,一种基于归一化流的可扩展生成模型,它在高分辨率图像合成方面取得了强大的性能。STARFlow的主要构建块是Transformer自回归流(TARFlow&am…...
字符串哈希+KMP
P10468 兔子与兔子 #include<bits/stdc.h> using namespace std; typedef unsigned long long ull; const int N 1000010; ull a[N], pw[N]; int n; ull gethash(int l, int r){return a[r] - a[l - 1] * pw[r - l 1]; } signed main(){ios::sync_with_stdio(false), …...
计算机系统结构复习-名词解释2
1.定向:在某条指令产生计算结果之前,其他指令并不真正立即需要该计算结果,如果能够将该计算结果从其产生的地方直接送到其他指令中需要它的地方,那么就可以避免停顿。 2.多级存储层次:由若干个采用不同实现技术的存储…...
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__ is not explicitly defined.
这个警告表明您在使用Vue的esm-bundler构建版本时,未明确定义编译时特性标志。以下是详细解释和解决方案: 问题原因: 该标志是Vue 3.4引入的编译时特性标志,用于控制生产环境下SSR水合不匹配错误的详细报告1使用esm-bundler…...
零基础在实践中学习网络安全-皮卡丘靶场(第十一期-目录遍历模块)
经过前面几期的内容我们学习了很多网络安全的知识,而这期内容就涉及到了前面的第六期-RCE模块,第七期-File inclusion模块,第八期-Unsafe Filedownload模块。 什么是"遍历"呢:对学过一些开发语言的朋友来说应该知道&…...