Spring的IOC
在现代 Java 开发中,Spring 框架几乎无处不在,特别是其核心的 IOC(Inversion of Control) 容器,几乎所有Spring的功能都与它紧密相关。
一、什么是IOC
IOC,全称为 Inversion of Control(控制反转),顾名思义,它是将原本由程序员控制的对象创建、对象依赖关系的管理等责任反转给框架来做,程序员只需要编写业务逻辑,框架会处理对象的创建和管理。
在java当中一个类想要使用另一个类的方法,就必须在这个类当中创建这个类的对象,那么可能会出现如下情况:比如A类当中创建着B对象,B类当中有C对象,C类当中有A对象,这个如果一个类出了问题,那么可能会导致这个框架出现问题。
Spring 将创建对象的权利给了IOC,在IOC当中创建了ABC三个对象吗,那么我们我们其他的类只需要调用集合,大大的解决了程序耦合性的问题。
通过 IOC,Spring 容器负责创建和管理对象的生命周期,同时还负责将需要的依赖注入到这些对象中。这就避免了传统编程方式中,程序员需要手动管理对象实例化和依赖关系的问题。
举个通俗的例子:
- 传统方式:你去餐厅吃饭,自己点菜、自己烹饪、自己上菜、自己清理桌面。
- IOC方式:你去餐厅吃饭,餐厅的服务员负责点菜、烹饪、上菜,甚至清理桌面,你只需要享受美食。
这样看,IOC 就像一个得力的服务员,帮你解决了很多繁琐的事情,而你只需要专注于业务逻辑即可。
二、IOC的底层原理
在 Spring 中,IOC 主要由 BeanFactory 和 ApplicationContext 两个核心容器实现。BeanFactory 是 Spring 的基本容器,而 ApplicationContext 是 BeanFactory 的扩展,具备更多的功能。
IOC的实现主要依赖于:
- dom4j 解析 xml 文档
- 工厂模式
- 采用反射设计模式创建对象
1、工厂模式
在当前情况之下A类想要调用B类就必须自己在自己的内部新建B类的对象,这样的耦合度太高,如何降低耦合度的呢?
public class A {public void run(){B b = AFactory.getB();b.print();}
}public class B {public void print(){System.out.println("你好");}
}public class BFactory {public static B getB(){return new B();}
}
创建一个工厂类BFactory,这样就能够使得A和B的耦合度降低到最小值
2、容器与 Bean 的管理
Spring 的 IOC 容器负责创建、管理和销毁应用中的所有 bean。每个 bean 都是由 Spring 容器根据配置创建的 Java 对象,并通过依赖注入(DI)来管理它们之间的依赖关系。
Bean管理指的是:
- 创建对象
- 注入操作
这两个操作
3、依赖注入(DI)
依赖注入是 IOC 的关键实现方式,Spring 提供了三种主要的 DI 方式:
- 构造器注入:通过构造函数传递依赖。
- Setter 注入:通过 setter 方法传递依赖。
- 接口注入:通过接口传递依赖(这种方式较少使用,Spring 没有默认支持)。
4、 Bean 生命周期
Spring 容器中的 Bean 在创建时,会经历以下生命周期:
- 实例化:根据配置实例化对象。
- 填充属性:根据配置文件将属性注入到 Bean 中。
- 初始化:初始化 Bean,执行自定义的初始化方法。
- 销毁:当容器销毁时,执行销毁方法。
三、基于XML配置文件实现Bean管理和依赖注入
1、Maven项目信息配置
配置Maven项目基本信息,构建一个 Spring IOC 示例项目,并集成了日志和单元测试支持。
<?xml version="1.0" encoding="UTF-8"?>
<!-- 声明 XML 版本和编码格式,UTF-8 适用于多语言支持 --><project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><!-- 定义项目的根元素 <project>,指定 POM 的 XML 命名空间xsi:schemaLocation 指定了 XML Schema 文件的位置,用于 POM 语法验证 --><modelVersion>4.0.0</modelVersion><!-- 指定 POM 的模型版本,当前 Maven 版本统一使用 4.0.0 --><groupId>com.goose</groupId><!-- 组 ID,通常采用公司或组织的反向域名,标识该项目属于哪个组织或团队 --><artifactId>Spring_IOCDemo</artifactId><!-- 工件 ID,代表当前项目的名称,最终生成的 JAR 或 WAR 文件会使用这个名称 --><version>1.0-SNAPSHOT</version><!-- 版本号,1.0-SNAPSHOT 表示开发中的快照版本,非正式发布 --><properties><maven.compiler.source>8</maven.compiler.source><!-- 指定 Java 源代码版本为 8 --><maven.compiler.target>8</maven.compiler.target><!-- 指定编译后的字节码版本为 Java 8 --></properties><dependencies><!-- 依赖管理,列出项目所需的外部库 --><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.0.2.RELEASE</version></dependency><!-- Spring Context 依赖,提供 IoC 容器和 AOP 等核心功能,版本 5.0.2.RELEASE --><dependency><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId><version>1.2</version></dependency><!-- commons-logging 依赖,Spring 使用它作为日志抽象层,可适配多种日志框架 --><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.12</version></dependency><!-- log4j 依赖,具体的日志实现,用于输出日志信息 --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><!-- JUnit 依赖,版本 4.12,scope 为 test,表示该依赖仅用于测试环境 --></dependencies>
</project>
<!-- 结束 <project> 标签,完整定义 Maven 项目 -->
2、创建Spring依赖
用于定义和管理不同的 bean(对象)及其依赖关系,使用 XML 配置方式 来定义应用程序的对象,Spring 容器会根据这个配置文件来创建和管理对象的生命周期,并注入它们之间的依赖。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
</beans>
3、创建对象
Spring.xml中定义一个名为 car 的 Bean,并指定它的实现类为 com.goose.entity.Car。
id :类的唯一标识符
class : 类的全路径名
<bean id="car" class="com.goose.entity.Car"/>
创建实体类 Car,方便观察,设计 run 方法来测试
public class Car{public void run(){System.out.println("汽车轱辘骨碌碌的转.........");}
}
创建测试类
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class CarTest {//传统方式创建对象@Testpublic void test(){// 创建对象Car car = new Car();// 调用方法car.run();}// Spring 创建对象@Testpublic void test_Spring(){ApplicationContext ac = new ClassPathXmlApplicationContext("Spring.xml");Car car = (Car) ac.getBean("car");// 方法调用car.run();}
}
4、注入属性
1.普通属性
Spring.xml中定义一个名为 car 的 Bean,并指定它的实现类为 com.goose.entity.Car,并指定属性和对应值。ref 用于表示该属性的值是引用另一个已经定义的 Bean。
ref="engine":这表示 car Bean 的 engine 属性将会通过引用另一个已定义的 Bean 来注入,那个 Bean 的 ID 为 engine。Spring 会从容器中查找一个 ID 为 engine 的 Bean,并将其注入到 car Bean 的 engine 属性中。
换句话说,ref="engine" 告诉 Spring 容器,car 这个对象的 engine 属性应该被赋值为 ID 为 engine 的 Bean,而不是一个普通的值。
<bean id="car" class="com.goose.entity.Car"><property name="brand" value="Geely"/><property name="IDs" value="18952"/><property name="engine" ref="engine"/>
</bean><bean id="engine" class="com.goose.entity.Engine"><constructor-arg name="cylinder" value="V8"/><constructor-arg name="displayment" value="6.0T"/><constructor-arg name="ratio" value="49%"/>
</bean>
创建实体类 Car 和 Engine ,其中 Engine 中实现了使用带参构造方法进行值的注入,在 xml 中需要使用 constructor-arg 关键字。
public class Car implements CarInterface {private Integer IDs;private String Brand;private Engine engine;@Overridepublic String toString() {return "Car{" +"IDs=" + IDs +", Brand='" + Brand + '\'' +", engine=" + engine +'}';}public Integer getIDs() {return IDs;}public void setIDs(Integer IDs) {this.IDs = IDs;}public String getBrand() {return Brand;}public void setBrand(String brand) {Brand = brand;}public Engine getEngine() {return engine;}public void setEngine(Engine engine) {this.engine = engine;}public void run(){System.out.println("汽车轱辘骨碌碌的转.........");}
}
public class Engine {private String cylinder;private String displayment;private String ratio;public Engine(String cylinder, String displayment, String ratio) {this.cylinder = cylinder;this.displayment = displayment;this.ratio = ratio;}@Overridepublic String toString() {return "Engine{" +"cylinder='" + cylinder + '\'' +", displayment='" + displayment + '\'' +", ratio='" + ratio + '\'' +'}';}public String getCylinder() {return cylinder;}public void setCylinder(String cylinder) {this.cylinder = cylinder;}public String getDisplayment() {return displayment;}public void setDisplayment(String displayment) {this.displayment = displayment;}public String getRatio() {return ratio;}public void setRatio(String ratio) {this.ratio = ratio;}
}
测试类
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class CarTest {@Testpublic void test_Spring(){ApplicationContext ac = new ClassPathXmlApplicationContext("Spring.xml");Car car = (Car) ac.getBean("car");// 方法调用car.run();System.out.println(car.toString());}
}
2.集合属性
Spring.xml中定义一个名为 bot 的 Bean,并指定它的实现类为 com.goose.entity.Bot。
<bean id="bot" class="com.goose.entity.Bot"><property name="list"><list><value>小新</value><value>小爱</value></list></property><property name="map"><map><entry key="1" value="广志"/><entry key="2" value="美伢"/></map></property><property name="strs"><array><value>正男</value><value>妮妮</value></array></property>
</bean>
创建实体类
import java.util.Arrays;
import java.util.List;
import java.util.Map;public class Bot {private String [] strs;private List<String> list;private Map<String,String> map;@Overridepublic String toString() {return "Bot{" +"strs=" + Arrays.toString(strs) +", list=" + list +", map=" + map +'}';}public String[] getStrs() {return strs;}public void setStrs(String[] strs) {this.strs = strs;}public List<String> getList() {return list;}public void setList(List<String> list) {this.list = list;}public Map<String, String> getMap() {return map;}public void setMap(Map<String, String> map) {this.map = map;}
}
测试类
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class CarTest {@Testpublic void test_Spring(){ApplicationContext ac = new ClassPathXmlApplicationContext("Spring.xml");Bot bot = (Bot) ac.getBean("bot");// 集合等普通变量设值System.out.println(bot.toString());}
}
在构造器中注入
<bean name="bot2" class="com.goose.entity.Bot_2"><constructor-arg name="strs"><array><value>正男</value><value>妮妮</value></array></constructor-arg><constructor-arg name="list"><list><value>正男</value><value>妮妮</value></list></constructor-arg><constructor-arg name="map"><map><entry key="1" value="广志"/><entry key="2" value="美伢"/></map></constructor-arg>
</bean>
import java.util.Arrays;
import java.util.List;
import java.util.Map;public class Bot_2 {private String [] strs;private List<String> list;private Map<String,String> map;public Bot_2(String[] strs, List<String> list, Map<String, String> map) {this.strs = strs;this.list = list;this.map = map;}@Overridepublic String toString() {return "Bot{" +"strs=" + Arrays.toString(strs) +", list=" + list +", map=" + map +'}';}public String[] getStrs() {return strs;}public void setStrs(String[] strs) {this.strs = strs;}public List<String> getList() {return list;}public void setList(List<String> list) {this.list = list;}public Map<String, String> getMap() {return map;}public void setMap(Map<String, String> map) {this.map = map;}
}
Bot_2 bot_2 = (Bot_2) ac.getBean("bot2");
// 集合等构造器实现注入
System.out.println(bot_2.toString());
四、基于注解实现Bean管理和注入
1、什么是注解
①:注解是代码特殊标记,格式:@注解名称(属性名称=属性值,属性名称=属性值...)
②:使用注解,注解作用在类上面,方法上面,属性上边
③:使用注解的目的:简化XML配置
2、Spring针对Bean管理创建对象提供的注解
@Component 普通的类
@Controller 表现层
@Service 业务层
@Repository 持久层
*上边四个功能一样,都可以用来创建bean实例
3、用注解创建对象
1.编写接口和实现类
public interface CarInterface {public void hello();
}
package com.goose.entity;import com.goose.config.CarInterface;
import org.springframework.stereotype.Component;
/* <bean id="us" class="UserServiceImpl"/> */
/*** 组件,作用:把当前类使用IOC容器进行管理,如果没有指定名称,默认使用类名,首字母是小写。* userServiceImpl。或者自己指定名称**/
@Component(value = "cars")
public class Car implements CarInterface {@Overridepublic void hello() {System.out.println("俺是注解创建对象测试......");}
}
2.编写配置文件,开启注解扫描
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><context:component-scan base-package="com.goose"/>
</beans>
3.测试类
@Test
public void test_Zhujie(){ApplicationContext ac = new ClassPathXmlApplicationContext("Spring.xml");Car car = (Car) ac.getBean("cars");car.hello();
}
4、用注解注入属性
@Value 用于注入普通类型(String,int,double等类型)
@Autowired 默认按类型进行自动装配(引用类型)
@Qualifier 不能单独使用必须和@Autowired一起使用,强制使用名称注入
@Resource Java提供的注解,也被支持。使用name属性,按名称注入
1.编写实现类
package com.goose.entity;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;@Component(value = "poss")
public class Possession {@Value("刘海柱")private String name;@Autowiredprivate Car car;@Overridepublic String toString() {return "Possession{" +"name='" + name + '\'' +", car=" + car +'}';}
}
package com.goose.entity;import com.goose.config.CarInterface;
import org.springframework.stereotype.Component;@Component(value = "cars")
public class Car implements CarInterface {private Integer IDs;private String Brand;private Engine engine;@Overridepublic String toString() {return "Car{" +"IDs=" + IDs +", Brand='" + Brand + '\'' +", engine=" + engine +'}';}public Integer getIDs() {return IDs;}public void setIDs(Integer IDs) {this.IDs = IDs;}public String getBrand() {return Brand;}public void setBrand(String brand) {Brand = brand;}public Engine getEngine() {return engine;}public void setEngine(Engine engine) {this.engine = engine;}public void run(){System.out.println("汽车轱辘骨碌碌的转.........");}@Overridepublic void hello() {System.out.println("俺是注解创建对象测试......");}
}
2.测试类
@Test
public void test_Zhuru(){ApplicationContext ac = new ClassPathXmlApplicationContext("Spring.xml");Possession poss = (Possession) ac.getBean("poss");System.out.println(poss.toString());
}
五、不同方式的对比
特性 | 基于 XML 配置 | 基于注解配置 |
配置方式 | 使用 XML 文件进行配置 | 使用注解来标记类和依赖关系 |
易用性 | 配置较繁琐,尤其是 Bean 多时 | 配置简单,类和依赖关系直接通过注解指定 |
灵活性 | 灵活,适用于复杂配置 | 配置简洁,适用于大多数应用 |
可维护性 | XML 配置文件容易维护,但文件较大 | 代码更加简洁,方便修改 |
相关文章:
Spring的IOC
在现代 Java 开发中,Spring 框架几乎无处不在,特别是其核心的 IOC(Inversion of Control) 容器,几乎所有Spring的功能都与它紧密相关。 一、什么是IOC IOC,全称为 Inversion of Control(控制反…...
常考计算机操作系统面试习题(四)
目录 1. Peterson 算法伪代码 2. 信号量生产者消费者问题分析 3. 注释 Peterson 主函数并分析输出结果 4. 用 fork 创建子进程的程序 1. Peterson 算法伪代码 题目: 写出 Peterson 算法的伪代码。 参考答案: // 定义变量 boolean flag[2]; //…...
Visual Studio Code 连接 SAP ERP 系统
首先确保服务打开 在vscode,在extension安装ABAP remote filesystem,然后打开设置SAP 系统的地址配置 CtrlshiftP 执行代码:AbapFS connect to an ABAP system,可以根据要求一步一步配置。 根据配置。加载系统 也可以直接在extens…...
从报错到成功:Mermaid 流程图语法避坑指南✨
🚀 从报错到成功:Mermaid 流程图语法避坑指南 🚀 🚨 问题背景 在开发文档或技术博客中,我们经常使用 Mermaid 流程图 来可视化代码逻辑。但最近我在尝试绘制一个 Java Stream 转换流程图时,遭遇了以下报错…...
TDengine 中的 show 命令
简介 SHOW 命令可以用来获取简要的系统信息。若想获取系统中详细的各种元数据、系统信息和状态,请使用 select 语句查询 INFORMATION_SCHEMA 数据库中的表, 详见 元数据查询 SHOW APPS SHOW APPS;显示接入集群的应用(客户端)信息。 SHOW …...
博弈论中的均衡精炼:完美贝叶斯均衡、序贯均衡与颤抖手均衡详解
博弈论中的均衡精炼:完美贝叶斯均衡、序贯均衡与颤抖手均衡详解 1. 引言:为什么需要均衡精炼? 在博弈论中,纳什均衡是分析策略互动的核心工具,但其存在一个显著缺陷:无法排除不合理的均衡。例如࿰…...
github代理 | 快速clone项目
代理网址: https://ghproxy.com/ https://ghproxy.com/代理网址: https://ghproxy.com/ 比如需要克隆的项目git地址为:https://github.com/AUTOMATIC1111/stable-diffusion-webui.git git clone https://ghproxy.com/https://github.com/AUTO…...
C语言基础与进阶学习指南(附运行效果图及术语解析)
C语言基础与进阶学习指南(附运行效果图及术语解析) 目录 C语言标准与编译流程CPU与内存基础C语言基础语法数据类型详解变量与内存管理运算符与表达式输入输出函数函数与内存管理指针与内存操作结构体与高级应用 1. C语言标准与编译流程 1.1 C语言标准演…...
【Scrapy】Scrapy教程8——处理子链接
通过前面几篇文章,已经了解了如何去爬取网页内容并存储到数据库,但是目前只是存储了一个页面的内容,现在想要获取每篇文章链接内的文章内容,我们来看看怎么获取。 生成新请求 首先我们肯定要先拿到链接,所以第一步都获取文章标题和链接肯定少不了,然后再爬取获取到到子…...
Python推导式深入解析
引言 Python 以其简洁、高效的语法而备受开发者喜爱,其中推导式(Comprehensions)更是 Python 语法的一大特色。推导式提供了一种简洁明了的方式来创建列表、集合和字典等数据结构,让代码更加紧凑和易读。本文将深入探讨 Python 推…...
在 macOS 上配置 SSH 连接 GitHub
在 macOS 上使用 SSH 连接 GitHub,可以免去每次使用 Git 时输入密码的麻烦,提高开发效率。本文将介绍如何在 macOS 上生成 SSH 密钥并配置 GitHub 进行身份认证。 1. 检查是否已有 SSH 密钥 在终端运行以下命令,检查是否已有 SSH 密钥&#…...
常考计算机操作系统面试习题(二)(中)
目录 24. 操作系统的主要功能有哪些? 25. 文件的属性主要有哪些? 26. 对文件的基本操作主要有哪些? 27. 目录的基本操作有哪些? 28. 目录的逻辑结构有哪些种? 29. 简述银行家算法的Available、Max、Allocation、…...
手机录视频风噪太大?华为Pura X“AI降风噪“太硬核了
你是否也在用手机录像时,比如大海海浪、阅览群山、空旷的原野的时候,呼啸的风总是能沦为刺耳的噪音,让精心构思的镜头,最后因为呼啸的风声最终成为“灾难现场”。传统的解决方式往往陷入两难:物理防风罩影响收音指向性…...
React 事件处理
1. React 事件处理的基本概念 React 事件处理的特点: 驼峰命名法:事件名采用驼峰命名法,如 onClick、onChange。JSX 语法:事件处理函数通过 JSX 传递给元素,如 <button onClick{handleClick}>。合成事件&#…...
搭建React简单项目
一、项目构建 目录结构: 安装脚手架 npm install -g create-react-app // or yarn add -g create-react-app 一、项目版本 1、react:"^18.3.1"; 2、react-router-dom:"^6.23.1"; 3、项目创…...
ROCK 280A-M 工业级电调:高性能无人机动力心脏,重塑严苛场景飞行边界
—— 工业级动力控制系统解决方案 —— 【产品概述】 针对工业级无人机高负载、复杂工况需求,南昌长空科技的ROCK 280A-M 电调以航空级标准打造动力控制中枢。采用工业级控制算法与智能自适应系统,为多旋翼 / 固定翼无人机提供稳定动力支撑,突…...
带你从入门到精通——自然语言处理(十. BERT)
建议先阅读我之前的博客,掌握一定的自然语言处理前置知识后再阅读本文,链接如下: 带你从入门到精通——自然语言处理(一. 文本的基本预处理方法和张量表示)-CSDN博客 带你从入门到精通——自然语言处理(二…...
八股JAVA并发
多线程 线程的创建方式有哪些? 1.继承Thread类 2.实现Runnable接口 3.Callable接口FutureTask 4.线程池 1.继承Thread类 这是最直接的一种方式,用户自定义类继承java.lang.Thread类,重写其run()方法,run()方法中定义了线程执行的具体任务。…...
#include <hello.h> 与 #include “hello.h“的区别
#include <hello.h> 和 #include "hello.h" 在C/C中用于包含头文件,但它们在搜索头文件时的行为有所不同,这可能导致前者找不到头文件的情况。 ### 区别 1. **搜索路径不同** - #include "hello.h":编译器首先…...
PyPDF2简单介绍
PyPDF2 是一个开源的纯 Python 库,用于读取、操作和创建 PDF 文件。它最初是 PyPDF 的改进版,功能更丰富。 安装: bash pip install PyPDF2核心功能 1.合并 PDF 文件 python from PyPDF2 import PdfMergermerger PdfMerger() merger.appe…...
记录flutter编译项目遇到的问题
目录 1.更换flutter版本 2.解压到指定地址 3.在Android Studio配置 问题: Flutter assets will be downloaded from https://storage.flutter-io.cn. Make sure you trust this source! Resolving dependencies... The current Dart SDK version is 3.3.0. Because coach d…...
小米AX6000上安装tailscale
在之前的文章中,已经介绍了如何解锁ax6000的ssh,以及必坑指南。 今天突发奇想,为了不让我的nas天天开着tailscale,所以我想让我的tailscale运行在路由器,这样完美实现穿透。 首先,通过ssh登录ax6000&#x…...
git使用经验(一)
git使用经验(一) 我之前已经下载了别人的代码,我想在此基础上进行修改,并移动到自己的私有仓库,方便上传到自己的私有仓库自己进行版本控制 git clone下来别人的代码,删除有关git的隐藏文件 进入到自己的…...
C语言【文件操作】详解中
引言 介绍和文件操作中文件的顺序读写相关的函数 看这篇博文前,希望您先仔细看一下这篇博文,理解一下文件指针和流的概念:C语言【文件操作】详解上-CSDN博客文章浏览阅读606次,点赞26次,收藏4次。先整体认识一下文件是…...
基于SpringBoot的在线学习平台
项目介绍 平台采用B/S结构,后端采用主流的SpringBoot语言进行开发,前端采用主流的Vue.js进行开发。是一个综合的在线学习平台,该平台有管理员、教师、学生三类角色,各项功能根据不同角色分别设定。 整个平台包括前台和后台两个部分…...
鸿蒙生态开发
鸿蒙生态开发概述 鸿蒙生态是华为基于开源鸿蒙(OpenHarmony)构建的分布式操作系统生态,旨在通过开放共享的模式连接智能终端设备、操作系统和应用服务,覆盖消费电子、工业物联网、智能家居等多个领域。以下从定义与架构、核心技术…...
qt实现一个简单http服务器和客户端
一、功能简介 服务器: 登录功能、下载文件功能 客户端: 登录功能、下载文件功能、上传成绩功能 二、服务器代码 //HttpServer.h #ifndef HTTPSERVER_H #define HTTPSERVER_H#include <QMainWindow> #include <QTcpSocket> #include <QTc…...
深入理解Linux网络随笔(五):深度理解本机网络I/O
深入理解Linux网络随笔(五):深度理解本机网络I/O 文章目录 深入理解Linux网络随笔(五):深度理解本机网络I/O本机发送过程本机接收过程总结 分析本机网络I/O部分源码需要知道本机I/O是什么?扮演什…...
Debian12生产环境配置笔记
在 Debian 12 上进行生产环境配置的详细步骤,涵盖软件更新、基础软件安装、Docker 及 Redis 部署,以及 Nginx 配置多个虚拟主机等内容。所有命令均以 root 用户身份执行,无需添加 sudo 1. 更新软件 首先,确保系统上的所有软件包…...
工业物联网的范式革命:从“云边“ 到“边边” 协的技术跃迁
基于DIOS操作系统的去中心化重构 一、云边协同模式的局限性:技术瓶颈与成本困局 当前工业物联网主流的云边协同架构(Cloud-Edge Collaboration)已暴露出显著短板,其核心问题源于对中心云的过度依赖: 带宽资源挤占与…...
python学习笔记--实现简单的爬虫(二)
任务:爬取B站上最爱欢迎的编程课程 网址:编程-哔哩哔哩_bilibili 打开网页的代码模块,如下图: 标题均位于class_"bili-video-card__info--tit"的h3标签中,下面通过代码来实现,需要说明的是URL中…...
【蓝桥杯速成】| 8.回溯算法
因为在进行背包问题的练习时,发现很多题目需要回溯,但本人作为小白当然是啥也不知道 那么就先来补充一下回溯算法的知识点,再进行练习 理论基础 回溯算法本质上是一种递归函数,是纯暴力搜索方法, 适合组合问题、排列…...
聚水潭商品信息集成MySQL的高效解决方案
聚水潭商品信息集成到MySQL的技术案例分享 在数据驱动的业务环境中,如何高效、准确地将聚水潭系统中的商品信息集成到MySQL数据库,是许多企业面临的重要挑战。本文将详细介绍一个实际运行的方案——“聚水潭-商品信息查询-->BI崛起-商品信息表_copy”…...
【数学建模】多目标规划模型:原理、方法与应用
多目标规划模型:原理、方法与应用 文章目录 多目标规划模型:原理、方法与应用引言1. 多目标规划的基本概念1.1 数学模型1.2 Pareto最优解/有效解1.3 满意解方法 2. 多目标规划的主要求解方法2.1 加权求和法2.2 ε-约束法2.3 理想点法2.4 优先级法&#x…...
基于Spring Boot的党员学习交流平台的设计与实现(LW+源码+讲解)
专注于大学生项目实战开发,讲解,毕业答疑辅导,欢迎高校老师/同行前辈交流合作✌。 技术范围:SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:…...
Flink CDC 与 SeaTunnel CDC 简单对比
Flink CDC 与 SeaTunnel CDC 简单对比 CDC 技术概述 变更数据捕获(Change Data Capture,简称 CDC)是一种用于捕获数据库中数据变更的技术,能够实时识别、捕获并输出数据库中的插入、更新和删除操作。CDC 技术在现代数据架构中扮…...
ARM 汇编基础
ARM 汇编是嵌入式开发、操作系统底层编程和性能优化的核心技能之一。以下是一份系统的 ARM 汇编指令教学指南,涵盖基础语法、核心指令、编程模式和实用示例。 1. ARM 汇编基础 1.1 寄存器 ARM 架构(32位)包含 16 个通用寄存器&…...
【嵌入式狂刷100题】- 1基础知识部分
准备新开专栏【嵌入式狂刷100题】😶🌫️😶🌫️🤧加油!!!,内容包括 基础知识部分操作系统部分处理器架构部分外设驱动部分通信协议部分存储器管理部分硬件设计部分多媒体部分调试故障排除部分编码开发部…...
【模板】计算几何入门
来源 计算几何基本模板(二维) 目录 基本设置点 向量 Point(Vector)点积(数量积、内积)向量积,叉积两点间距离向量的模单位向量两向量的夹角判断点在直线的哪边逆转角 线 直线表达式Line判断…...
PostgreSQL 数据库中导入大量数据
在 PostgreSQL 数据库中导入大量数据,可根据数据来源和格式选择不同的方法。以下为你详细介绍几种常见的方式: 1. 使用 COPY 命令(适用于本地数据文件) COPY 命令是 PostgreSQL 内置的高效数据导入工具,适合处理本地的数据文件。 步骤 准备数据文件 确保你的数据文件格…...
DeepSeek和Kimi在Neo4j中的表现
以下是2个最近爆火的人工智能工具, DeepSeek:DeepSeek Kimi: Kimi - 会推理解析,能深度思考的AI助手 1、提示词: 你能帮我生成一个知识图谱吗,等一下我会给你一篇文章,帮我从内容中提取关键要素,然后以N…...
xQueueSendToBack的中文释义和裸机调用
如果不在 FreeRTOS 环境下运行,而是裸机环境中实现类似的功能,需要移除 xQueueSendToBack 的依赖,并直接调用 CAN 发送函数。以下是修改后的代码和实现思路: 1. FreeRTOS 中的 xQueueSendToBack 功能 作用:将消息发送…...
2025年- G24-Lc98-217.包含重复(使用hashSet解决)-java版
1.题目描述 2.思路 思路一: 我的想法是直接用集合来判断,如果集合的元素不能添加说明之前已经存在这个元素,也就是发现了重复元素,所以返回false。 补充一: Map、ArrayList的定义和声明 3.代码实现 class Soluti…...
【树莓派驱动验证步骤】
终端操作和输出: 清理项目 adaraspberrypi:~/mt3502 $ make clean make -C /lib/modules/6.6.51rpt-rpi-v8/build M/home/ada/mt3502 clean make[1]: 进入目录“/usr/src/linux-headers-6.6.51rpt-rpi-v8”CLEAN /home/ada/mt3502/Module.symvers make[1]: 离开…...
百度SEO和必应SEO优化方法
如需SEO服务,可以搜索:深圳市信科网络科技有限公司。 一、搜索引擎生态格局:流量入口的重新洗牌 2025 年,中国 PC 端搜索引擎市场正经历戏剧性变革。StatCounter 数据显示,必应凭借 Edge 浏览器的预装优势与 ChatGPT …...
2025年3月AI搜索发展动态与趋势分析:从技术革新到生态重构
025年3月AI搜索发展动态与趋势分析:从技术革新到生态重构 一、行业动态:巨头布局与技术升级 谷歌推出“AI模式”,重新定义搜索体验 谷歌上线全新“AI模式”,集成多模态交互与实时数据能力,用户可通过文本、图片或语音…...
封闭图形个数
0封闭图形个数 - 蓝桥云课 小蓝对蓝桥王国的数字大小规则十分感兴趣。现在,他将给定你n个数a1, a2, ..., an,请你按照蓝桥王国的数字大小规则,将这n数从小到大排序,并输出排序后结果。 输入格式 第一行包含一个整数n࿰…...
VSCode 抽风之 两个conda环境同时在被激活
出现了神奇的(toolsZCH)(base) 提示符,如下图所示: 原因大概是:conda 环境的双重激活:可能是 conda 环境没有被正确清理或初始化,导致 base 和 toolsZCH 同时被激活。 解决办法就是 :conda deactivate 两次…...
Django 生产环境静态文件处理
python manage.py collectstatic 是 Django 提供的一个非常重要的管理命令,用于将项目中的静态文件收集到一个指定的目录中。这在部署 Django 项目时尤其重要,因为静态文件需要被 Web 服务器(如 Nginx 或 Apache)提供服务…...
语法: result=frexp(value, exp);
FREXP()是C语言里的内部函数,根据需要了解。 语法: resultfrexp(value, &exp); 参数: value是一个浮点数; exp是一个有符号的整型数; 返回值: 返回值result是一个浮点数,其有效范围是 0.5(含)到 1.0(不含&…...