SpringBoot入门【java全端课35】

119 阅读13分钟

一、SpringBoot入门

1.1 SpringBoot概述

1.1.1 SpringBoot简介

Spring Boot 是由 Pivotal 团队提供的全新框架,旨在简化基于 Spring 框架的开发。它通过提供开箱即用的配置、自动配置依赖管理等功能,使得开发者能够快速构建独立的、生产级别的基于 Spring 的应用程序。

SpringBoot 帮我们简单、快速地创建一个独立的、生产级别的 Spring 应用(说明:SpringBoot底层是Spring Framework)

大多数 SpringBoot 应用只需要编写少量配置即可快速整合 Spring 平台以及第三方技术

1.2 SpringBoot特性

  • 直接嵌入Tomcat、Jetty or Undertow(无需部署 war 包)【Servlet容器】
  • 提供可选的启动器[starter],简化应用整合
  • 按需自动配置 Spring 以及 第三方库组件
  • 总结:简化开发,简化配置,简化整合,简化部署,简化监控,简化运维。

1.3 SpringBoot场景启动器

  • SpringBoot工程默认都会继承父工程:spring-boot-starter-parent
    • 父工程定义SpringBoot配置文件名称及类型
  • SpringBoot父工程的父工程:spring-boot-dependencies
    • 定义SpringBoot支持环境版本号
  • 场景启动器
    • 作用:导入一堆jar包
      • 一个启动器对应多个坐标,一个坐标对应多个jar包
    • 类型
      • 原生启动器:spring-boot-starter-xxx

      • 第三方启动器:xxx-spring-boot-starter

  • 新建工程:导入启动器

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>3.0.3</version>
        </dependency>
    
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter-test</artifactId>
            <version>3.0.3</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    
  • 编写配置文件:application.properties

    #设置数据库连接
    spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
    spring.datasource.url=jdbc:mysql://localhost:3306/0923_demo?useSSL=false&serverTimezone=UTC
    spring.datasource.username=root
    spring.datasource.password=root
    
    #mybatis
    mybatis.mapper-locations=classpath:mappers/*.xml
    mybatis.configuration.map-underscore-to-camel-case=true
    #设置自动映射full(selectAllEmpAndDeptAssociation)
    mybatis.configuration.auto-mapping-behavior=full
    #开启延迟加载(懒加载)
    mybatis.configuration.lazy-loading-enabled=true
    mybatis.configuration.aggressive-lazy-loading=false
    mybatis.type-aliases-package=com.mytest.pojo
    logging.level.com.mytest.mapper=debug
    
    #服务器端口号(默认值8080)
    server.port=8080
    #配置上下文路径(默认值/)
    server.servlet.context-path=/
    #静态资源路径(默认值:)
    spring.web.resources.static-locations=classpath:/static/
    
  • 启动类启动服务器

1.3.2 常用场景启动器

  • SpringBoot基启动器

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    
  • SpringBoot整合MVC

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
  • SpringBoot整合Mybatis

    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>3.0.3</version>
    </dependency>
     <dependency>
         <groupId>com.mysql</groupId>
         <artifactId>mysql-connector-j</artifactId>
         <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter-test</artifactId>
        <version>3.0.3</version>
        <scope>test</scope>
    </dependency>
    

    二、 SpringBoot配置文件详解

SpringBoot配置文件必须是:application*.properties或application*.yml或application*.yaml

SpringBoot配置文件中支持自定义配置内置配置

  • 内置配置特点:会自带提示
  • 自定义配置特点:默认不会提示,也可以配置属性类使用@ConfigurationProperties注解添加提示

2.1 SpringBoot配置文件类型

  • springboot配置支持配置文件:properties或yml(yaml)
  • 优先级:properties>yml>yaml

2.2 yml配置文件语法

application.yml 是 Spring Boot 中常用的配置文件格式之一,它使用 YAML(YAML Ain't Markup Language)语法来定义应用程序的配置项。相比传统的 application.properties 文件,YAML 语法更加简洁、层次分明,特别适合表达嵌套结构。以下是关于 application.yml 文件中 YAML 语法的详细解析:

  • 键值对:YAML 文件中的每一行通常表示一个键值对,格式为 key: value。注意:后必须有空格

  • 缩进:YAML 使用缩进来表示层级关系,每个层级的缩进通常是两个空格(不是 Tab),不同的缩进级别表示不同级别的嵌套。

  • 注释:以 # 开头的行是注释,不会被解析。

  • 多级配置:YAML 支持多级配置,通过缩进来表示父子关系。例如:

    spring:
      datasource:
        url: jdbc:mysql://localhost:3306/mydb
        username: root
        password: secret
        driver-class-name: com.mysql.cj.jdbc.Driver
    
  • 数组和列表:可以使用 - 来定义列表或数组元素,也可以直接用方括号表示:

    myapp:
      servers:
        - server1.example.com
        - server2.example.com
        - server3.example.com
    #或
    myapp:
      servers: [server1.example.com, server2.example.com, server3.example.com]
    
  • 数字和日期:直接写入即可,YAML 会自动识别

    myapp:
      timeout: 30000  # 整数
      date: 2024-01-01  # 日期
    
  • 空值:可以通过 null 或者 ~ 来表示空值

    myapp:
      optional: ~
    

三、@ConfigurationProperties注解详解

3.1 配置属性注解:@ConfigurationProperties简介

@ConfigurationProperties 注解是 Spring 框架中用于将配置文件中的属性绑定到 Java Bean 的一种方式。它使得你可以轻松地从外部配置源(如 application.propertiesapplication.yml 文件)读取配置信息,并将其映射为应用程序中的对象结构。以下是关于 @ConfigurationProperties 注解的详细解析:

  1. 基本概念

  • 作用@ConfigurationProperties 用于标注一个类,表示该类是一个配置属性的载体,可以自动从配置文件中加载对应的属性值。

  • 前缀:通常需要指定一个 prefix 属性来定义这些配置项在配置文件中的前缀,确保它们能够正确映射到相应的字段上。

  1. 使用场景

当你有多个相关的配置项时,@ConfigurationProperties 可以帮助你将它们组织成一个结构化的对象模型,而不是分散在整个应用程序的不同地方。这不仅提高了代码的可维护性,也便于管理复杂的配置逻辑。

3.2 @ConfigurationProperties注解基本使用

SpringBoot环境中默认的数据源对象是:com.zaxxer.hikari.HikariDataSource

当我们需要DruidDataSource时,需要配置德鲁伊数据源

3.2.1 准备环境

  • 导入DruidDataSource依赖坐标

    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid-spring-boot-starter</artifactId>
        <version>1.2.8</version>
    </dependency>
    
  • 编写配置文件:application.yml

    #配置数据源信息(第三方)
    jdbc:
      datasource:
        driverClassName: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/0923_demo
        username: root
        password: root
    #注意:下方是HikariDataSource默认数据源配置(暂时不用)    
    spring:
      datasource:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/0923_demo?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=false
        username: root
        password: rootn    
    

3.2.2 定义属性类

package com.mytest.properties;

import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Data
@Component
@ConfigurationProperties(prefix = "jdbc.datasource") //注意:prefix属性值与配置文件中前缀一致
public class JdbcProperty {

    private String driverClassName;
    private String url;
    private String username;
    private String password;

}

3.2.3 配置类中综合应用

package com.mytest.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.mytest.properties.JdbcProperty;
import com.zaxxer.hikari.util.DriverDataSource;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;

@Configuration
public class MybatisConfig {

    //注意:使用属性类,代替下方各属性
    @Autowired
    private JdbcProperty jdbcProperty;

//    private String driverClassName;
//    @Value("${jdbc.datasource.url}")
//    private String url;
//    @Value("${jdbc.datasource.username}")
//    private String username;
//    @Value("${jdbc.datasource.password}")
//    private String password; 
    
    @Bean
    public DataSource dataSource(){

        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(jdbcProperty.getDriverClassName());
        dataSource.setUrl(jdbcProperty.getUrl());
        dataSource.setUsername(jdbcProperty.getUsername());
        dataSource.setPassword(jdbcProperty.getPassword());
        return dataSource;
    }

}

3.3 注意事项

  • 启用配置处理:为了使 @ConfigurationProperties 生效,你需要确保项目中包含了 spring-boot-configuration-processor 依赖。这对于生成元数据文件非常重要,有助于 IDE 提供更好的代码补全和支持。
  • 注册为 Bean:虽然可以直接在组件上使用 @Component@ConfigurationProperties,但推荐的做法是通过 @EnableConfigurationProperties 或者 @Import 将配置类注册为 Spring 管理的 Bean。
  • 默认值设置:可以通过构造函数或直接在字段上赋值的方式来提供属性的默认值。
  • 安全性考虑:对于敏感信息(如密码),建议不要直接暴露在配置文件中,而是采用加密存储或其他安全措施。
  • 配置更新监听:如果需要在配置更新时做出响应,可以实现 ApplicationListener<ConfigurationPropertiesBindingEvent> 接口。

四、@SpringBootApplication注解详解

4.1 @SpringBootApplication注解简介

4.1.1 @SpringBootApplication源码

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package org.springframework.boot.autoconfigure;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.context.TypeExcludeFilter;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.core.annotation.AliasFor;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
    excludeFilters = {@Filter(
    type = FilterType.CUSTOM,
    classes = {TypeExcludeFilter.class}
), @Filter(
    type = FilterType.CUSTOM,
    classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
    @AliasFor(
        annotation = EnableAutoConfiguration.class
    )
    Class<?>[] exclude() default {};

    @AliasFor(
        annotation = EnableAutoConfiguration.class
    )
    String[] excludeName() default {};

    @AliasFor(
        annotation = ComponentScan.class,
        attribute = "basePackages"
    )
    String[] scanBasePackages() default {};

    @AliasFor(
        annotation = ComponentScan.class,
        attribute = "basePackageClasses"
    )
    Class<?>[] scanBasePackageClasses() default {};

    @AliasFor(
        annotation = ComponentScan.class,
        attribute = "nameGenerator"
    )
    Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;

    @AliasFor(
        annotation = Configuration.class
    )
    boolean proxyBeanMethods() default true;
}

4.1.2 @SpringBootApplication作用

  • @SpringBootApplication:实际上是以下三个注解的组合

    • @SpringBootConfiguration:标识该类为一个配置类,可以使用 Java 配置来定义组件(例如通过 @Bean 注解)。
    • @EnableAutoConfiguration:启用 Spring Boot 的自动配置机制,根据类路径中的依赖自动配置 Spring 应用程序。它会尝试猜测并配置你可能需要的 Bean,从而减少了大量的手动配置工作。
    • @ComponentScan:自动扫描并注册带有 @Component、@Service、@Repository 和 @Controller 等注解的类作为 Spring Beans。默认情况下,它会从声明 @SpringBootApplication 的类所在的包及其子包中查找组件。
  • @SpringBootApplication使用场景

    • @SpringBootApplication 通常被放置在应用程序的主类上,也就是包含 public static void main(String[] args) 方法的那个类。这样做的好处是可以让整个应用程序的所有配置都集中在这个主类中,便于管理和维护。
  • @SpringBootApplication自定义配置

    • 虽然 @SpringBootApplication 提供了一套合理的默认设置,但你可以根据需要对其进行自定义。比如,如果你想改变组件扫描的基础包或者关闭某些自动配置,可以通过如下方式实现:

      • 自定义 @ComponentScan 的基础包

        @SpringBootApplication(scanBasePackages = {"com.example.package1", "com.example.package2"})
        public class MyApplication {
            // ...
        }
        
      • 禁用特定的自动配置:如果你不想使用某些自动配置,可以通过 exclude 参数来排除它们

        @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
        public class MyApplication {
            // ...
        }
        

4.2 @ComponentScan注解详解

@ComponentScan 注解是 Spring 框架中的一个重要组件,用于指定哪些包应该被扫描以查找带有特定注解(如 @Component@Service@Repository@Controller)的类,并将这些类注册为 Spring 容器中的 Bean。通过使用 @ComponentScan,你可以自动发现并配置应用程序中的组件,而无需手动在 XML 文件中定义每个 Bean。以下是关于 @ComponentScan 注解的详细解析:

4.2.1 基本概念

  • 作用@ComponentScan 主要用于启动组件扫描机制,让 Spring 自动寻找和注册组件。
  • 默认行为:当 @ComponentScan 被应用到一个配置类上时,默认情况下它会从该配置类所在的包开始递归扫描所有子包。

4.2.2 常用属性

  • basePackagesvalue:指定需要扫描的基础包路径,可以是一个或多个包名,用逗号分隔。例如:
@ComponentScan(basePackages = {"com.example.package1", "com.example.package2"})
public @interface SpringBootApplication {}
  • basePackageClasses:通过提供具体类来确定基础包,Spring 将从这些类所在的包开始扫描。这比直接指定包名更加灵活,尤其是在模块化项目中。例如:

    @ComponentScan(basePackageClasses = {MyClass1.class, MyClass2.class})
    public @interface SpringBootApplication {}
    
  • includeFiltersexcludeFilters:允许你自定义过滤规则来包含或排除某些类型的组件。每个过滤器都是一个 FilterType 枚举值加上相应的模式匹配表达式。例如:

    @ComponentScan(
        includeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = MyCustomAnnotation.class),
        excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = MyExcludedClass.class)
    )
    public @interface SpringBootApplication {}
    

4.3 @SpringBootConfiguration注解详解

4.3.1 源码

package org.springframework.boot;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.AliasFor;
import org.springframework.stereotype.Indexed;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
@Indexed
public @interface SpringBootConfiguration {
    @AliasFor(
        annotation = Configuration.class
    )
    boolean proxyBeanMethods() default true;
}

4.3.2 @SpringBootConfiguration注解简介

@SpringBootConfiguration 注解是 Spring Boot 提供的一个专门用于标识配置类的注解。它实际上是 @Configuration 注解的一个变体,主要用于避免与其他框架或库中的 @Configuration 注解发生冲突。以下是关于 @SpringBootConfiguration 注解的详细解析:

  1. 基本概念

  • 作用@SpringBootConfiguration 标识一个 Java 类为 Spring 的配置类,意味着该类中可以包含使用 @Bean 注解的方法来定义和初始化 Spring 容器中的 Bean。

  • 区别于 @Configuration:虽然 @SpringBootConfiguration@Configuration 在功能上几乎相同,但前者是专门为 Spring Boot 应用程序设计的,以确保不会与其他框架的 @Configuration 注解产生混淆。

  1. 自动应用

在大多数情况下,你不需要显式地使用 @SpringBootConfiguration,因为:

  • @SpringBootApplication 注解已经隐含了 @SpringBootConfiguration 的功能。当你在一个主应用程序类上添加 @SpringBootApplication 时,实际上等于同时应用了 @SpringBootConfiguration@EnableAutoConfiguration@ComponentScan

4.4 @EnableAutoConfiguration注解详解

4.4.1 @EnableAutoConfiguration注解简介

@EnableAutoConfiguration 是 Spring Boot 提供的一个注解,用于启用 Spring Boot 的自动配置机制。Spring Boot 的设计初衷是为了简化 Spring 应用的创建过程,特别是针对那些有常见模式的应用程序(如嵌入式服务器、安全性、数据库连接等)。自动配置是 Spring Boot 的一个核心特性,它试图根据你的类路径和配置来猜测并自动配置你应用程序的 bean。

以下是 @EnableAutoConfiguration 注解的一些关键点:

  1. 自动检测依赖:当在应用程序中使用 @EnableAutoConfiguration 时,Spring Boot 会扫描类路径上的 jar 包,并尝试根据它们的内容来推断应该应用哪些自动配置。

  2. 排除特定自动配置:有时你可能不希望某些自动配置生效。你可以通过 exclude 属性来排除不需要的自动配置类,例如:

    java深色版本

    @EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
    
  3. 排除名称空间:如果你知道要排除的自动配置类的名称,但不想直接引用它们,可以使用 excludeName 属性,例如:

    java深色版本

    @EnableAutoConfiguration(excludeName={"org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration"})
    
  4. 与@SpringBootApplication的关系:通常情况下,你不会直接使用 @EnableAutoConfiguration,而是使用 @SpringBootApplication 注解。@SpringBootApplication 是一个组合注解,它包含了 @EnableAutoConfiguration@ComponentScan@Configuration 的功能。

  5. 条件化配置:自动配置类通常是条件化的,这意味着它们只有在满足一定条件时才会被应用。比如,只有在没有检测到用户定义的相同类型的 bean 时,自动配置类才会起作用。

  6. 自定义配置优先:如果开发者自己定义了配置,那么这些配置会覆盖自动配置。这允许开发者保持对应用程序配置的完全控制。

总之,@EnableAutoConfiguration 是 Spring Boot 简化开发体验的关键部分,它使得开发者能够快速启动和运行应用程序,同时仍然保留足够的灵活性来自定义配置。

4.4.2 @EnableAutoConfiguration源码

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
    String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

    Class<?>[] exclude() default {};

    String[] excludeName() default {};
}

4.4.3 自动配置原理

Spring Boot 的自动配置原理依赖于 Spring 框架的核心特性,如条件化配置(Conditional Configuration)、Bean 定义、以及对类路径和环境的检测。以下是 Spring Boot 自动配置的主要工作原理:

  1. 条件化注解

自动配置广泛使用了 @Conditional 注解及其变种,例如 @ConditionalOnClass@ConditionalOnMissingBean 等等。这些条件化注解使得特定的配置只在满足一定条件下才会生效。比如,只有当类路径中存在某些类时,或者当容器中不存在某个类型的 Bean 时,自动配置才会起作用。

  1. 自动配置类

Spring Boot 提供了一组自动配置类,它们通常位于 org.springframework.boot.autoconfigure 包下。每个自动配置类都针对某一特定技术或功能模块(如数据源配置、模板引擎配置、安全配置等)进行配置。这些类会根据应用程序的类路径和配置文件来决定是否应用配置。

  1. spring.factories 文件

Spring Boot 使用 META-INF/spring.factories 文件来加载自动配置类。这个文件列出了所有可用的自动配置类,并允许第三方库向 Spring Boot 注册自己的自动配置类。启动时,Spring Boot 会读取该文件并加载其中定义的自动配置类。

  1. 类路径扫描

Spring Boot 会扫描类路径中的 jar 包,查找是否存在与特定功能相关的类或库。如果找到,它会尝试通过自动配置类为这些功能提供默认配置。

  1. 属性覆盖

尽管有自动配置,开发者仍然可以通过在 application.propertiesapplication.yml 文件中定义属性来覆盖默认设置。这允许开发者根据需要自定义配置。

  1. 启用自动配置

要启用自动配置,通常只需要添加 @EnableAutoConfiguration 或者更常见的 @SpringBootApplication 注解到主应用程序类上。@SpringBootApplication 实际上是三个注解的组合:

  • @Configuration:将该类标记为一个配置类。

  • @ComponentScan:启用组件扫描,以便发现和注册其他带有 @Component@Service@Repository@Controller 等注解的类。

  • @EnableAutoConfiguration:启用自动配置机制。

  1. 应用程序上下文事件

在应用程序启动过程中,Spring Boot 发布了一系列的应用上下文事件,允许开发者在不同阶段响应或修改自动配置行为。

总之,Spring Boot 的自动配置是一种灵活且强大的方式,它简化了应用程序的配置过程,同时保持了足够的灵活性以适应不同的需求。通过这种方式,开发者可以专注于业务逻辑,而不必花费太多时间在基础架构配置上。