《Spring Guides系列学习》guide26 - guide30

news2024/11/28 8:40:15

要想全面快速学习Spring的内容,最好的方法肯定是先去Spring官网去查阅文档,在Spring官网中找到了适合新手了解的官网Guides,一共68篇,打算全部过一遍,能尽量全面的了解Spring框架的每个特性和功能。
在这里插入图片描述
接着上篇看过的guide25,接着往下看。

guide26、Building a Reactive RESTful Web Service

简单介绍了怎么构建一个简单的响应式的restful web服务。

1、构建实体类

public class Greeting {
  private String message;
  public Greeting() {
  }
  public Greeting(String message) {
    this.message = message;
  }
  public String getMessage() {
  return this.message;
}

public void setMessage(String message) { this.message = message; }
}

2、创建响应式类,用来处理请求和响应,这个响应类返回一个"hello spring"的json对象。

@Component
public class GreetingHandler {

  public Mono<ServerResponse> hello(ServerRequest request) {
    return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON)
      .body(BodyInserters.fromValue(new Greeting("Hello, Spring!")));
  }
}

3、创建路由器,路由器侦听路径/hello,并返回我们的反应式处理程序类提供的值。

@Configuration(proxyBeanMethods = false)
public class GreetingRouter {

  @Bean
  public RouterFunction<ServerResponse> route(GreetingHandler greetingHandler) {
    return RouterFunctions
      .route(GET("/hello").and(accept(MediaType.APPLICATION_JSON)), greetingHandler::hello);
  }
}

4、创建网络客户端,平常的spring restTemplate本质上是阻塞的,而对于响应式应用程序,webclinet是非阻塞的。webclient使用响应式特性,使用mono的形式保存方法返回的内容。

@Component
public class GreetingClient {

  private final WebClient client;

  public GreetingClient(WebClient.Builder builder) {
    this.client = builder.baseUrl("http://localhost:8080").build();
  }

  public Mono<String> getMessage() {
    return this.client.get().uri("/hello").accept(MediaType.APPLICATION_JSON)
        .retrieve()
        .bodyToMono(Greeting.class)
        .map(Greeting::getMessage);
  }

}

5、测试


@SpringBootApplication
public class Application {

  public static void main(String[] args) {
    ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
    GreetingClient greetingClient = context.getBean(GreetingClient.class);
    // We need to block for the content here or the JVM might exit before the message is logged
    System.out.println(">> message = " + greetingClient.getMessage().block());
  }
}

测试结果:
在这里插入图片描述

响应式编程概念理解:https://www.jianshu.com/p/035db36c5918


guide27、Building a Gateway

了解了gateway的一些基本功能,

1、对路径包含/get的请求进行路由到https://httpbin.org/get,并且在路由配置中,增加了一个过滤器,过滤器在路由之前加上一个header到请求里。直接启动项目,就可以curl一下了。

@SpringBootApplication
@RestController
public class Application {

   public static void main(String[] args) {
      SpringApplication.run(Application.class, args);
   }

   @Bean
   public RouteLocator myRoutes(RouteLocatorBuilder builder) {
      return builder.routes()
            .route(p -> p
                  .path("/get")
                  .filters(f -> f.addRequestHeader("Hello", "World"))
                  .uri("http://httpbin.org:80"))
            .build();
   }

在这里插入图片描述

2、还可以再加一个路由。有时候由于网关背后的服务可能表现不佳,我们还可以将创建的路由包装在断路器中。并且新的路由中precidate变成了host,意思是host是*.circuitbreaker.com,才会被路由。

@Bean
public RouteLocator myRoutes(RouteLocatorBuilder builder) {
   return builder.routes()
         .route(p -> p
               .path("/get")
               .filters(f -> f.addRequestHeader("Hello", "World"))
               .uri("http://httpbin.org:80"))
         .route(p -> p
               .host("*.circuitbreaker.com")
               .filters(f -> f.circuitBreaker(config -> config
                     .setName("mycmd")
               .uri("http://httpbin.org:80"))
         .build();
}

在这里插入图片描述

3、可以看到,断路器在等待 HTTPBin 的响应时超时。当断路器超时时,我们可以选择提供回退,以便客户端不会收到504而是其他更有意义的东西。例如,在生产场景中,我们可能会从缓存中返回一些数据,但在下述的简单示例中,我们会返回一个字符串response.


@SpringBootApplication
@RestController
public class Application {

   public static void main(String[] args) {
      SpringApplication.run(Application.class, args);
   }

   @RequestMapping("/fallback")
   public Mono<String> fallback() {
      return Mono.just("fallback");
   }

   @Bean
   public RouteLocator myRoutes(RouteLocatorBuilder builder) {
      return builder.routes()
            .route(p -> p
                  .path("/get")
                  .filters(f -> f.addRequestHeader("Hello", "World"))
                  .uri("http://httpbin.org:80"))
            .route(p -> p
                  .host("*.circuitbreaker.com")
                  .filters(f -> f.circuitBreaker(config -> config
                        .setName("mycmd")
                        .setFallbackUri("forward:/fallback")))
                  .uri("http://httpbin.org:80"))
            .build();
   }
}

在这里插入图片描述

涉及概念:

http://httpbin.org/ 这个网站能测试 HTTP 请求和响应的各种信息,比如 cookie、ip、headers
和登录验证等,且支持 GET、POST 等多种方法,对 web
开发和测试很有帮助。简单使用参考:https://blog.csdn.net/Hubz131/article/details/89157089

spring cloud
gateway官网文献:https://cloud.spring.io/spring-cloud-gateway/reference/html/,核心的三个概念:
1、Route(路由) 这是Spring Cloud
Gateway的基本构建块,可简单理解成一条转发规则。包含:ID、目标URL、一组断言和一组过滤器 2、Predicate(断言) 这是一个
Java 8 的
Predicate,即java.util.function.Predicate这个接口,Gateway使用Predicate实现路由的匹配条件。断言,路径相匹配的进行路由。
3、Filter(过滤器) 一个标准的Spring WebFilter。Spring cloud
gateway中的filter分为两种类型的Filter,分别是Gateway Filter和Global
Filter。过滤器Filter将会对请求和响应进行修改处理。


guide28、Spring Cloud Stream

Spring Cloud Stream 是用来构建消息驱动的微服务程序的一个框架,它们通过 Apache Kafka 和 RabbitMQ 等消息中间件进行通信,涉及的概念主要包括source、processor、sink。

这块没有仔细深入。


guide29、Spring Cloud Task

Spring Cloud Task 是一个用于构建短期 Spring Boot微服务的框架,只需添加@EnableTask并将应用程序作为Spring Boot应用程序运行(单个应用程序上下文)。

Spring Cloud Task使用关系数据库存储已执行任务的结果。

写个demo, 首先是导入task、jdbc的依赖,application.yml配置文件连接好本地的mysql数据库。

@SpringBootApplication
@EnableTask
public class SpringCloudTaskDemoApplication {

  @Bean
  public CommandLineRunner helloRunner() {
    return new CommandLineRunner() {
      @Override
      public void run(String... args) throws Exception {
        System.out.println("开始执行任务") ;
        TimeUnit.SECONDS.sleep(1) ;
        System.out.println("任务执行完成") ;
      }
    };
  }
  
  public static void main(String[] args) {
    SpringApplication.run(SpringCloudTaskDemoApplication.class, args);
  }

}

直接执行,得出结果。run方法执行完以后我们的JVM进程也跟着结束了。这就是所谓的短期任务了,我们不需要任务一直执行,只需要在需要的时候执行即可。

在这里插入图片描述

注意:

@EnableTask: 该注解可以开启task功能。

任务执行完以后会在数据表中记录相关的执行结果信息:
在这里插入图片描述


guide30、Accessing data with R2DBC

Spring Data R2DBC项目是Spring提供的数据库响应式编程框架。
R2DBC是Reactive Relational Database Connectivity的首字母缩写词。 R2DBC是一个API规范倡议,它声明了一个响应式API,由驱动程序供应商实现,并以响应式编程的方式访问他们的关系数据库。

引入r2dbc相关的依赖:

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-r2dbc</artifactId>
</dependency>
 <dependency>
      <groupId>dev.miku</groupId>
      <artifactId>r2dbc-mysql</artifactId>
      <version>0.8.2.RELEASE</version>
    </dependency>

以及定义好实体类:

public class Customer {
	@Idprivate Long id;
	private final String firstName;
	private final String lastName;
...

核心的是创建存储库接口,CustomerRepository扩展ReactiveCrudRepository接口。

public interface CustomerRepository extends ReactiveCrudRepository<Customer, Long> {

    @Query("SELECT * FROM customer WHERE last_name = :lastname")
    Flux<Customer> findByLastName(String lastName);

}

ReactiveCrudRepository继承了Repository,实现了基本的增删改查的模版方法。Spring Data R2DBC 还允许通过使用@Query注释来定义其他查询方法。

在这里插入图片描述

如果想要自定义操作,可以

1、按照方法名定义

findByName -> findBy<fieldName>
findByIdGreaterThan -> findBy<fieldName>GreaterThan

例如:

// 按名称查找
Flux<Customer> findByName(String name);

// 查找给定范围内的
Flux<Customer> findByIdGreaterThan(Long startId);

// 查找大于给定id的数据
Flux<Customer> findByIdGreaterThan(Long startId);

// 查询名称以给定字符串开头的数据
Flux<Customer> findByNameStartingWith(String start);

// 分页
Flux<Customer> findByIdGreaterThanEqual(Long startId, Pageable pageable);

2、手动编写SQL

例如上述的那种,用@Query注解。

进行主类的编写,并且对R2DBC进行测试。

@SpringBootApplication
public class AccessingDataR2dbcApplication {

    private static final Logger log = LoggerFactory.getLogger(AccessingDataR2dbcApplication.class);

    public static void main(String[] args) {
        SpringApplication.run(AccessingDataR2dbcApplication.class, args);
    }

    @Bean
    ConnectionFactoryInitializer initializer(ConnectionFactory connectionFactory) {

        ConnectionFactoryInitializer initializer = new ConnectionFactoryInitializer();
        initializer.setConnectionFactory(connectionFactory);
        initializer.setDatabasePopulator(new ResourceDatabasePopulator(new ClassPathResource("schema.sql")));

        return initializer;
    }

    @Bean
    public CommandLineRunner demo(CustomerRepository repository) {

        return (args) -> {
            // save a few customers
            repository.saveAll(Arrays.asList(new Customer("Jack", "Bauer"),
                new Customer("Chloe", "O'Brian"),
                new Customer("Kim", "Bauer"),
                new Customer("David", "Palmer"),
                new Customer("Michelle", "Dessler")))
                .blockLast(Duration.ofSeconds(10));

            // fetch all customers
            log.info("Customers found with findAll():");
            log.info("-------------------------------");
            repository.findAll().doOnNext(customer -> {
                log.info(customer.toString());
            }).blockLast(Duration.ofSeconds(10));

            log.info("");

            // fetch an individual customer by ID
            repository.findById(1L).doOnNext(customer -> {
                log.info("Customer found with findById(1L):");
                log.info("--------------------------------");
                log.info(customer.toString());
                log.info("");
            }).block(Duration.ofSeconds(10));


            // fetch customers by last name
            log.info("Customer found with findByLastName('Bauer'):");
            log.info("--------------------------------------------");
            repository.findByLastName("Bauer").doOnNext(bauer -> {
                log.info(bauer.toString());
            }).blockLast(Duration.ofSeconds(10));;
            log.info("");
        };
    }

}

输出结果:

在这里插入图片描述

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

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

相关文章

numpy库报错has no attribute ‘_no_nep50_warning‘的解决

本文介绍在Python中&#xff0c;numpy库出现报错module numpy has no attribute _no_nep50_warning的解决方法。 一次&#xff0c;在运行一个Python代码时&#xff0c;发现出现报错module numpy has no attribute _no_nep50_warning&#xff0c;如下图所示。 其中&#xff0c;这…

华为nova11系列:一个月的深度体验感受,告诉你值不值得入手

作为一个追求时尚风格的年轻人&#xff0c; nova系列手机一直是我的关注重点。nova 11 Pro发布之后&#xff0c;独特少见的11号色一下子就戳中了我&#xff0c;于是第一时间我给我自己和我老婆分别下单了一台nova 11和nova 11 Pro。 作为主力机深度使用一个月后&#xff0c;可以…

如何做好建筑行业的信息化建设?

如何做好建筑行业的信息化建设&#xff1f; 首先&#xff0c;我们来了解一下&#xff0c;什么是信息化转型&#xff1f; 信息化转型是指企业或组织通过应用信息技术&#xff0c;以提高业务效率和创新能力&#xff0c;实现组织战略目标的过程。 随着数字技术的发展&#xff0…

把字节大佬花3个月时间整理的软件测试面经偷偷给室友,差点被他开除了···

写在前面 “这份软件测试面经看起来不错&#xff0c;等会一起发给他吧”&#xff0c;我看着面前的面试笔记自言自语道。 就在这时&#xff0c;背后传来了leder“阴森森”的声音&#xff1a;“不错吧&#xff0c;我可是足足花了三个月整理的” 始末 刚入职字节的我收到了大学室…

Junit常见用法

一.Junit的含义 Junit是一种Java编程语言的单元测试框架。它提供了一些用于编写和运行测试的注释和断言方法&#xff0c;并且可以方便地执行测试并生成测试报告。Junit是开源的&#xff0c;也是广泛使用的单元测试框架之一。 二.Junit常用注解 1.Test 表示执行此测试用例 T…

代码随想录训练营Day51| 300.最长递增子序列 674. 最长连续递增序列 718. 最长重复子数组

目录 学习目标 学习内容 300.最长递增子序列 674. 最长连续递增序列 718. 最长重复子数组 学习目标 300.最长递增子序列 674. 最长连续递增序列 718. 最长重复子数组 学习内容 300.最长递增子序列 300. 最长递增子序列 - 力扣&#xff08;LeetCode&#xff09;https…

便携式水质检测仪应用范围

随着环境污染的加剧&#xff0c;人们对水质检测的关注越来越多。传统的水质检测仪器往往只能测定单一参数&#xff0c;难以全面准确地反映水质情况。而多参数水质检测仪可以实现同时测定多个参数&#xff0c;为水质检测提供了更加全面准确的数据。它采用多种先进的技术&#xf…

STM32【H7】理论——MPU、Cache

文章目录 1. MPU - 内存保护单元 1. MPU - 内存保护单元 MPU&#xff1a;(Memory Protection Unit,内存保护单元),早在 STM32F1 和 F4 芯片上面也是有这个功能的,但是基本用不上。但是到了 H7 就得用上了,因为要设置 Cache&#xff1b; MPU的作用&#xff1a; 将 memory map&a…

医疗健康元宇宙仿真场景为治疗提供个性化方案

虚拟现实VR元宇宙是一种基于VR虚拟现实制作的全新交互平台&#xff0c;可以为用户提供沉浸式的体验。随着人们对医院就诊服务要求不断提高&#xff0c;借助VR元宇宙平台&#xff0c;将医生为医生、护士和患者提供了一个全新的交流和治疗场景&#xff0c;对提高诊疗水平和服务体…

「实在RPA·税务数字员工」助力税务乘上数字化转型快车

中共中央办公厅国务印发《关于进一步深化税收征管改革的意见》表示&#xff1a;着力建设以服务纳税人缴费人为中心、以发票电子化为改革突破口、以税收大数据为驱动力的具有高集成功能、高安全性能、高应用效能的智慧税务。2023年实现从经验式执法向科学精确执法转变&#xff1…

k8s滚动更新

1.编写一个yaml文件 vi deployment-nginx.yaml apiVersion: apps/v1 kind: Deployment metadata: labels:app: nginxname: nginxnamespace: default spec:replicas: 3progressDeadlineSeconds: 600 #表示在这个时间段内&#xff0c;如果 Deployment 的 Pod 没有完成更新&…

EtherCAT运动控制卡开发教程之python

众所周知&#xff0c;Python作为一门面向对象的新兴开发语言&#xff0c;具有非常完善的基础代码库&#xff0c;更注重实用&#xff0c;同时代码可读极强&#xff0c;编写完程序即可直接运行&#xff0c;被越来越多的人广泛将它用于机器视觉和自动化控制。 今天正运动技术与大…

第三十七章 扩展知识点

1、setState (1). setState(stateChange, [callback])------对象式的setState1.stateChange为状态改变对象(该对象可以体现出状态的更改)2.callback是可选的回调函数, 它在状态更新完毕、界面也更新后(render调用后)才被调用(2). setState(updater, [callback])------函数式的…

敏捷专题:新一代的汽车软件研发

过去&#xff0c;买车属于一锤子买卖&#xff0c;但近年来智能制造、新能源汽车等概念的狂飙突进下&#xff0c;个性化、定制化、智能化的新车型正倍速来到消费者面前&#xff0c;不到20万元就能买到各大车企搭载了智能座舱和智能驾驶功能的产品。 ▲智能座舱 众所周知&#xf…

(一)微服务中间键工作原理——nacos客户端服务注册原理说明及源码解读

前言 本节内容我们主要介绍一下中间键nacos的客户端服务注册原理及其源码解读&#xff0c;便于我们理解nacos作为服务注册中心的具体实现。在springcloud的微服务体系中&#xff0c;nacos客户端的注册是通过使用spring的监听机制ApplicationListener实现的。学习本节内容&…

golang常见导致panic的场景

1、越界 常见有数组越界和字符串越界 2、空指针引用 直接引用空指针结构体的字段会引发panic&#xff0c;但调用成员方法里如果没引用结构体的字段不会引发panic 3、断言失败 4、map操作错误 map未初始化&#xff0c;可读不可写。 map的value如果是结构体指针&#xf…

G0第21章 :gin框架介绍、RESTful API、Gin渲染

G0第21章 &#xff1a;gin框架 01 内容介绍 web本质 Web是基于HTTP协议进行交互的应用网络Web就是通过使用浏览器/APP访问的各种资源 package mainimport ("fmt""net/http" )func sayHello(w http.ResponseWriter, r *http.Request){_, _ fmt.Fprintln(…

MKS SERVO4257D 闭环步进电机_系列1 产品简介

第1部分 产品概述 1.1 产品介绍 MKS SERVO 28D/35D/42D/57D 系列闭环步进电机是创客基地为满足市场需求而自主研发的一款产品。具备脉冲接口&#xff0c;RS485接口和CAN接口&#xff0c;内置高效FOC矢量算法&#xff0c;采用高精度编码器&#xff0c;通过位置反馈&#xff0c;有…

《深入理解计算机系统》读书笔记1.1-1.5

1.1信息就是位上下文 只由ASCLL字符构成的文件称为文本文件&#xff0c;所有其他文件都称为二进制文件。 系统中的所有的信息都由一串比特表示。区分不同数据对象的唯一方法是读到这些数据对象时的上下文。 1.2程序被其他程序翻译成不同的格式 预编译&#xff0c;编译&#xf…

EasyCVR视频融合平台设备分组共享功能的使用介绍

EasyCVR视频融合平台基于云边端一体化架构&#xff0c;具有强大的数据接入、处理及分发能力&#xff0c;平台支持海量视频汇聚管理&#xff0c;可支持多协议、多类型的设备接入&#xff0c;并能对设备进行分级、分组管理&#xff0c;并支持权限、角色分配&#xff0c;属于功能全…