SpringBoot : ch08 自动配置原理

news2024/11/9 9:35:45

前言

在现代的Java开发中,Spring Boot已经成为了一个备受欢迎的框架。它以其简化开发流程、提高效率和强大的功能而闻名,使得开发人员能够更加专注于业务逻辑的实现而不必过多地关注配置问题。

然而,你是否曾经好奇过Spring Boot是如何做到自动配置的?为什么我们只需要简单的几行代码,就能够快速搭建一个可用的应用程序?在本博客中,我们将深入探索Spring Boot自动配置的原理,揭开其神秘面纱。

首先,我们将介绍Spring Boot的核心思想和设计原则,以便更好地理解自动配置的背后逻辑。接着,我们将深入研究Spring Boot自动配置的机制,包括条件注解、自动配置类和加载顺序等方面。通过这些详细的解析,我们将揭示Spring Boot是如何根据应用程序的依赖和配置信息,自动完成各种功能的初始化和配置。

一、Spring Boot是如何做到自动配置的?

Spring Boot实现自动配置的核心思想是基于约定优于配置的原则。它通过一系列的机制和规则,根据应用程序的依赖和配置信息,自动完成各种功能的初始化和配置。

下面是Spring Boot实现自动配置的主要机制:

  1. 条件注解(Conditional Annotations):Spring Boot使用条件注解来根据特定条件来决定是否应用某个配置。条件注解是基于Spring框架的@Conditional注解扩展而来,它可以根据一些条件判断来决定是否加载某个配置类或Bean。

  2. 自动配置类(Auto-Configuration Classes):Spring Boot提供了大量的自动配置类,这些类都以AutoConfiguration作为后缀命名,例如DataSourceAutoConfiguration。这些自动配置类通过条件注解和配置信息来判断是否需要进行自动配置。当满足条件时,自动配置类将会注册相应的Beans和配置。

  3. 配置文件(Properties and YAML):Spring Boot使用属性文件(application.propertiesapplication.yml)来存储应用程序的配置信息。这些配置文件中定义了各种属性和值,Spring Boot可以根据这些配置信息来决定是否进行自动配置,并设置相应的默认值。

  4. 启动器(Starters):Spring Boot提供了一系列的启动器,它们是一组预定义的依赖项集合,可以简化项目的构建和配置。启动器会自动引入所需的依赖,并根据这些依赖来触发相应的自动配置。

  5. 条件属性(Conditional Properties):Spring Boot使用条件属性来进一步控制自动配置。条件属性允许你根据特定的属性值或环境条件来决定是否应用某个配置。

通过以上机制,Spring Boot可以根据应用程序的依赖和配置信息,在运行时自动进行初始化和配置,以提供一套合理的默认行为。开发人员可以根据需要进行自定义配置和扩展,同时也可以通过禁用某些自动配置来精确地控制应用程序的行为。

总结起来,Spring Boot实现自动配置的关键在于条件注解、自动配置类、配置文件和启动器等机制的结合运用,使得开发人员能够更加专注于业务逻辑的实现而不必过多地关注繁琐的配置细节。

 

二、为什么能简单配置?

Spring Boot的设计目标之一就是简化开发流程和减少样板代码,使得开发人员能够快速搭建可用的应用程序。以下是几个原因解释为什么只需要简单的几行代码就能够实现这一点:

  1. 自动配置:Spring Boot利用自动配置机制,根据应用程序的依赖和配置信息,自动完成各种功能的初始化和配置。通过默认的自动配置,开发人员可以省去很多手动配置的步骤,只需要引入相关的依赖并添加必要的配置属性,就能够获得一个可用的应用程序。

  2. 启动器:Spring Boot提供了一系列的启动器(starters),它们是预定义的依赖项集合。启动器会自动引入所需的依赖,并触发相应的自动配置。开发人员只需要引入适当的启动器,就能够获取所需的功能和依赖,而不需要手动添加每个依赖的配置。

  3. 约定优于配置:Spring Boot遵循约定优于配置的原则,即通过约定来减少配置。它有一套默认的约定,例如在标准的项目结构中放置Java类、资源文件等,使用注解进行自动配置等。这些约定可以让开发人员专注于业务逻辑的实现,而不必过多地关注配置细节。

  4. 开箱即用:Spring Boot提供了很多开箱即用的特性和功能,例如内嵌的Servlet容器、自动扫描和注册等。这些特性默认就是启用的,开发人员只需要进行必要的配置即可使用它们,无需手动编写大量的代码。

  5. 统一的配置方式:Spring Boot采用了统一的配置方式,即通过属性文件(application.propertiesapplication.yml)来存储应用程序的配置信息。开发人员可以在配置文件中设置各种属性和值,Spring Boot会根据这些配置信息进行自动配置,并提供默认的属性值。这种统一的配置方式使得配置更加简洁明了。

总之,Spring Boot通过自动配置、启动器、约定优于配置和统一的配置方式等机制,使得开发人员只需要简单的几行代码就能够快速搭建一个可用的应用程序。这样的设计理念大大提高了开发效率,减少了繁琐的配置工作,让开发人员能够更专注于业务逻辑的实现。

 

 三、前期准备

1、新建项目

本次案例需要新建两个项目,一个是使用c3p0实现自动装配,最后打包在其他项目引入使用我们自己写的自动装配。

2、导入依赖
1)c3p0-spring-boot-starter
 <dependencies>
        <!-- 添加Spring自动配置的依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
            <version>2.7.17</version>
        </dependency>

        <!-- 这个依赖将配置类的属性注入到元数据中,这样在 idea 中
        就可以提供良好的代码提示功能-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure-processor</artifactId>
            <version>2.7.17</version>
        </dependency>

        <!-- c3p0连接池 -->
        <!-- https://mvnrepository.com/artifact/c3p0/c3p0 -->
        <dependency>
            <groupId>c3p0</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.1.2</version>
        </dependency>


    </dependencies>

这是一个Java项目的Maven依赖配置文件,主要包含了Spring Boot自动配置、c3p0连接池等依赖项。Spring Boot自动配置可以让开发者更方便地构建Spring应用程序,而c3p0连接池则提供了数据库连接池的功能,方便应用程序与数据库进行数据交互。

2)ch08
  <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- c3p0的starter -->
        <dependency>
            <groupId>org.c3p0.spring.boot</groupId>
            <artifactId>c3p0-spring-boot-starter</artifactId>
            <version>1.0</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>11</source>
                    <target>11</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>
                <configuration>
                    <mainClass>edu.nf.ch08.Ch08Application</mainClass>
                    <skip>true</skip>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

 这是一个Java项目的Maven依赖配置文件,主要包含了Spring Boot、c3p0连接池(自己写的)和MySQL驱动等依赖项。这些依赖将用于构建一个使用Spring Boot框架、c3p0连接池和MySQL数据库的Java应用程序。

在dependencies部分,首先引入了spring-boot-starter依赖,它是Spring Boot的核心依赖,包含了Spring框架的基本功能模块。接着引入了spring-boot-starter-test依赖,它是用于编写测试的依赖,并且被设置为test作用域,表示只在测试阶段起作用。

然后引入了c3p0-spring-boot-starter依赖,它是c3p0连接池的Spring Boot集成依赖,可以快速配置和使用c3p0连接池。

最后引入了mysql-connector-java依赖,它是MySQL数据库的Java驱动程序。

在dependencyManagement部分,引入了spring-boot-dependencies依赖,用于管理Spring Boot的版本号。

在build部分,定义了Maven插件的配置。maven-compiler-plugin插件用于指定编译器的版本和编码方式。spring-boot-maven-plugin插件用于打包和运行Spring Boot应用程序。

需要注意的是,该配置文件中的${spring-boot.version}是一个变量,实际值需要根据具体情况进行替换。

 

四、实现 c3p0-spring-boot-starter 

1、实现配置类  C3p0DataSourceProperties 

@ConfigurationProperties(prefix = "spring.datasource.c3p0")
public class C3p0DataSourceProperties {

    private String driverClassName;
    private String url;
    private String username;
    private String password;
    private Integer minPoolSize;
    private Integer maxPoolSize;
    private Integer initialPoolSize;
    private Integer maxIdleTime;

    public String getDriverClassName() {
        return driverClassName;
    }

    public void setDriverClassName(String driverClassName) {
        this.driverClassName = driverClassName;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Integer getMinPoolSize() {
        return minPoolSize;
    }

    public void setMinPoolSize(Integer minPoolSize) {
        this.minPoolSize = minPoolSize;
    }

    public Integer getMaxPoolSize() {
        return maxPoolSize;
    }

    public void setMaxPoolSize(Integer maxPoolSize) {
        this.maxPoolSize = maxPoolSize;
    }

    public Integer getInitialPoolSize() {
        return initialPoolSize;
    }

    public void setInitialPoolSize(Integer initialPoolSize) {
        this.initialPoolSize = initialPoolSize;
    }

    public Integer getMaxIdleTime() {
        return maxIdleTime;
    }

    public void setMaxIdleTime(Integer maxIdleTime) {
        this.maxIdleTime = maxIdleTime;
    }



}

这段代码是一个配置类,用于配置C3P0数据源的属性。通过@ConfigurationProperties(prefix = "spring.datasource.c3p0")注解,将配置文件中以spring.datasource.c3p0为前缀的属性与该类的属性进行绑定。

具体来说,这个配置类有以下属性:

  • driverClassName: 数据库驱动类名
  • url: 数据库连接URL
  • username: 数据库用户名
  • password: 数据库密码
  • minPoolSize: 连接池中的最小连接数
  • maxPoolSize: 连接池中的最大连接数
  • initialPoolSize: 初始化连接池时的连接数
  • maxIdleTime: 连接在连接池中闲置的最长时间

通过提供对应的getter和setter方法,可以获取和设置这些属性的值。

使用该配置类,可以方便地管理和配置C3P0数据源的相关属性。在Spring Boot应用程序中,可以在application.propertiesapplication.yml配置文件中设置这些属性,然后通过@EnableConfigurationProperties(C3p0DataSourceProperties.class)注解将配置类生效,并自动将属性值注入到其他需要使用数据源的组件中。

 2、实现 C3p0DataSourceAutoConfigure

@Configuration
@ConditionalOnClass(ComboPooledDataSource.class)
@AutoConfigureBefore(DataSourceAutoConfiguration.class)
@EnableConfigurationProperties(C3p0DataSourceProperties.class)
public class C3p0DataSourceAutoConfigure {

    private C3p0DataSourceProperties c3p0DataSourceProperties;

    @Autowired
    public void setC3p0DataSourceProperties(C3p0DataSourceProperties c3p0DataSourceProperties) {
        this.c3p0DataSourceProperties = c3p0DataSourceProperties;
    }

    @Bean
    // 这个条件注解标识当容器中存在这个bean的时候才会执行装配
    // @ConditionalOnBean
    // 这个条件注解标识当容器中不存在这个bean的时候才会执行装配
    @ConditionalOnMissingBean
    public DataSource dataSource() throws PropertyVetoException {
        // 创建 c3p0 的数据源
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        // 将配置属性设置到 dataSource 中
        dataSource.setDriverClass(c3p0DataSourceProperties.getDriverClassName());
        dataSource.setJdbcUrl(c3p0DataSourceProperties.getUrl());
        dataSource.setUser(c3p0DataSourceProperties.getUsername());
        dataSource.setPassword(c3p0DataSourceProperties.getPassword());
        dataSource.setMinPoolSize(c3p0DataSourceProperties.getMinPoolSize());
        dataSource.setMaxPoolSize(c3p0DataSourceProperties.getMaxPoolSize());
        dataSource.setInitialPoolSize(c3p0DataSourceProperties.getInitialPoolSize());
        dataSource.setMaxIdleTime(c3p0DataSourceProperties.getMaxIdleTime());
        return dataSource;
    }

}

 这段代码是一个自动配置类,用于将C3P0数据源配置为Spring Boot应用程序的默认数据源。

首先,通过@Configuration注解将该类标识为一个配置类。然后,通过@ConditionalOnClass(ComboPooledDataSource.class)注解,当ComboPooledDataSource类存在于类路径中时,才会进行自动配置。

接下来,通过@AutoConfigureBefore(DataSourceAutoConfiguration.class)注解,保证在DataSourceAutoConfiguration类之前进行自动配置。这样可以确保C3P0数据源会覆盖默认的数据源配置。

通过@EnableConfigurationProperties(C3p0DataSourceProperties.class)注解,启用对C3p0DataSourceProperties类的配置属性的支持。这样,在该自动配置类中就可以自动注入C3p0DataSourceProperties类的实例。

在该自动配置类中定义了一个dataSource()方法,用于创建并配置C3P0数据源。通过@Bean注解,将该方法的返回值作为一个Spring Bean注册到容器中。

dataSource()方法中,首先创建了一个ComboPooledDataSource实例,然后将C3p0DataSourceProperties类中的属性值设置到数据源中。最后,返回创建的数据源。

总结起来,这个自动配置类的作用是将C3P0数据源配置为Spring Boot应用程序的默认数据源,并将C3p0DataSourceProperties类中的属性值应用到数据源中。这样,其他使用数据源的组件就可以直接注入DataSource类型的Bean,并使用C3P0数据源进行数据库访问。

 3、配置META-INF下的配置文件
org.springframework.boot.autoconfigure.EnableAutoConfiguration = \
  org.c3p0.spring.boot.autoconfigure.C3p0DataSourceAutoConfigure

这是META-INF目录下的spring.factories文件,用于配置Spring Boot自动配置的类。

在该文件中,org.springframework.boot.autoconfigure.EnableAutoConfiguration是一个键,后面的\表示换行,而org.c3p0.spring.boot.autoconfigure.C3p0DataSourceAutoConfigure是对应的值,表示需要自动配置的类是C3p0DataSourceAutoConfigure

通过这种方式,Spring Boot会在启动时自动加载并应用C3p0DataSourceAutoConfigure类中的配置。这样,C3P0数据源的自动配置就会生效,将C3P0作为默认的数据源配置到Spring Boot应用程序中。

4、打包
 

将此maven项目打包,方便在后面的项目依赖此项目。 

 

五、实现 ch08

1、配置 yml 
spring:
  datasource:
    c3p0:
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://localhost:3306/psm
      username: root
      password: 123456
      min-pool-size: 5
      initial-pool-size: 5
      max-pool-size: 20
      max-idle-time: 5000

 这是一个Spring Boot中配置c3p0数据源的示例。通过配置文件来设置c3p0连接池的相关属性,包括驱动类名、数据库URL、用户名、密码以及连接池的最小大小、初始大小、最大大小和最大空闲时间等。

在上述配置中,spring.datasource.c3p0.driver-class-name指定了MySQL数据库的驱动类名。spring.datasource.c3p0.url指定了数据库的URL。spring.datasource.c3p0.usernamespring.datasource.c3p0.password分别指定了数据库的用户名和密码。

spring.datasource.c3p0.min-pool-sizespring.datasource.c3p0.initial-pool-sizespring.datasource.c3p0.max-pool-size分别指定了连接池的最小大小、初始大小和最大大小。

spring.datasource.c3p0.max-idle-time指定了连接池中连接的最大空闲时间,单位为毫秒。

这些配置项可以根据实际情况进行调整,以满足应用程序的需求。在应用程序启动时,Spring Boot会根据这些配置信息创建并管理c3p0连接池,从而实现对数据库的连接和操作。

注意:这是我们刚刚自己配置的,我们引入了我们自己写的c3p0的项目。

2、测试
 @Autowired
    private DataSource dataSource;


    @Test
    void contextLoads() throws SQLException {
        ComboPooledDataSource ds = (ComboPooledDataSource) dataSource;
        System.out.println(ds.getConnection());
        System.out.println(ds.getDriverClass());
        System.out.println(ds.getJdbcUrl());
        System.out.println(ds.getMinPoolSize());
        System.out.println(ds.getMaxPoolSize());
        System.out.println(ds.getInitialPoolSize());
    }

 这段代码是一个在Spring Boot中使用c3p0数据源的示例。

首先,通过@Autowired注解将DataSource对象注入到当前类中,表示将由Spring容器自动创建和管理数据源。

然后,在contextLoads()方法中,将注入的DataSource对象强制转换为ComboPooledDataSource类型,以便获取c3p0特定的属性。

接下来,通过调用getConnection()方法可以获取一个数据库连接,并使用System.out.println()打印出连接对象。这样可以验证数据源配置是否正确,以及检查连接是否成功。

然后,通过调用getDriverClass()getJdbcUrl()getMinPoolSize()getMaxPoolSize()getInitialPoolSize()等方法,分别获取c3p0数据源的驱动类名、JDBC URL、最小连接池大小、最大连接池大小和初始连接池大小,并通过System.out.println()打印出来。

这些操作可以帮助你验证数据源配置是否生效,以及获取连接池的相关属性信息。

运行结果:

 

六、springboot自动装配的原理是什么?

Spring Boot的自动装配是基于Spring框架的依赖注入和控制反转(IoC)机制实现的。

自动装配的原理如下:

  1. 组件扫描:Spring Boot会在启动时自动扫描应用程序的包及其子包,查找带有特定注解的类(如@Component@Service@Repository等)。

  2. 隐式Bean定义:当Spring Boot找到带有特定注解的类时,它会隐式地将这些类解析为Bean定义,即创建相应的Bean实例所需的元数据。

  3. 自动配置:Spring Boot根据应用程序的依赖关系和配置信息,通过条件化配置来自动决定需要创建哪些Bean。自动配置是通过使用@Conditional注解进行条件判断来实现的,例如判断某个类是否在类路径上、是否存在某个Bean等。

  4. Bean创建和注入:根据Bean定义和自动配置的结果,Spring Boot会创建相应的Bean实例,并将其注入到需要依赖的地方。这是通过依赖注入(DI)机制实现的,可以使用@Autowired@Inject或构造函数等方式进行注入。

总结起来,Spring Boot的自动装配通过组件扫描、隐式Bean定义、自动配置和依赖注入等机制,实现了对应用程序中各个组件的自动发现、创建和注入,减少了手动配置的工作量,提高了开发效率。同时,Spring Boot还提供了一些默认的自动配置,可以根据应用程序的需求进行定制和扩展。

 

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

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

相关文章

7000字+24张图带你彻底弄懂线程池

大家好&#xff0c;我是三友。今天跟大家聊一聊无论是在工作中常用还是在面试中常问的线程池&#xff0c;通过画图的方式来彻底弄懂线程池的工作原理&#xff0c;以及在实际项目中该如何自定义适合业务的线程池。 一、什么是线程池 线程池其实是一种池化的技术的实现&#xff0…

控制台gbk乱码

引用IntelliJ IDEA中 统一设置编码为utf-8或GBK-CSDN博客 特别注意file coding 的文件path和java的编码格式 配置

9.增删改操作

目录 一、插入操作 1、为表的所有字段插入数据 2、为表的指定字段插入数据 3、同时插入多条记录 4、将查询结果插入表中&#xff1a; 二、更新操作 三、删除操作 四、练习题 一、插入操作 在使用数据库之前&#xff0c;数据库中必须要有数据&#xff0c;MYSQL中使INSE…

ESP32-Web-Server编程-HTML 基础

ESP32-Web-Server编程-HTML 基础 概述 HTML(HyperText Markup Language) 是用来描述网页的一种语言。其相关内容存储在前端代码的 .html 文件中。 当浏览器向 web 服务器请求网页时&#xff0c;一个 HTML 文件被发送给浏览器&#xff0c;浏览器解释该文件的内容&#xff0c;…

【重磅】:Spring Initializer 已经不支持Java8,也就是SpringBoot2.x项目初始化

Spring Initializer 已经不支持Java8 问题描述解决方案升级java版本更换IDEA内置的Spring Initializer中 Server URL的镜像地址 问题描述 我们可以看到在IDEA内置的Spring Initializer中 Java版本选择模块已经不支持1.8了&#xff0c;同样的&#xff0c;官网也不再支持了 解决…

YOLOv8 onnx 文件推理多线程加速视频流

运行环境&#xff1a; MacOS&#xff1a;14.0Python 3.9Pytorch2.1onnx 运行时 模型文件&#xff1a; https://wwxd.lanzouu.com/iBqiA1g49pbc 密码:f40v 下载 best.apk后将后缀名修改为 onnx 即可模型在英伟达 T4GPU 使用 coco128 训练了 200 轮如遇下载不了可私信获取 代码…

Ubuntu18.04安装Ipopt-3.12.8流程

本文主要介绍在Ubuntu18.04中安装Ipopt库的流程&#xff0c;及过程报错的解决方法&#xff0c;已经有很多关于Ipopt安装的博客&#xff0c;但经过我的测试&#xff0c;很多都失效了&#xff0c;经过探索&#xff0c;找到可流畅的安装Ipopt的方法&#xff0c;总结成本篇博客。 …

《尚品甄选》:后台系统——权限管理之菜单管理,递归实现树形结构查询(debug一遍)

文章目录 一、表结构设计二、菜单管理接口2.1 查询菜单2.2 添加菜单2.3 修改菜单2.4 删除菜单 三、分配菜单3.1 查询菜单3.2 保存菜单(批量插入) 四、动态菜单五、解决bug 一、表结构设计 菜单管理就是对系统的首页中的左侧菜单进行维护。 一个用户可以担任多个角色&#xff…

解密人工智能:线性回归

导言 人工智能&#xff08;AI&#xff09;已经成为当今科技领域的热门话题&#xff0c;其应用领域涵盖了各个行业。线性回归作为人工智能中的一种关键统计学方法&#xff0c;被广泛应用于预测和决策支持系统中。本文将为您详细介绍线性回归在人工智能中的应用原理与方法&#x…

将用户的session改为分布式共享session

将用户的session改为分布式session 分布式session理解 使用分布式session的原因&#xff1a; 后台服务器是分布式的&#xff08;比如要负载均衡&#xff09;&#xff0c;在A服务器请求的的信息&#xff08;如用户登录信息&#xff09;存在A的session中&#xff0c;B服务器并不…

代码随想录算法训练营 ---第四十八天

第一题&#xff1a; 简介&#xff1a; 注&#xff1a;本题简介是我的思路&#xff0c;题解思路看下方。 动态规划五部曲&#xff1a; 1.确定dp数组的含义 //dp[i]表示 偷到第i家能偷到的最大金额 for(int i2;i<nums.size();i){if(i-3>0)dp[i] max(dp[i-2],dp[i-3])nu…

vue中的keep-alive详解与应用场景

​&#x1f308;个人主页&#xff1a;前端青山 &#x1f525;系列专栏&#xff1a;Vue篇 &#x1f516;人终将被年少不可得之物困其一生 依旧青山,本期给大家带来vue篇专栏内容:vue-keep-alive 目录 一、Keep-alive 是什么 二、使用场景 三、原理分析 四、案例实现 activa…

NB-IoT BC260Y Open CPU SDK④开发环境搭建

NB-IoT BC260Y Open CPU SDK④开发环境搭建 1、SDK包的介绍2、编程工具3、程序框架1、SDK包的介绍 (1)、SDK包的下载: 链接: (2)、文件目录介绍 文件名描述device启动文件、底层配置文档等doc存放 QuecOpen 项目相关的说明文档osFreeRTOS 相关代码out输出编译 App 和调…

06-学成在线添加课程,包含课程基本信息,营销信息,课程计划信息,师资信息

添加课程 界面原型 第一步: 用户进入课程查询列表,点击添加课程按钮,选择课程类型是直播还是录播,课程类型不同那么授课方式也不同 添加的课程和教学机构是一对一的关系 第二步: 用户选完课程形式后,点击下一步填写课程的基本信息和营销信息(两张表) 用户只要填完课程信息就…

SpringCloud--分布式事务实现

一、分布式事务 首先要明白事务是指数据库中的一组操作&#xff0c;这些操作要么全部成功执行&#xff0c;要么全部不执行&#xff0c;以保持数据的一致性和完整性。在本地事务中&#xff0c;也就是传统的单机事务&#xff0c;必须要满足原子性(Atomicity)、一致性(Consistenc…

错误:FinalShell连接CentOs连接失败

需要说明的是:这个错误不是首次连接发生的,而是多次使用后可能发生的错误 正文: 可能的原因是虚拟机的ip地址发生了变更,原因有以下几点: 最最可能的原因:1.DHCP分配变更&#xff1a; 如果虚拟机使用DHCP来获取IP地址&#xff0c;那么DHCP服务器可能会分配给虚拟机一个新的I…

java设计模式学习之【单例模式】

文章目录 引言单例模式简介定义与用途实现方式&#xff1a;饿汉式懒汉式 UML 使用场景优势与劣势单例模式在spring中的应用饿汉式实现懒汉式实现数据库连接示例代码地址 引言 单例模式是一种常用的设计模式&#xff0c;用于确保在一个程序中一个类只有一个实例&#xff0c;并且…

不小心删除了短信,如何在 Android 上恢复已删除的短信

不小心删除了文字消息在 Android 手机上使用可能会是一种令人痛苦的体验。这些消息可能包含有价值的信息、珍贵的回忆或重要的细节。幸运的是&#xff0c;您可以探索多种方法来恢复这些丢失的消息。在本文中&#xff0c;我们将深入研究可用于检索已删除短信的选项&#xff0c;并…

vue3中readonly和shallowReadonly

readonly: 深度只读数据 获取一个对象 (响应式或纯对象) 或 ref 并返回原始代理的只读代理。 只读代理是深层的&#xff1a;访问的任何嵌套 property 也是只读的。 shallowReadonly 浅只读数据 创建一个代理&#xff0c;使其自身的 property 为只读&#xff0c;但不执行…

WhatsApp API号解封教程(内含图片指引和申诉模板)

WhatsApp API 是专门为中大型企业设置的WhatsApp APP页面&#xff0c;API号并不像WhatsApp个人号和企业号一样可以直接从App Store 或Google Play 下载&#xff0c;而是需要对接官方来连接API。 虽然申请WhatsApp API号的程序和手续比较复杂&#xff0c;但是这个操作对于企业来…