玩转 Spring 全家桶
丁雪丰
美团研究员,《Spring Boot 实战》、《Spring 攻略》译者,腾讯云 TVP。
97978 人已学习
新⼈⾸单¥68
课程目录
已完结/共 123 讲
第十一章:Spring Cloud及Cloud Native概述 (5讲)
玩转 Spring 全家桶
登录|注册
留言
14
收藏
沉浸
阅读
分享
手机端
回顶部
当前播放: 38 | SpringBucks实战项目进度小结
00:00 / 00:00
高清
  • 高清
1.0x
  • 2.0x
  • 1.5x
  • 1.25x
  • 1.0x
  • 0.75x
  • 0.5x
网页全屏
全屏
00:00
付费课程,可试看
01 | Spring课程介绍
02 | 一起认识Spring家族的主要成员
03 | 跟着Spring了解技术趋势
04 | 编写你的第一个Spring程序
05 | 如何配置单数据源
06 | 如何配置多数据源
07 | 那些好用的连接池们:HikariCP
08 | 那些好用的连接池们:Alibaba Druid
09 | 如何通过Spring JDBC访问数据库
10 | 什么是Spring的事务抽象(上)
11 | 什么是Spring的事务抽象(下)
12 | 了解Spring的JDBC异常抽象
13 | 课程答疑(上)
14 | 课程答疑(下)
15 | 认识Spring Data JPA
16 | 定义JPA的实体对象
17 | 开始我们的线上咖啡馆实战项目:SpringBucks
18 | 通过Spring Data JPA操作数据库
19 | Spring Data JPA的Repository是怎么从接口变成Bean的
20 | 通过MyBatis操作数据库
21 | 让MyBatis更好用的那些工具:MyBatis Generator
22 | 让MyBatis更好用的那些工具:MyBatis PageHelper
23 | SpringBucks实战项目进度小结
24 | 通过Docker辅助开发
25 | 在Spring中访问MongoDB
26 | 在Spring中访问Redis
27 | Redis的哨兵与集群模式
28 | 了解Spring的缓存抽象
29 | Redis在Spring中的其他用法
30 | SpringBucks实战项目进度小结
31 | Project Reactor介绍(上)
32 | Project Reactor介绍(下)
33 | 通过Reactive的方式访问Redis
34 | 通过Reactive的方式访问MongoDB
35 | 通过Reactive的方式访问RDBMS
36 | 通过AOP打印数据访问层的摘要(上)
37 | 通过AOP打印数据访问层的摘要(下)
38 | SpringBucks实战项目进度小结
39 | 编写第一个Spring MVC Controller
40 | 理解Spring的应用上下文
41 | 理解请求的处理机制
42 | 如何定义处理方法(上)
43 | 如何定义处理方法(下)
44 | Spring MVC中的视图解析机制(上)
45 | Spring MVC中的视图解析机制(下)
46 | Spring MVC中的常用视图(上)
47 | Spring MVC中的常用视图(下)
48 | 静态资源与缓存
49 | Spring MVC中的异常处理机制
50 | 了解Spring MVC的切入点
51 | SpringBucks实战项目进度小结
52 | 课程答疑
53 | 通过RestTemplate访问Web资源
54 | RestTemplate的高阶用法
55 | 简单定制RestTemplate
56 | 通过WebClient访问Web资源
57 | SpringBucks实战项目进度小结
58 | 设计好的RESTful Web Service(上)
59 | 设计好的RESTful Web Service(下)
60 | 什么是HATEOAS
61 | 使用Spring Data REST实现简单的超媒体服务(上)
62 | 使用Spring Data REST实现简单的超媒体服务(下)
63 | 分布式环境中如何解决Session的问题
64 | 使用WebFlux代替Spring MVC(上)
65 | 使用WebFlux代替Spring MVC(下)
66 | SpringBucks实战项目进度小结
67 | 认识Spring Boot的组成部分
68 | 了解自动配置的实现原理
69 | 动手实现自己的自动配置
70 | 如何在低版本Spring中快速实现类似自动配置的功能
71 | 了解起步依赖及其实现原理
72 | 定制自己的起步依赖
73 | 深挖Spring Boot的配置加载机制
74 | 理解配置背后的PropertySource抽象
75 | 认识Spring Boot的各类Actuator Endpoint
76 | 动手定制自己的Health Indicator
77 | 通过Micrometer获取运行数据
78 | 通过Spring Boot Admin了解程序的运行状态
79 | 如何定制Web容器的运行参数
80 | 如何配置容器支持HTTP/2(上)
81 | 如何配置容器支持HTTP/2(下)
82 | 如何编写命令行运行的程序
83 | 了解可执行Jar背后的秘密
84 | 如何将Spring Boot应用打包成Docker镜像文件
85 | SpringBucks实战项目进度小结
86 | 简单理解微服务
87 | 如何理解云原生(Cloud Native)
88 | 12-Factor App(上)
89 | 12-Factor App(下)
90 | 认识Spring Cloud的组成部分
91 | 使用Eureka作为服务注册中心
92 | 使用Spring Cloud Loadbalancer访问服务
93 | 使用Feign访问服务
94 | 深入理解服务发现背后的DiscoveryClient
95 | 使用Zookeeper作为服务注册中心
96 | 使用Consul作为服务注册中心
97 | 使用Nacos作为服务注册中心
98 | 如何定制自己的DiscoveryClient
99 | SpringBucks实战项目进度小结
100 | 使用Hystrix实现服务熔断(上)
101 | 使用Hystrix实现服务熔断(下)
102 | 如何观察服务熔断
103 | 使用Resilience4j实现服务熔断
104 | 使用Resilience4j实现服务限流(上)
105 | 使用Resilience4j实现服务限流(下)
106 | SpringBucks实战项目进度小结
107 | 基于Git的配置中心(上)
108 | 基于Git的配置中心(下)
109 | 基于Zookeeper的配置中心
110 | 深入理解Spring Cloud的配置抽象
111 | 基于Consul的配置中心
112 | 基于Nacos的配置中心
113 | SpringBucks实战项目进度小结
114 | 认识Spring Cloud Stream
115 | 通过Spring Cloud Stream访问RabbitMQ
116 | 通过Spring Cloud Stream访问Kafka
117 | SpringBucks实战项目进度小结
118 | 通过Dapper理解链路治理
119 | 使用Spring Cloud Sleuth实现链路追踪
120 | 如何追踪消息链路
121 | 除了链路还要治理什么
122 | SpringBucks实战项目进度小结
123 | 结课测试&结束语
本节摘要

PDF 课件和源代码下载地址:

https://gitee.com/geektime-geekbang/geektime-spring-family

猜你喜欢

unpreviewunpreview

登录 后留言

全部留言(14)

  • 最新
  • 精选
巍楠
老师您好: 关于aop的使用,有一个建议: 在spring-boot中,如果需要使用aop,需要引入spring-boot-starter-aop依赖。 示例项目:performance-aspcet-demo的依赖项目(spring-boot-starter-data-jpa)包含了spring-boot-starter-aop,但是如果选用了mybatis的dao框架,只需要引入aop这个依赖就好了,建议在视频中说明一下,帮助新手理解

作者回复: 谢谢,视频都制作完了有一段时间了,改起来可能会前后衔接不太理想(就算话能接上,我衣服也穿一样,发型也不同啊)。不过我想大家会看到你的留言的哈。

2019-05-15
14
碧雪天虹
老师, 复杂的lambda嵌套调用, 适当使用换行和缩进可以增加可读性, 并相对轻松地看出层级关系. @Repository public class CoffeeOrderRepository { @Autowired private DatabaseClient databaseClient; public Mono<Long> save(CoffeeOrder order) { return databaseClient .insert() .into("t_order") .value("customer", order.getCustomer()) .value( "state", order .getState() .ordinal() ) .value( "create_time", new Timestamp( order .getCreateTime() .getTime() ) ) .value( "update_time", new Timestamp( order .getUpdateTime() .getTime() ) ) .fetch() .first() .flatMap(m -> Mono.just((Long) m.get("ID"))) .flatMap(id -> Flux .fromIterable(order.getItems()) .flatMap(c -> databaseClient .insert() .into("t_order_coffee") .value("coffee_order_id", id) .value("items_id", c.getId()) .then() ) .then(Mono.just(id)) ); } }

作者回复: 好的,我以后会注意的,多谢提醒

2019-04-27
2
achenbj
您好,我想用StringRedisTemplate缓存Bean,里面的price属性能用fastjson序列化为string吗? 如果只有money的话可以使用toString和parseMoney来转换. 可是如果我用做类属性,能用stringRedisTemplate存储转化后的price属性吗? 感谢.

作者回复: 先不说FastJSON,假设是Jackson JSON,Spring Boot里提供了Module和类型转换的支持,可以把对象序列化成JSON,这里的Money的序列化和反序列化器就是你自己提供的,想转成什么样的你说了算,反正最后JSON就是个字符串,你把这个字符串往哪里放就是你的事了。

2019-04-15
2
Nick1407
老师您好,关于序列化和反序列化,他的使用场景有哪些呢,就像代码示例里一样,为什么要使用那两个注解。

作者回复: 对象传输时,都是需要经过序列化后才能传输出去的,接收方再把收到的东西反序列化成对象。

2019-07-30
1
Sonny721
老师您好:同一条数据缓存,需要两种以上的查询方式(比如通过Id和Name)来查询缓存,如何存储?通常的处理方式是以Id为键创建一条缓存,再以Name为键创建一条缓存,但两条缓存的数据是一样的,是不是浪费存储空间了,有什么方案么?

作者回复: 缓存本来就是用空间换时间,就和索引一样,既然你的确有两种查询,为什么不为高频的查询做缓存呢。

2019-04-01
1
徐宁
项目启动全部放入缓存,缓存失效怎么处理,byName查找有缓存,byID要再放一次?

作者回复: 这里只是做个例子而已,实际你肯定还是要根据自己的情况来做缓存的。比如我们有些配置数据不怎么会变,启动后就加载上来,然后定时刷新。另外同一个数据根据不同的查询条件也可以分开缓存。

2019-03-19
1
jeray
老师你好,我这里报了一个错误,不知道是什么回事 java.lang.IllegalArgumentException: Cannot encode parameter of type java.sql.Timestamp at io.r2dbc.h2.codecs.DefaultCodecs.encode(DefaultCodecs.java:73) ~[r2dbc-h2-0.8.4.RELEASE.jar:0.8.4.RELEASE] Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: Error has been observed at the following site(s): |_ checkpoint ⇢ SQL "INSERT INTO t_order (customer, state, createTime, updateTime) VALUES ($1, $2, $3, $4)" [DatabaseClient] Stack trace:

作者回复: r2dbc-h2升级成最新版本的试试。 可以把相关的r2dbc相关的库都先升级一下,比如spring-data-r2dbc和r2dbc-h2。

2020-08-06
2
大妖怪😀
老师,您好: 我想请教一下,通过reactive方式入库的时候,数据库事务是怎么保证的呢? 比如您项目中的CoffeeOrderRepository类,在做save操作的时候,代码如下: return databaseClient.insert().into("t_order") .value("customer", order.getCustomer()) .value("state", order.getState().ordinal()) .value("create_time", new Timestamp(order.getCreateTime().getTime())) .value("update_time", new Timestamp(order.getUpdateTime().getTime())) .fetch() .first() .flatMap(m -> Mono.just((Long) m.get("ID"))) .flatMap(id -> Flux.fromIterable(order.getItems()) .flatMap(c -> databaseClient.insert().into("t_order_coffee") .value("coffee_order_id", id) .value("items_id", c.getId()) .then()).then(Mono.just(id))); 是先入库了t_order,然后获取ID以后,再循环入库t_order_coffee。如果在入库t_order_coffee的时候,有一个数据出错了,如何保证事务统一呢?另外,您前面也讲过,我们可以指定不同线程来执行flux操作,我们在做这种批量数据入库的时候,是不是要保证在一个线程下才能保证事物呢?

作者回复: 关于事务的问题,可以看一下R2DBC的文档,其中有13.8节就是事务 https://docs.spring.io/spring-data/r2dbc/docs/1.0.0.RC1/reference/html/#r2dbc.datbaseclient.transactions

2019-12-02
陶智
老师为什么要定制reactiveRedisTemplate呢 springboot提供的有哪不够好?

作者回复: 因为大家用的序列化方式不一样,所以我稍微改了下,做个演示

2019-09-30
york
老师,我在本章节示例代码的基础上,做如下修改: 1. 先不执行CoffeeService中的initCache方法,即先不将数据库中的咖啡放入redis 2.修改CoffeeService中的findOneCoffee方法,以实现将从数据库查询到的咖啡放入redis的功能,但为何不起作用(未被放入redis)? 修改后的findOneCoffee代码如下: public Mono<Coffee> findOneCoffee(String name) { return reactiveRedisTemplate.opsForValue().get(PREFIX + name) .switchIfEmpty( coffeeRepository.findByName(name) .doOnSuccess(coffee -> { log.info("Loading Coffee {} From Database", coffee.getName()); reactiveRedisTemplate.opsForValue() .set(PREFIX + coffee.getName(), coffee) .map(o -> reactiveRedisTemplate.expire(PREFIX + coffee.getName(), Duration.ofMinutes(1)) .doOnSuccess(v -> log.info("Save Coffee {} to Cache Successfully!", coffee.getName()))); }) ); }

作者回复: 因为你最后放缓存的这个动作没有执行,简单的话,你在doOnSuccess后面加个block(),等它放完再继续

2019-07-30
收起评论