Java基础——分层解耦——IOC和DI入门

devtools/2025/2/3 23:00:32/

目录

三层架构

Controller

Service

Dao

​编辑

调用过程

面向接口编程

分层解耦

耦合

内聚

软件设计原则

控制反转

依赖注入

Bean对象

如何将类产生的对象交给IOC容器管理?

容器怎样才能提供依赖的bean对象呢?


三层架构

Controller

控制层,也称为控制器,主要职责是接收前端发来的请求,并且给前端响应数据

Service

业务逻辑层,负责具体的业务逻辑处理

Dao

数据访问层,也叫持久层,负责数据访问操作,包括数据的增删改查

在mybatis中通常叫mapper

调用过程

浏览器发起请求先访问Controller,而Controller层仅仅负责接收请求响应数据,并不负责逻辑处理,所以Controller要去调用Service,Service再来进行逻辑处理,而Service进行逻辑处理的前提是要拿到数据,所以Service再来调用Dao,Dao再来访问文件,从文件中加载数据,Dao将数据加载回来后访问Service,Service再来对数据进行逻辑处理,逻辑处理完毕后再将处理后的数据返回给Controller,Controller再将数据响应给前端

面向接口编程

将来项目会升级,项目中的数据肯定不会在文件中存储,他是要存储在专门的数据库中这个时候又要定义一个dao,这个dao要从数据库中加载数据,也有可能项目中的数据来源于网络,这个时候要再定义一个dao,那么dao层就会有多种实现,多种实现加载的数据来源是不一样的。那在项目中为了提高程序的拓展性,便于项目的统一维护管理,我们通常会为dao的多种实现提供一个统一的接口,在接口中定义一个统一的规范,允许的不同的实现,各个实现来实现统一的接口,也就是面向接口编程

提供一个统一的接口

分层解耦

耦合

衡量软件中各个层/各个模块的依赖关联程度

业务层Service代码发生变化,Contrller层代码也要发生跟着变化,我们成为Controller和Service之间耦合了

内聚

软件中各个功能模块内部的功能联系

比如 userSerivice是用户信息操作的Service,这个类中只会去处理用户相关的逻辑,非用户相关的逻辑不会定义在这个类中,我们就说这个类的内聚程度较高,即高内聚

软件设计原则

高内聚低耦合

“高内聚”就是模块内部的联系越紧密越好,“低耦合”是指模块与模块||层与层之间要降低耦合,最好能做到解除耦合,也就是所谓的“解耦”

解耦后service层的代码变动是不会影响controller层的,dao层代码变动也不会影响service层,

想要解耦就不能去new对象,因为service层的代码发生变化,new对象代码部分也要跟着变化,那么层与层之间又耦合起来了

不去new对象,声明了这个对象默认值就是null,调用userService的list方法就会报空指针异常

如何做到不new对象解除耦合又能不报空指针异常呢?

提供一个容器用来存储一些对象,比如想用UserService这个实现类产生的对象,那就可以将这个实现类产生的对象交给容器来管理,在容器中就会产生UserService这个实现类产生的对象,也就是这个一号对象

Controller运行时需要用到UserService这个类型的对象,那么就可以从容器中查找这个对象,让容器给应用程序来提供这个类型的对象,

由此看来,即使Service类的类名发生了变化,或者切换了一个实现类,对于Controller层来说是不用动任何的代码,这样就完成了层与层的解耦

控制反转

简称IOC||Spring容器

对象的创建控制权由程序自身new转移到外部容器,这种思想成为控制反转

依赖注入

简称DI

容器为应用程序提供运行时所依赖的资源,这个过程称为依赖注入

Bean对象

在IOC容器中创建管理的对象,称之为Bean对象

如何将类产生的对象交给IOC容器管理?

在实现类上面加上注释@Conponent,代表将这个类交给IOC容器管理,由IOC容器来负责这个对象的创建

如果是mybatis统一的接口xxxMapper,则在接口上方加上注解@Mapper,代表程序运行时,会自动为这个接口创建一个实现类对象(代理对象),并自动将该实现类对象存入IOC容器中,成为IOC容器的bean对象

容器怎样才能提供依赖的bean对象呢?

在成员变量上加上注解@Autowired,会自动找到容器中UserDao类型的对象,并赋值给这个成员变量,这样就完成了依赖注入的过程。


http://www.ppmy.cn/devtools/155847.html

相关文章

DeepSeek R1与OpenAI o1深度对比

文章目录 引言技术原理DeepSeek R1OpenAI o1 性能表现官方数据推理任务知识密集型任务通用能力 价格对比应用场景科研与技术开发自然语言处理(NLP)企业智能化升级教育与培训数据分析与智能决策 部署与集成DeepSeek R1OpenAI o1 伦理考量DeepSeek R1OpenA…

Spark Streaming的背压机制的原理与实现代码及分析

Spark Streaming的背压机制是一种根据JobScheduler反馈的作业执行信息来动态调整Receiver数据接收率的机制。 在Spark 1.5.0及以上版本中,可以通过设置spark.streaming.backpressure.enabled为true来启用背压机制。当启用背压机制时,Spark Streaming会自…

Springboot集成WebFlux响应式开发详解

下面从Spring WebFlux集成依赖开始WebFlux实际应用场景WebFlux完整示例(以POST方式为例)总结Spring Framework 中包含的原始 Web 框架 Spring Web MVC 是专门为 Servlet API 和 Servlet 容器构建的。响应式堆栈 Web 框架 Spring WebFlux 是在 5.0 版本中添加的。它是完全非阻…

OpenAI的真正对手?DeepSeek-R1如何用强化学习重构LLM能力边界——DeepSeek-R1论文精读

2025年1月20日,DeepSeek-R1 发布,并同步开源模型权重。截至目前,DeepSeek 发布的 iOS 应用甚至超越了 ChatGPT 的官方应用,直接登顶 AppStore。 DeepSeek-R1 一经发布,各种资讯已经铺天盖地,那就让我们一起…

第九章:内存池的调整与测试

目录 第一节:线程私有ThreadCache 第二节:线程申请/释放内存的函数 2-1.ConcurrentAlloc 2-2.ConcurrentFree 第三节:测试优化 第四节:基数树优化 第五节:再次测试 第六节:下期预告 第一节&#xff1…

使用CSS实现一个加载的进度条

文章目录 使用CSS实现一个加载的进度条一、引言二、步骤一:HTML结构与CSS基础样式1、HTML结构2、CSS基础样式 三、步骤二:添加动画效果1、使用CSS动画2、结合JavaScript控制动画 四、使用示例五、总结 使用CSS实现一个加载的进度条 一、引言 在现代网页…

Rust 的基本类型有哪些,他们存在堆上还是栈上,是否可以COPY?

Rust 的基本类型主要包括以下几类: 1. 整数类型(Integer) Rust 提供了有符号和无符号的整数类型: 有符号整数(i8, i16, i32, i64, i128, isize)无符号整数(u8, u16, u32, u64, u128, usize&a…

Git进阶之旅:tag 标签 IDEA 整合 Git

第一章:tag 标签远程管理 git 标签 tag 管理: 标签有两种: 轻量级标签(lightweight)带有附注标签(annotated) git tag 标签名:创建一个标签git tag 标签名 -m 附注内容 :创建一个附注标签git tag -d 标签名…