Java-26 深入浅出 Spring - 实现简易Ioc-02 无IoC与AOP场景下实现业务

点一下关注吧!!!非常感谢!!持续更新!!!

大数据篇正在更新!https://blog.csdn.net/w776341482/category_12713819.html

在这里插入图片描述

目前已经更新到了:

  • MyBatis(已更完)
  • Spring(正在更新…)

在这里插入图片描述

无 IoC 无 AOP

在没有 Spring 的情况下,我们先手动实现业务上的逻辑,并且分层:

  • DAO
  • Servi
  • Controller

IoC(Inversion of Control,控制反转)简介

控制反转(IoC)是一种设计原则,用于实现组件间的解耦,是面向对象编程中非常重要的概念之一。IoC的核心思想是将程序中对对象的控制权从调用方转移到框架或容器中,使得对象之间的依赖关系由容器来管理。

IoC 的特点

解耦

IoC通过将依赖的管理和创建责任交给容器,减少了模块之间的耦合性,增强了系统的可维护性和可扩展性。

动态依赖管理

容器根据配置或注解动态地将依赖注入到对象中,而不需要硬编码的依赖关系。

灵活性

对象的依赖可以在运行时动态修改,只需更改配置即可,不需要修改代码。

IoC 的应用场景

IoC被广泛应用于各种软件开发框架和项目中,以下是几个典型应用:

  • Spring Framework:Spring框架使用IoC容器管理Bean的生命周期和依赖关系。开发者只需定义组件及其依赖,具体的实例化和依赖注入由Spring容器完成。
  • Guice 和 Dagger:这些轻量级DI框架在Java项目中也很流行,提供了简单高效的依赖注入功能。
  • 前端框架(如Angular):Angular中也实现了IoC,通过其依赖注入系统来管理组件和服务之间的依赖关系。

IoC 的优势

  • 增强模块化:通过减少模块之间的直接依赖,促进模块化设计。
  • 提高测试性:依赖注入可以方便地替换依赖对象,从而支持单元测试。
  • 增强灵活性:通过配置或注解动态注入依赖,无需修改代码即可适应变化。
  • 便于维护:解耦使得系统在增加或修改功能时影响最小。

IoC 的限制

  • 学习曲线:初学者需要一定时间理解IoC和DI的概念。
  • 运行时性能开销:IoC容器在运行时解析依赖关系可能会引入一些性能开销。
  • 复杂性:在大型项目中,过度使用IoC可能导致配置和依赖关系变得复杂。

Utils

WzkDruidUtils

/**
 * Druid 工具类
 * 这里用到了单例设计模式、静态代码块初始化
 * @author wzk
 * @date 16:38 2024/11/18
**/
public class WzkDruidUtils {

    private static DruidDataSource druidDataSource = new DruidDataSource();

    static {
        druidDataSource.setDriverClassName("com.mysql.jdbc.Driver");
        druidDataSource.setUrl("jdbc:mysql://172.16.1.130:3306/wzk-mybatis");
        druidDataSource.setUsername("hive");
        druidDataSource.setPassword("hive@wzk.icu");
    }

    private WzkDruidUtils() {

    }

    public static DruidDataSource getInstance() {
        return druidDataSource;
    }
}

对应的代码的截图如下所示:
在这里插入图片描述

WzkConnectionUtils

/**
 * 当前线程SQL 链接器
 * 通过 ThreadLocal 的方式 对 connection 进行传递
 * @author wzk
 * @date 16:43 2024/11/18
**/
public class WzkConnectionUtils {

    private final ThreadLocal<Connection> threadLocal = new ThreadLocal<>();

    public Connection getCurrentConnection() throws SQLException {
        Connection connection = threadLocal.get();
        if (null == connection) {
            connection = WzkDruidUtils.getInstance().getConnection();
            threadLocal.set(connection);
        }
        return connection;
    }
}

对应的代码的截图如下所示:
在这里插入图片描述

DAO层

WzkAccountDao

package wzk.dao;

import wzk.model.WzkAccount;

public interface WzkAccountDao {

    WzkAccount selectWzkAccount(String card) throws Exception;

    int updateWzkAccount(WzkAccount wzkAccount) throws Exception;

}

对应的截图如下所示:
在这里插入图片描述

JdbcWzkAccountDaoImpl

public class JdbcWzkAccountDaoImpl implements WzkAccountDao {

    private WzkConnectionUtils wzkConnectionUtils;

    public void setWzkConnectionUtils(WzkConnectionUtils wzkConnectionUtils) {
        this.wzkConnectionUtils = wzkConnectionUtils;
    }


    @Override
    public WzkAccount selectWzkAccount(String card) throws Exception {
        Connection connection = wzkConnectionUtils.getCurrentConnection();
        String sql = "select * from wzk_account where card = ? limit 1";
        PreparedStatement prepareStatement = connection.prepareStatement(sql);
        prepareStatement.setString(1, card);
        ResultSet resultSet = prepareStatement.executeQuery();
        WzkAccount wzkAccount = new WzkAccount();
        while (resultSet.next()) {
            wzkAccount.setCard(resultSet.getString("card"));
            wzkAccount.setName(resultSet.getString("name"));
            wzkAccount.setMoney(resultSet.getInt("money"));
        }
        resultSet.close();
        prepareStatement.close();
        return wzkAccount;
    }

    @Override
    public int updateWzkAccount(WzkAccount wzkAccount) throws Exception {
        Connection connection = wzkConnectionUtils.getCurrentConnection();
        String sql = "update wzk_account set money =? where card =?";
        PreparedStatement prepareStatement = connection.prepareStatement(sql);
        prepareStatement.setInt(1, wzkAccount.getMoney());
        prepareStatement.setString(2, wzkAccount.getCard());
        int result = prepareStatement.executeUpdate();
        prepareStatement.close();
        return result;
    }
}

对应的截图如下所示:
在这里插入图片描述

Service层

WzkTransferService

package wzk.service;

public interface WzkTransferService {

    void transfer(String fromCard, String toCard, int money) throws Exception;

}

对应的截图如下所示:
在这里插入图片描述

WzkTransferServiceImpl

public class WzkTransferServiceImpl implements WzkTransferService {

    private WzkAccountDao wzkAccountDao;

    public void setWzkAccountDao(WzkAccountDao wzkAccountDao) {
        this.wzkAccountDao = wzkAccountDao;
    }


    @Override
    public void transfer(String fromCard, String toCard, int money) throws Exception {
        WzkAccount from = wzkAccountDao.selectWzkAccount(fromCard);
        WzkAccount to = wzkAccountDao.selectWzkAccount(toCard);
        from.setMoney(from.getMoney() - money);
        to.setMoney(to.getMoney() + money);
        int fromResult = wzkAccountDao.updateWzkAccount(from);
        int toResult = wzkAccountDao.updateWzkAccount(to);
        System.out.println("transfer fromResult: " + fromResult + " toResult: " + toResult);
    }
}

对应的截图如下所示:
在这里插入图片描述

Controller 层

这里就用 Servlet 了,不具体实现了。

WzkServlet

@WebServlet(name="wzkServlet", urlPatterns = "/wzkServlet")
public class WzkServlet extends HttpServlet {

    @Override
    protected void doGet(javax.servlet.http.HttpServletRequest req, javax.servlet.http.HttpServletResponse resp) throws javax.servlet.ServletException, IOException {
        System.out.println("=== WzkServlet doGet ===");
        // 由于没有 Spring 的帮助 我们就需要手动去创建和维护依赖之间的关系
        // 组装 DAO DAO层依赖于 ConnectionUtils 和 DruidUtils
        JdbcWzkAccountDaoImpl jdbcWzkAccountDaoImpl = new JdbcWzkAccountDaoImpl();
        jdbcWzkAccountDaoImpl.setConnectionUtils(new WzkConnectionUtils());
        // 组装 Service
        WzkTransferServiceImpl wzkTransferService = new WzkTransferServiceImpl();
        wzkTransferService.setWzkAccountDao(jdbcWzkAccountDaoImpl);

        // 执行业务逻辑
        try {
            wzkTransferService.transfer("1", "2", 100);
        } catch (Exception e) {
            System.out.println("=== transfer error ====");
        }
        resp.setContentType("application/json;charset=utf-8");
        resp.getWriter().print("=== WzkServlet doGet ===");
    }

}

对应的截图如下所示:
在这里插入图片描述

测试运行

我们启动服务,在浏览器或者Postman 中访问我们的 URL。

http://localhost:8999/wzkServlet

对应的输出结果如下所示:
在这里插入图片描述
我们查询数据库的信息,可以看到如下的内容:
在这里插入图片描述

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

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

相关文章

工作流审批功能全解析:提升流程效率的关键要素

1. 引言 在当今数字化时代&#xff0c;企业与组织的运营效率在很大程度上依赖于高效、精准的工作流审批系统。随着业务日益复杂且多样化&#xff0c;审批流程变得愈加细致和灵活。一个完善的工作流审批系统不仅能确保任务在组织内部有序流转、协调各方资源&#xff0c;还能实现…

API接口示例:电商商品评论数据

当然&#xff0c;以下是一个简化的电商商品评论数据API接口的示例。请注意&#xff0c;这只是一个示例&#xff0c;实际的API接口可能会更加复杂&#xff0c;并且会包含更多的验证、错误处理和安全措施。 API接口示例&#xff1a;电商商品评论数据 基础信息 API名称&#xf…

HCIA-Access V2.5_2_2_2网络通信基础_IP编址与路由

网络层数据封装 首先IP地址封装在网络层&#xff0c;它用于标识一台网络设备&#xff0c;其中IP地址分为两个部分&#xff0c;网络地址和主机地址&#xff0c;通过我们采用点分十进制的形式进行表示。 IP地址分类 对IP地址而言&#xff0c;它细分为五类&#xff0c;A,B,C,D,E,…

Microsemi Libero使用技巧11——CoreUARTAPB RX管脚分配时不显示

调用串口IP核CoreUARTAPB&#xff0c;并例化到顶层设计&#xff0c;发现UART_RX管脚在进行管脚分配时没有显示出来&#xff0c;最后发现是CoreAPB3总线IP核配置不对导致&#xff0c;改为如下配置后正常。

SEGGER | 基于STM32F405 + Keil - RTT组件01 - 移植SEGGER RTT

导言 RTT(Real Time Transfer)是一种用于嵌入式中与用户进行交互的技术&#xff0c;它结合了SWO和半主机的优点&#xff0c;具有极高的性能。 使用RTT可以从MCU非常快速输出调试信息和数据&#xff0c;且不影响MCU实时性。这个功能可以用于很多支持J-Link的设备和MCU&#xff0…

SpringBoot集成JWT和Redis实现鉴权登录功能

目前市面上有许多鉴权框架&#xff0c;鉴权原理大同小异&#xff0c;本文简单介绍下利用JWT和Redis实现鉴权功能&#xff0c;算是抛砖引玉吧。 主要原理就是“令牌主动失效机制”&#xff0c;主要包括以下4个步骤&#xff1a; (1)利用拦截器LoginInterceptor实现所有接口登录拦…

29.在Vue 3中使用OpenLayers读取WKB数据并显示图形

在Web开发中&#xff0c;地理信息系统&#xff08;GIS&#xff09;应用越来越重要&#xff0c;尤其是在地图展示和空间数据分析的场景中。OpenLayers作为一个强大的开源JavaScript库&#xff0c;为开发者提供了丰富的地图展示和空间数据处理能力。在本篇文章中&#xff0c;我将…

【bWAPP】 HTML Injection (HTML注入)

我们都是在一条铺满荆棘的新路上摸索着前行&#xff0c;碰个鼻青眼肿几乎不可避免&#xff0c;而问题在于&#xff0c;我们能不能在这条路上跌倒之后&#xff0c;爬起来继续走下去。 HTML Injection - Reflected (GET) get方式的html代码注入 漏洞url&#xff1a;http://ran…

内网是如何访问到互联网的(华为源NAT)

私网地址如何能够访问到公网的&#xff1f; 在上一篇中&#xff0c;我们用任意一个内网的终端都能访问到百度的服务器&#xff0c;但是这是我们在互联网设备上面做了回程路由才实现的&#xff0c;在实际中&#xff0c;之前也说过运营商是不会写任何路由过来的&#xff0c;那对于…

tomcat的优化和动静分离

tomcat的优化 1.tomcat的配置优化 2.操作系统的内核优化 注意&#xff1a;设置保存后&#xff0c;需要重新ssh连接才会看到配置更改的变化 vim /etc/security/limits.conf # 65535 为Linux系统最大打开文件数 * soft nproc 65535 * hard nproc 65535 * soft nofile 65535 *…

粗略的过一下StableDiffusion3的一些方面

什么是Stable Diffusion 3 Stable Diffusion 3是由Stability AI开发的最新且最先进的文本生成图像模型之一&#xff0c;在图像保真度、多主体处理和文本遵循性方面实现了显著提升。该模型采用了全新的多模态扩散变压器&#xff08;MMDiT&#xff09;架构&#xff0c;并为图像和…

测试工程师八股文04|计算机网络 和 其他

一、计算机网络 1、http和https的区别 HTTP和HTTPS是用于在互联网上传输数据的协议。它们都是应用层协议&#xff0c;建立在TCP/IP协议栈之上&#xff0c;用于客户端&#xff08;如浏览器&#xff09;和服务器之间的通信。 ①http和https的主要区别在于安全性。http是一种明…

doxygen–自动生成文档工具

原文地址&#xff1a;doxygen–自动生成文档工具 – 无敌牛 欢迎参观我的个人博客&#xff1a;无敌牛 – 技术/著作/典籍/分享等 简介 doxygen是软件开发中广泛使用的文档生成工具。它可以从源代码注释中自动生成文档&#xff0c;解析类、函数、参数相关信息&#xff0c;并生…

ElasticSearch04-高级操作

零、文章目录 ElasticSearch04-高级操作 1、文档添加 &#xff08;1&#xff09;生成文档ID 不指定 ID&#xff0c;即自动生成ID&#xff0c;ID 是一行数据的唯一键。语法&#xff1a;POST /index/_doc # 创建索引 PUT testid# 默认情况下自动生成ID POST /testid/_doc {&…

【GitHub分享】you-get项目

【GitHub分享】you-get 一、介绍二、安装教程三、使用教程四、配置ffmpeg五&#xff0c;卸载 如果大家想要更具体地操作可去开源网站查看手册&#xff0c;这里只是一些简单介绍&#xff0c;但是也够用一般&#xff0c;有什么问题&#xff0c;也可以留言。 一、介绍 you-get是一…

Polars数据聚合与旋转实战教程

在这篇博文中&#xff0c;我们的目标是解决数据爱好者提出的一个常见问题&#xff1a;如何有效地从Polars DataFrame中创建汇总视图&#xff0c;以便在不同时间段或类别之间轻松进行比较。我们将使用一个实际的数据集示例来探索实现这一目标的各种方法。 Polars简介 Polars 是…

ECharts柱状图-柱图2,附视频讲解与代码下载

引言&#xff1a; 在数据可视化的世界里&#xff0c;ECharts凭借其丰富的图表类型和强大的配置能力&#xff0c;成为了众多开发者的首选。今天&#xff0c;我将带大家一起实现一个柱状图图表&#xff0c;通过该图表我们可以直观地展示和分析数据。此外&#xff0c;我还将提供…

Oracle进行exp导出密码中有特殊字符报EXP-00056和ORA-12154错处理

今天&#xff0c;业务人员反馈&#xff0c;在本地进行exp导出时报错&#xff0c;报错内容如下&#xff1a; 在Oracle密码中有特殊字符时&#xff0c;需要加引号&#xff0c;但引号怎么加呢&#xff1f;总结如下&#xff1a; 1、在windows系统中 exp 用户名/“““密码”””n…

解决没法docker pull问题

没想到国内源死差不多了&#xff0c;以下内容需要提前科学上网 su cd /etc/systemd/system/docker.service.d vim proxy.conf 参照下图修改&#xff0c;代理服务器改成你自己的。 ​​[Service] Environment"HTTP_PROXYsocks5://192.168.176.180:10810" Environment&…

LeNet-5:深度学习与卷积神经网络的里程碑

目录 ​编辑 引言 LeNet-5的结构与原理 输入层 C1层&#xff1a;卷积层 S2层&#xff1a;池化层 C3层&#xff1a;卷积层 S4层&#xff1a;池化层 C5层&#xff1a;卷积层 F6层&#xff1a;全连接层 输出层 LeNet-5的算法基础 LeNet-5的优点 LeNet-5的现代应用 …