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

手写Spring:第3章-实现Bean的定义、注册、获取

文章目录

  • 一、目标:实现Bean的定义、注册、获取
  • 二、设计:实现Bean的定义、注册、获取
  • 三、实现:实现Bean的定义、注册、获取
    • 3.1 工程结构
    • 3.2 实现Bean的定义、注册、获取类图
    • 3.3 定义Bean异常
    • 3.4 BeanDefinition定义和注册
      • 3.4.1 BeanDefinition定义
      • 3.4.2 BennDefinition定义注册接口
    • 3.5 单例注册接口定义和实现
      • 3.5.1 单例注册接口
      • 3.5.2 单例注册接口的实现
    • 3.6 抽象类定义模板方法
      • 3.6.1 Bean工厂接口
      • 3.6.2 抽象Bean工厂基类,定义模板方法
      • 3.6.3 实例化Bean类
      • 3.6.4 核心类:默认的Bean工厂实现
  • 四、测试:实现Bean的定义、注册、获取
  • 五、总结:实现Bean的定义、注册、获取

一、目标:实现Bean的定义、注册、获取

💡 实现 Bean 容器关于 Bean 对象的注册和获取?

  • Bean 的创建交给容器,而不是我们在调用时候传递一个实例化好的 Bean 对象。
  • 另外还需要考虑单例对象,在对象的二次获取时是可以从内存中获取对象的。
  • 此外不仅要实现功能还需要完善基础容器框架的类结构体,否则将来就很难扩容进去其他的功能。

二、设计:实现Bean的定义、注册、获取

💡 实现Bean的定义、注册、获取?

  • 首先是在 Bean 注册的时候只注册一个类信息,而不会直接把实例化信息注册到 Spring 容器中。
  • 那么就需要修改 BeanDefinition 中的属性 ObjectClass,接下来就是在获取 Bean 对象时需要处理 Bean 对象的实例化操作以及判断当前单例对象在容器中是否已经缓存起来。

在这里插入图片描述

  • 首先需要定义 BeanFactory 这样一个 Bean 工厂,提供 Bean 的获取方法 getBean(String name),之后这个 Bean 工厂接口由抽象类 AbstractBeanFactory 实现。
    • 这样用 模板模式 的设计方式,可以统一设计通用核心方法的调用逻辑和标准定义,也就很好的控制了后续的实现者不用关心调用逻辑。
    • 按照统一方式执行。那么类型的继承者只需要关心具体方法的逻辑实现即可。
  • 在继承抽象类 AbstractBeanFactory 后的 AbstractAutowireCapableBeanFactory 就可以实现相应的抽象方法了。
    • 因为 AbstractAutowireCapableBeanFactory 本身也是一个抽象类,所以它只会实现属于自己的抽象方法,其他抽象方法由继承 AbstractAutowireCapableBeanFactory 的类实现。
    • 这里就体现了类实现过程中的各司其职,你只需要关心属于你的内容,不是你的内容,不要参与。
  • 另外还有块重要的知识点,就是关于单例 SingletonBeanRegistry 的接口定义实现,而 DefaultSingletonBeanRegistry 对接口实现后,会被抽象类 AbstractBeanFactory 继承。
    • 现在 AbstractBeanFactory 就是一个非常完整且强大的抽象类了,也能非常好的体现出它对模板模式的抽象定义。

三、实现:实现Bean的定义、注册、获取

3.1 工程结构

spring-step-02
|-src|-main|   |-java|       |-com.lino.springframework|           |-factory|           |   |-config|           |   |   |-BeanDefinition.java|           |   |   |-SingletonBeanRegistry.java|           |   |-support|           |   |   |-AbstractAutowireCapableBeanFactory.java|           |   |   |-AbstractBeabFactory.java|           |   |   |-BeanDefinitionRegistry.java|           |   |   |-DefaultListableBeanFactory.java|           |   |   |-DefaultSingletonBeanRegistry.java|           |   |-BeanFactory.java|           |-BeansException.java|-test|-java|-com.lino.springframework.test|-bean|   |-UserService.java|-ApiTest.java

3.2 实现Bean的定义、注册、获取类图

在这里插入图片描述

  • Spring Bean 容器的功能实现,已经具备了一定的设计复杂性,这些复杂的类关系设计在各个接口定义和实现以及在抽象类继承中都有所体现。
    • BeanFactory 的定义由 AbstractBeanFactory 抽象类实现接口的 getBean 方法。
    • AbstractBeanFactory 又继承实现了 SingletonBeanRegistryDefaultSingletonBeanRegistry 类。这样 AbstractBeanFactory 抽象类就具备了单例 Bean 的注册功能。
    • AbstractBeanFactory 中又定义了两个抽象方法:getBeanDefinition(String beanName)createBean(String beanName, BeanDefinition beanDefinition),这两个抽象方法分别由 DefaultListableBeanFactoryAbstractAutowireCapableBeanFactory 实现。
    • 最终 DefaultListableBeanFactory 还会继承抽象类 AbstractAutowireCapableBeanFactory 也就可以调用抽象类中的 createBean 方法了。
  • 所有的实现都以职责划分、共性分离以及调用关系定义为标准搭建的类关系。

3.3 定义Bean异常

BeansException.java

package com.lino.springframework;/*** @description: 定义 Bean 异常*/
public class BeansException extends RuntimeException {public BeansException(String msg) {super(msg);}public BeansException(String msg, Throwable cause) {super(msg, cause);}
}

3.4 BeanDefinition定义和注册

3.4.1 BeanDefinition定义

BeanDefinition.java

package com.lino.springframework.factory.config;/*** @description: Bean 对象信息定义*/
public class BeanDefinition {/*** bean对象*/private Class beanClass;public BeanDefinition(Class beanClass) {this.beanClass = beanClass;}public Class getBeanClass() {return beanClass;}public void setBeanClass(Class beanClass) {this.beanClass = beanClass;}
}
  • Bean 定义类中把 Object 替换为 Class,这样就可以把 Bean 的实例化操作放到容器中处理了。

3.4.2 BennDefinition定义注册接口

BeanDefinitionRegistry.java

package com.lino.springframework.factory.support;import com.lino.springframework.factory.config.BeanDefinition;/*** @description: Bean 定义注册接口*/
public interface BeanDefinitionRegistry {/*** 向注册表中注册 BeanDefinition** @param beanName       Bean 名称* @param beanDefinition Bean 定义*/void registerBeanDefinition(String beanName, BeanDefinition beanDefinition);
}
  • Bean 定义注册接口只有一个接口方法,就是向注册表中注册 BeanDefinition

3.5 单例注册接口定义和实现

3.5.1 单例注册接口

SingletonBeanRegistry

package com.lino.springframework.factory.config;/*** @description: 单例 Bean 注册表*/
public interface SingletonBeanRegistry {/*** 返回在给定名称下注册的(原始)单例对象** @param beanName 要查找的bean的名称* @return 返回注册的单例对象*/Object getSingleton(String beanName);/*** 注册单例对象** @param beanName        Bean 对象名称* @param singletonObject Bean 对象*/void registerSingletonBean(String beanName, Object singletonObject);
}
  • 这个类比较简单,主要是定义了一个获取单例对象和注册单例对象的接口。

3.5.2 单例注册接口的实现

DefaultSingletonBeanRegistry.java

package com.lino.springframework.factory.support;import com.lino.springframework.factory.config.SingletonBeanRegistry;
import java.util.HashMap;
import java.util.Map;/*** @description: 通用的注册表实现*/
public class DefaultSingletonBeanRegistry implements SingletonBeanRegistry {private Map<String, Object> singletonObjects = new HashMap<>();@Overridepublic Object getSingleton(String beanName) {return singletonObjects.get(beanName);}@Overridepublic void registerSingletonBean(String beanName, Object singletonObject) {singletonObjects.put(beanName, singletonObject);}
}
  • DefaultSingletonBeanRegistry 主要实现 getSingleton 方法和 registerSingletonBean 方法。

3.6 抽象类定义模板方法

3.6.1 Bean工厂接口

BeanFactory.java

package com.lino.springframework.factory;import com.lino.springframework.BeansException;
import com.lino.springframework.factory.config.BeanDefinition;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;/*** @description: 定义 Bean 工厂接口*/
public interface BeanFactory {/*** 返回 Bean 的实例对象** @param name 要检索的bean的名称* @return 实例化的 Bean 对象* @throws BeansException 不能获取 Bean 对象,抛出异常*/Object getBean(String name) throws BeansException;
}

3.6.2 抽象Bean工厂基类,定义模板方法

AbstractBeanFactory.java

package com.lino.springframework.factory.support;import com.lino.springframework.BeansException;
import com.lino.springframework.factory.BeanFactory;
import com.lino.springframework.factory.config.BeanDefinition;/*** @description: 抽象的 Bean 工厂基类,定义模板方法*/
public abstract class AbstractBeanFactory extends DefaultSingletonBeanRegistry implements BeanFactory {@Overridepublic Object getBean(String name) throws BeansException {Object bean = getSingleton(name);if (bean != null) {return bean;}BeanDefinition beanDefinition = getBeanDefinition(name);return createBean(name, beanDefinition);}/*** 获取 Bean 对象** @param beanName 要检索的bean的名称* @return Bean 对象*/protected abstract BeanDefinition getBeanDefinition(String beanName);/*** 创建Bean对象** @param beanName       要检索的bean的名称* @param beanDefinition Bean对象* @return 实例化的Bean对象*/protected abstract Object createBean(String beanName, BeanDefinition beanDefinition);
}
  • AbstractBeanFactory 首先继承了 DefaultSingletonBeanRegistry,也就具备了使用单例注册类方法。
  • 接下来很重要的一点是关于接口 BeanFactory 的实现。
    • 在方法 getBean 的实现过程中可以看到,主要是对单例 Bean 对象的获取以及在获取不到时需要拿到 Bean 的定义做相应 Bean 实例化操作。
    • 那么 getBean 并没有自身的去实现这些方法,而是只定义了调用过程以及提供了抽象方法,由实现此抽象类的其他类做相应实现。
  • 后续继承抽象类 AbstractBeanFactory 的类有两个。
    • 包括:AbstractAutowireCapableBeanFactoryDefaultListableBeanFactory,这两个类分别做了相应的实现处理。

3.6.3 实例化Bean类

AbstractAutowireCapableBeanFactory.java

package com.lino.springframework.factory.support;import com.lino.springframework.BeansException;
import com.lino.springframework.factory.config.BeanDefinition;/*** @description: 实现默认bean创建的抽象bean工厂超类*/
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory {@Overrideprotected Object createBean(String beanName, BeanDefinition beanDefinition) {Object bean = null;try {bean = beanDefinition.getBeanClass().newInstance();} catch (InstantiationException | IllegalAccessException e) {throw new BeansException("Instantiation of bean failed", e);}registerSingletonBean(beanName, bean);return bean;}
}
  • AbstractAutowireCapableBeanFactory 类中实现了 Bean 的实例化操作 newInstance
  • 在处理完 Bean 对象的实例化后,直接调用 registerSingletonBean 方法存放到单例对象的缓存中去。

3.6.4 核心类:默认的Bean工厂实现

DefaultListableBeanFactory.java

package com.lino.springframework.factory.support;import com.lino.springframework.BeansException;
import com.lino.springframework.factory.config.BeanDefinition;
import java.util.HashMap;
import java.util.Map;/*** @description: 默认的Bean工厂实现类*/
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements BeanDefinitionRegistry {private Map<String, BeanDefinition> beanDefinitionMap = new HashMap<>();@Overrideprotected BeanDefinition getBeanDefinition(String beanName) {BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);if (beanDefinition == null) {throw new BeansException("No bean named '" + beanName + "' is defined");}return beanDefinition;}@Overridepublic void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) {beanDefinitionMap.put(beanName, beanDefinition);}
}
  • DefaultListableBeanFactorySpring 的源码中也是一个非常核心的类。
  • DefaultListableBeanFactory 继承了 AbstractAutowireCapableBeanFactory 类,也就具备了接口 BeanFactoryAbstractBeanFactory 等一连串的功能实现。
  • 除此之外这个类还实现了接口 BeanDefinitionRegistry 中的 registerBeanDefinition(String beanName, BeanDefinition beanDefinition) 方法。
    • 还会看到一个 getBeanDefinition 的实现,这个方法是抽象类 AbstractBeanFactory 中定义的抽象方法。现在注册 Bean 定义与获取 Bean 定义就可以同时使用了。
    • 接口定义了注册,抽象类定义了获取,都集中在 DefaultListableBeanFactory 中的 beanDefinitionMap 里。

四、测试:实现Bean的定义、注册、获取

ApiTest.java

@Test
public void test_BeanFactory() {// 1.初始化 BeanFactoryDefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();// 2.注册beanBeanDefinition beanDefinition = new BeanDefinition(UserService.class);beanFactory.registerBeanDefinition("userService", beanDefinition);// 3.第一次获取beanUserService userService = (UserService) beanFactory.getBean("userService");userService.queryUserInfo();// 3.第二次获取beanUserService userService_singleton = (UserService) beanFactory.getBean("userService");userService_singleton.queryUserInfo();
}
  • 在此次的单元测试中处理包括:Bean 工厂、注册 Bean、获取 Bean 三个步骤,还额外增加了一次对象的获取和调用。
    • 这里主要测试验证单例对象是否正确的存放到了缓存中。
  • 此时,我们把 UserService.class 传递给了 BeanDefinition

测试结果

查询用户信息查询用户信息

在这里插入图片描述

  • 这里会有两次测试信息,一次是获取 Bean 时直接创建的对象,另外一次是从缓存中获取的实例化对象。
  • 此外从调试的截图中看出第二次获取单例对象,是从内存中获取的。

五、总结:实现Bean的定义、注册、获取

  • Spring Bean 容器的实现类中要重点关注类之间的职责和关系,几乎所有的程序功能设计都离不开接口、抽象类、实现、继承。
    • 而这些不同特性类的使用就可以非常好的隔离开类的功能职责和作用范围。

相关文章:

手写Spring:第3章-实现Bean的定义、注册、获取

文章目录 一、目标&#xff1a;实现Bean的定义、注册、获取二、设计&#xff1a;实现Bean的定义、注册、获取三、实现&#xff1a;实现Bean的定义、注册、获取3.1 工程结构3.2 实现Bean的定义、注册、获取类图3.3 定义Bean异常3.4 BeanDefinition定义和注册3.4.1 BeanDefinitio…...

这些国外客户真直接

最近在某平台上遇到的客户&#xff0c;很大一部分都是非英语国家的客户&#xff0c;然而他们也有很多共性的习惯。 第一种&#xff1a;直接表达自己对这个产品感兴趣&#xff0c;然后接下来就没有下文了&#xff0c;而之所以可以看得懂&#xff0c;则是借助平台本身的翻译系统&…...

使用Apache Doris自动同步整个 MySQL/Oracle 数据库进行数据分析

Flink-Doris-Connector 1.4.0 允许用户一步将包含数千个表的整个数据库&#xff08;MySQL或Oracle &#xff09;摄取到Apache Doris&#xff08;一种实时分析数据库&#xff09;中。 通过内置的Flink CDC&#xff0c;连接器可以直接将上游源的表模式和数据同步到Apache Doris&…...

【1++的数据结构】之哈希(一)

&#x1f44d;作者主页&#xff1a;进击的1 &#x1f929; 专栏链接&#xff1a;【1的数据结构】 文章目录 一&#xff0c;什么是哈希&#xff1f;二&#xff0c;哈希冲突哈希函数哈希冲突解决 unordered_map与unordered_set 一&#xff0c;什么是哈希&#xff1f; 首先我们要…...

【网络编程】深入了解UDP协议:快速数据传输的利器

(꒪ꇴ꒪ )&#xff0c;Hello我是祐言QAQ我的博客主页&#xff1a;C/C语言&#xff0c;数据结构&#xff0c;Linux基础&#xff0c;ARM开发板&#xff0c;网络编程等领域UP&#x1f30d;快上&#x1f698;&#xff0c;一起学习&#xff0c;让我们成为一个强大的攻城狮&#xff0…...

WordPress(5)在主题中添加文章字数和预计阅读时间

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 样式图一、添加位置二、找到主题文件样式图 提示:以下是本篇文章正文内容,下面案例可供参考 一、添加位置 二、找到主题文件 在主题目录下functions.php文件把下面的代码添加进去: // 文章字数…...

STM32WB55开发(1)----套件概述

STM32WB55开发----1.套件概述 所用器件视频教学样品申请优势支持协议系统控制和生态系统访问功能示意图系统框图跳线设置开发板原理图 所用器件 所使用的器件是我们自行设计的开发板&#xff0c;该开发板是基于 STM32WB55 系列微控制器所构建。STM32WBXX_VFQFPN68 不仅是一款评…...

CUDA相关知识科普

显卡 显卡&#xff08;Video card&#xff0c;Graphics card&#xff09;全称显示接口卡&#xff0c;又称显示适配器&#xff0c;是计算机最基本配置、最重要的配件之一。就像电脑联网需要网卡&#xff0c;主机里的数据要显示在屏幕上就需要显卡。因此&#xff0c;显卡是电脑进…...

恒运资本:总市值和总资产区别?

总市值和总财物是财政术语中经常被提到的两个概念&#xff0c;很多人会将它们混淆。在金融领域中&#xff0c;了解这两个概念的差异十分重要。本文将从多个视点深入分析总市值和总财物的差异。 1.定义 ​ 总市值是指公司发行的一切股票的商场总价值。所谓商场总价值&#xf…...

CTF安全竞赛介绍

目录 一、赛事简介 二、CTF方向简介 1.Web&#xff08;Web安全&#xff09; &#xff08;1&#xff09;简介 &#xff08;2&#xff09;涉及主要知识 2.MISC&#xff08;安全杂项&#xff09; &#xff08;1&#xff09;介绍 &#xff08;2&#xff09;涉及主要知识 3…...

DC/DC开关电源学习笔记(四)开关电源电路主要器件及技术动态

(四)开关电源电路主要器件及技术动态 1.半导体器件2.变压器3.电容器4.功率二极管5.其他常用元件5.1 电阻5.2 电容5.3 电感5.4 变压器5.5 二极管5.6 整流桥5.7 稳压管5.8 绝缘栅-双极性晶体管1.半导体器件 功率半导体器件仍然是电力电子技术发展的龙头, 电力电子技术的进步必…...

数据可视化与数字孪生:理解两者的区别

在数字化时代&#xff0c;数据技术正在引领创新&#xff0c;其中数据可视化和数字孪生是两个备受关注的概念。尽管它们都涉及数据的应用&#xff0c;但在本质和应用方面存在显著区别。本文带大探讨数据可视化与数字孪生的差异。 概念 数据可视化&#xff1a; 数据可视化是将复…...

C++ socket编程(TCP)

服务端保持监听客户端&#xff0c; 服务端采用select实现&#xff0c;可以监听多个客户端 客户端源码 在这里插入代码片 #include <iostream> //#include <windows.h> #include <WinSock2.h> #include <WS2tcpip.h> using namespace std; #pragma co…...

ldd用于打印程序或库文件所依赖的共享库列表

这是一个Linux命令行指令&#xff0c;将两个常用的命令 ldd 和 grep 组合使用。我来逐一为您解释&#xff1a; ldd: 这是一个Linux工具&#xff0c;用于打印程序或库文件所依赖的共享库列表。通常&#xff0c;当你有一个可执行文件并且想知道它链接到哪些动态库时&#xff0c;你…...

vue+elementUI el-table实现单选

if (selection.length > 1) {this.$refs.table.clearSelection();this.$refs.table.toggleRowSelection(selection.pop());}...

前端组件库造轮子——Message组件开发教程

前端组件库造轮子——Message组件开发教程 前言 本系列旨在记录前端组件库开发经验&#xff0c;我们的组件库项目目前已在Github开源&#xff0c;下面是项目的部分组件。文章会详细介绍一些造组件库轮子的技巧并且最后会给出完整的演示demo。 文章旨在总结经验&#xff0c;开…...

单片机第二季:温度传感器DS18B20

目录 1&#xff0c;DS18B20介绍 2&#xff0c;DS18B20数据手册 2.1&#xff0c;初始化时序 2.2&#xff0c;读写时序 3&#xff0c;DS18B20工作流程 4&#xff0c;代码 1&#xff0c;DS18B20介绍 DS18B20的基本特征&#xff1a; (1)内置集成ADC&#xff0c;外部数字接…...

抓包工具fiddler的基础知识

目录 简介 1、作用 2、使用场景 3、http报文分析 3.1、请求报文 3.2、响应报文 4、介绍fiddler界面功能 4.1、AutoResponder(自动响应器) 4.2、Composer(设计请求) 4.3、断点 4.4、弱网测试 5、app抓包 简介 fiddler是位于客户端和服务端之间的http代理 1、作用 监控浏…...

监控基本概念

监控&#xff1a;这个词在不同的上下文中有不同的含义&#xff0c;在讲到监控MySQL或者监控Redis时&#xff0c;这里只涉及数据采集和可视化&#xff0c;不涉及告警引擎和事件处理。要是监控系统的话&#xff0c;不但包括数据采集和可视化&#xff0c;而且也包括告警和事件发送…...

【数据结构】 七大排序详解(壹)——直接插入排序、希尔排序、选择排序、堆排序

文章目录 &#x1f340;排序的概念及引用&#x1f431;‍&#x1f464;排序的概念&#x1f431;‍&#x1f453;排序运用&#x1f431;‍&#x1f409;常见的排序算法 &#x1f334;插入排序&#x1f38b;基本思想&#xff1a;&#x1f6eb;直接插入排序&#x1f4cc;算法步骤&…...

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻

在如今就业市场竞争日益激烈的背景下&#xff0c;越来越多的求职者将目光投向了日本及中日双语岗位。但是&#xff0c;一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧&#xff1f;面对生疏的日语交流环境&#xff0c;即便提前恶补了…...

Java 语言特性(面试系列2)

一、SQL 基础 1. 复杂查询 &#xff08;1&#xff09;连接查询&#xff08;JOIN&#xff09; 内连接&#xff08;INNER JOIN&#xff09;&#xff1a;返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

label-studio的使用教程(导入本地路径)

文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

mongodb源码分析session执行handleRequest命令find过程

mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程&#xff0c;并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令&#xff0c;把数据流转换成Message&#xff0c;状态转变流程是&#xff1a;State::Created 》 St…...

解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错

出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上&#xff0c;所以报错&#xff0c;到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本&#xff0c;cu、torch、cp 的版本一定要对…...

k8s业务程序联调工具-KtConnect

概述 原理 工具作用是建立了一个从本地到集群的单向VPN&#xff0c;根据VPN原理&#xff0c;打通两个内网必然需要借助一个公共中继节点&#xff0c;ktconnect工具巧妙的利用k8s原生的portforward能力&#xff0c;简化了建立连接的过程&#xff0c;apiserver间接起到了中继节…...

IT供电系统绝缘监测及故障定位解决方案

随着新能源的快速发展&#xff0c;光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域&#xff0c;IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选&#xff0c;但在长期运行中&#xff0c;例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...

【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具

第2章 虚拟机性能监控&#xff0c;故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令&#xff1a;jps [options] [hostid] 功能&#xff1a;本地虚拟机进程显示进程ID&#xff08;与ps相同&#xff09;&#xff0c;可同时显示主类&#x…...

代码规范和架构【立芯理论一】(2025.06.08)

1、代码规范的目标 代码简洁精炼、美观&#xff0c;可持续性好高效率高复用&#xff0c;可移植性好高内聚&#xff0c;低耦合没有冗余规范性&#xff0c;代码有规可循&#xff0c;可以看出自己当时的思考过程特殊排版&#xff0c;特殊语法&#xff0c;特殊指令&#xff0c;必须…...