【示例】Spring-IOC理解

前言

本文从常规的开发示例(DAO、Service、Client)入手,逐步体会理解IOC的原理及实现。

文中示例的代码地址:

GitHubhttps://github.com/Web-Learn-GSF/Java_Learn_Examples
父工程Java_Framework_Spring

示例 | 常规三层开发示例

层级结构及代码展示

代码层级结构:经典三层:

  • Dao:获取数据库数据,处于数据库和Service层之间(在示例中没有真的获取数据库,仅展示)

  • Service层:业务逻辑实现的地方

  • Client:客户端调用,在这里面就是UserTest

image-20240409212205420

源码实现

DAO | UserDao

public interface UserDao {
   public void getUser();
}

DAO | UserDaoImpl

public class UserDaoImpl implements UserDao {
   @Override
   public void getUser() {
       System.out.println("Dao获取用户数据");
  }
}

Service | UserService

public interface UserService {
   public void getUser();
}

Service | UserServiceImpl

public class UserServiceImpl implements UserService {
   private UserDao userDao = new UserDaoImpl();

   @Override
   public void getUser() {
       userDao.getUser();
  }
}

UserTest

public class UserTest {
    @Test
    public void test(){
        UserService service = new UserServiceImpl();
        service.getUser();
    }
}

增加一个新的实现

增加一个新的实现需要:新增DAO实现、修改Service实现的代码

Dao | UserSqlImpl

public class UserSqlImpl implements UserSql {
   @Override
   public void getUser() {
       System.out.println("Sql获取用户数据");
  }
}

Service | UserServiceImpl

public class UserServiceImpl implements UserService {
    // 原内容
	// private UserDao userDao = new UserDaoImpl();
   	
    // 修改后的内容
    private UserSqlImpl userDao = new UserSqlImpl();

   @Override
   public void getUser() {
       userDao.getUser();
  }
}

思考?

针对常规开发模式,每增加一个源码实现,都需要对服务端实现的代码进行更改,非常麻烦。代码耦合性太高。

怎样降低代码之间的耦合度呢?利用Set函数

添加Set()函数

保持其他内容不变,修改服务端实现类的代码内容:

public class UserServiceImpl implements UserService {
   private UserDao userDao;
   
    // 利用set实现
   public void setUserDao(UserDao userDao) {
       this.userDao = userDao;
  }

   @Override
   public void getUser() {
       userDao.getUser();
  }
}

修改客户端代码实现如下:

@Test
public void test(){
   
    UserServiceImpl service = new UserServiceImpl();
    // Dao实现
    service.setUserDao( new UserDaoImpl() );
    service.getUser();

    //Sql实现
    service.setUserDao( new UserSqlImpl() );
    service.getUser();
}

思考?

可以看到,针对新的源码实现,不再需要修改业务端的逻辑,仅是在客户端,通过传入不同的业务端实现对象,即可完成更改。

添加set函数前后的对比:

添加前添加后(IOC原型)
对象创建主动权在程序,在Service层对象创建主动权在调用者,在Client层
对象是写死的,更改实现对象,就需要更改业务端Service代码对象是通过接口动态接收的,调用者给什么,就实现什么

理解 | IOC

在没有应用IOC思想的程序中,我们使用面向对象编程,对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制。

在使用IOC的思想后,控制反转,将对象的创建转移给第三方,实现解耦。

image-20231113224431882

示例 | 修改上述示例为IOC实现

引入xml配置文件

image-20240409215342042

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--底层源码实现-->
    <bean id="MysqlImpl" class="com.example.Dao.UserDaoImpl"/>
    <bean id="DaoImpl" class="com.example.Dao.UserSqlImpl"/>

    <!--业务端代码实现-->
    <bean id="ServiceImpl" class="com.example.Service.UserServiceImpl">
        <!--注意: 这里的name并不是属性, 而是UserServiceImpl实现类里面setUserDao方法中set后面的那部分, 其中首字母要小写-->
        <!--该方法的参数是引用另外一个bean, 这里不能用value,而是用ref:一个已经存在的对象-->
        <property name="userDao" ref="MysqlImpl"/>
    </bean>

</beans>

修改客户端的实现

public class UserTest {
    @Test
    public void test(){
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        UserServiceImpl serviceImpl = (UserServiceImpl) context.getBean("ServiceImpl");
        serviceImpl.getUser();
    }
}

思考?

可以看到,使用Spring的IOC容器后,我们并没有在客户端中实例化Dao层对象,也没有把Dao的实例化对象传递给Service,但是完成了结果输出。

我们可以思考下面两个问题:

  • Dao层的实例化对象由谁创建?
由Spring创建的
  • Service层userDao这个对象属性是怎么设置的?
通过DI-属性注入的方式实现外部注入

	- 外部:指xml配置文件
	- 属性注入:本质是利用类的set()方法

上述示例,可以总结为一句话:

  • IoC(Inversion of Control,控制反转) 是一种设计思想,DI(Dependency Injection,依赖注入) 是实现IoC的一种方法
  • 在Spring中,通过DI,可以将对象的创建和管理交由Spring来完成

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

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

相关文章

智能合约NFT代币系统的开发:构建数字资产生态

随着区块链技术的迅速发展和数字资产市场的不断壮大&#xff0c;智能合约NFT&#xff08;非同质化代币&#xff09;代币系统成为了吸引眼球的焦点之一。本文将深入探讨智能合约NFT代币系统的开发&#xff0c;以及它如何构建数字资产生态。 引言 数字资产市场的迅速发展和区块链…

RAGFlow:基于OCR和文档解析的下一代 RAG 引擎

一、引言 在人工智能的浪潮中&#xff0c;检索增强生成&#xff08;Retrieval-Augmented Generation&#xff0c;简称RAG&#xff09;技术以其独特的优势成为了研究和应用的热点。RAG技术通过结合大型语言模型&#xff08;LLMs&#xff09;的强大生成能力和高效的信息检索系统…

抖音评论ID批量提取采集软件|视频评论下载工具

抖音评论ID批量提取采集软件&#xff1a;拓展你的抖音市场营销&#xff01; 正文&#xff1a; 在当今社交媒体兴盛的时代&#xff0c;抖音作为一款风靡全球的短视频应用&#xff0c;成为了企业营销的热门平台之一。然而&#xff0c;如何获取并利用抖音用户的评论信息进行精准…

电脑更新到win11后不能上网,更新win11后无法上网

越来越多的用户升级了win11系统使用&#xff0c;然而有些用户发现电脑更新到win11后不能上网了&#xff0c;这是怎么回事呢?而且奇怪的是&#xff0c;网络状态显示已连接&#xff0c;但就是无法上网&#xff0c;原本以为重置网络就能搞定&#xff0c;但结果相反。针对这一情况…

Windows系统上运行appium连接iOS真机自动化测试

步骤: 1、windows安装tidevice工具 2、Mac系统打包安装WebDriverAgent(WDA)工具 3、安装Appium 4、连接iOS手机 iOS自动化的实现和执行都依赖Mac系统,因为需要通过Xcodebuild编译安装WDA (WebDriverAgent)到iOS设备中,通过WDA实现对被测应用进行操作。而Windows系统无…

1.Godot引擎|场景|节点|GDS|介绍

Godot介绍 Godot是一款游戏引擎 可以通过在steam商城免费下载 初学者和编程基础稍差的推荐学习使用GDScript&#xff0c;和python有些相似 Godot节点 Godot的开发思想——围绕节点 节点的特征与优势 最常用基本的开发组件大部分都具有具体的功能&#xff0c;如图片&#xf…

python课后习题三

题目&#xff1a; 解题过程&#xff1a; 模式A&#xff1a; num int(input("&#xff08;模式A&#xff09;输入数字&#xff1a;")) for i in range(num): for j in range(num): if j < i 1: …

软件杯 深度学习人体跌倒检测 -yolo 机器视觉 opencv python

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

VBA 实现outlook 当邮件设置category: red 即触发自动创建jira issue

1. 打开: Outlook VBA&#xff08;Visual Basic for Applications&#xff09; 方法一: 在邮件直接搜索:Visual Basic editor 方法二: File -> Options -> Customize Ribbon-> 打钩 如下图: 2.设置运行VBA 脚本: File -> Options -> Trust center -> Trus…

2024年03月CCF-GESP编程能力等级认证Scratch图形化编程二级真题解析

本文收录于专栏《Scratch等级认证CCF-GESP真题解析》,专栏总目录・点这里 一、单选题(一共 15 个题目,每题 2 分,共 30 分) 第1题 小杨的父母最近刚刚给他买了一块华为手表,他说手表上跑的是鸿蒙,这个鸿蒙是?( ) A、小程序 B、计时器 C、操作系统 D、神话人物 答案…

ArcGIS Desktop使用入门(三)图层右键工具——使用符号级别

系列文章目录 ArcGIS Desktop使用入门&#xff08;一&#xff09;软件初认识 ArcGIS Desktop使用入门&#xff08;二&#xff09;常用工具条——标准工具 ArcGIS Desktop使用入门&#xff08;二&#xff09;常用工具条——编辑器 ArcGIS Desktop使用入门&#xff08;二&#x…

Jmeter —— jmeter利用取样器中http发送请求

使用Jmeter发送HTTP请求 取样器是用来模拟用户操作&#xff0c;向服务器发送请求以及接收服务器的响应数 据的一类元件&#xff0c;其中HTTP请求取样器是用来模拟常用的http请求的 步骤如下&#xff1a; 步骤一&#xff1a;添加线程组 右击测试计划——添加——线程&#x…

部署GlusterFS群集

目录 一、部署GlusterFS群集 1. 服务器节点分配 2. 服务器环境&#xff08;所有node节点上操作&#xff09; 2.1 关闭防火墙 2.2 磁盘分区&#xff0c;并挂载 2.3 修改主机名&#xff0c;配置/etc/hosts文件 3. 安装、启动GlusterFS&#xff08;所有node节点上操作&…

【opencv】示例-drawing.cpp画线、箭头、矩形、多边形、椭圆、圆形以及在图像上渲染文本并通过循环实现动态绘制效果...

#include "opencv2/core.hpp" // 引入opencv2核心头文件 #include "opencv2/imgproc.hpp" // 引入opencv2图像处理头文件 #include "opencv2/highgui.hpp" // 引入opencv2高级GUI(head-up display)头文件 #include <stdio.h> // 引入标准输…

智慧工厂如何利用ARM运算平台实现边缘智能控制

AI边缘智能控制成为了推动智慧工厂等领域革新的关键力量。在这个变革的浪潮中&#xff0c;ARM运算平台以其高效能、低功耗的特性&#xff0c;为AI边缘智能控制提供了坚实的硬件基础。通过ARM运算平台&#xff0c;智能设备能够在边缘端实时处理数据&#xff0c;避免了数据传输的…

[Kubernetes集群:master主节点初始化]:通过Calico和Coredns网络插件方式安装

文章目录 前置&#xff1a;Docker和K8S安装版本匹配查看0.1&#xff1a;安装指定docker版本 **[1 — 7] ** [ 配置K8S主从集群前置准备操作 ]一&#xff1a;主节点操作 查看主机域名->编辑域名->域名配置二&#xff1a;安装自动填充&#xff0c;虚拟机默认没有三&#xf…

如何在前后端一体的项目中引入element-ui,即引入index.js、index.css等文件。

24年接手了一个18年的项目&#xff0c;想使用el-ui的组件库&#xff0c;得自己手动引入。 通过官网可以知道&#xff0c;首先得准备以下文件 <!-- 引入样式 --> <link rel"stylesheet" href"https://unpkg.com/element-ui/lib/theme-chalk/index.css…

目标检测——YOLO系列学习(一)YOLOv1

YOLO可以说是单阶段的目标检测方法的集大成之作&#xff0c;必学的经典论文&#xff0c;从准备面试的角度来学习一下yolo系列。 YOLOv1 1.RCNN系列回顾 RCNN系列&#xff0c;无论哪种算法&#xff0c;核心思路都是Region Proposal&#xff08;定位&#xff09; classifier&am…

Redis中的集群(三)

集群 槽指派 记录节点的槽指派信息。 clusterNode结构的slots属性和numslot属性记录了节点负责处理哪些槽: struct clusterNode { // ... unsigned char slots[16384/8];int numslots; // ... }slots属性是一个二进制位数组(bit array)&#xff0c;这个数组的长度位16384/8…

XILINX 7系列时钟资源

文章目录 前言一、时钟概要1.1、CC1.2、BUFR、BUFIO、BUFMR1.3、CMT1.4、BUFH1.5、BUFG 二、时钟路由资源三、CMT 前言 本文主要参考xilinx手册ug472 一、时钟概要 7系列FPGA时钟资源主要有CC、BUFR、BUFIO、BUFMR、CMT、BUFG、BUFH和GTE_COMMON 1.1、CC “CC”&#xff0…