• Spring Boot 笔记 (1)


    一. Spring Boot 简介

    开箱即用的一站式 Java EE 解决方案
    Spring 技术栈的大整合

    核心问题

    暂时无法回答

    Spring Boot 和 SOA 有什么区别?

    Spring Boot 与 Spring Cloud 的区别与关系?

    SpringBoot 做了什么应对微服务的趋势?

    其他问题

    微服务是什么?
    SOA 是什么?
    Serveless 又是什么?
    Spring Cloud 是什么?

    二. Maven

    更多 Maven相关内容, 可参考 Maven 笔记 - 难以想象的晴朗

    完整 POM 文件

    <?xml version="1.0" encoding="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">
        <modelVersion>4.0.0</modelVersion>
    
        <!--项目信息-->
        <groupId>com.imzhizi.work</groupId>
        <artifactId>xingren</artifactId>
        <version>1.2.0-SNAPSHOT</version>
    
        <!--Spring Boot 的父依赖, 统一控制版本-->
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.0.7.RELEASE</version>
        </parent>
    
        <!--构建打包时的编码和 Java 版本-->
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <java.version>1.8</java.version>
        </properties>
    
        <!--通过该插件, 项目将打包为 xingren-1.2-SNAPSHOT.jar -->
        <!--项目运行命令为 mvn spring-boot:run -->
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
        <dependencies>
            <!--一些 Spring Boot 依赖-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
    
            <!--数据库-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
            </dependency>
            
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
            </dependency>
    
    <!--一些推荐的工具库-->
            <!-- getter、setter 省略工具 -->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <optional>true</optional>
            </dependency>
    
            <!--JSON 处理工具-->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.47</version>
            </dependency>
    
            <!--DTO 处理工具-->
            <dependency>
                <groupId>org.modelmapper</groupId>
                <artifactId>modelmapper</artifactId>
                <version>2.3.0</version>
            </dependency>
    
            <!-- JWT 鉴权工具类-->
            <dependency>
                <groupId>io.jsonwebtoken</groupId>
                <artifactId>jjwt</artifactId>
                <version>0.9.1</version>
            </dependency>
        </dependencies>
    
    </project>
    

    其他配置

    <groupId>edu.北京邮电大学</groupId>
    <artifactId>coope</artifactId>
    <version>1.0-SNAPSHOT</version>
    <!--表明打包为 war 包-->
    <packaging>war</packaging>
    
    <build>
        <!--决定了最终生成的包的名称, 默认为 项目名+版本-->
        <finalName>coope</finalName>
    </build>
    

    三. 核心注解

    SpringBootApplication

    @SpringBootApplication
    ||
    @SpringBootConfiguration    // springboot 配置类, 代表以前的 xml
    @EnableAutoConfiguration    // 开启自动配置功能, 配置上面的 springboot
    
    # 其中
    @EnableAutoConfiguration
    ||
    @AutoConfigurationPackage   // 自动配置包
    @Import({EnableAutoConfigurationImportSelector.class})  // 导入自动配置类
    public @interface EnableAutoConfiguration   // 里面放满了各种AutoConfiguration 类名
    
    # 其中
    @AutoConfigurationPackage
    ||
    @Import({Registrar.class})
    // 自动配置包使用了 Spring 的底层注解 import, 给容器中导入Registrar.class
    // 将 SpringBootApplication 所标注的类全部扫描到 Spring 容器中
    // 哪里标注了哪些类需要加载呢? 或许是下面的选择器(Selector)
    
    @Import({EnableAutoConfigurationImportSelector.class})
    ||
    EnableAutoConfigurationImportSelector
    ||继承
    AutoConfigurationImportSelector
    // 会把该场景需要的所有自动配置类扫描进来 annotationMetadata
    // 此类含有 getAutoConfigurationImportListeners 方法
    // 此方法使用SpringFactoriesLoader.loadFactories() 加载配置类
    // 工厂会完成自动配置工作(把这些自动配置类配置的东西标记为Bean, 然后加载进去)
    

    Controller

    一些常见的注解, 没什么新奇的

    @Controller
        @RestController
        @GetMapping
        @PostMapping
        @PutMapping
        @DeleteMapping
        
        @RequestMapping
            @PathVarible
            @RequestParam
            @RequestBody        // 用于实体 JSON 类型数据的实例化
            @ModelAttributes    // 用于非 JSON 类型的数据, 尤其是多媒体文件
    
    @Service
    
    @Repository
    
    @Entity
    
    @AutoWired
    @Bean
    

    四. SpringBoot 配置

    配置文件, 两个均可使用, 用于 修改默认的配置

    • applicaiton.properties
    • application.yml (递归命名, 以数据为中心, 更适合做配置文件)

    通过此注解

    • 可以把配置中的每一个值配置到组件中
    • 通过 presfix 和配置中的前缀相匹配
    • 既然是组件中, 所以配置类必须声明为组件

    配置文件加载顺序

    SpringApplication 将从以下位置的 application.properties 文件加载属性,并将它们添加到Spring Environment, 按照以下顺序优先级从高到低, 高优先级会覆盖低优先级的配置

    • ./config 项目根目录的config目录
    • 项目根目录 ./
    • A 类路径 classpath/config 包
    • A 类路径根 classpath/
    • 为生成的 jar 启动时指定参数 --spring.config.location="config path" 来追加配置, 与之前的默认配置形成互补

    外部配置文件加载

    1. 命令行参数

      所有的配置都可以在命令行上进行指定
      多个配置用空格分开; --配置项=值
      java -jar spring-boot-02-config-02-0.0.1-SNAPSHOT.jar --server.port=8087 --server.context-path=/abc

    2. 来自 java:comp/env 的JNDI属性

    3. Java系统属性(System.getProperties())

    4. 操作系统环境变量

    5. RandomValuePropertySource配置的random.*属性值

    6. jar包外部的application-{profile}.properties或application.yml(带spring.profile)配置文件

    7. jar包内部的application-{profile}.properties或application.yml(带spring.profile)配置文件

      再来加载不带profile

    8. jar包外部的application.properties或application.yml(不带spring.profile)配置文件

    9. jar包内部的application.properties或application.yml(不带spring.profile)配置文件

    10. @Configuration注解类上的@PropertySource

    11. 通过SpringApplication.setDefaultProperties指定的默认属性

    配置文件 YAML 用法

    为什么不用 applicaiton.properties, 主要因为 applicaiton.properties 需要写很多遍 prefix

    # yaml 写法
    # 简单值
    k: v                # 字符串默认不加引号
    k: 'hello 
     world' # 原形输出
    k: "hello 
     world" # 转义输出
    
    # 对象, map 写法
    k:
        sk: sv          # 换行缩进写出
        sub-name1:
        subName2:       # 效果是一样的
    k: {sk1: sv1, sk2: sv2}
    
    # 数组写法
    k: {v1,v2}          # 大括号写法
    k:                  # 换行缩进写法
        - v1
        - v2
    

    配置文件占位符

    ## 随机数
    my.secret=${random.value}
    my.number=${random.int}
    my.bignumber=${random.long}
    my.uuid=${random.uuid}
    my.number.less.than.ten=${random.int(10)}
    my.number.in.range=${random.int[1024,65536]}
    
    ## 占位符
    my.secret=${random.value}
    my.number=${my.secret:my-secret}
    # 读取配置文件中的其他值, 通过:指定该值不存在时的默认值
    

    配置信息读取

    配置注入 @ConfigurationProperties

    maven 需要导入 spring-boot-configuration-processor

    @Component  // 声明为组件, 会被自动加载到 Spring 容器中
    @ConfigurationProperties(prefix="config-test")   // 从文件中读取配置的类
    public class ConfigurationTest {
        private String name;
    }
    

    值注入注解 @Value

    // 通过 ${} 从配置文件, 环境中加载值
    // 通过 #{} 使用 SpEL 表达式来计算值
    public class ConfigurationTest {
        @Value("${config-test.name}")
        private String name;
    }
    

    配置类测试

    使用 SpringBoot 自带的测试框架来替代 JUnit

    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class XxxTest{
        @AutoWired
        Xxx xxx;
        
        @Test
        public void contextLoads(){
            // 使用 xxx 进行测试
        }
    } 
    

    @ConfigurationProperties VS @Value

    功能 @ConfigurationProperties @Value
    松散绑定 支持 支持
    SpEL 不支持 支持
    JSR303 数据校验 支持 不支持
    元数据 支持 不支持
    批量绑定 支持 不支持
    复杂类型封装 支持 不支持

    松散绑定是指 lastName == last-name == last_name == LAST-NAME
    所以 @Value 一般是用于取到某项值
    而 @ConfigurationProperties 用于真正的配置类
    校验注解 @Validated 用于数据校验, 直接加在属性值上, 比如说 @Email

    其他来源的配置文件@PropertySource @ImportResource

    默认加载的配置都是项目的全局配置文件, 假如想把一些与全局无关的配置抽取出来, 读取此新建配置文件时就需要使用 PropertySource 注解来指定.
    @PropertySource(value = {"classpath:xxxx.properties"})

    当使用了 Spring 早期的 xml 配置文件, 希望把该 配置文件加再进来, 那么就要用 @ImportResource 导入进来
    @ImportResource(locations = {"classpath:beans.xml"})

    配置类 @Configuration - 消灭 xml !!!

    @Configuration
    public class MyAppConfig{
    
        @Bean // 代替 xml 来进行配置, 添加组件, 其实@Component 可以直接注册到容器中
        public HelloService helloService(){
            // 初始化 Bean 并返回
            return helloService;
        }
    }
    

    五. Profile 实现多配置

    多 properties 配置文件方式

    # application-dev.properties 文件
    server.port=8080
    
    # application-prod.properties 文件
    server.port=80
    

    YAML 多文档块方式

    通过三个 - 进行文档分块

    # application.yml 文件
    server:
        profiles:
            active: name(dev 或 prod)
    
    ---
    server:
        port: 8080
        profiles: dev
        
    ---
    server:
        port: 80
        profiles: prod
    
    

    激活不同 Profile 的方法

    # 配置文件中声明
    spring.profiles.active = 要激活的配置文件
    spring:
        profiles:
            active: 要激活 profile
    
    # 参数控制
    # 在运行 jar 时传参激活
    --spring.profiles.active=dev
    
    # 指定 Java 虚拟机参数激活
    -Dspring.profiles.active=dev
    
    
  • 相关阅读:
    SpringMVC自动封装List对象 —— 自定义参数解析器
    fetch封装
    基于jQuery实现简单的js模块化
    CSS实现树形结构 + js加载数据
    java多线程
    JS中AOP的实现和运用
    移动端通过ajax上传图片(文件)并在前台展示——通过H5的FormData对象
    chart.js使用常见问题
    用PHP和Ajax进行前后台数据交互——以用户登录为例
    用JS添加和删除class类名
  • 原文地址:https://www.cnblogs.com/imzhizi/p/spring-boot-note-1-basic-guide.html
Copyright © 2020-2023  润新知