微服务一站式开发

课程介绍

本达人课结合我当前自身的微服务的设计、开发工作,为有志于从传统开发模式向当前比较流行的微服务架构模式转变的开发者,提供比较完整的知识梳理及全技术栈障碍的打通。

其中的技术栈主要包括 Spring、Spring MVC 常用注解以及请求流程的梳理,Spring Boot 工作中常用基础知识以及主要会涉及到的各种技术框架的整合,Spring Cloud 的各个组件设计原理梳理以及如何使用,Docker 架构介绍以及容器化管理平台等。

达人课分为五大部分:

第一部分(第01-05课),主要分享微服务开发过程中,Spring、Spring MVC 常用的主要知识点,并讲解 Spring Boot 在实际工作如何整合常用技术,诸如 Spring Data JPA、Redis、MongoDB、RabbitMQ、Elasticsearch 等。

第二部分(第06-09课),除了分享 Consul 相关知识,带领大家利用 Spring Cloud 和 Consul 实现服务的注册与发现,还将介绍 Spring Cloud 常用组件(如 Zuul、Ribbon、Hystrix、Feign 等)及在实际工作中的使用方法。此外,在网关层整合 OAuth 2 实现微服务鉴权、配置中心及请求链路跟踪等内容也会在本部分进行详细解读与演示。

第三部分(第10-14课),主要包括几大核心内容,(1)对 Redis 分片原理、集群搭建、分片数据迁移,Redis 与 Lua 脚本整合进行详解;(2)对 ZooKeeper 相关算法(如 Paxos、ZAB)进行介绍,并对其 watcher 的实现原理及 ZooKeeper 集群搭建过程进行分析与说明;(3)分析如何利用 Redis、DB、ZooKeeper 等实现分布式锁,介绍分布式事务相关原理,并演示在工作中如何利用消息中间件实现数据最终一致性和利用第三方组件实现数据实时一致性等内容。

第四部分(第15-17课):主要介绍 Docker 架构及常用命令,并对常用容器管理平台如 Rancher、K8S 进行详细说明,同时讲解工作中如何使用其管理容器。

第五部分(第18-19课),实战部分,对前面所讲内容进行综合实战演练,让读者了解在工作中如何应用以上技术。其中主要包括微服务开发、微服务网关、负载均衡、熔断、微服务鉴权、微服务镜像生成、容器管理平台搭建及如何管理容器等内容。

专家推荐

本课程全面介绍了基于 Spring Cloud 体系开发微服务的全过程,不仅包含基础的服务开发,而且深入地介绍了完整的微服务架构需要的服务治理、分布式事务等核心要素,课程还介绍了容器化部署微服务,微服务能够通过 DevOps 支持快速上线运营。

——润和软件研发总监,吴昊

随着技术的发展,Spring Boot 以其高效的开发越来越受广大开发者喜爱,本课程从基础到实践全方位解读了 Spring Boot,很值得学习。

——中国石油规划总院高级开发工程师,李熠

技术理论知识往往是枯燥、理想化的,如果没有实践和运用,终将停留在纸面上。黄朝兵通过实践和运用实例生动阐述了技术理论知识,使技术人员易懂会用。

——江苏润和软件股份有限公司资深 PMO,陈伟荣

作者介绍

黄朝兵,本科毕业于南京工业大学,目前在南京大学软件学院读软件工程硕士;工作10年左右,现就职于某家跨国公司担任资深开发工程师,主要从事微服务相关设计、开发工作;曾在日企从事过医疗软件核心系统开发工作;在国企完成电力调度、操作票核心系统开发与维护;在互联网公司职位为高级工程师,从事金融系统研发,主要职责是完成交易系统的核心功能的架构设计、开发。

课程内容

导读:初识微服务架构

单体架构(Monolithic)

十年前左右,我去公司面试时,面试官问我的第一个问题是让我简要介绍下软件设计中的三层设计模型(表示层、业务逻辑处理层、数据访问层):

  • 表示层:通常理解为用于和用户交互的视图层;
  • 业务逻辑处理层:用户提交请求,经过业务逻辑层处理后,对用户请求作出响应;
  • 数据库访问层:主要用于操作数据库。

尽管在软件设计过程中,架构师或者程序设计者遵守了流行一时的经典的三层模型,但由于并未按照业务场景进行划分,使得最终的系统应用将所有的业务场景的表示层、业务逻辑处理层、数据访问层放在一个 Project 中,然后经过编译、打包并部署到一台服务器上。

这种架构适用于用户业务不复杂、访问量较小的时候,甚至可以将应用服务、数据库、文件服务器部署在一台服务器上。但随着用户业务场景变得越来越复杂,单体架构的局限性就很快暴露出来了,主要体现在如下几方面:

  • 随着业务越来越复杂,单体应用代码量急剧膨胀,最终导致代码可 读性、可维护行和可扩展性得不到保证;
  • 随着用户访问量增加,单体应用的并发能力有限;
  • 随着系统代码量的剧增,当修改应用程序或者新增需求时,测试难度成指数级增长;
  • 部署效率低下;
  • 技术选型单一。

SOA 架构(Service Oriented Architecture)

SOA 是一种粗粒度、松耦合服务架构,服务之间通过简单、精确定义接口进行通讯,不涉及底层编程接口和通讯模型。SOA 可以看作是 B/S 模型、XML(标准通用标记语言的子集)/Web Service 技术之后的自然延伸。

其主要优点有:

  • 把模块(即服务)拆分,使用接口通信,降低模块之间的耦合度;
  • 把项目拆分成若干个子项目,不同的团队负责不同的子项目;
  • 增加功能时只需要再增加一个子项目,调用其它系统的接口就可以;
  • 可以灵活的进行分布式部署。

主要缺点:

  • 和单体架构相比,增加了系统复杂度,系统整体性能有较大影响;
  • 多服务数据通信协议之间转换过程复杂,容易造成 ESB(Enterprise Service Bus)性能瓶颈。

微服务架构(MicroServices)

微服务的概念是 Martin Flower 在2014年写的一篇论文《MicroServices》中提出来的,其主要特点是:

  • 每个服务按照业务划分;
  • 服务之间通过轻量级 API 调用;
  • 可以使用不同语言开发;
  • 可以使用不同的数据存储技术;
  • 可独立部署,服务之间互相不影响;
  • 可针对用户访问流量大的服务单独扩展,从而能够节约资源;
  • 管理自动化。

主要挑战:

  • 微服务粒度大小难以划分,需要设计人员对业务有很好的掌握;
  • 分布式复杂性,主要体现在分布式事务、网络延迟、系统容错等问题解决难度较大;
  • 微服务之间通信成本较高,对微服务之间网络稳定性、通信速度要求较高;
  • 由于微服务数量较大,运维人员运维、部署有较大的挑战。

通过以上对微服务的分析,相信各位读者已了解了微服务开发过程中我们将会面临的各种挑战。为了让大家在微服务开发过程中更加顺利,少踩坑,我在本达人课中分享了自己在微服务开发过程中的所有总结,希望对各位读者有所帮助。

众所周知,对于做技术的工程师而言,除了理论之外,我们更关注于实战,因此在课程的每篇文章中,主要以实战为主,比较关键的理论将同步为各位做详细说明。

为了方便大家更清晰地学习本课程,我们来看下课程目录安排。

  • 第01-02课:主要演示微服务开发过程中,Spring、Spring MVC 常用主要知识点;
  • 第03-05课:主要演示在实际工作中,Spring Boot 如何整合诸如 Spring Data JPA、Redis、MongoDB、RabbitMQ、Elasticsearch 此类的常用技术;
  • 第06-09课:将对 Consul 相关知识做详解,并利用 Spring Cloud 和 Consul 实现服务的注册与发现;同时将演示 Spring Cloud常用组件(如 Zuul、Ribbon、Hystrix、Feign 等)在实际工作中使用方法;此外,在网关层整合 OAuth 2 实现微服务鉴权、配置中心及请求链路跟踪等内容也会在本部分进行详细解读与演示;
  • 第10-13课:首先会对 Redis 分片原理、集群搭建、分片数据迁移,Redis 与 Lua 脚本整合进行详解;接着,对 ZooKeeper 相关算法(如 Paxos、ZAB)进行介绍,并对其 watcher 的实现原理及 ZooKeeper 集群搭建过程作分析与说明;之后讲解如何利用 Redis、DB、ZooKeeper 等实现分布式锁,介绍分布式事务相关原理,并演示在工作中如何利用消息中间件实现数据最终一致性和利用第三方组件实现数据实时一致性等内容;
  • 第14课:主要演示如何实现微服务监控;
  • 第15-17课:介绍 Docker 架构及常用命令;对常用容器管理平台如 Rancher、K8S 进行详细说明,并说明工作中如何用其管理容器;
  • 第18课:实战部分,对前17课所讲内容进行综合实战,让读者了解在工作中如何应用以上技术。其中主要包括微服务开发、微服务网关、微服务调用、负载均衡、熔断、微服务鉴权、日志监控、配置中心、微服务镜像生成、容器管理平台搭建及如何管理容器等技术内容。
第01课:Spring Boot 基础详解(一)

Spring Boot 未出现之前,我们利用 Spring、Spring MVC 进行项目开发时,整个项目从引入依赖 Jar 包,书写配置文件,打包部署到开发环境、测试环境、生产环境都需要大量人力,但是最终的效果仍不尽如人意,甚至还会给一个项目组带来项目延期的风险等。

随着敏捷开发思想被越来越多的人接受以及开发者对开发效率的不断追求,最终推出了具有颠覆和划时代意义的框架 Spring Boot。

Spring Boot 首先遵循“习惯优于配置”原则,言外之意即是尽量使用自动配置让开发者从繁琐的书写配置文件的工作中解放出来;Spring Boot 另外一个比较明显的特点就是尽量不使用原来 Spring 框架中的 XML 配置,而主要使用注解代替。

Spring Boot 由 Spring、Spring MVC 演化而来,注解也继承自两者。下面我们看下 Spring MVC 中常用的注解:

  1. @Controller:该注解用于类上,其表明该类是 Spring MVC 的 Controller;
  2. @RequestMapping:该注解主要用来映射 Web 请求,其可以用于类或者方法上;
  3. @RequestParam:该注解主要用于将请求参数数据映射到功能处理方法的参数上;
  4. @ResponseBody:该注解的作用是将方法的返回值放在 Response 中,而不是返回一个页面,其可以用于方法上或者方法返回值前;
  5. @RequestBody:用于读取 HTTP 请求的内容(字符串),通过 Spring MVC 提供的 HttpMessageConverter 接口将读到的内容转换为 JSON、XML 等格式的数据并绑定到 Controller 方法的参数上;
  6. @PathVariable:用于接收请求路径参数,将其绑定到方法参数上;
  7. @RestController:该注解是一个组合注解,只能用于类上,其作用与 @Controller@ResponseBody一起用于类上等价。

:在 Spring 4.3 中引进了 @GetMapping@PostMapping@PutMapping@DeleteMapping@PatchMapping

简单使用,如下代码所示:

@RestController@RequestMapping("/springmvc")public class TestAnnotationController {    @RequestMapping(value = "/setUserInfo",method = RequestMethod.GET)    public String setUserInfo(@RequestParam(name = "userName") String userName){        System.out.println(userName);        return "success";    }}

利用 Postman 测试结果如下图所示:

微服务一站式开发_第1张图片

以上是运用 Spring MVC 注解的一个简单实例,下面对其发送请求到结果返回的整个流程进行简要分析:

1. 调用类 DispatcherServlet 中 doService 方法对请求进行处理,该方法主要就进一步调用 doDispatch 方法对请求进行处理,源码如下:

微服务一站式开发_第2张图片

2. 根据请求 processedRequest 获取 HandlerExecutionChain,源码如下:

微服务一站式开发_第3张图片

3. 获取 HandlerAdapter,源码如下:

微服务一站式开发_第4张图片

4. 调用类 RequestMappingHandlerAdapter 中方法 handleInternal 初始化 invocableMethod 的方法参数解释器和返回值解释器,源码如下:

微服务一站式开发_第5张图片

微服务一站式开发_第6张图片

5. 调用 invocableMethod 的方法 invokeAndHandle 对请求进行处理,源码如下:

微服务一站式开发_第7张图片

在该方法中主要调用 invokeForRequest 方法获取参数之后,再利用反射调用 @RequestMapping 注解对应的方法获取返回值,代码如下:

微服务一站式开发_第8张图片

6. 最后再利用返回值处理器对步骤4中的结果进行处理后得到最终结果并填充到 Response 对象中,源码如下:

enter image description here

以上就是从前端发送一个请求到后端,后端收到请求处理后返回结果的主要流程。因为篇幅问题很多环节无法一一写出,假如需要详细了解请自行根据以上主线 Debug 查看源代码。

第02课:Spring Boot 基础详解(二)

第01课中,主要为各位读者介绍了实际开发中常用注解和 Spring Boot 中的请求主要流程。本课中,主要带大家掌握 Spring Boot 开发时所需要的以下技能:

  • 简单的 RESTful 风格接口开发;
  • 多环境配置文件动态切换,并读取配置文件内容;
  • Listener 的使用;
  • Filter 的使用;
  • Interceptor 的使用。

开发简单的 RESTful 风格接口

首先,我们访问:http://start.spring.io/,选择构建工具 Maven,采用编程语言 Java,输入如图中的信息,下载项目压缩包:

微服务一站式开发_第9张图片

将下载的项目压缩包解压后,导入 idea 中,然后在此基础项目结构中进行开发即可,在此实例中,项目结构如下图所示:

微服务一站式开发_第10张图片

为了能够开发 RESTful 风格的接口,需要在 pom.xml 文件中添加如下依赖:

 org.springframework.boot spring-boot-starter-web

继下来编写 Controller:

@RestController@RequestMapping(value = "/restful")public class TestRestfulInterfaceController{    @RequestMapping("/test")    public String testRestfulInterface(@RequestParam("name") String name){        return "hello" + name;    }}

将程序启动起来,并利用 Postman 进行测试,输出如下结果:

微服务一站式开发_第11张图片

多环境配置文件动态切换并读取配置文件内容

利用 Spring Boot 进行微服务开发时,配置文件既可以利用 *.properties 文件格式,又可以利用 *.yml 格式文件。不过在开发中,通常选择利用 yml 格式配置文件,该格式文件可读性更好。

下面分别新建 application.yml、application-dev.yml、application-test.yml、application-prod.yml 四个配置文件:

微服务一站式开发_第12张图片

将配置文件切换到测试环境并启动程序后,程序监听的端口变为8100,利用 Postman 测试结果如下:

微服务一站式开发_第13张图片

读取配置文件中的配置项,分别在 dev、test、prod 对应配置文件中添加 student 相关配置信息,在程序中读取配置文件并将其内容打印出来。

配置文件内容,如下图所示:

微服务一站式开发_第14张图片

读取配置文件内容代码:

@Componentpublic class StudentConfig {    @Value("${student.name}")    private String name;    @Value("${student.age}")    private Integer age;    ...此处省略get set方法}

打印学生信息代码:

@RestController@RequestMapping(value = "/restful")public class TestRestfulInterfaceController{    @Autowired    private StudentConfig studentConfig;    @RequestMapping("/test")    public String testRestfulInterface(@RequestParam("name") String name){        return "hello:" + name;    }    @RequestMapping("/printStudentInfo")    public String getStudentInfo(){            return "studentName:" + studentConfig.getName() +      "   studentAge:" + studentConfig.getAge();    }}

Postman 测试结果,见下图:

微服务一站式开发_第15张图片

监听器 Listener 的使用

Listener 是 Spring 为开发人员提供的一种监听、订阅实现机制,其实现原理是设计模式之观察者模式,设计的初衷是为了系统业务之间进行解耦,以便提高系统可扩展性、可维护性。Listener 主要包括定义事件、事件监听、事件发布。下面分别对它们做介绍。

1. 定义用户注册事件

/** *事件定义类 */public class UserRegisterEvent extends ApplicationEvent {    private User user;    /**     * source 表示事件源对象     * user表示注册用户对象     * @param source     * @param user     */    public UserRegisterEvent(Object source,User user) {        super(source);        this.user = user;    }    public User getUser() {        return user;    }    public void setUser(User user) {        this.user = user;    }}

2. 用户注册服务实现类

@Service("userService")public class UserServiceImpl implements IUserService {    @Autowired    private ApplicationContext applicationContext;    /**     * 用户注册     * @param user     */    @Override    public void registerUser(User user) {        if (user != null) {            //调用持久层注册用户            //发布用户注册事件            applicationContext.publishEvent(new UserRegisterEvent(this, user));        }    }}

3. 用户注册控制类

 @RestController@RequestMapping("/user")public class UserController {    @Autowired    private IUserService userService;    @RequestMapping("/register")    public String registerUser(@NotNull String userName, @NotNull Integer age) {        String msg = "success";        try {            userService.registerUser(new User(userName,age));        } catch (Exception e) {            msg = "error";        }        return msg;    }}

4. 监听器代码

利用 @EventListener 实现监听用户注册事件:

 /** * 利用@EventListener注解监听用户注册事件 */@Componentpublic class AnnotationUserRegisterListener {    @EventListener    public void sendMailToUser(UserRegisterEvent userRegisterEvent){        System.out.println("利用@EventListener注解监听用户注册事件并向用户发送邮件");        System.out.println("注册用户名:" + userRegisterEvent.getUser().getName());    }}

利用接口 ApplicationListener 实现监听用户注册事件:

/** * 实现ApplicationListener实现用户注册监听 */@Componentpublic class RegisterUserApplicationListener implements ApplicationListener {    @Override    public void onApplicationEvent(UserRegisterEvent userRegisterEvent) {        System.out.println("实现接口ApplicationListener监听用户注册事件并向用户发送邮件");        System.out.println("注册用户名:" + userRegisterEvent.getUser().getName());    }}

利用接口 SmartApplicationListener 实现监听用户注册事件:

/** *实现接口SmartApplicationListener实现监听用户注册 */@Componentpublic class RegisterUserSmartApplicationListener implements SmartApplicationListener {    @Override    public boolean supportsEventType(Class aClass) {        return aClass == UserRegisterEvent.class;    }    /**     * 注意此处aClass不能与IUserService.class比较     * @param aClass     * @return     */    @Override    public boolean supportsSourceType(Class aClass) {        return aClass == UserServiceImpl.class;    }    @Override    public void onApplicationEvent(ApplicationEvent applicationEvent) {        UserRegisterEvent userRegisterEvent = (UserRegisterEvent) applicationEvent;        System.out.println("实现接口SmartApplicationListener监听用户注册事件并向用户发送邮件");        System.out.println("注册用户名:" + userRegisterEvent.getUser().getName());    }    /**     * 返回值越小监听越靠前     * @return     */    @Override    public int getOrder() {        return 1;    }}

利用 Postman 调用接口:

http://localhost:8100/user/register?userName=huangchaobing&age=32

实现用户注册,控制台输出监听相关信息:

微服务一站式开发_第16张图片

以上三种监听都属于同步监听,必须等监听逻辑处理完成之后,用户注册业务逻辑才算完成。然而这样,当有用户操作时,会让用户进行等待,给用户的体验不太好,因此下面我们用 @Async 注解实现异步监控。

1. 为异步监听器设置异步线程池对象:

@Configuration@EnableAsyncpublic class AsyncListenerConfiguration implements AsyncConfigurer {    /**     * 获取异步线程池执行对象     * @return     */    @Override    public Executor getAsyncExecutor() {        ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();        //设置线程数量        threadPoolTaskExecutor.setCorePoolSize(10);        threadPoolTaskExecutor.setMaxPoolSize(10);        threadPoolTaskExecutor.setQueueCapacity(50);        threadPoolTaskExecutor.initialize();        return threadPoolTaskExecutor;    }    @Override    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {        return null;    }} 

2. 在需要执行异步监听方法上面添加 @Async注解:

@Componentpublic class AsyncAnnotationUserRegisterListener {    @Async    @EventListener    public void sendMailToUser(UserRegisterEvent userRegisterEvent) {        try {            Thread.sleep(5000);        } catch (Exception e) {        }        System.out.println("利用@EventListener注解监听用户注册事件并异步向用户发送邮件");    }}

3. 发送注册用户请求,测试异步监听:

微服务一站式开发_第17张图片

以上是自定义事件、发布事件、监听事件的常用开发方式。为了方便开发者开发,在 Spring Boot 2.0 以后,为开发者定义了如下事件:

微服务一站式开发_第18张图片

  • ApplicationFailedEvent:Spring Boot 启动失败时触发;
  • ApplicationPreparedEvent:上下文 Context 准备时触发;
  • ApplicationReadyEvent:上下文准备完毕的时触发;
  • ApplicationStartedEvent:Spring Boot 启动监听类;
  • SpringApplicationEvent:获取 SpringApplication;
  • ApplicationEnvironmentPreparedEvent:装配完参数和环境后触发的事件。

在工作中我们经常在程序上下文和 Bean 创建成功后做一些比如初始化缓存、缓存预热等操作,这时,便会通过监听 ApplicationReadyEvent 事件完成,该过程分两步完成。

1. 定义监听器:

/** 1. 初始化redis缓存listener */public class InitializeRedisCacheListener implements ApplicationListener {    @Override    public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {        ConfigurableApplicationContext applicationContext = applicationReadyEvent.getApplicationContext();        RedisUtil redisUtil = applicationContext.getBean(RedisUtil.class);        if(redisUtil != null){            redisUtil.initializeRedisData();        }    }}

2. 注册监听器 Listener:

@SpringBootApplicationpublic class Lesson2Application {    public static void main(String[] args) {        SpringApplication springApplication = new SpringApplication(Lesson2Application.class);        springApplication.addListeners(new InitializeRedisCacheListener());        springApplication.run(args);    }}

启动程序后,开始初始化 Redis 缓存数据,如下图所示:

enter image description here

Filter 的使用

Filter 通常用于在请求过程中对用户身份进行认证、过滤等操作,开发过程如下。

1. 继承 Filter 接口定义过滤器:

 @WebFilter(filterName = "loginFilter",urlPatterns = "/*")public class LoginFilter implements Filter {    @Override    public void init(FilterConfig filterConfig) throws ServletException {    }    @Override    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {        System.out.println("对登录进行过滤操作");        //请求放行     filterChain.doFilter(servletRequest,servletResponse);    }    @Override    public void destroy() {    }}

2. 在程序启动类加上注解 @ServletComponentScan,将过滤器加入过滤器链:

 @SpringBootApplication@ServletComponentScanpublic class Lesson2Application {    public static void main(String[] args) {        SpringApplication springApplication = new SpringApplication(Lesson2Application.class);        springApplication.addListeners(new InitializeRedisCacheListener());        springApplication.run(args);    }}

启动程序利用 Postman 发送请求,测试结果如下:

enter image description here

除了利用 @ServletComponentScan 将 Filter 加入过滤器链,还可以在程序启动类中加入 @Bean 注解将 Filter 加入过滤器链:

@SpringBootApplication//@ServletComponentScanpublic class Lesson2Application {    public static void main(String[] args) {        SpringApplication springApplication = new SpringApplication(Lesson2Application.class);        springApplication.addListeners(new InitializeRedisCacheListener());        springApplication.run(args);    }    @Bean    public FilterRegistrationBean securityFilter() {        FilterRegistrationBean registration = new FilterRegistrationBean();        Filter loginFilter = new LoginFilter();        registration.setFilter(loginFilter);        registration.addUrlPatterns("/*");        registration.setName("loginFilter");        registration.setOrder(1);        return registration;    }}

测试结果如下:

enter image description here

Interceptor 的使用

本节将大家利用拦截器 Interceptor 完成请求过滤、记录请求日志、判断用户是否登录等操作。

实现自定义拦截器需要如下三步:

1. 实现接口 HandlerInterceptor 并根据需要重载其方法。其方法主要有:

  • preHandle,该方法在处理器方法执行之前执行;
  • postHandle,该方法在处理器方法执行之后执行;
  • afterCompletion,该方法在视图渲染之后被执行;

示例代码如下:

public class WebInterceptor implements HandlerInterceptor {    @Override    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse            httpServletResponse, Object o) throws Exception {        System.out.println("============== request before ==============");        return true;    }    @Override    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse            httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {        System.out.println("==============  request  ==============");    }    @Override    public void afterCompletion(HttpServletRequest httpServletRequest,                                HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {        System.out.println("==============  request completion  ==============");    }}

2. 创建类 DefInterceptorConfig,并继承于 WebMvcConfigurerAdapter,重写其 addInterceptors 方法,将自定义拦截器加入拦截器链中:

 @Configurationpublic class DefInterceptorConfig extends WebMvcConfigurerAdapter {    @Override    public void addInterceptors(InterceptorRegistry registry) {        registry.addInterceptor(new WebInterceptor()).addPathPatterns("/**");    }}

3. 启动应用程序,访问接口,查看自定义拦截器输出如下:

微服务一站式开发_第19张图片

本文就分享到此了,内容不少,各位好好消化下。下一课我将大家学习 Spring Boot 整合常用技术框架的方法。

第03课:整合常用技术框架之 JPA 和 Redis
第04课:整合常用技术框架之 MongoDB 和 RabbitMQ
第05课:整合常用技术框架之 Elasticsearch
第06课:Spring Cloud 整合 Consul 实现服务注册、发现
第07课:Spring Cloud 整合常用组件详解
第08课:Zuul 整合 OAuth 2 实现鉴权
第09课:配置中心及链路监控
第10课:Redis 高级技术点解析
第11课:ZooKeeper 高级技术点解析
第12课:分布式锁
第13课:分布式事务
第14课:微服务监控
第15课:Docker 架构及常用命令
第16课:容器管理 Rancher 平台架构
第17课:利用 K8S 搭建容器管理平台
第18课:微服务综合实战(上)
第19课:微服务综合实战(下)

阅读全文: http://gitbook.cn/gitchat/column/5b4fd439bf8ece6c81e44cfb

你可能感兴趣的:(微服务一站式开发)