当前位置: 首页 > news >正文

IOC容器实现分层解耦

         文章开始之前,先引入软件开发的两个名词:耦合和内聚。耦合是指:衡量软件中各个层(三层架构)/各个模块的依赖关联程度;内聚是指:软件中各个功能模块内部的功能联系。三层架构中Controller、Service、Dao是相互依赖关联的,是耦合的,并且在各层级中,直接使用new创建的依赖的对象,假如依赖的对象发生了变化,就必须去修改源代码,这是我们不愿意看到的。三层架构的每一层内部的功能都是独立的,都只处理自身的业务逻辑,其他业务逻辑不会定义在该类中,所以说类聚程度很高。软件开发就是需要“高内聚,低耦合”。

        三层架构解耦的思路

        需要依赖其他层完成业务时,在声明对象的时候,不要直接new对象;需要使用一个容器,将需要使用的对象存储起来,当需要使用该对象时,直接在容器中获得即可,避免用new实例化对象,从而解除耦合。那么如何实现这个操作呢?Spring提供了两个思想(方法):控制反转,依赖注入。

        控制反转、依赖注入、Bean对象

        控制反转

        控制反转(Inversion Of Control),简称IOC。其主要思想是:对象的创建控制权由程序自身(new对象)转移到外部(容器),这个容器也可以称为IOC容器或者Spring容器(一般不用这个名字)。

        依赖注入

        依赖注入(Dependency Injection),简称DI。其主要思想是:IOC容器为应用程序提供运行时所依赖的资源(需要使用的实体类)。

        Bean对象

        Bean对象是IOC容器中创建和管理的对象。

        具体实现

        因为Controller层依赖了Service层、Service层依赖了Dao层,所以说我们要将Dao及Service层的实现类交给IOC容器管理,并且为Controller及Service层注入运行时所依赖的对象(DI)。Spring框架提供了两个注解实现IOC和DI,分别是:@Component,将该类交给IOC容器管理,这个注解一般使用在实现类上面;@AutoWired,从IOC容器中自动寻找依赖的类并注入,使用在类的声明上。

        Controller层

        没有哪一层需要依赖Controller层,所以说Controller不需要交给IOC容器管理,但是Controller层依赖了Service层,所以说在声明Service对象的时候,要在声明上添加@AutoWired注解,表示从IOC容器中进行依赖注入:

package com.wzb.controller;import cn.hutool.json.JSONConfig;
import cn.hutool.json.JSONUtil;
import com.wzb.pojo.User;
import com.wzb.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.List;@RestController
public class UserController {@Autowiredprivate UserService userService;// 获取用户数据的代码不能写在此处,类的成员变量初始化是在类的实例化阶段进行的,此时可能@AutoWired注入还未完成,导致Null// private final List<User> userList = userService.findUser();@RequestMapping("/list")public String list() {List<User> userList = userService.findUser();return JSONUtil.toJsonStr(userList, JSONConfig.create().setDateFormat("yyyy-MM-dd HH:mm:ss"));}}

        特别提醒:在不使用IOC容器的时候,可以将获取数据当作成员变量书写,因为事先已经完成了UserService的初始化,不会为null;但是使用之后,获取数据必须在方法中定义,因为类的成员变量初始化是在类的实例化阶段进行的,此时可能@AutoWired注入还未完成,导致Null。

        Service层

        Service层作为Controller层的依赖,所以说在类名上必须加上@Component注解,代表将该类交给IOC容器管理;Service层还依赖了Dao层,所以说在声明的时候需要使用AutoWired注解

package com.wzb.service.impl;
import com.wzb.dao.UserDao;
import com.wzb.pojo.User;
import com.wzb.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;/*** Service层实现类**/
@Component
public class UserServiceImpl implements UserService {@Autowiredprivate UserDao userDao;// 获取用户数据的代码不能写在此处,类的成员变量初始化是在类的实例化阶段进行的,此时可能@AutoWired注入还未完成,导致Null// private final List<String> lines = userDao.findUser();public List<User> findUser() {List<String> lines = userDao.findUser();List<User> userList = lines.stream().map(line -> {String[] parts = line.split(",");Integer id = Integer.parseInt(parts[0]);String username = parts[1];String password = parts[2];String name = parts[3];Integer age = Integer.parseInt(parts[4]);LocalDateTime updateTime = LocalDateTime.parse(parts[5], DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));return new User(id, username, password, name, age, updateTime);}).collect(Collectors.toList());return userList;}
}

        Dao层

        Dao层不需要依赖其他层,但是Service依赖了Dao层,所以说只需要在类名上添加@Component注解即可:

package com.wzb.dao.impl;import cn.hutool.core.io.IoUtil;
import com.wzb.dao.UserDao;
import org.springframework.stereotype.Component;import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;/*** Dao层的实现类**/
@Component
public class UserDaoImpl implements UserDao {@Overridepublic List<String> findUser() {InputStream in = this.getClass().getClassLoader().getResourceAsStream("user.txt");return IoUtil.readLines(in, StandardCharsets.UTF_8, new ArrayList<>());}
}

        通过Spring框架提供的IOC和DI,简单的实现了分层解耦,降低了模块之间的耦合度,但是也并不是大量使用IOC和DI就是完美的,这其实破坏类的不可变属性:字段注入使得类的依赖对象可以在类实例化后被外部(Spring 容器)随意修改。所以说使用还是要合理。

 

 

 

相关文章:

IOC容器实现分层解耦

文章开始之前&#xff0c;先引入软件开发的两个名词&#xff1a;耦合和内聚。耦合是指&#xff1a;衡量软件中各个层&#xff08;三层架构&#xff09;/各个模块的依赖关联程度&#xff1b;内聚是指&#xff1a;软件中各个功能模块内部的功能联系。三层架构中Controller、Servi…...

Flutter 共性元素动画

在 Flutter 中&#xff0c;共性元素动画&#xff08;Shared Element Transitions&#xff09;用于在页面导航或组件切换时创建视觉上更流畅和连贯的动画效果。这种动画可以使用户感受到两个界面之间的“物理联系”&#xff0c;比如图片从缩略图到全屏的扩大效果。 前置知识点整…...

K8s内存溢出问题剖析:排查与解决方案

文章目录 一、背景二、排查方案&#xff1a;1. 可能是数据量超出了限制的大小&#xff0c;检查数据目录大小2. 查看是否是内存溢出2.1 排查数据量&#xff08;查看数据目录大小是否超过limit限制&#xff09;2.2 查看pod详情发现问题 三、解决过程 一、背景 做redis压测过程中…...

乌班图单机(不访问外网)部署docker和服务的方法

面向对象:Ubuntu不能访问外网的机子,部署mysql、redis、jdk8、minio 过程: 1、安装docker(照着图去这里找对应的下载下来https://download.docker.com/linux/static/stable/),将7个docker官网下载的文件下载下来后,传上去服务器随便一个文件夹或者常用的opt或者/usr/lo…...

使用 pycharm 新建使用 conda 虚拟 python 环境的工程

1. conda 常见命令复习&#xff1a; conda env list // 查看 conda 环境列表 conda activate xxxenv // 进入指定 conda 环境2. 环境展示&#xff1a; 2.1. 我的物理环境的 Python 版本为 3.10.9&#xff1a; 2.2. 我的 conda 虚拟环境 env_yolov9_python_3_8 中的 pyth…...

Docker的save和export命令的区别,load和import的区别 笔记241124

Docker的save和export命令的区别,load和import的区别 解说1: Docker的save和export命令&#xff0c;以及load和import命令&#xff0c;在功能和使用场景上存在显著的区别。以下是对这两组命令的详细对比和解释&#xff1a; Docker save和export命令的区别 使用方式和目的&am…...

通俗理解人工智能、机器学习和深度学习的关系

最近几年人工智能成为极其热门的概念和话题&#xff0c;可以说彻底出圈了。但人工智能的概念在1955年就提出来了&#xff0c;可以说非常古老。我在上小学的时候《科学》课本上就有人工智能的概念介绍&#xff0c;至今还有印象&#xff0c;但那些年AI正处于“寒冬”&#xff0c;…...

使用 pycharm 新建不使用 python 虚拟环境( venv、conda )的工程

有时候我们发现一个好玩的 demo&#xff0c;想赶快在电脑上 pip install 一下跑起来&#xff0c;发现因为 python 的 venv、conda 环境还挺费劲的&#xff0c;因为随着时间的发展&#xff0c;之前记得很清楚的 venv、conda 的用法&#xff0c;不经常使用&#xff0c;半天跑不起…...

【大数据学习 | Spark-SQL】SparkSQL读写数据

我们使用sparksql进行编程&#xff0c;编程的过程我们需要创建dataframe对象&#xff0c;这个对象的创建方式我们是先创建RDD然后再转换rdd变成为DataFrame对象。 但是sparksql给大家提供了多种便捷读取数据的方式。 //原始读取数据方式 sc.textFile().toRDD sqlSc.createDat…...

AI赋能公共服务转型升级 | 第十届中国行业互联网大会暨腾讯云TVP行业大使三周年庆典公共服务专场圆满举办!

引言 党的二十大报告把“基本公共服务实现均等化”作为 2035 年我国发展的总体目标之一&#xff0c;强调要“健全基本公共服务体系&#xff0c;提高公共服务水平”。AI 作为新质生产力的核心驱动力之一&#xff0c;正在公共服务领域发挥着越来越重要的作用。 2024 年 10 月 2…...

关于按天切割Tomcat的catalina.out日志文件的配置

1、catalina.out 是 Tomcat 的标准输出和标准错误日志&#xff0c;通常输出到 Tomcat 安装目录下的 logs 文件夹中。这个日志文件会记录 Tomcat 启动、停止以及运行过程中产生的所有日志信息。 2、在Apache Tomcat中&#xff0c;日志文件catalina.out默认情况下不会自动按天切割…...

【人工智能】深入解析GPT、BERT与Transformer模型|从原理到应用的完整教程

在当今人工智能迅猛发展的时代&#xff0c;自然语言处理&#xff08;NLP&#xff09;领域涌现出许多强大的模型&#xff0c;其中GPT、BERT与Transformer无疑是最受关注的三大巨头。这些模型不仅在学术界引起了广泛讨论&#xff0c;也在工业界得到了广泛应用。那么&#xff0c;G…...

彻底理解如何保证ElasticSearch和数据库数据一致性问题

一.业务场景举例 需求&#xff1a; 一个卖房业务&#xff0c;双十一前一天&#xff0c;维护楼盘的运营人员突然接到合作开发商的通知&#xff0c;需要上线一批热门的楼盘列表&#xff0c;上传完成后&#xff0c;C端小程序支持按楼盘的名称、户型、面积等产品属性全模糊搜索热门…...

2024-2025热门留学趋势

在信息爆炸的时代&#xff0c;留学已成为许多人规划未来、拓宽视野的重要途径。随着全球教育格局的不断变化&#xff0c;留学领域也涌现出一系列新热点和趋势。本文将为您解读2024年最热门的留学话题&#xff0c;并提供实用的准备策略&#xff0c;助您在留学之路上一帆风顺。 热…...

寻找视频特效素材的优质网站推荐 轻松提升作品魅力

在短视频、影视和广告制作中&#xff0c;视频特效素材已成为提升作品专业感的关键元素。炫酷的光效、震撼的爆炸、动感的粒子效果和流畅的转场特效&#xff0c;都能让作品更具吸引力。那么&#xff0c;视频特效素材去哪里找呢&#xff1f;今天&#xff0c;小编为大家精心挑选了…...

【英特尔IA-32架构软件开发者开发手册第3卷:系统编程指南】2001年版翻译,2-36

文件下载与邀请翻译者 学习英特尔开发手册&#xff0c;最好手里这个手册文件。原版是PDF文件。点击下方链接了解下载方法。 讲解下载英特尔开发手册的文章 翻译英特尔开发手册&#xff0c;会是一件耗时费力的工作。如果有愿意和我一起来做这件事的&#xff0c;那么&#xff…...

信息安全实验--密码学实验工具:CrypTool

1. CrypTool介绍&#x1f4ad; CrypTool 1的开源教育工具&#xff0c;用于密码学研究。通过CrypTool 1&#xff0c;可以实现加密和解密操作&#xff0c;数字签名。CrypTool1和2有很多区别的。 2. CrpyTool下载&#x1f527; 在做信息安全实验--密码学相关实验时&#xff0c;发…...

python的class 类创建、方法调用以及属性赋值

题目&#xff1a;购物车系统 创建一个简单的购物车系统&#xff0c;要求如下&#xff1a; 定义一个 Product 类&#xff0c;表示商品&#xff0c;包含以下属性和方法&#xff1a; 属性&#xff1a; name&#xff1a;商品名称&#xff08;字符串&#xff09; price&#xff1…...

Angular v19 (二):响应式当红实现signal的详细介绍:它擅长做什么、不能做什么?以及与vue、svelte、react等框架的响应式实现对比

本文紧接着Angular v19 新版本来啦&#xff0c;一起瞧瞧新特性吧&#xff01;&#xff0c;主要针对它在v18引入了一项全新的响应式技术——Signal&#xff0c;这引起了开发者社区的广泛关注&#xff0c;最新的v19版本推出了更多的signal工具。Signal的加入旨在优化Angular的响应…...

IMX 平台UART驱动情景分析:write篇--从 TTY 层到硬件驱动的写操作流程解析

往期内容 本专栏往期内容&#xff1a;Uart子系统 UART串口硬件介绍深入理解TTY体系&#xff1a;设备节点与驱动程序框架详解Linux串口应用编程&#xff1a;从UART到GPS模块及字符设备驱动 解UART 子系统&#xff1a;Linux Kernel 4.9.88 中的核心结构体与设计详解IMX 平台UART驱…...

网络安全拟态防御技术

一. 拟态防御 拟态现象&#xff08;Mimic Phenomenon, MP&#xff09;是指一种生物如果能够在色彩、纹理和形状等特征上模拟另一种生物或环境&#xff0c;从而使一方或双方受益的生态适应现象。按防御行为分类可将其列入基于内生机理的主动防御范畴&#xff0c;又可称之为拟…...

灵活开源低代码平台——Microi吾码(一)

开源低代码平台-Microi吾码-平台简介1. 什么是低代码平台&#xff1f;2. 它能做什么&#xff1f;3. 它的优点是什么&#xff1f; 平台预览图平台亮点版本区别成功案例源码目录说明Microi吾码 - 系列文档 开源低代码平台-Microi吾码-平台简介 技术框架&#xff1a;.NET8 Redis …...

frida_hook_libart(简单解释)

一&#xff1a;直接取代码 //frida -U -f com.xingin.xhs -l hook_art.js -o xhsart.log //frida -U -f com.tencent.mobileqq -l hook_art.js -o qqart.logconst STD_STRING_SIZE 3 * Process.pointerSize; class StdString {constructor() {this.handle Memory.alloc(STD_S…...

计算机网络八股整理(二)

计算机网络八股整理&#xff08;二&#xff09; 应用层 1&#xff1a;dns的全称了解过吗&#xff1f; dns全称domain-name-system&#xff0c;翻译过来就是域名系统&#xff0c;是在计算机网络中将域名转换成ip地址的分布式数据库系统&#xff1b; 域名服务器的层级类似一个树…...

强化学习off-policy进化之路(PPO->DPO->KTO->ODPO->ORPO->simPO)

需要LLM在训练过程中做生成的方法是 On Policy&#xff0c;其余的为Off Policy。 On Policy是包含了反馈机制&#xff0c;Off Policy不包含反馈机制。 若进行环境交互的模型与被更新的模型是相同的模型&#xff0c;通常这种更新策略被称为on-policy的策略。on-policy的方法会有…...

Linux 如何创建逻辑卷并使用

一、逻辑卷的介绍 生成环境中逻辑卷使用率很高 逻辑卷的诞生&#xff1a;如果对磁盘直接使用fdisk分区&#xff0c;那么这中分区&#xff0c;我们叫做Linux的标准分区&#xff0c;Linux的标准分区格式化成文件系统之后&#xff0c;挂载使用&#xff0c;那么一旦文件系统的空间…...

java实现将图片插入word文档

插入图片所用依赖 private static void insertImage(XWPFDocument document, String path) {List<XWPFParagraph> paragraphs document.getParagraphs();for (XWPFParagraph paragraph : paragraphs) {CTP ctp paragraph.getCTP();for (int dwI 0; dwI < ctp.sizeO…...

初识java(3)

大家好&#xff0c;今天我们来讲讲我们的老伙计-变量&#xff0c;在哪一门编程语言中&#xff0c;变量的作用都是不可或缺的&#xff0c;那么下面我们就来详细了解一下java中的变量。 一.变量概念 在程序中&#xff0c;除了有始终不变的常量外&#xff0c;有些内容可能会经常…...

coqui-ai TTS 初步使用

项目地址&#xff1a;https://github.com/coqui-ai/TTS 1. 创建一个新的conda环境&#xff0c;如果自己会管理python环境也可以用其他方法 克隆项目下来 pip install -r requirements.txt # 安装依赖 pip install coqui-tts # 只要命令行工具的话 下载自己想要的模型 …...

matlab代码--卷积神经网络的手写数字识别

1.cnn介绍 卷积神经网络&#xff08;Convolutional Neural Network, CNN&#xff09;是一种深度学习的算法&#xff0c;在图像和视频识别、图像分类、自然语言处理等领域有着广泛的应用。CNN的基本结构包括输入层、卷积层、池化层&#xff08;Pooling Layer&#xff09;、全连…...

wordpress隐藏菜单/推广公司品牌

一、在上一篇博客中&#xff0c;我们已经安装配置成功Maven,并且建立一个基于Maven的web项目&#xff0c;并且导入mahout依赖。 问题&#xff1a;在网上找到的两个例子ChartTwo与Collaborative Filtering中均没有用Maven建立项目&#xff0c;直接用Mahout。那我们这里为啥要用…...

可信的大连网站建设/地推接单平台

centos7全面升级了引导程序和系统管理程序&#xff0c;使用grub2替代了grub来引导操作系统&#xff0c;使用systemd替换了init管理系统程序&#xff0c;systemd的升级比较激进&#xff0c;从架构上变更init管理程序。微服务docker却希望使用docker domean管理微服务中的进程&am…...

wordpress设置静态访问不了/百度seo关键词排名优化

本文首发 http://zhaoda.net/2018/05/22/centos-php-nginx/转载请注明出处创建用户、组和目录 # web 用户和组 groupadd www useradd -g www www -s /sbin/nologin# 网站目录 mkdir -p /data/htdocs# 日志目录 mkdir -p /data/logs# 创建软件包下载和编译目录&#xff0c;后续软…...

汕尾好网站建设推广/google关键词排名查询

概览 JpaRepository 继承 PagingAndSortingRepository 继承 CrudRepository 继承 Repository 1 Repository 这是一个空接口&#xff0c;主要是用来指定它的子接口是一个持久层接口 实现了Repository的接口默认就是一个持久层接口&#xff0c;会被容器管理起来&#xff1b;这就是…...

自己免费做网站的流程/百度大数据查询怎么用

源码下载 http://www.byamd.xyz/hui-zong-1/1&#xff0e;引言 1.1编写目的 合同管理系统详细设计是设计的第二个阶段&#xff0c;这个阶段的主要任务是在合同管理系统概要设计书基础上&#xff0c;对概要设计中产生的功能模块进行过程描述&#xff0c;设计功能模块的内部细…...

绿化公司和苗圃做网站/seo企业建站系统

Flutter 按钮组件 Flutter里面有很多的Button组件很多&#xff0c;常见的按钮组件有&#xff1a;RaisedButton&#xff0c;FlatButton&#xff0c;IconButton&#xff0c;OutlineButton&#xff0c;ButtonBar&#xff0c;FloationActionButton等.. 组件描述RaisedButton凸起的…...