Java大师成长计划之第20天:Spring Framework基础

news2025/5/14 17:29:49

📢 友情提示:

本文由银河易创AI(https://ai.eaigx.com)平台gpt-4o-mini模型辅助创作完成,旨在提供灵感参考与技术分享,文中关键数据、代码与结论建议通过官方渠道验证。

在Java开发领域,Spring Framework作为一个强大的框架,已成为企业级应用开发的事实标准。它通过提供全面的基础设施支持,使得开发者可以专注于应用程序的业务逻辑。在本篇博文中,我们将深入探讨Spring Framework的核心概念,特别是控制反转(IoC)和依赖注入(DI),并通过示例来帮助理解这些概念。

一、Spring Framework概述

Spring Framework 是一个轻量级的开源框架,广泛应用于企业级Java应用程序的开发。它为开发者提供了一个全面的编程和配置模型,简化了开发工作,增强了应用的灵活性和可维护性。Spring框架的目标是通过提供全面的基础设施支持,让开发者能够专注于业务逻辑的实现,而无需担心底层技术细节。

Spring最早由Rod Johnson在2002年提出,并随着时间的推移,逐渐发展成一个功能强大且高度模块化的框架。如今,Spring已经成为Java开发中不可或缺的工具,尤其在构建大规模的企业级应用时,Spring几乎是首选框架。

1. Spring框架的核心思想

Spring的核心思想是控制反转(Inversion of Control,IoC)依赖注入(Dependency Injection,DI)。这两个概念的提出,使得Spring能够管理应用程序的对象生命周期和依赖关系,从而减少了类之间的耦合度。

1.1 控制反转(IoC)

控制反转是一种设计原则,它将对象的控制权从程序代码中转移到外部容器中。传统的开发方式中,应用程序通过构造函数或工厂方法来创建对象,而在Spring中,这些对象的创建和管理工作交给了IoC容器,程序只需要关心对象之间的协作,而不必显式地创建对象或管理对象的生命周期。

1.2 依赖注入(DI)

依赖注入是控制反转的一种实现方式。它允许将一个对象的依赖关系从外部注入到对象内部。通过DI,Spring容器可以自动地管理对象之间的依赖关系,而无需在对象中显式地创建或查找依赖对象。常见的依赖注入方式有构造函数注入、setter方法注入和接口注入。

1.3 面向切面编程(AOP)

面向切面编程(Aspect-Oriented Programming,AOP)是Spring的另一个核心特性。AOP使得开发者能够将应用程序中的横切关注点(如日志记录、安全控制、事务管理等)从业务逻辑中分离出来,通过切面(Aspect)进行集中管理,从而提高了应用程序的模块化和可维护性。

1.4 数据访问集成

Spring提供了对数据库访问的集成支持,主要包括对JDBC、ORM(如Hibernate、JPA)、事务管理等方面的封装。Spring对数据访问的整合使得开发者可以更加高效地处理数据库操作,减少了直接操作数据库时可能出现的繁琐代码和潜在的错误。

1.5 Spring MVC

Spring MVC是Spring框架的一部分,旨在简化Web应用程序的开发。它遵循经典的MVC(Model-View-Controller)设计模式,分离了应用程序的不同层次,增强了可测试性和扩展性。Spring MVC不仅支持传统的JSP技术,还与现代的前端框架(如Angular、React等)兼容,能够有效支持RESTful API的开发。

2. Spring的模块化设计

Spring框架是高度模块化的,它将框架的功能划分成不同的模块,开发者可以根据需要选择使用相应的模块。Spring的模块包括:

  • Core Container(核心容器):这是Spring的核心,负责管理IoC容器、AOP等基本功能。

    • Spring Core:Spring的核心功能模块,提供IoC容器和Bean工厂的基本功能。
    • Spring Beans:提供Bean的创建和管理功能。
    • Spring Context:提供应用程序上下文(ApplicationContext)及事件机制。
    • Spring AOP:支持面向切面编程(AOP),用于处理横切关注点。
    • Spring Expression Language (SpEL):Spring的表达式语言,用于在Spring配置中表达复杂的条件。
  • Data Access/Integration(数据访问与集成)

    • JDBC:对JDBC操作的简化,避免了直接操作JDBC时繁琐的代码。
    • ORM:对Hibernate、JPA等ORM框架的集成。
    • JMS:Java消息服务的支持,用于消息传递。
    • Transactions:支持声明式事务管理,简化事务控制。
  • Web模块

    • Spring Web:Spring的Web模块,提供Web应用开发的基础设施。
    • Spring Web MVC:基于MVC设计模式的Web框架,简化了Web应用的开发。
    • Spring Web Flow:支持Web应用中业务流程管理的模块。
  • Test模块

    • 提供对JUnit和TestNG的集成,帮助开发者在Spring应用中进行单元测试。

3. 为什么使用Spring?

Spring之所以能成为Java开发中的核心框架,主要得益于它的以下优势:

3.1 减少样板代码

Spring为开发者提供了大量的默认配置和抽象,极大地减少了需要编写的样板代码。比如,Spring的自动装配(Autowiring)机制允许开发者无需显式声明对象的依赖关系,Spring容器会自动根据类型或名称注入所需的Bean。

3.2 提高可维护性

通过IoC和DI,Spring降低了类之间的耦合度,使得每个类的职责更加单一和明确。这种结构使得代码更加模块化,后期的维护、修改和扩展变得更加容易。

3.3 提升可测试性

Spring的IoC容器使得类的依赖关系得以集中管理,开发者可以在测试时方便地替换或模拟依赖对象,从而提高单元测试的可操作性和可维护性。

3.4 强大的社区和生态系统

Spring拥有一个活跃的社区和丰富的生态系统。除了核心框架外,Spring还提供了许多子项目,如Spring Boot(简化应用程序的创建和配置)、Spring Cloud(微服务架构的支持)、Spring Security(安全框架)等。这些项目使得开发者能够在多个领域中高效地使用Spring框架。

4. 小结

Spring Framework是一个功能全面的Java开发框架,它通过控制反转和依赖注入的核心机制,大大简化了开发过程,并提升了应用程序的灵活性和可维护性。它的模块化设计使得开发者可以根据具体需求选择使用不同的功能模块,在企业级应用开发中,Spring无疑是一个不可忽视的重要工具。

在接下来的篇章中,我们将详细介绍Spring框架的核心功能之一——控制反转(IoC)和依赖注入(DI)。通过深入理解这些机制,您将能够更加高效地使用Spring进行开发。

二、控制反转(IoC)

控制反转(Inversion of Control,简称IoC)是Spring框架的核心概念之一,也是整个Spring框架的基础。它本质上是一种设计原则,用于降低对象之间的耦合度,使得系统更加灵活和易于维护。在传统的编程模式中,对象通常通过创建其他对象来实现功能,而控制反转则将对象的创建和管理交给外部容器。Spring通过IoC容器来实现这一设计思想,从而使得应用程序中的对象不再显式地负责自身的创建和管理。

1. IoC的定义

控制反转的定义简单来说,就是“控制权的转移”。通常,在传统的编程模式下,一个对象在创建时,会直接依赖于其他对象,而自己也负责这些对象的创建与管理。而IoC则将这种对象创建的控制权交给外部的容器或框架(在Spring中是IoC容器),容器负责管理对象的生命周期和依赖关系。通过这种方式,开发者不再需要自己管理对象的生命周期和依赖关系,从而使得系统更加松耦合。

举个例子,传统方式中,如果一个类需要依赖另一个类,它可能会在自己的构造函数中创建该类的实例。反转控制则是通过外部容器来负责该类的实例化和依赖注入,从而减少了类之间的耦合度。

2. IoC的工作原理

Spring IoC容器的工作原理基于依赖注入(Dependency Injection,DI),即将一个对象的依赖关系由外部容器管理,而不是由对象自己管理。在Spring中,IoC容器负责对象的创建、初始化、销毁以及依赖关系的注入等工作。

IoC容器的实现有两种主要形式:

  • BeanFactory:是Spring IoC容器的最基本形式,适用于简单应用。它只负责管理Bean的实例化和基本配置。
  • ApplicationContext:是BeanFactory的一个更高级的扩展,提供了更多的功能,如国际化支持、事件传播、AOP支持等。通常,开发者会选择使用ApplicationContext。

3. IoC容器的配置

在Spring中,IoC容器通过配置文件来定义和管理Bean。Bean是Spring中的基本对象,它们代表了系统中的一个功能模块。每个Bean都会有一个唯一的标识符,可以通过这个标识符从容器中获取到该Bean的实例。

3.1 基本的IoC容器配置

Spring IoC容器的配置文件通常是一个XML文件,文件中定义了系统所需要的Bean及其依赖关系。下面是一个简单的配置示例:

<!-- applicationContext.xml -->
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 定义一个Bean -->
    <bean id="messageService" class="com.example.MessageServiceImpl" />
    
    <!-- 定义另一个Bean,并注入第一个Bean -->
    <bean id="messageProcessor" class="com.example.MessageProcessor">
        <property name="messageService" ref="messageService" />
    </bean>
</beans>

在上述配置中,我们定义了两个Bean:messageServicemessageProcessormessageProcessor依赖于messageService,并通过property标签将其注入。Spring容器会自动管理这些Bean,并在需要时注入它们的依赖关系。

3.2 使用Annotation进行配置

Spring框架支持基于注解的配置方式,这使得配置文件更加简洁。在现代开发中,使用注解配置Spring IoC容器已成为主流。下面是基于注解的配置示例:

// Service接口
public interface MessageService {
    void sendMessage(String message, String recipient);
}

// Service实现类
@Service
public class MessageServiceImpl implements MessageService {
    @Override
    public void sendMessage(String message, String recipient) {
        System.out.println("Sending message: " + message + " to " + recipient);
    }
}

// Client类
@Component
public class MessageProcessor {

    private final MessageService messageService;

    // 构造函数注入依赖
    @Autowired
    public MessageProcessor(MessageService messageService) {
        this.messageService = messageService;
    }

    public void processMessage(String message, String recipient) {
        messageService.sendMessage(message, recipient);
    }
}

在上述示例中,使用了@Service@Component注解来标识Spring的Bean,并使用@Autowired注解来自动注入依赖。Spring会自动扫描类路径中的注解,自动创建Bean并管理其生命周期。

3.3 注解驱动的配置

在基于注解的配置中,通常需要使用@Configuration注解标记一个配置类,并使用@ComponentScan注解来扫描指定包中的类,以自动注册Bean:

@Configuration
@ComponentScan(basePackages = "com.example")
public class AppConfig {
    // 这里不再需要手动定义Bean,Spring会自动扫描并注册
}

然后,在主程序中,通过AnnotationConfigApplicationContext来加载这个配置类:

public class Main {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        
        // 获取bean
        MessageProcessor processor = context.getBean(MessageProcessor.class);
        processor.processMessage("Hello, World!", "user@example.com");
        
        context.close();
    }
}

4. IoC容器的生命周期

Spring IoC容器不仅负责Bean的创建和注入,还负责管理Bean的生命周期。每个Bean在容器中的生命周期分为以下几个阶段:

  1. 实例化(Instantiation):当容器启动时,它会根据配置文件或注解定义的类来创建Bean实例。
  2. 填充属性(Populate Properties):容器会根据配置或注解中的依赖关系将属性值注入到Bean中。
  3. 初始化(Initialization):在所有属性注入完成后,Spring会调用Bean的初始化方法(如果有的话)。例如,可以通过@PostConstruct注解或实现InitializingBean接口来定义初始化方法。
  4. 销毁(Destruction):当容器关闭时,Spring会调用Bean的销毁方法(如果有的话)。例如,可以通过@PreDestroy注解或实现DisposableBean接口来定义销毁方法。

5. IoC的优点

控制反转(IoC)为开发者提供了以下几个显著的优点:

5.1 降低了耦合度

传统的面向对象编程中,类与类之间的依赖关系是通过硬编码来实现的,导致了类之间的紧密耦合。而IoC通过将对象的创建和管理交给容器,减少了类之间的依赖,提升了系统的灵活性和可维护性。

5.2 提升了可测试性

IoC容器使得对象的依赖关系得以外部管理,这意味着在进行单元测试时,可以方便地替换或模拟依赖对象。比如,可以通过Mock对象替换实际的服务实现,从而进行单元测试。

5.3 便于扩展和维护

IoC通过将配置和依赖关系集中管理,使得系统更加模块化。当系统需求发生变化时,开发者只需修改配置或注解,而不需要修改代码中的依赖关系,从而降低了维护的复杂度。

6. 小结

控制反转(IoC)是Spring框架中的核心概念之一,它通过外部容器来管理对象的创建、初始化、销毁和依赖注入,从而降低了系统的耦合度,提升了可维护性和可扩展性。通过Spring IoC容器,开发者可以更加专注于业务逻辑的开发,而不需要关心对象的生命周期和依赖关系的管理。在下一章中,我们将继续深入探讨**依赖注入(DI)**这一与IoC密切相关的概念。

三、依赖注入(DI)

依赖注入(Dependency Injection,简称DI)是控制反转(IoC)的一种具体实现方式,它是Spring框架的核心机制之一。通过依赖注入,Spring容器能够自动管理和注入对象之间的依赖关系,而不需要开发者手动处理。依赖注入让开发者能够更专注于业务逻辑的实现,而将对象的创建和依赖关系的管理交给Spring容器,从而提高了代码的灵活性、可维护性和可测试性。

在本章中,我们将详细探讨依赖注入的工作原理、常见的注入方式、以及如何在Spring应用中使用依赖注入。

1. 依赖注入的定义

依赖注入(DI)是控制反转的一种形式,它指的是对象的依赖关系(如依赖其他服务或资源)不是由对象自己负责创建的,而是由外部容器负责注入。当一个对象依赖于另一个对象时,Spring容器会根据配置自动为对象注入所需的依赖,而不需要开发者显式地去创建这些依赖。

简单来说,依赖注入就是通过“注入”方式将一个对象的依赖传递给它,而不是让对象自己去创建或查找这些依赖。依赖注入不仅减少了对象之间的耦合度,还使得类的职责更加单一、清晰,并且使得单元测试更加容易。

2. 依赖注入的工作原理

依赖注入的工作原理非常简单,基本流程如下:

  1. 定义依赖关系:首先,在Spring中定义好需要依赖注入的对象及其依赖关系。开发者通过配置文件或注解声明哪些对象需要依赖注入。

  2. Spring容器管理:Spring容器(例如ApplicationContext)在启动时会扫描配置文件或注解,并根据定义的依赖关系创建对象。

  3. 依赖注入:当一个对象创建时,Spring容器会根据配置自动将依赖对象注入到该对象中。

  4. 使用注入的对象:注入完成后,应用程序可以直接使用这些依赖,而无需关心依赖的创建和管理过程。

Spring通过多种方式支持依赖注入,常见的注入方式包括构造函数注入、setter方法注入和字段注入。

3. 依赖注入的方式

在Spring框架中,依赖注入主要有三种方式:构造函数注入Setter方法注入字段注入。我们将依次介绍这三种方式,并提供相关的代码示例。

3.1 构造函数注入

构造函数注入是通过类的构造函数将依赖传递给类。在Spring中,使用构造函数注入时,Spring会自动调用构造函数并将需要的依赖作为参数传入。

构造函数注入通常用于强制依赖,即被注入的依赖是必须的,没有默认值。它能确保在类实例化时就能初始化所有依赖关系,从而避免出现空指针异常。示例代码

// 服务接口
public interface MessageService {
    void sendMessage(String message, String recipient);
}

// 实现类
public class EmailService implements MessageService {
    @Override
    public void sendMessage(String message, String recipient) {
        System.out.println("Sending email: " + message + " to " + recipient);
    }
}

// 客户端类
public class MessageProcessor {

    private MessageService messageService;

    // 构造函数注入
    public MessageProcessor(MessageService messageService) {
        this.messageService = messageService;
    }

    public void processMessage(String message, String recipient) {
        messageService.sendMessage(message, recipient);
    }
}

Spring配置(XML方式)

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd">
    
    <!-- 注入EmailService到MessageProcessor -->
    <bean id="emailService" class="com.example.EmailService" />
    <bean id="messageProcessor" class="com.example.MessageProcessor">
        <constructor-arg ref="emailService" />
    </bean>
</beans>

在这个例子中,MessageProcessor类通过构造函数注入了MessageService依赖。Spring容器会自动注入EmailService实例。

3.2 Setter方法注入

Setter方法注入是通过类的setter方法来注入依赖。与构造函数注入不同,Setter方法注入允许在对象创建之后设置依赖项。通常,Setter方法注入用于可选的依赖关系,或者当需要为对象提供某些默认值时。示例代码

public class MessageProcessor {

    private MessageService messageService;

    // Setter方法注入
    public void setMessageService(MessageService messageService) {
        this.messageService = messageService;
    }

    public void processMessage(String message, String recipient) {
        messageService.sendMessage(message, recipient);
    }
}

Spring配置(XML方式)

<bean id="emailService" class="com.example.EmailService" />
<bean id="messageProcessor" class="com.example.MessageProcessor">
    <property name="messageService" ref="emailService" />
</bean>

在这个例子中,MessageProcessor类通过setMessageService方法来注入MessageService依赖。Spring容器会调用setMessageService方法来设置依赖。

3.3 字段注入(不推荐)

字段注入是通过反射直接注入字段的值,而不是通过构造函数或setter方法。尽管字段注入能够使代码更加简洁,但它不利于代码的可测试性和可维护性,因为它隐藏了依赖关系。尽量避免使用字段注入。示例代码

public class MessageProcessor {

    @Autowired
    private MessageService messageService;

    public void processMessage(String message, String recipient) {
        messageService.sendMessage(message, recipient);
    }
}

Spring配置(XML方式)

<bean id="emailService" class="com.example.EmailService" />
<bean id="messageProcessor" class="com.example.MessageProcessor" />

在这个例子中,messageService字段通过@Autowired注解进行注入,Spring会自动查找MessageService类型的Bean并注入到该字段。

4. 依赖注入的优势

依赖注入为开发者提供了诸多优势,以下是一些主要的优点:

4.1 降低耦合度

依赖注入通过将对象的创建和依赖关系的管理从类内部转移到Spring容器,使得类之间的耦合度大大降低。每个类只需要声明自己依赖的对象,而无需关心如何创建或管理这些对象。这样,类之间的依赖关系变得更加灵活,易于扩展和维护。

4.2 提高可测试性

依赖注入使得单元测试变得更加容易,因为我们可以通过Mock对象或Stub对象来替代实际的依赖,从而进行隔离测试。开发者可以通过构造函数、Setter方法或注解来注入依赖,极大提高了代码的可测试性。

4.3 增强代码可维护性

随着项目的复杂度增加,依赖注入能够减少类之间的直接依赖关系,使得代码更加模块化,便于维护和扩展。当需求发生变化时,只需要修改配置文件或注解,而不需要更改类内部的实现,极大地降低了系统的维护成本。

5. 小结

依赖注入(DI)是Spring框架的核心功能之一,它通过外部容器来管理和注入对象之间的依赖关系,从而减少了类之间的耦合度,提升了代码的可测试性、可维护性和可扩展性。通过构造函数注入、Setter方法注入和字段注入,Spring提供了多种方式来实现依赖注入,开发者可以根据实际需求选择适合的方式。在实际开发中,依赖注入是构建高效、可扩展、易于维护的应用程序的重要手段。

四、总结

控制反转和依赖注入是Spring Framework中的两个核心概念,它们通过简化对象管理和减少类之间的耦合,提高了代码的可维护性和可测试性。Spring通过IoC容器为我们提供了灵活而强大的方式来管理依赖关系,使得开发者可以更加专注于业务逻辑的实现。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Innovus 25.1 版本更新:助力数字后端物理设计新飞跃

在数字后端物理设计领域&#xff0c;每一次工具的更新迭代都可能为项目带来巨大的效率提升与品质优化。今天&#xff0c;就让我们一同聚焦 Innovus 25.1 版本&#xff08;即 25.10 版本&#xff09;的更新要点&#xff0c;探寻其中蕴藏的创新能量。 一、核心功能的强势进 AI…

CodeBuddy 中国版 Cursor 实战:Redis+MySQL双引擎驱动〈王者荣耀〉战区排行榜

文章目录 一、引言二、系统架构设计2.1、整体架构概览2.2、数据库设计2.3、后端服务设计 三、实战&#xff1a;从零构建排行榜3.1、开发环境准备3.2、用户与战区 数据管理3.2.1、MySQL 数据库表创建3.2.2、实现用户和战区数据的 CURD 操作 3.3、实时分数更新3.4、排行榜查询3.5…

在线SQL转ER图工具

在线SQL转ER图网站 在数据库设计、软件开发或学术研究中&#xff0c;ER图&#xff08;实体-关系图&#xff09; 是展示数据库结构的重要工具。然而&#xff0c;手动绘制ER图不仅耗时费力&#xff0c;还容易出错。今天&#xff0c;我将为大家推荐一款非常实用的在线工具——SQL…

python高级特性

json.dumps({a:1,n:2}) #Python 字典类型转换为 JSON 对象。相当于jsonify data2 json.loads(json_str)#将 JSON 对象转换为 Python 字典 异步编程&#xff1a;在异步编程中&#xff0c;程序可以启动一个长时间运行的任务&#xff0c;然后继续执行其他任务&#xff0c;而无需等…

汇编:子程序设计

一、 实验要求 实验目的&#xff1a; 熟练掌握算术运算汇编指令的使用熟练掌握子程序设计的基本方法熟练掌握程序的调试方法 实验内容&#xff1a; 编程实现两个数&#xff1a;#8888H和#79H的乘除运算结合实验1的代码&#xff0c;将加减乘除四则运算写成四个子程序&#xff…

从概念表达到安全验证:智能驾驶功能迎来系统性规范

随着辅助驾驶事故频发&#xff0c;监管机制正在迅速补位。面对能力表达、使用责任、功能部署等方面的新要求&#xff0c;行业开始重估技术边界与验证能力&#xff0c;数字样机正成为企业合规落地的重要抓手。 2025年以来&#xff0c;围绕智能驾驶功能的争议不断升级。多起因辅…

DeepSeek基于注意力模型的可控图像生成

DeepSeek大模型高性能核心技术与多模态融合开发 - 商品搜索 - 京东 图像的加噪与模型训练 在扩散模型的训练过程中&#xff0c;首先需要对输入的信号进行加噪处理&#xff0c;经典的加噪过程是在图像进行向量化处理后在其中添加正态分布&#xff0c;而正态分布的值也是与时间…

“端 - 边 - 云”三级智能协同平台的理论建构与技术实现

摘要 随着低空经济与智能制造的深度融合&#xff0c;传统集中式云计算架构在实时性、隐私保护和资源效率上的瓶颈日益凸显。本文提出“端 - 边 - 云”三级智能协同平台架构&#xff0c;以“时空 - 资源 - 服务”三维协同理论为核心&#xff0c;构建覆盖终端感知、边缘计算、云端…

AI时代,如何实现人机共舞?

在科技飞速发展的当下&#xff0c;人工智能&#xff08;AI&#xff09;已不再是科幻作品中的遥远想象&#xff0c;而是深入渗透到我们生活与工作的方方面面。从智能手机中的语音助手&#xff0c;到金融领域的风险预测模型&#xff1b;从医疗影像的智能诊断&#xff0c;到工业生…

OceanBase 在业务监控系统中的应用实践

本文作者来自于一家总部在宁波的新能源上市公司&#xff0c;公司业务包括光伏新能源产品的研发与产销。 作为年产值达百亿的企业&#xff0c;监控系统是不可或缺的IT管理体系之一&#xff0c;对于确保业务连续性及预警风险非常重要。2022年&#xff0c;公司选择把Zabbix作为企业…

每日Prompt:品牌化键盘键帽

提示词 一个超逼真的3D渲染图&#xff0c;展示了四个机械键盘键帽&#xff0c;排列成紧密的2x2网格&#xff0c;所有键帽相互接触。从等轴测角度观察。一个键帽是透明的&#xff0c;上面用红色印刷着“{just}”字样。另外三个键帽采用颜色&#xff1a;{黑色、紫色和白色}。一个…

超声波传感器模块

欢迎来到 破晓的历程的 博客 ⛺️不负时光&#xff0c;不负己✈️ 文章目录 1.HC-SR04介绍2.HC-SR04原理介绍2.1原理概述3.2原理详解 4驱动代码编写4.1写前思考4.2硬件连线 5.总结hcsr04.hhcsr04.c 1.HC-SR04介绍 超声波传感器有很多种类的型号&#xff1a;HC-SR04、UC-025、…

LeetCode 513 找树左下角的值 LeetCode 112 路径总和 LeetCode106 从中序与后序遍历序列构造二叉树

LeetCode 513 找树左下角的值 迭代法——层序遍历 思路&#xff1a;对树进行层序遍历操作&#xff0c;层序遍历完后&#xff0c;输出树最后一层的第一个节点。 # Definition for a binary tree node. # class TreeNode(object): # def __init__(self, val0, leftNone, r…

『大模型笔记』Langchain作者Harrison Chase专访:环境智能体与全新智能体收件箱

Langchain作者Harrison Chase专访:环境智能体与全新智能体收件箱 文章目录 摘要访谈内容什么环境智能体为什么要探索环境智能体怎么让人类能更方便地和环境智能体互动参考文献摘要 LangChain 的 CEO Harrison Chase 提出了_“环境智能体”(Ambient Agents)的概念,这是一种…

SpringBoot的外部化配置

一、什么是外部化配置 外部化配置是指把应用程序中各种可配置的参数、属性等信息&#xff0c;从代码内部提取出来&#xff0c;放置在外部的配置文件、数据库或配置中心等地方&#xff08;比如使用.properties、.yml 或.xml 等格式的文件&#xff09;进行管理。提高应用程序的可…

数字IC后端实现教程 | Early Clock Flow和Useful skew完全不是一个东西

数字后端零基础入门系列 | Innovus零基础LAB学习Day10 Q: Early clock flow和useful skew都是做短某段路径&#xff0c;这两个有什么区别呢&#xff0c;既然这样还用useful skew是不是有点多余了? Useful Skew技术 在不使用useful skew技术&#xff0c;第一级FF到第二级FF的…

MySQL OCP试题解析(3)

试题如图所示&#xff1a; 一、解析 正确选项&#xff1a;D&#xff09;The backup can be impacted when DDL operations run during the backup&#xff08;备份期间运行的 DDL 操作可能影响备份&#xff09; 1. 关键知识点解析&#xff1a; 题目中的命令 mysqlbackup 使用了…

SpringCloud之Gateway基础认识-服务网关

0、Gateway基本知识 Gateway 是在 Spring 生态系统之上构建的 API 网关服务&#xff0c;基于 Spring &#xff0c;Spring Boot 和 Project Reactor 等技术。 Gateway 旨在提供一种简单而有效的方式来对 API 进行路由&#xff0c;以及提供一些强大的过滤器功能&#xff0c;例如…

STM32-DMA数据转运(8)

目录 一、简介 二、存储器映像 三、DMA框图​编辑 四、DMA基本结构 五、两个数据转运的实例 一、简介 直接存储器存取简称DMA&#xff08;Direct Memory Access&#xff09;&#xff0c;它是一个数据转运小助手&#xff0c;主要用来协助CPU&#xff0c;完成数据转运的工作…

电机控制储备知识学习(一) 电机驱动的本质分析以及与磁相关的使用场景

目录 电机控制储备知识学习&#xff08;一&#xff09;一、电机驱动的本质分析以及与磁相关的使用场景1&#xff09;电机为什么能够旋转2&#xff09;电磁原理的学习重要性 二、电磁学理论知识1&#xff09;磁场基础知识2&#xff09;反电动势的公式推导 附学习参考网址欢迎大家…