下载APP
登录
关闭
讲堂
算法训练营
Python 进阶训练营
企业服务
极客商城
客户端下载
兑换中心
渠道合作
推荐作者
当前播放: 38 | SpringBucks实战项目进度小结
00:00 / 00:00
标清
  • 标清
1.0x
  • 2.0x
  • 1.5x
  • 1.25x
  • 1.0x
  • 0.5x
网页全屏
全屏
00:00
付费课程,可试看

玩转Spring全家桶

共123讲 · 123课时,1300分钟
24695
免费
01 | Spring课程介绍
免费
02 | 一起认识Spring家族的主要...
免费
03 | 跟着Spring了解技术趋势
免费
04 | 编写你的第一个Spring程序
免费
05 | 如何配置单数据源
免费
06 | 如何配置多数据源
07 | 那些好用的连接池们:Hika...
08 | 那些好用的连接池们:Alib...
09 | 如何通过Spring JDBC访问...
10 | 什么是Spring的事务抽象(...
11 | 什么是Spring的事务抽象(...
免费
12 | 了解Spring的JDBC异常抽象
13 | 课程答疑(上)
14 | 课程答疑(下)
15 | 认识Spring Data JPA
16 | 定义JPA的实体对象
17 | 开始我们的线上咖啡馆实战...
18 | 通过Spring Data JPA操...
19 | Spring Data JPA的Repos...
20 | 通过MyBatis操作数据库
21 | 让MyBatis更好用的那些工...
22 | 让MyBatis更好用的那些工...
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的方式访问Re...
34 | 通过Reactive的方式访问Mo...
35 | 通过Reactive的方式访问RD...
36 | 通过AOP打印数据访问层的...
37 | 通过AOP打印数据访问层的...
38 | SpringBucks实战项目进度...
39 | 编写第一个Spring MVC C...
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 Se...
59 | 设计好的RESTful Web Se...
60 | 什么是HATEOAS
61 | 使用Spring Data REST实...
62 | 使用Spring Data REST实...
63 | 分布式环境中如何解决Sess...
64 | 使用WebFlux代替Spring M...
65 | 使用WebFlux代替Spring M...
66 | SpringBucks实战项目进度...
67 | 认识Spring Boot的组成部...
68 | 了解自动配置的实现原理
69 | 动手实现自己的自动配置
70 | 如何在低版本Spring中快速...
71 | 了解起步依赖及其实现原理
72 | 定制自己的起步依赖
73 | 深挖Spring Boot的配置加...
74 | 理解配置背后的PropertyS...
75 | 认识Spring Boot的各类Ac...
76 | 动手定制自己的Health In...
77 | 通过Micrometer获取运行数...
78 | 通过Spring Boot Admin...
79 | 如何定制Web容器的运行参...
80 | 如何配置容器支持HTTP/2...
81 | 如何配置容器支持HTTP/2...
82 | 如何编写命令行运行的程序
83 | 了解可执行Jar背后的秘密
84 | 如何将Spring Boot应用打...
85 | SpringBucks实战项目进度...
86 | 简单理解微服务
87 | 如何理解云原生(Cloud N...
88 | 12-Factor App(上)
89 | 12-Factor App(下)
90 | 认识Spring Cloud的组成...
91 | 使用Eureka作为服务注册中...
92 | 使用Spring Cloud Loadb...
93 | 使用Feign访问服务
94 | 深入理解服务发现背后的Di...
95 | 使用Zookeeper作为服务注...
96 | 使用Consul作为服务注册中...
97 | 使用Nacos作为服务注册中...
98 | 如何定制自己的Discovery...
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 Stre...
115 | 通过Spring Cloud Stre...
116 | 通过Spring Cloud Stre...
117 | SpringBucks实战项目进度...
118 | 通过Dapper理解链路治理
119 | 使用Spring Cloud Sleu...
120 | 如何追踪消息链路
121 | 除了链路还要治理什么
122 | SpringBucks实战项目进度...
123 | 结束语
本节摘要

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

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

猜你喜欢

unpreviewunpreview

展开

精选留言(11)

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

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

    6
  • 2019-04-27
    老师, 复杂的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))
                );
        }
    }
    展开

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

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

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

    1
  • 2019-12-02
    老师,您好:
         我想请教一下,通过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-09-30
    老师为什么要定制reactiveRedisTemplate呢 springboot提供的有哪不够好?

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

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

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

  • 2019-07-30
    老师,我在本章节示例代码的基础上,做如下修改:
    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-05-29
    老师,第四章刚开始的时候你抛出一个问题,subscrib之前不会执行任何动作,说后续章节会看源码解释,这部分拉了呀

    作者回复: 我在第32讲最后解释过了呀,你可以跳回去看看。

  • T
    2019-05-07
    老师您好,我在这章中看到您使用@JsonSerialize和@JsonDeserialize,于是乎想自己试一把,我自己写了ListSerialize和ListDeserialize,然后在entity中的List<String>类型的imageUrls属性上使用,目的就是想在JPA持久化该entity到数据库时使用ListSerialize,从数据库获取数据后使用ListDeserialize,但在项目启动的时候,就报了如下错误:
    Caused by: org.hibernate.MappingException: Could not determine type for: java.util.List, at table: image_urls, for columns: [org.hibernate.mapping.Column(image_urls)]

    现在我想请问老师,是不是我对这两个注解的使用上理解有问题?
    展开

    作者回复: 你的确理解错了……@JsonSerialize和@JsonDeserialize是用来做JSON序列化和反序列化的,并不是和数据库交互的

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

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

  • 2019-03-19
    项目启动全部放入缓存,缓存失效怎么处理,byName查找有缓存,byID要再放一次?

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