【微服务】SpringBoot 4.0 新特性整合项目实战应用详解

目录

一、前言

[二、SpringBoot4 介绍](#二、SpringBoot4 介绍)

[2.1 SpringBoot4 概述](#2.1 SpringBoot4 概述)

[2.2 SpringBoot4 新特性介绍](#2.2 SpringBoot4 新特性介绍)

[2.2.1 优雅的版本控制](#2.2.1 优雅的版本控制)

[2.2.2 便捷的Bean注入方式](#2.2.2 便捷的Bean注入方式)

[2.2.3 空值安全改进](#2.2.3 空值安全改进)

[2.2.4 轻松创建HTTP代理](#2.2.4 轻松创建HTTP代理)

[2.2.5 虚拟线程支持](#2.2.5 虚拟线程支持)

[2.2.6 原生支持 GraalVM Native Image](#2.2.6 原生支持 GraalVM Native Image)

[2.2.7 全新 Actuator 端点体系与可观测性增强](#2.2.7 全新 Actuator 端点体系与可观测性增强)

[2.2.8 内置 Spring AI 模块(官方集成)](#2.2.8 内置 Spring AI 模块(官方集成))

三、前置准备

[3.1 环境准备](#3.1 环境准备)

[3.2 搭建并配置springboot工程](#3.2 搭建并配置springboot工程)

[3.2.1 pom中增加基础依赖](#3.2.1 pom中增加基础依赖)

[3.2.2 配置文件信息](#3.2.2 配置文件信息)

[四、springboot 40 新特性项目实战](#四、springboot 40 新特性项目实战)

[4.1 版本控制](#4.1 版本控制)

[4.1.1 基于请求header的版本号控制介绍](#4.1.1 基于请求header的版本号控制介绍)

[4.1.2 springboot4 版本控制案例演示](#4.1.2 springboot4 版本控制案例演示)

[4.1.3 基于请求url路径参数的版本号控制介绍](#4.1.3 基于请求url路径参数的版本号控制介绍)

[4.1.4 基于请求参数的版本号控制介绍](#4.1.4 基于请求参数的版本号控制介绍)

[4.2 容错和重试](#4.2 容错和重试)

[4.2.1 @Retryable 说明](#4.2.1 @Retryable 说明)

[4.2.2 @Retryable 代码实现](#4.2.2 @Retryable 代码实现)

[4.2.3 @Retryable 其他注解补充](#4.2.3 @Retryable 其他注解补充)

[4.2.4 @ConcurrencyLimit 并发控制](#4.2.4 @ConcurrencyLimit 并发控制)

[4.3 bean的动态注册](#4.3 bean的动态注册)

[4.3.1 增加两个自定义的类](#4.3.1 增加两个自定义的类)

[4.3.2 增加自定义bean的注册管理配置类](#4.3.2 增加自定义bean的注册管理配置类)

[4.3.3 通过@Import配置类导入](#4.3.3 通过@Import配置类导入)

[4.3.4 效果验证](#4.3.4 效果验证)

[4.4 JsonView 使用](#4.4 JsonView 使用)

[4.4.1 JsonView 介绍](#4.4.1 JsonView 介绍)

[4.4.2 JsonView 代码整合](#4.4.2 JsonView 代码整合)

[4.5 SpringBoot Admin 使用](#4.5 SpringBoot Admin 使用)

[4.5.1 SpringBoot Admin介绍](#4.5.1 SpringBoot Admin介绍)

[4.5.2 创建一个监控应用(服务端)](#4.5.2 创建一个监控应用(服务端))

[4.5.3 启动类添加注解(服务端)](#4.5.3 启动类添加注解(服务端))

[4.5.4 启动服务(服务端)](#4.5.4 启动服务(服务端))

[4.5.5 增加核心的依赖(客户端)](#4.5.5 增加核心的依赖(客户端))

[4.5.6 调整配置文件(客户端)](#4.5.6 调整配置文件(客户端))

[4.5.7 效果验证](#4.5.7 效果验证)

五、写在文末


一、前言

可以说在日常的微服务项目开发过程中,SpringBoot已经是基本的技术框架了。得益于SpringBoot的不断的发展,依托于Spring这个大家族的持续输出,和Spring生态体系的庞大家族,自从SpringBoot 与开发者见面后就得到了广大微服务开发者的青睐,也将微服务的开发模式升级到全新的高度。经过多年的发展,SpringBoot经历了多个版本的迭代升级,不断的开疆拓土,完善自身的技术体系,到目前为止,Spring 官方也实时的推出了SpringBoot4版本,增加了更多丰富强大的功能,本篇将实际案例详细介绍下SpringBoot4的新功能。

二、SpringBoot4 介绍

2.1 SpringBoot4 概述

Spring Boot 4 是 Spring Boot 框架的最新版本,它是在 Spring Boot 3.x 系列基础上进一步发展和改进的。Spring Boot 简化了基于Spring框架的应用程序开发,通过自动配置和嵌入式服务器等技术,大大降低了开发难度和部署成本。官网文档:https://spring.io/projects/spring-boot#learn

2.2 SpringBoot4 新特性介绍

在SpringBoot4 中增加了很多的新的功能特性,下面简单介绍一下。

2.2.1 优雅的版本控制

新版本引入了对API版本控制的优雅支持,允许开发者通过@RequestMapping注解中的version参数来实现版本控制,从而更好的管理API版本。

2.2.2 便捷的Bean注入方式

新版本引入了新的BeanRegistrar契约,允许开发者更灵活的Bean注册(一次注册多个Bean)。注册bean一直是很多开发者不愿意面对的事情,一方面是复杂,而是比较底层不好控制,有了这个BeanRegistrar之后就更简单的可以操作Bean的注册工作了。

2.2.3 空值安全改进

新版本采用JSpecify注解来声明其API的空值安全性,使用@Nullable表示值可以为空,使用@NonNull表示不能为空。这与IntelliJ IDEA配合使用可以提供警告或错误消息。

2.2.4 轻松创建HTTP代理

新版本提供了@ImportHttpServices注解,使创建HTTP接口代理变得更加容易。它允许您轻松声明、检测和配置整个HTTP服务组。

2.2.5 虚拟线程支持

基于 JDK 21 提供的虚拟线程特性,Spring Boot 4.0 对线程池模型进行了重构,支持实现百万级并发。在支付网关场景测试中,虚拟线程的应用使每秒请求处理量(RPS)从 1.2 万提升至 8.5 万,同时 CPU 占用率下降了 40%。

开发者只需通过简单配置 spring.threads.virtual.enabled=true 即可全局启用虚拟线程,且原有的 @Async 注解也能无缝适配,无需额外改动代码。此外,为了便于监控,Actuator 引入了 /virtual-threads 端点,开发者可以通过该端点实时查看线程状态与阻塞事件。

2.2.6 原生支持 GraalVM Native Image

Spring Boot 4 将 GraalVM 原生镜像构建 作为官方标准功能集成,无需额外配置 spring-native 模块。

java 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-native</artifactId>
</dependency>

并执行:

bash 复制代码
./mvnw native:compile

即可生成百毫秒启动、内存占用<100MB 的原生可执行文件。适用场景:

  • Serverless 函数(AWS Lambda、Azure Functions)

  • 边缘计算节点

  • 容器化微服务(Kubernetes 节点资源优化)

  • 低延迟金融交易系统

2.2.7 全新 Actuator 端点体系与可观测性增强

Spring Boot 4 对 actuator 模块进行了重构,引入:

  • 新的 /metrics/v2 端点:支持 OpenTelemetry 标准格式

  • 健康检查支持 gRPC/health/grpc 端点

  • 分布式追踪自动集成 :无需手动配置 OpenTelemetry Agent

  • 日志结构化输出:默认输出 JSON 格式日志(兼容 Loki、ELK)

2.2.8 内置 Spring AI 模块(官方集成)

Spring Boot 4 首次官方集成 Spring AI,提供统一的 AI 服务抽象层,支持:

  • OpenAI、Anthropic、Hugging Face、本地 LLM(如 Llama 3)

  • 文本生成、嵌入向量、RAG(检索增强生成)

  • 自动提示模板管理与缓存

  • 与 Spring Security 集成实现 AI 请求鉴权

三、前置准备

3.1 环境准备

springboot4 的使用需要依赖一定的环境,下面给出在本地运行springboot4 的工程最低的环境要求

|-------|---------|-------|
| 环境项 | 版本号 | 推荐版本 |
| JDK | >=17 | 21 |
| maven | >=3.6 | 3.6.3 |
| idea | >=2022 | 最新版本 |

3.2 搭建并配置springboot工程

在idea在搭建一个springboot工程,然后做一些前置的配置

3.2.1 pom中增加基础依赖

在pom中增加springboot4基础的环境依赖,下面给出的是最小的依赖,可以根据自己的实际需求酌情添加

java 复制代码
<properties>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>4.0.0-M3</version>
    <relativePath/>
</parent>

<dependencies>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-webmvc</artifactId>
    </dependency>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>

</dependencies>

3.2.2 配置文件信息

在yml配置文件中增加一个端口号配置

java 复制代码
server:
  port: 8087

四、springboot 40 新特性项目实战

接下来通过实际案例操作演示下springboot4 的相关新特性。

4.1 版本控制

4.1.1 基于请求header的版本号控制介绍

在实际项目中,版本控制是一个非常常见的需求,版本控制在一些特殊的场景下很有用,比如做灰度发布,回滚操作,流量分发等场景下,版本是一个很实用的操作手段。

细化到接口层,通过版本控制可以让不同的请求打给不同的版本服务,从而得到不同的数据。在之前的开发中,使用版本控制还是有点麻烦的,一般来说,可以通过在外部的配置中心配置一个控制参数(也称开关),通过这个配置参数进行控制,这么做从开发,到运维都有一定的实施成本。

springboot4 增加了针对接口级别的版本控制功能,对开发者来说,你只需要在 @RequestMapping 里加个 version 参数,就可以轻松实现接口多版本共存。这样是不是很优雅。

4.1.2 springboot4 版本控制案例演示

在springboot4 中如果需要实现一个请求接口URL的版本控制,只需要做下面2步即可:

  1. 根据业务需求编写不同版本使用的接口;

  2. 设定请求头参数,即你需要请求头中设置什么参数来控制对版本进行分发;

  3. 将请求头参数配置到WebMvcConfig中;

1)增加2个测试接口

在下面的类中,增加了2个接口,版本的控制通过version 这个属性来控制,属性值可以自定义,只需要最终调用接口的时候传入即可,接口的路由地址是一样的,都是/getUser

java 复制代码
package com.congge.web;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/api/boot/test")
public class WebController {

    @GetMapping(value = "/getUser",version = "1.0")
    public Object getUser1(){
        Map<String, Object> map = new HashMap<>();
        map.put("version", "1.0");
        map.put("name", "shadow");
        map.put("age", "19");
        return map;
    }

    @GetMapping(value = "/getUser",version = "2.0")
    public Object getUser2(){
        Map<String, Object> map = new HashMap<>();
        map.put("version", "2.0");
        map.put("name", "shadow");
        map.put("age", "19");
        return map;
    }
}

2)配置WebMvcConfig

为了让基于请求header的接口版本控制生效,还需要在WebMvcConfig配置类中指定一下,也就是针对请求头中携带的什么参数进行拦截,注意,下面的请求头参数中设置的参数名可以自己指定,最后在请求接口的时候传递过去即可。

java 复制代码
package com.congge.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ApiVersionConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void configureApiVersioning(ApiVersionConfigurer configurer) {
        configurer.useRequestHeader("X-API-VERSION");
    }
}

3)效果测试

启动工程后,分别测试下两个接口,通过效果可以看到,整个过程,仅仅是调整了请求header的值,接口的请求地址是不变的。

4.1.3 基于请求url路径参数的版本号控制介绍

springboot4 还提供了另一种版本号控制,即基于url的路径参数的方式,简单来说,就是在请求的url中通过一个可变参数来达到版本控制的目的,比如 /api/v1/user 与 /api/v2/user ,这就是两个不同的版本号对应的请求url ,下面看具体的操作。

1)增加两个测试接口

为方便后面的测试效果,增加两个测试接口,从代码中不难看到,在接口的url中使用了 {version} 这样的写法作为占位符,后续会通过外部参数的形式动态的传入进去,从而起到版本控制的效果

java 复制代码
package com.congge.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
public class WebUrlController {

    //localhost:8082/api/v1/user
    @RequestMapping(value = "/api/{version}/user",version = "v1")
    public Object getUser1(){
        Map<String, Object> map = new HashMap<>();
        map.put("version", "1.0");
        map.put("name", "shadow");
        map.put("age", "19");
        return map;
    }

    //localhost:8080/boot/url/api/v2/user
    @RequestMapping(value = "/api/{version}/user",version = "v2")
    public Object getUser2(){
        Map<String, Object> map = new HashMap<>();
        map.put("version", "2.0");
        map.put("name", "shadow");
        map.put("age", "19");
        return map;
    }
}

2)配置WebMvcConfig

在上一步的WebMvcConfig进行配置,在实际开发中,配置的具体版本号可以通过外部的配置参数传递进去

java 复制代码
package com.congge.component;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ApiVersionConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void configureApiVersioning(ApiVersionConfigurer configurer) {
        //configurer.useRequestHeader("X-API-VERSION");
        configurer.usePathSegment(1);
    }
}

3)效果测试

在接口工具中进行测试,调用接口的时候,分别替换url中的v1和v2即可

4.1.4 基于请求参数的版本号控制介绍

最后再介绍一种版本控制的方式就是基于参数的版本控制,这种在使用起来对于客户端调用的时候就更友好了,只需要在请求的参数中制定版本即可达到目的,下面来看具体的操作。

1)增加两个请求接口

参考下面的代码

java 复制代码
package com.congge.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
public class WebReqParamController {

    //localhost:8082/api/v1/user
    @RequestMapping(value = "/api/user",version = "v1")
    public Object getUser1(){
        Map<String, Object> map = new HashMap<>();
        map.put("version", "1.0");
        map.put("name", "shadow");
        map.put("age", "19");
        return map;
    }

    //localhost:8080/boot/url/api/v2/user
    @RequestMapping(value = "/api/user",version = "v2")
    public Object getUser2(){
        Map<String, Object> map = new HashMap<>();
        map.put("version", "2.0");
        map.put("name", "shadow");
        map.put("age", "19");
        return map;
    }
}

2)配置WebMvcConfig

在上一个WebMvcConfig配置类中做如下配置

java 复制代码
public void configureApiVersioning(ApiVersionConfigurer configurer) {
    //configurer.useRequestHeader("X-API-VERSION");
    //configurer.usePathSegment(1);
    configurer.useQueryParam("version");
}

3)接口效果验证

在接口工具中调用验证效果,如下:

4.2 容错和重试

接口的容错和重试是项目开发中经常需要考虑的,在springboot4 中默认引入了对该功能的支持,通过几个注解即可完成,而不再需要单独引入spring-retry这样的模块即可完成重试和并发的功能。

springboot4 基于Spring Framework7.0,通过声明式注解即可实现复杂的重试策略,无需手写复杂的处理逻辑,代码优雅且功能强大。

主要涉及到的注解包括:

  • @Retryable :方法级别的重试功能;

  • @ConcurrencyLimit : 并发限制功能;

4.2.1 @Retryable 说明

@Retryable 指定了单个方法(在方法级别指明注释)或给定类中的所有代理调用方法(类级别声明注解)的重试特性,如下代码:

java 复制代码
@Retryable
public Object getUserOrders(){
    System.out.println("第 " + (count++) + " 次调用");
    String url = "http://localhost:8082/api/order/getOrder";
    RestTemplate restTemplate = new RestTemplate();
    Order order = restTemplate.getForObject(url, Order.class);
    return order;
}

@Retryable重试策略说明:

  • 对于抛出的任何异常都会进行重试;

  • 在初始失败后最多重试3次;

  • 两次重试之间间隔1秒(固定时间间隔);

4.2.2 @Retryable 代码实现

下面给出完整的实现代码。

1)增加一个被调用的接口

该接口被其他服务或接口调用

java 复制代码
package com.congge.controller;

import com.congge.entity.Order;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/order")
public class OrderController {

    @GetMapping("/getOrder")
    public ResponseEntity getOrder(){
        Order order = new Order();
        order.setOrderId("A0001");
        order.setOrderName("User01订单");
        try {
            Thread.sleep(500);
            throw new RuntimeException("订单查询异常");
        } catch (InterruptedException e) {
            return ResponseEntity.internalServerError().body(new Order("A0001", "错误的订单信息"));
        }
    }

}

2)增加一个测试调用的接口

该接口用于模拟重试使用的

java 复制代码
package com.congge.controller;

import com.congge.entity.Order;
import org.springframework.resilience.annotation.Retryable;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
@RequestMapping("/api/user-order")
public class UserController {

    private Integer count = 1;

    //localhost:8082/api/user-order/get-orders
    @GetMapping(value = "/get-orders")
    @Retryable
    public Object getUserOrders(){
        System.out.println("第 " + (count++) + " 次调用");
        String url = "http://localhost:8082/api/order/getOrder";
        RestTemplate restTemplate = new RestTemplate();
        Order order = restTemplate.getForObject(url, Order.class);
        return order;
    }

}

3)在启动类增加注解

在启动类上面增加一个@EnableResilientMethods注解,表示启用重试机制

4)效果测试

启动工程后,调用上面的测试接口,通过控制台的输出日志可以看到,一共进行了4次调用

4.2.3 @Retryable 其他注解补充

在@Retryable这个注解中,当你点击进去之后会发现,里面还提供了其他的一些参数,这些参数的配合使用可以更好的对重试进行控制,下面做简单的说明:

  • maxAttempts,最大重试次数,比如maxAttempts=5,表示第一次失败后,最多重试5次;

  • delay,初始延迟时间,比如delay=200,表示第一次失败后,第一次重试会在200ms后执行;

  • jitter,随机抖动值,比如jitter=100,第一次失败后,实际延迟可能会有波动,会在基础上增加一个随机值(通常在100ms范围内);

  • multiplier,退避倍数,multiplier=2,表示每次重试的延迟时间为翻倍;

  • maxDelay,最大延迟上限,比如 maxDelay = 1000,表示最大延迟上限为1000ms,即使退避倍数计算出来了更长的延迟时间,也不会超过这个值;

4.2.4 @ConcurrencyLimit 并发控制

@ConcurrencyLimit这个注解用于实现并发控制,限制并发访问数量,类级别和方法级别均可使用,默认并发限制为1,比如在下面的代码中,实现了对方法的并发访问控制

java 复制代码
@GetMapping(value = "/get-orders")
@Retryable
@ConcurrencyLimit(value = 5)
public Object getUserOrders(){
    System.out.println("第 " + (count++) + " 次调用");
    String url = "http://localhost:8082/api/order/getOrder";
    RestTemplate restTemplate = new RestTemplate();
    Order order = restTemplate.getForObject(url, Order.class);
    return order;
}

4.3 bean的动态注册

使用过spring框架的同学对bean的概念应该不陌生了,在springboot的项目开发中,底层可以说就是一个个bean的注册和使用,但是在实际使用过程中,开发者并不需要关心bean究竟是怎么注册的,但是偶尔在某些特殊的场景下,也需要开发者进行手动注册bean的操作,这时候很多伙伴都会觉得比较陌生。

从springboot4开始,spring框架提供了编程式的方式注册bean,通过BeanRegistrar接口即可灵活高效的注册一个bean,这个特性为开发者提供了更强大的工具来动态管理应用上下文中的Bean的定义。仅需2步即可完成:

  • 编程需要注册的Bean;

  • 配置类@Import;

接下来看具体的代码实现。

4.3.1 增加两个自定义的类

只需要两个普通类即可,后续需要将这两个类作为注册bean

java 复制代码
package com.congge.config;

public class OldCar {

    private int speed = 150;

    public int maxSpeed(int addCount){
        return speed + addCount;
    }

}
java 复制代码
package com.congge.config;

public class NewCar {

    private int speed = 150;

    public int maxSpeed(int addCount){
        return speed + addCount + 50;
    }

}

4.3.2 增加自定义bean的注册管理配置类

该类用于注册指定的类到spring容器中

java 复制代码
package com.congge.config;

import org.springframework.beans.factory.BeanRegistrar;
import org.springframework.beans.factory.BeanRegistry;
import org.springframework.core.env.Environment;

public class ManageBeanRegistrar implements BeanRegistrar {

    @Override
    public void register(BeanRegistry registry, Environment env) {
        System.out.println("============ 注册第一个 bean ============");

        if(env.matchesProfiles("dev")){
            System.out.println("============ 开发环境下的bean注册 ============");
            registry.registerBean("oldCar",OldCar.class,specification -> {
                specification.description("老汽车的bean")
                        .lazyInit()
                        .order(-1);
            });
        }else if(env.matchesProfiles("prod")){
            System.out.println("============ 线上环境下的bean注册 ============");
            registry.registerBean("newCar",NewCar.class,specification -> {
                specification.description("新车的bean")
                        .lazyInit()
                        .order(-1);
            });
        }

    }
}

通过代码可以看到,这里我根据环境进行了bean的注册区分,所以在配置文件中添加下面的信息

java 复制代码
server:
  port: 8082

spring:
  profiles:
    active: dev

4.3.3 通过@Import配置类导入

增加一个配置类,通过@Import这个注解进入导入

java 复制代码
package com.congge.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
@Import(ManageBeanRegistrar.class)
public class ManageBeanConfig {

}

4.3.4 效果验证

启动工程后,通过控制台的输出日志可以看到,基于开发环境下的bean注册完成了

4.4 JsonView 使用

4.4.1 JsonView 介绍

前后端分离项目中,使用Json字符串 来完成前后端之间的通信。默认情况下,只要前端发起请求,就会返回对象的所有 字段。但有的时候,后端不能把所有字段全部返回。这样做的结果往往有下面几个问题:

  • 一方面,有些字段前端不需要,返回过多的数据会占用网络带宽;

  • 另一方面是出于安全性 考虑,比如,不可以将密码返回给前端,否则,网站攻击者可以用REST工具直接获取密码。

JsonView的作用,就是用来控制C层返回哪些字段 的。@JsonView 它是 Jackson 库中的一个强大注解。通过定义不同的视图类(通常为接口或类),并在实体类的字段上使用 @JsonView 注解标记该字段在哪个视图中可见,同时在控制器方法中通过 @JsonView 注解指定返回的视图,就可以灵活控制返回的字段内容,实现了根据不同场景动态选择序列化字段的目的,大大提高了代码的简洁性和可维护性。

4.4.2 JsonView 代码整合

在接下来的案例中,我们的需求是,仿照日常开发中,定义一个VO对象,该对象中有众多的属性,通过自定义的视图,从而被不同的属性进行引用,最后根据实际的场景进行字段的返回,也就是说,在不同的接口中,针对相同的返回VO,字段却不一样。

1)增加一个自定义的视图

参考下面的代码,自定义一个视图配置类,该类中可以根据实际情况定义多个视图标志用于不同的场景下

java 复制代码
package com.congge.jsonview;

public class ArticleJsonView {

    //定义表示author的视图标志
    public static class AUTHOR {

    }
}

2)自定义VO对象

对象中有众多的字段,但是其中有部分的字段上面,引用了上一步的自定义视图,这样的话,最终的接口返回中,仅仅是这些标准了自定义视图的字段才会展示出来,其他的字段都会被屏蔽

java 复制代码
package com.congge.vo;

import com.congge.jsonview.ArticleJsonView;
import com.fasterxml.jackson.annotation.JsonView;
import lombok.Data;

@Data
public class ArticleVO {

    private Integer id;

    private String title;

    private Integer age;

    @JsonView(ArticleJsonView.AUTHOR.class)
    private String author;

    @JsonView(ArticleJsonView.AUTHOR.class)
    private String email;

    @JsonView(ArticleJsonView.AUTHOR.class)
    private String content;

}

3)添加测试接口

添加一个测试接口用于看效果,在下面的接口中,给VO对象设置了所有的属性值

java 复制代码
package com.congge.controller;

import com.congge.jsonview.ArticleJsonView;
import com.congge.vo.ArticleVO;
import com.fasterxml.jackson.annotation.JsonView;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/article")
public class ArticleController {

    // localhost:8082/api/article/getArticle
    @JsonView(ArticleJsonView.AUTHOR.class)
    @GetMapping("/getArticle")
    public ArticleVO getArticle(){
        ArticleVO articleVO = new ArticleVO();
        articleVO.setId(1);
        articleVO.setTitle("SpringBoot4 集成 Excel");
        articleVO.setAge(18);
        articleVO.setAuthor("limeng");
        articleVO.setEmail("limeng@163.com");
        articleVO.setContent("SpringBoot4 集成 Excel");
        return articleVO;
    }

}

4)效果验证

使用接口工具调用一下接口,可以看到,仅仅是那些指定的字段返回了,其他的字段均被隐藏了

小结:

  • JsonView 这个功能有点像给字段进行分组,通过分组的思想,在最终的接口返回值中实现了隐藏和显示的效果。

4.5 SpringBoot Admin 使用

4.5.1 SpringBoot Admin介绍

SpringBoot Admin 是一个管理和监控SpringBoot 应用的工具,核心主要有2部分组成:

  • 一个服务端,提供可视化的用户界面,显示与SpringBoot Actuator交互,在SpringBoot Actuator基础上提供更简洁的可视化WEB UI展示效果;

  • 一个客户端,用于在服务端注册,并允许访问SpringBoot Actuator端点;

文档地址:https://docs.spring-boot-admin.com/3.0.0/getting-started.html

SpringBoot Actuator 文档地址:https://docs.spring.io/spring-boot/3.5-SNAPSHOT/how-to/actuator.html

主要的功能包括:

  • 健康检查

  • 度量指标

  • 日志管理

  • 环境信息

4.5.2 创建一个监控应用(服务端)

创建一个单独的springboot应用工程,用于搜集监控信息,添加如下的核心依赖

java 复制代码
<properties>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.5.6</version>
    <relativePath/>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>de.codecentric</groupId>
        <artifactId>spring-boot-admin-starter-server</artifactId>
        <version>3.2.0</version>
    </dependency>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>

</dependencies>

4.5.3 启动类添加注解(服务端)

在启动类中增加核心的注解 @EnableAdminServer,如下:

4.5.4 启动服务(服务端)

启动服务之后,访问监控服务端的界面,等到后续其他客户端的应用接入了界面中就会展示相应的信息了

4.5.5 增加核心的依赖(客户端)

在客户端工程pom中增加下面的依赖

java 复制代码
<dependency>
    <groupId>de.codecentric</groupId>
    <artifactId>spring-boot-admin-starter-client</artifactId>
    <version>3.5.0</version>
</dependency>

4.5.6 调整配置文件(客户端)

在客户端的yml配置文件中增加下面的配置信息,核心是配置springboot admin的端点信息,以及actuator的信息

java 复制代码
server:
  port: 8082

spring:
  profiles:
    active: dev

  boot:
    admin:
      client:
        url: http://localhost:8081
        instance:
          name: fast-app-boot
          service-url: http://localhost:8082

management:
  endpoints:
    web:
      exposure:
        include: ["*"]
  info:
    env:
      enabled: true

4.5.7 效果验证

启动客户端的工程,然后再在上一个控制台界面上就可以看到这个客户端的信息了,相关的服务指标内容也就可以通过这里进行展示,如果想进一步看各项指标数据可以点进去细看

五、写在文末

本文通过较大的篇幅详细介绍了SpringBoot 4.0的相关新特性,并通过案例操作演示了具体的功能点使用,更多的新特性使用有兴趣的同学还可以基于此继续深入研究,本篇到此结束,感谢观看。