【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依赖
    1
    父模块 导入子都需要的依赖,子模块继承:
    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 基于无参构造

  1. 创建无参构造 类
  2. 创建spring配置文件
  3. 配置文件中 创建bean

1

-   bean标签:通过配置bean标签告诉IOC容器需要创建对象的组件信息
-   id属性:bean的唯一标识,方便后期获取Bean!
-   class属性:组件类的全限定符!
-   注意:要求当前组件类必须包含无参数构造函数!

1

1.2 基于静态 工厂方法实例化

静态
factory-method: 指定静态工厂方法,注意,该方法必须是static方法。

1.3 基于非静态 工厂方法实例化

1

<!-- 将工厂类进行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

1.2 基于构造函数的依赖注入(多构造参数解析)

1

-   constructor-arg标签:指定构造参数和对应的值
-   constructor-arg标签:name属性指定参数名、index属性指定参数角标、value属性指定普通属性值

* 1.3 基于Setter方法依赖注入

1

  • 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容器实例化和销毁组件对象

  1. 周期方法声明
    1

  2. 周期方法配置bean

<bean id="beanPeriod" class="com.doug.BeanPeriod" init-method="Init" destroy-method="destroy"/>
  1. 测试
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-bean-01.xml");// 正常关闭 , 没调用这个方法,就只执行初始化,然后直接寄(非正常死亡)applicationContext.close();

1.2 组件作用域

1
默认就是单例模式,

多例模式:组件对象 getBean 一次就会创建一个组件对象

五、 高级特性:FactoryBean特性和使用:

1. 1 FactoryBean简介

  • BeanFactory IoC容器最大的接口 IoC容器
  • FactoryBean 标准化组件工厂的接口 组件

FactoryBean用于配置复杂的Bean对象,可以将创建过程存储在FactoryBeangetObject方法

FactoryBean<T> 接口提供三种方法:

  • T getObject():

    返回此工厂创建的对象的实例。该返回值会被存储到IoC容器!

  • boolean isSingleton():

    如果此 FactoryBean 返回单例,则返回 true ,否则返回 false 。此方法的默认实现返回 true (注意,lombok插件使用,可能影响效果)。

  • Class<?> getObjectType(): 返回 getObject() 方法返回的对象类型,如果事先不知道类型,则返回 null

1

1.2 FactoryBean应用

FactoryBean使用场景:

  1. 代理类的创建
  2. 第三方框架整合
  3. 复杂对象实例化等
  • 准备FactoryBean的实现类
    1
  • 配置FactoryBean实现类
    <!--id -> getObject方法返回的对象标识class -> factoryBean标准化工厂类--><bean id="javaBean" class="com.doug.ioc02.JavaBeanFactoryBean"><property name="value" value="道格维克"/></bean>
  • 测试
    1

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 项目准备

  • 数据库:
    1
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

1.5 三层结构 搭建 开始

  • dao
    1

  • 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();}

1


总结

lambada
1

XMLIoC方式问题总结 :

  1. 注入的属性必须添加setter方法、代码结构乱!
  2. 配置文件和Java代码分离、编写不是很方便!
  3. XML配置文件解析效率低

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++ bfs 的状态表示(六十二)【第九篇】

今天我们来学习一下bfs的复杂状态表示 1.bfs状态表示 无论是深度优先搜索还是广度优先搜索&#xff0c;搜索的过程均会建立一棵 搜索树&#xff0c;搜索树上的每一个结点都是一个 状态&#xff0c;而搜索的过程又可以看作是 状态的转移。 对于 BFS&#xff0c;搜索过程中产生…

计算机设计大赛 深度学习人体跌倒检测 -yolo 机器视觉 opencv python

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; **基于深度学习的人体跌倒检测算法研究与实现 ** 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f947;学长这里给一个题目综合评分(每项满…

P6354 [COCI2007-2008#3] TAJNA

题目传送门 题目描述 使用一种加密算法。 设字符串的长度为 n&#xff0c;则构造一个矩阵&#xff0c;使得 rcn 且在 r≤c 的情况下使得 r 尽量大。 然后把给定的明文按照由上到下&#xff0c;从左到右的顺序填充这个 rc 的矩阵。 得到的密文就是把矩阵按照从左到右&#…

内存计算研究进展- 针对图计算的近数据计算架构

针对图计算的近数据计算架构的代表性工作有&#xff1a; Seoul National University的 Tesseract和 Georgia Institute of Technology 的 GraphPIM&#xff0c;具体如下。 1 Tesseract Tesseract是一个针对图计算的可编程的内存计算系统架构&#xff0c;它综合了图计算的特点&…

VMware的三种连接模式

桥接模式 就是将主机网卡与虚拟机虚拟的网卡利用虚拟网桥进行通信。在桥接的作用下&#xff0c;类似于把物理主机虚拟为一个交换机&#xff0c;所有桥接设置的虚拟机连接到这个交换机的一个接口上&#xff0c;物理主机也同样插在这个交换机当中&#xff0c;所以所有桥接下的网…

weblog项目开发记录--SpringBoot后端工程骨架

知识点查漏补缺 跟着犬小哈做项目实战时发现好多知识点都忘了&#xff0c;还有一些小的知识点可能之前没学过&#xff0c;记录下&#xff01;顺带整理下开发流程。 完整项目学习见犬小哈实战专栏 SpringBoot后端工程骨架 搭建好的工程骨架中实现了很多基础功能&#xff0c;…

如何在同一个module里面集成多个数据库的多张表数据

确保本公司数据安全&#xff0c;通常对数据的管理采取很多措施进行隔离访问。 但是&#xff0c;Mendix应怎样访问散布于异地的多个数据库呢&#xff1f; 前几期我们介绍过出海跨境的大企业对于Mendix的技术、人才的诉求后&#xff0c;陆陆续续有其他客户希望更聚焦具体的实际场…

量子计算:数据安全难题

当今数字技术面临的最大挑战之一是安全系统和数据。为此&#xff0c;人们设计了复杂的算法来加密数据并通过称为对称加密的框架来保护数据。虽然这已被证明是成功的&#xff0c;但量子计算的进步&#xff08;利用量子力学比传统计算机更快地解决复杂问题&#xff09;可能会彻底…

【Pytorch 基础教程2】10分钟掌握Tensor基础 VSCode +Pytorch配置

Pytorch 基础教程 02 Tensor PyTorch 作为Numpy的代替品&#xff0c;可以使用GPU的强大计算能力 提供最大的灵活性和告诉的深度学习研究平台 这里补充上实验环境调试&#xff1a;第一次使用VS Code可以参考&#xff1a;PyTorch&#xff08;超详细&#xff09;部署与激活 举起Py…

优先队列C

由于看到P1629 邮递员送信这题,就去学了优先队列.为学习Dijkstra算法做准备 什么是优先队列 优先队列:是一种特殊类型的队列&#xff0c;每个元素都有一个相关的优先级。在优先队列中&#xff0c;元素按照优先级的顺序进行排列&#xff0c;具有最高&#xff08;或最低&#x…

Prometheus 教程

目录 一、简介二、下载安装1、安装 prometheus2、安装 alertmanager3、安装 grafana4、安装 node_exporter5、安装 mysqld_exporter 一、简介 Prometheus 是一个开源的系统监控和警报工具。它最初由 SoundCloud 开发&#xff0c;并于 2012 年发布为开源项目。Prometheus 专注于…

利用vite快速搭建vue3项目

1、选择一个文件夹&#xff0c;在vscode终端打开&#xff0c;输入命令【npm create vitelatest】 npm create vitelatest 2、提示你输入项目名称之后&#xff0c;我这里设置的是【rookiedemo】 3、回车之后&#xff0c;出现选择框架的提示&#xff0c;我们选择【vue】回车 4、…

js中使用for in注意事项,key的类型为string类型

for in是一个非常实用的存在&#xff0c;既可以遍历数组&#xff0c;又可以遍历对象&#xff0c;所以我一般都是会用来遍历可迭代的数据&#xff0c;遍历数组和对象的时候&#xff0c;要注意使用万能遍历方式&#xff1a; const users [1, 3, 45, 6]// const users {// 1…

Polyspace静态检测步骤

Polyspace 是一个代码静态分析和验证的工具&#xff0c;隶属于MATLAB&#xff0c;用于检测代码中的错误和缺陷&#xff0c;包括内存泄漏、数组越界、空指针引用等。帮助开发团队提高代码质量&#xff0c;减少软件开发过程中的错误和风险。 1、打开MATLAB R2018b 2、找到Polys…

AR智能眼镜主板硬件设计_AR眼镜光学方案

AR眼镜凭借其通过导航、游戏、聊天、翻译、音乐、电影和拍照等交互方式&#xff0c;将现实与虚拟进行无缝融合的特点&#xff0c;实现了更加沉浸式的体验。然而&#xff0c;要让AR眼镜真正成为便捷实用的智能设备&#xff0c;需要解决一系列技术难题&#xff0c;如显示、散热、…

Stable Diffusion 绘画入门教程(webui)-图生图

通过之前的文章相信大家对文生图已经不陌生了&#xff0c;那么图生图是干啥的呢&#xff1f; 简单理解就是根据我们给出的图片做为参考进行生成图片。 一、能干啥 这里举两个例子 1、二次元头像 真人转二次元&#xff0c;或者二次元转真人都行&#xff0c; 下图为真人转二次…

小清新卡通人物404错误页面源码

小清新卡通人物404错误页面源码由HTMLCSSJS组成,记事本打开源码文件可以进行内容文字之类的修改&#xff0c;双击html文件可以本地运行效果&#xff0c;也可以上传到服务器里面&#xff0c;重定向这个界面 蓝奏云&#xff1a;https://wfr.lanzout.com/i6XbU1olftde

二叉树(6)——二叉树的创建和销毁

1 二叉树的创建 整体思路 将数组里的元素一直分为根&#xff0c;左子树&#xff0c;右子树&#xff0c;遇到#就返回NULL&#xff0c;链接到上层递归的左子树或者右子树&#xff0c;一定要把一个节点的左子树全部递归完才能返回到右子树。这种方法也可以scanf一个数组里的元素&…

Spring Boot项目怎么对System.setProperty(key, value)设置的属性进行读取加解密

一、前言 之前我写过一篇文章使用SM4国密加密算法对Spring Boot项目数据库连接信息以及yaml文件配置属性进行加密配置&#xff08;读取时自动解密&#xff09;&#xff0c;对Spring Boot项目的属性读取时进行加解密&#xff0c;但是没有说明对System.setProperty(key, value)设…

Docker Compose映射卷的作用是什么,dockerfile这个文件有什么区别和联系?

Docker Compose中映射卷&#xff08;Volumes&#xff09;的作用和Dockerfile之间既有区别也有联系。下面详细解释两者的作用、区别和联系&#xff1a; Docker Compose映射卷的作用 在Docker Compose中&#xff0c;卷&#xff08;Volumes&#xff09;用于数据持久化和数据共享…