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

Java-27 深入浅出 Spring - 实现简易Ioc-03 在上节的业务下手动实现IoC

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

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

在这里插入图片描述

目前已经更新到了:

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

在这里插入图片描述

上节进度

上节完成了基本代码的编写,本节我们继续。本节将进行 IoC的实现。

IoC 实现

此时我们需要一个 Bean 的管理容器,当我们需要 new 对象的时候,可以直接从容器中获取出来。但是我们需要在程序启动的时候(当然也可以懒加载)就把这些对象初始化出来,所以我们需要 XML 来告诉容器需要加载什么内容。

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可能导致配置和依赖关系变得复杂。

Resources

Resources 目录下

beans.xml

我们先编写一个 XML 来保存我们的 Bean 的信息:

<?xml version="1.0" encoding="UTF-8" ?>
<!-- BeanFactory 类会进行处理这块内容 -->
<beans><!-- WzkConnectionUtils 交给容器管理 --><bean id="wzkConnectionUtils" class="wzk.utils.WzkConnectionUtils"></bean><!-- 依赖了工具类 WzkConnectionUtils --><!-- id 是放入到容器中的名称 --><bean id="wzkAccountDao" class="wzk.dao.impl.JdbcWzkAccountDaoImpl"><!-- name是成员变量名字 ref是引用从容器中拿对象 --><property name="WzkConnectionUtils" ref="wzkConnectionUtils"/></bean><!-- 依赖了 WzkAccountDao --><bean id="wzkTransferService" class="wzk.service.impl.WzkTransferServiceImpl"><!-- name是成员变量名字 ref是引用从容器中拿对象 --><property name="WzkAccountDao" ref="wzkAccountDao"></property></bean>
</beans>

对应的内容截图如下所示:
在这里插入图片描述
注意:需要将 beans.xml 放置到 resources 目录下。
在这里插入图片描述

Proxy

BeanFactory

public class BeanFactory {private BeanFactory() {}/*** 全局容器 对象都存储到这里*/private static Map<String, Object> map = new HashMap<>();static {// 对 XML 进行处理,这里可以参考我们之前 手写的MyBatis的部分// 静态代码块 来进行初始化InputStream resourceAsSteam = BeanFactory.class.getClassLoader().getResourceAsStream("beans.xml");SAXReader saxReader = new SAXReader();try {Document document = saxReader.read(resourceAsSteam);Element rootElement = document.getRootElement();List<Element> beanList = rootElement.selectNodes("//bean");for (Element element : beanList) {// 处理每个 Bean 元素String id = element.attributeValue("id");String clazz = element.attributeValue("class");// 反射拿到对象Class<?> aClass = Class.forName(clazz);Object object = aClass.newInstance();// 保存到容器中map.put(id, object);}List<Element> propertyList = rootElement.selectNodes("//property");for (Element element : propertyList) {// 处理每个依赖关系String name = element.attributeValue("name");String ref = element.attributeValue("ref");// 拿到父级节点 它下边的 property都是它的依赖Element parentElement = element.getParent();String parentId = parentElement.attributeValue("id");// 通过父级的 ID 拿到对象Object parentObject = map.get(parentId);// 拿到父级的所有方法 Get Set 等等Method[] methods = parentObject.getClass().getMethods();for (Method method : methods) {// 如果是 set 方法的话 我们调用就可以将它的依赖赋值给父级if (method.getName().equalsIgnoreCase("set" + name)) {method.invoke(parentObject, map.get(ref));}}// 记得更新容器的内容map.put(parentId, parentObject);}System.out.println("BeanFactory 初始化完毕 map:" + map);} catch (Exception e) {System.out.println("BeanFactory 初始化失败");e.printStackTrace();}}public static Object getBean(String id) {return map.get(id);}}

对应的截图如下所示:

在这里插入图片描述

Controller

WzkServlet

我们对 WzkServlet 进行一些修改:

@WebServlet(name="wzkServlet", urlPatterns = "/wzkServlet")
public class WzkServlet extends HttpServlet {// ========================== 2 ==========================// 由 BeanFactory 处理private WzkTransferService wzkTransferService = (WzkTransferService) BeanFactory.getBean("wzkTransferService");// =======================================================@Overrideprotected void doGet(javax.servlet.http.HttpServletRequest req, javax.servlet.http.HttpServletResponse resp) throws javax.servlet.ServletException, IOException {System.out.println("=== WzkServlet doGet ===");// ======================= 1 =============================// 由于没有 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) {e.printStackTrace();System.out.println("=== transfer error ====");}resp.setContentType("application/json;charset=utf-8");resp.getWriter().print("=== WzkServlet doGet ===");}}

WzkServlet(2)

还有一种写法也是类似的,这样的处理方式也可以顺利执行的。

// ========================== 3 ==========================// 另一种方式 相同的private WzkTransferService wzkTransferService;@Overridepublic void init() throws ServletException {super.init();this.wzkTransferService = (WzkTransferService) BeanFactory.getBean("wzkTransferService");}// ======================================================

测试运行

我们运行代码之后,可以看到控制台如下所示:

BeanFactory 初始化完毕 map:{wzkTransferService=wzk.service.impl.WzkTransferServiceImpl@5dfdd67c, wzkAccountDao=wzk.dao.impl.JdbcWzkAccountDaoImpl@380d9fc0, wzkConnectionUtils=wzk.utils.WzkConnectionUtils@2d150354}
=== WzkServlet doGet ===
Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.
1118, 2024 6:24:24 下午 com.alibaba.druid.pool.DruidDataSource info
信息: {dataSource-1} inited
transfer fromResult: 1 toResult: 1

对应的控制台结束如下所示:
在这里插入图片描述

查看结果

数据库的结果已经变化了,可以看到结果如下:
在这里插入图片描述
当然,刚才的代码打印的内容,也说明我们的代码是正常工作的。
(你可以打断点进行调试)

目前问题

我们虽然已经实现了简易的 IoC,但是对于当前业务来说,我们还需要对事务进行控制,此时需要我们实现一个事务的管理器,将采取和数据库一样,用 ThreadLocal 来进行控制。

相关文章:

Java-27 深入浅出 Spring - 实现简易Ioc-03 在上节的业务下手动实现IoC

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 大数据篇正在更新&#xff01;https://blog.csdn.net/w776341482/category_12713819.html 目前已经更新到了&#xff1a; MyBatis&#xff…...

kubernetes学习-使用metrics-server监控集群资源和查看日志

kubernetes学习-使用metrics-server监控集群资源和查看日志 一 、简介二、应用场景三、部署四、查看日志 一 、简介 Metrics Server 是一个用于 Kubernetes 集群的监控工具&#xff0c;它用于收集、存储和提供关于集群中各种资源的度量数据。Metrics Server 是 Kubernetes 中一…...

解决 Git Permission denied 问题

前言 push项目时出现gitgithub.com: Permission denied (publickey). fatal: Could not read from remote repository.Please make sure you have the correct access rights and the repository exists.出现这个问题表示你在尝试将本地代码推送到GitHub时&#xff0c;没有提供…...

CCNP_SEC_ASA 第三天作业

实验需求&#xff1a; ASA 使用列表放行 Outside 路由器到 DMZ 路由器的 WWW 流量并拒绝 Telnet 流量&#xff0c;当放行和拒绝流量匹配后产生日志通告。 提示&#xff1a;需要使能 ASA的日志功能和 DMZ路由器的 HTTP功能。 设备配置&#xff1a; ##此处展示各设备的配置&am…...

TypeError: Cannot read properties of null (reading ‘ce‘)

vue项目本地跑不起来&#xff0c;但是build之后能运行&#xff0c;本地报错 是因为你的vue版本不对&#xff0c;你的package可能是这样写的 这个表示你允许你的npm安装vue3的任意版本&#xff0c;但是build是按照这个版本来的&#xff0c;所以build之后能运行&#xff0c;本地运…...

AdminJS - 集成 MySQL 的现代化管理面板开发指南

AdminJS - 集成 MySQL 的现代化管理面板开发指南 MySQL 集成配置 首先需要安装必要的依赖&#xff1a; npm install adminjs adminjs/express express npm install adminjs/sequelize sequelize mysql2基础配置示例 const AdminJS require(adminjs) const AdminJSExpress …...

上传文件(vue3)

使用el-upload 先上传到文件服务器&#xff0c;生成url 然后点击确定按钮&#xff1a; 保存数据 <template><el-dialog top"48px" width"500" title"新增协议" :modelValue"visible" close"handleClose()">…...

【Win10 环境vscode配置boost】

文章目录 Boost exe版本windows环境安装vscode配置安装测试总结 Boost exe版本windows环境安装 这里不介绍boost源码安装&#xff0c;请自行网络搜索。本文要介绍的是window下单c文件&#xff08;cpp&#xff09;&#xff0c;调用boost库的执行配置。不涉及多文件。 安装文件下…...

中间件 redis安装

redis官网地址&#xff1a;Redis - The Real-time Data Platform 环境 CentOS Linux release 7.9.2009 (Core) java version "17.0.12" 2024-07-16 LTS 1、通过压缩包安装redis 1&#xff0c;远程下载redis压缩包&#xff0c;或去官网下载&#xff1a;Downloads …...

[java] 简单的熔断器scala语言案例

failureRateInterval时间内如果addEx(错误)达到 maxFailuresPerInterval 次数&#xff0c;则fused方法返回true,表示触发熔断&#xff0c;进入冷却期coolingInterval&#xff0c;冷却期内fused方法返回true&#xff0c;冷却期过后进入下一个错误统计周期。 scala语言完成 imp…...

【java】序列化的种类和使用场景

文章目录 序列化概述什么是序列化&#xff1f;序列化的作用 Java内置序列化java.io.Serializable接口使用ObjectOutputStream和ObjectInputStream优缺点分析 自定义序列化实现Externalizable接口自定义序列化方法适用场景 第三方序列化框架KryoProtobuf (Google Protocol Buffe…...

Qt5与Qt6中的高DPI缩放属性解析

在Qt5中&#xff0c;高DPI缩放默认是禁用的。为了启用它&#xff0c;开发者需要设置Qt::AA_EnableHighDpiScaling应用程序属性。然而&#xff0c;在Qt6中&#xff0c;高DPI缩放默认是启用的&#xff0c;并且不能被禁用。这种变化使得开发者在处理高分辨率屏幕时更加方便&#x…...

Mac使用总结

Mac 常用快捷键 复制&#xff1a;Cmdc粘贴&#xff1a;Cmdv只粘贴文档&#xff1a; ShiftCmdv行首&#xff1a; Cmd<行尾&#xff1a;Cmd>鼠标处选中到行首&#xff1a;ShiftCmd<鼠标处选中到行尾&#xff1a;ShiftCmd>选中整行&#xff1a;上面两个命令组合鼠标处…...

【日期规则】EXCEl 自定义日期匹配规则,学习基础知识,自由匹配场景

excel 新建规则工具路径&#xff1a;开始 - 条件格式 - 新建规则 B$1TODAY() 注意&#xff1a;新建规则后&#xff0c;要点击 条件格式 - 管理规则 - 应用于 要选择规则应用范围 使用场景&#xff1a; excel 做进度管理当中可以查看当天的情况&#xff1b;每周的学习规划 或…...

苹果电脑可以安装windows操作系统吗?Mac OS X/OS X/macOS傻傻分不清?macOS系统的Java支持?什么是macOS的五大API法王?

苹果电脑可以安装windows操作系统吗? 先抛开虚拟机安装&#xff0c;苹果电脑可以安装Windows操作系统。苹果公司提供了一个名为Boot Camp的软件&#xff0c;它允许用户在Mac电脑上安装Windows操作系统。通过Boot Camp&#xff0c;用户可以在启动电脑时选择是要进入macOS还是Wi…...

芋道SpringBoot配置Maven、创建SpringBoot项目、创建Web接口、读取配置信息

&#x1f339;作者主页&#xff1a;青花锁 &#x1f339;简介&#xff1a;Java领域优质创作者&#x1f3c6;、Java微服务架构公号作者&#x1f604; &#x1f339;简历模板、学习资料、面试题库、技术互助 &#x1f339;文末获取联系方式 &#x1f4dd; 系列文章目录 第一章 芋…...

物理机内网穿透

前言&#xff1a; 本文主要讲述如何使用内网穿透以及其安全性。 将带领大家在公网上搭建几个常用靶场。 一&#xff0c;什么是内网穿透。 大多数情况下&#xff0c;我们的个人电脑都处于内网&#xff0c;即没有可公开访问的独立 IP 地址&#xff0c;因此其他内网用户找不到…...

Vue 3: 通过图片链接获取图片颜色,间接设置背景颜色

在现代Web开发中&#xff0c;动态获取和处理图像数据是一个常见的需求。例如&#xff0c;你可能希望自动提取一张图片的主色调&#xff0c;以便根据这些颜色进行UI主题调整或其他视觉效果的处理。本文将介绍如何在Vue 3项目中&#xff0c;通过一个图片链接获取图片的颜色信息。…...

opencv-python的简单练习

题目1.读取一张彩色图像并将其转换为灰度图。 import cv2 # 读取图片文件 img cv2.imread(./1.png)# 将原图灰度化 img_gray cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)# 输出图片 cv2.imshow(img,img) cv2.imshow(img_g,img_gray) # 进行阻塞 cv2.waitKey(0) 题目2&#xff1a;…...

如何使用生成式AI实现跨领域内容生成

文章目录 引言生成式AI的基本概念定义与分类技术发展现状 跨领域内容生成的技术实现数据准备模型选择与设计训练策略 应用案例分析教育培训新闻媒体文化创意产业 实践建议确定明确的目标构建合适的团队持续迭代改进遵守法律法规 结论 引言 在当今数字化时代&#xff0c;信息的…...

避坑指南:Vue2中xlsx-style设置行高无效?手把手教你修改源码并封装通用导出函数

Vue2中xlsx-style行高设置失效的深度解决方案与工程化封装 在Vue2项目中处理Excel导出时&#xff0c;很多开发者会遇到一个令人困惑的问题&#xff1a;明明按照xlsx-style的文档设置了row.hpx属性&#xff0c;导出的Excel文件却依然保持默认行高。这背后其实隐藏着xlsx.js源码中…...

Qwen-Image-Edit-2511商业落地:快速生成产品设计图,提升工作效率

Qwen-Image-Edit-2511商业落地&#xff1a;快速生成产品设计图&#xff0c;提升工作效率 1. 产品设计效率的革命性提升 在当今快节奏的商业环境中&#xff0c;产品设计团队面临着前所未有的压力&#xff1a;需要在更短时间内交付更多设计方案&#xff0c;同时保持高质量和创新…...

qmcdump:三分钟解锁你的QQ音乐加密音频文件

qmcdump&#xff1a;三分钟解锁你的QQ音乐加密音频文件 【免费下载链接】qmcdump 一个简单的QQ音乐解码&#xff08;qmcflac/qmc0/qmc3 转 flac/mp3&#xff09;&#xff0c;仅为个人学习参考用。 项目地址: https://gitcode.com/gh_mirrors/qm/qmcdump 你是否曾下载过Q…...

OpenClaw安全防护指南:Qwen3-32B私有化部署下的权限管控策略

OpenClaw安全防护指南&#xff1a;Qwen3-32B私有化部署下的权限管控策略 1. 为什么需要关注OpenClaw的安全防护&#xff1f; 当我第一次把OpenClaw部署在自己的开发机上时&#xff0c;那种兴奋感至今记忆犹新——一个能帮我自动处理文件、整理资料、甚至写代码的AI助手&#…...

别再死记硬背了!用MONAI Transform处理医学图像,这5个实战场景帮你一次搞懂

医学图像处理实战&#xff1a;5个MONAI Transform核心场景解析 医学影像AI开发中最令人头疼的环节&#xff0c;往往不是模型设计&#xff0c;而是数据预处理。我曾见过不少团队花费80%的时间在数据清洗和转换上&#xff0c;却依然难以构建标准化的处理流程。MONAI Transform的出…...

OpenClaw学术场景应用:Qwen3-32B镜像辅助论文数据处理

OpenClaw学术场景应用&#xff1a;Qwen3-32B镜像辅助论文数据处理 1. 为什么需要自动化论文数据处理&#xff1f; 作为一名经常需要处理实验数据的研究人员&#xff0c;我过去常常花费大量时间在Excel和Python之间来回切换。数据清洗、格式转换、异常值检测这些重复性工作不仅…...

Qwen-Image-2512风格迁移实战:将名画风格应用于产品设计

Qwen-Image-2512风格迁移实战&#xff1a;将名画风格应用于产品设计 1. 引言 你有没有想过&#xff0c;把梵高《星空》的笔触用在你的咖啡杯上&#xff0c;或者让莫奈的睡莲色调渲染你的手机壳&#xff1f;听起来像是顶级设计师的专属魔法&#xff0c;但现在&#xff0c;借助…...

IBM与Arm达成战略合作,携手开发“双架构硬件”

IBM正式宣布与Arm达成合作。双方将携手共同开发新型“双架构硬件”&#xff0c;旨在助力企业以更高的灵活性、可靠性与安全性&#xff0c;运行未来的人工智能&#xff08;AI&#xff09;及数据密集型工作负载。这一计算平台充分融合了IBM在系统可靠性、安全性和可扩展性方面的显…...

OpenClaw+SecGPT-14B:构建无需编程的内网资产管理系统

OpenClawSecGPT-14B&#xff1a;构建无需编程的内网资产管理系统 1. 为什么需要无代码内网资产管理 去年接手公司IT运维时&#xff0c;我发现内网设备清单还是三年前的Excel表格。每当新设备接入或旧设备淘汰&#xff0c;手动更新文档总会被遗忘。更麻烦的是&#xff0c;不同…...

7个Live-Charts单元测试实战技巧:确保图表组件稳定运行的完整指南

7个Live-Charts单元测试实战技巧&#xff1a;确保图表组件稳定运行的完整指南 【免费下载链接】Live-Charts Simple, flexible, interactive & powerful charts, maps and gauges for .Net 项目地址: https://gitcode.com/gh_mirrors/li/Live-Charts Live-Charts是一…...