深入理解java web分层架构的高内聚低耦合

在软件开发中,构建一个高效、可维护且可扩展的应用系统一直是开发者追求的目标。分层架构依赖注入(IOC)是实现这一目标的重要策略。本文将深入探讨三层架构的高内聚特性、低耦合的设计原则,以及如何通过IOC(控制反转)技术来进一步提升应用的灵活性和可维护性。

一、三层架构的含义

三层架构是一种常见的软件设计模式,它将应用程序分为三个主要的逻辑层:表示层(请求层)、业务逻辑层(业务处理层)和数据访问层(数据层)。每个层都有特定的职责,这样设计可以提高系统的可维护性、可扩展性和可复用性。具体介绍如下:
在这里插入图片描述

  1. 请求层(controller):

    请求层是系统与外部交互的接口,负责接收用户的请求或其他系统的调用。

  2. 业务逻辑层:

    这一层主要包含系统的核心业务规则和处理逻辑。它接收来自请求层的请求,进行业务处理和数据加工,然后将结果返回给请求层。

  3. 数据访问层:
    数据访问层主要负责与数据库或其他数据源进行交互,实现数据的存储和读取。它将业务逻辑层的抽象数据操作转换为具体的数据库操作。
    ·


    @RestController
    public class UserController {

        @GetMapping("/getUser")
        public String getUser(@RequestParam("userId") int userId) {
            // 将 userId 传递给服务层进行处理
            return "请求已接收,即将传递给服务层处理 userId: " + userId;
        }
    }

二、三层架构的高内聚

高内聚意味着每个层次内部的功能紧密相关,具有明确的职责和功能边界。
请求层只负责处理客户端发来的网络请求,业务层是负责实现业务逻辑,数据层只负责读取存储数据。

三、三层架构的低耦合

低耦合意味着各个层次之间的依赖关系尽可能地减少,相互之间的影响降到最低
比如服务层的serverA换成了serverB,只用更改服务层的代码,不用修改请求层的代码,这就是低耦合。spring项目通过IOC来实现低耦合性
四、IOC 容器
IOC(Inversion of Control,控制反转)容器是一种用于管理对象创建和依赖关系的工具。
在这里插入图片描述

解耦对象的创建和使用:在传统的软件开发中,对象的创建通常由使用它的代码直
接负责。而在 IOC 容器中,对象的创建和生命周期管理由容器负责,使用对象的
代码只需要从容器中获取所需的对象即可,大大降低了代码之间的耦合度。方便依
赖注入:IOC 容器能够自动将对象之间的依赖关系注入到需要的对象中,使得对象
之间的依赖关系更加清晰和易于管理。

在 Spring 框架里,Spring 容器属于典型的 IOC 容器。举个例子,对于一个订单服
务接口(OrderService),它存在两个实现类(serviceA 与 serviceB)。倘若没有
IOC 容器,那么 controller 类或许就得自行创建相应订单实现类的实例。然而,在
Spring IOC 容器的环境下,仅需在 controller 类中运用依赖注入(比如借助
@Autowired 注解)订单服务接口,并且在对应的实现类上添加 @Service 注解,
Spring 容器便会自动把订单服务实现类的实例注入到 controller 之中。

以下示例代码:

  1. 首先创建订单服务接口 OrderService
public interface OrderService {
    void processOrder();
}
  1. 创建两个实现类 ServiceAServiceB

ServiceA.java

import org.springframework.stereotype.Service;


public class ServiceA implements OrderService {
    @Override
    public void processOrder() {
        System.out.println("ServiceA is processing the order.");
    }
}

ServiceB.java

import org.springframework.stereotype.Service;

@Service
public class ServiceB implements OrderService {
    @Override
    public void processOrder() {
        System.out.println("ServiceB is processing the order.");
    }
}
  1. 创建 Controller
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class OrderController {

    @Autowired
    private OrderService orderService;

    @GetMapping("/processOrder")
    public void handleOrder() {
        orderService.processOrder();
    }
}

在上述代码中,@Service 注解用于将 ServiceA 标记为 Spring 管理的服务类。在 OrderController 中,通过 @Autowired 注解实现了对 OrderService 的依赖注入,Spring 容器会根据具体的配置和扫描自动选择合适的实现类注入到 Controller 中。
如果订单服务实现类换成了ServiceB,只用将@Service 注解加到ServiceB上

五、IOC注意事项

  1. 当某个包与启动程序不在同一个包时使用 @ComponentScan
    例子:假设项目的启动类位于 com.example.main 包中,而一些自定义的组件位于 DAO 包中。如果不使用 @ComponentScan 指定包含自定义组件的包,Spring 容器将无法自动扫描和注册这些组件。
    在这里插入图片描述

    代码示例:

@MapperScan({"com.example.springboot","DAO"})
@EnableScheduling
@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
public class MainApplication {

    public static void main(String[] args) {
        SpringApplication.run(MainApplication.class, args);
    }

}    
  1. @Autowired 介绍及遇到多个同类型 bean 的解决方案:

    @Autowired 是 Spring 框架中用于自动装配(依赖注入)的注解。它会根据类型自动在 Spring 容器中查找匹配的 bean 并注入到目标对象中。在刚才那个订单服务例子中,有两个订单服务类,如果ServiceA和ServiceB都注入IOC容器内,程序运行时将会报错,因为这个两个都继承了OrderService接口他们的bean类型相同。

    当遇到多个同类型 bean 的情况时,可以使用以下解决方案:

    @Primary:为某个 bean 添加 @Primary 注解,提高其优先级,确保在注入时优先选择该 bean。
    例子:假设有两个 UserRepository 的实现类 UserRepositoryImpl1UserRepositoryImpl2,如果希望 UserRepositoryImpl1 优先被注入,可以在 UserRepositoryImpl1 上添加 @Primary 注解:
    java @Repository @Primary public class UserRepositoryImpl1 implements UserRepository { // 实现方法 }

    @Qualifier("beanName"):在 @Autowired 注解上面添加 @Qualifier 注解,并指定 bean 的名称,可以精确地选择要注入的 bean。
    例子:
    java @Service public class UserService { @Autowired @Qualifier("userRepositoryImpl2") private UserRepository userRepository; // 其他业务方法 }

    @Resource(name = ''):这也是一种指定 bean 名称进行注入的方式,与 @Qualifier 类似。
    例子:
    java @Service public class UserService { @Resource(name = "userRepositoryImpl2") private UserRepository userRepository; // 其他业务方法 }

总之,三层架构结合 IOC 容器和合理的依赖注入技术,能够构建出结构清晰、易于维护和扩展的软件系统。在实际开发中,我们需要根据项目的具体需求和特点,灵活运用这些技术和设计模式,以提高软件的质量和开发效率。

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

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

相关文章

FPGA开发——在线调试工具Signal Tap的使用

一、简介 在我们进行FPGA进行开发时通常都会经历代码编写,仿真,下板验证等过程。使用FPGA进行开发的小伙伴都知道,在代码编写时往往花费不了太长的时间,下板验证更是。在开发中占绝大部分时间的是仿真,有时候编写代码只…

基于Python的火车票售票系统/基于django的火车购票系统

摘 要 随着信息技术和网络技术的飞速发展,人类已进入全新信息化时代,传统管理技术已无法高效,便捷地管理信息。为了迎合时代需求,优化管理效率,各种各样的管理系统应运而生,各行各业相继进入信息管理时代&…

Ubuntu虚拟机服务器的搭建

01.VMware安装 略。 02.Ubuntu虚拟机安装 略。 03.配置Ubuntu虚拟机网络 参考视频: Ubutu虚拟机网络配置(桥接)https://www.bilibili.com/video/BV1bG411V72A/?spm_id_from333.999.0.0&vd_sourced1fd4bcc46805ab35cc8bbb5a8bf318f…

解决springboot中Aspect注解不生效问题

如下图所示,配置了一个注解类型的Aspect,结果一直不生效 运行结果可以看到,其他非注解类型的Aspect都顺利执行了,但是这个注解的切面就是没有执行 当时也在网上搜了半天,包括在启动类增加配置,接口都要加上…

HTTPS通讯全过程

HTTPS通讯全过程 不得不说,https比http通讯更加复杂惹。在第一次接触https代码的时候,不知道为什么要用用证书,公钥是什么?私钥是什么?他们作用是什么?非对称加密和对称加密是啥?天,…

深度学习设计模式之外观模式

文章目录 前言一、介绍二、特点三、详细分析1.核心组成2.代码示例3.优缺点优点缺点 4.使用场景 总结 前言 外观模式是结构型设计模式,定义一个高层接口,用来访问子系统中的众多接口,使系统更加容易使用。 一、介绍 外观设计模式&#xff08…

一文掌握 Web 测试:功能、界面、兼容与安全的综合测试指南!

随着Web技术的不断演进,测试除了对应用的功能性、界面美观性、跨平台兼容性的基本要求外、安全性和性能的要求也逐步增高。因此,全面、系统的测试思维和策略成为了保证Web应用高质量的关键因素。本篇文章将从功能测试、界面测试、兼容性测试和安全测试四…

transformer-explainer

安装和启动 找到这个项目,然后装好了。 这个项目的目的如名字。 https://github.com/poloclub/transformer-explainerTransformer Explained: Learn How LLM Transformer Models Work with Interactive Visualization - poloclub/transformer-explainerhttps:/…

BVS:多强联手,李飞飞也参与的超强仿真数据生成工具,再掀数据狂潮 | CVPR 2024

BEHAVIOR Vision Suite(BVS)是一个新型工具包,旨在系统评估和全面理解计算机视觉模型。研究人员能够在场景、对象和相机级别控制各种参数,有助于创建高度定制的数据集。 来源:晓飞的算法工程笔记 公众号 论文: BEHAVIO…

Java基础开发之编译异常和运行异常

一、getProperties()方法 1.System类提供一个getProperties()方法用来**当前系统的全部属性,它会返回一个Properties对象,也封装了系统的全部属性,这些属性的存在是以键值对的形式。 2.getProperties()方法使用例子: public cl…

springboot粮仓管理系统的设计与实现论文源码调试讲解

第3章 系统分析 本文作者在确定了研究的课题之后,从各大数字图书馆下载文献来阅读,并了解同类型的网站具备的大致功能,然后具体事务具体分析,得出本系统要研究的具体功能与性能。虽然分析系统这一阶段性工作主要是确定功能&#…

Java二十三种设计模式-状态模式(20/23)

本文深入探讨了状态模式,一种允许对象根据其内部状态变化而改变行为的软件设计模式。文章从定义、组成部分、实现方式、使用场景、优缺点分析、与其他模式的比较,到最佳实践和建议,全面介绍了状态模式的各个方面。通过Java语言的实现示例和实…

如何高效搜集知乎热门话题? 掌握这五种搜索技巧

本文将深入探讨如何高效地在知乎平台上挖掘热门话题,通过揭秘五大实用搜索技巧,帮助内容创作者、市场分析师快速捕捉网络热点,提升内容相关性和曝光率。掌握这些技巧,让你的文章或产品始终站在潮流前沿。 一、为何关注知乎热门话…

Ropdump:针对二进制可执行文件的安全检测工具

关于Ropdump Ropdump是一款针对二进制可执行文件的安全检测工具,该工具基于纯Python开发,是一个命令行工具,旨在帮助广大研究人员检测和分析二进制可执行文件中潜在的ROP小工具、缓冲区溢出漏洞和内存泄漏等安全问题。 功能介绍 1、识别二进…

Python实现水果忍者(开源)

一、整体介绍: 1.1 前言: 游戏代码基于Python制作经典游戏案例-水果忍者做出一些改动,优化并增加了一些功能。作为自己Python阶段学习的结束作品,文章最后有源码链接。 1.2 Python主要知识: (1&#xf…

网络安全-防火墙初步认识。

文章目录 1. 防火墙是什么?2. 防火墙的工作原理是什么?3. 防火墙的分类有哪些?4. 实战4.1 防火墙管理和实验介绍4.2 防火墙命令行初体验实验目标:实验步骤: 4.3 防火墙Web初体验实验目标:实验步骤&#xff…

canvas实现图片矩形截图,矩形旋转后的截图,旋转后的截图摆正显示

一、效果图 二、主要代码 获取矩形框中地方的截图数据 1、先获取矩形四点在画布上的实际坐标值; 2、计算矩形此时实际的宽和高,便于设置后期临时矩形的宽和高; 3、可能矩形旋转了一定的角度,我们新建一个临时的画布tempCanvas&am…

mkv怎么改成mp4?3种mkv转mp4格式方法的介绍

mkv怎么改成mp4?将MKV格式视频转换为MP4格式,能显著提升兼容性,让视频在更多设备、平台上流畅播放。无论是智能手机、平板电脑、智能电视还是网页浏览器,MP4格式都具备广泛的支持,从而扩大视频的传播范围和受众群体。这…

【Hadoop】核心组件深度剖析:HDFS、YARN与MapReduce的奥秘

🐇明明跟你说过:个人主页 🏅个人专栏:《大数据前沿:技术与应用并进》🏅 🔖行路有良友,便是天堂🔖 目录 一、引言 1、Hadoop简介 2、Hadoop生态系统概览 二、Hadoo…

人工智能和机器学习 3(复旦大学计算机科学与技术实践工作站)python机器学习、Pytorch库入门、d2l学习+<机器学习、神经网络————原理、理论>

前言 安装 — 动手学深度学习 2.0.0 documentation (d2l.ai)https://zh.d2l.ai/chapter_installation/index.html 安装 我们需要配置一个环境来运行 Python、Jupyter Notebook、相关库以及运行本书所需的代码,以快速入门并获得动手学习经验。 安装 Miniconda 最…