写了一套优雅接口之后,领导让我给大家讲讲这背后的技术原理(上)

简介: Hello,各位小伙伴们,宣布一个好消息:咱们的公号终于有留言功能了!!!以后小伙们就可以在留言区留言跟阿粉一起交流咯~

上周文章年轻人不讲武德,竟然重构出这么优雅后台 API 接口我们使用  @ControllerAdviceResponseBodyAdvice 重构后端的 API 接口,降低了复杂度,减少了重复代码,后续接口开发非常简洁优雅。

知其然而知其所以然,今天这篇文章来聊聊这个注解背后的原理,让我们彻底掌握这个注解,避免后续踩坑。

另外,有个小伙伴看完上篇文章,觉得这个注解的跟 Spring Interceptor 功能很类似,再加上之前还学习了 Servlet 体系 Filter 功能,不知道这几个有什么区别,感觉很混乱。

所以今天这篇文章下面两个部分出发,详细解释一下。

  1. @ControllerAdviceResponseBodyAdvice  注解原理
  2. FilterInterceptorResponseBodyAdvice 区别

从源码解析背后的原理

上篇文章中我们看到 ResponseBodyAdvice的子类使用  @ControllerAdvice注解,大家有没有好奇,如果我将@ControllerAdvice换成 @Controller 注解,还能达到上篇文章的效果吗?

感兴趣的小伙伴可以自己尝试下,这里阿粉自己告诉大家结果了,实际测试结果是不行的。

那为什么一定要与@ControllerAdvice 搭配才会生效?

首先我们先查看一下 @ControllerAdvice 的源码:

20.jpg

image-20201128152447563

可以看到这个注解上还存在一个我们非常熟悉的 @Component 注解。这里我们可以将 @ControllerAdvice  理解成@Component 子类,所以其修饰的类也会成为 Spring 中 Bean

ps:大家可以看下 @Controller/@Service/@Repository,其实也是这个原理。

Spring 容器初始化过程,如果扫描到 @ControllerAdvice 注解,将会将其生成一个 ControllerAdviceBean Bean。

这个过程代码主要位于 RequestMappingHandlerAdapter#initControllerAdviceCache:

21.jpg

这段代码主要分为两步:

第一步使用 ControllerAdviceBean#findAnnotatedBeans获取所有被 @ControllerAdvice修饰的类。

22.jpg

第二步将所有实现了ResponseBodyAdvice 接口的 Bean 放入到 requestResponseBodyAdviceBeans 集合中,后续将会使用该集合。

24.jpg


相关文章
|
前端开发 API 数据安全/隐私保护
Web前端开发中的跨域资源共享(CORS)解决方案
【2月更文挑战第5天】在Web前端开发中,跨域资源共享(CORS)是一个常见的挑战。本文将探讨CORS的概念和原理,并介绍一些常用的解决方案,包括服务器端配置和前端处理方法,帮助开发者更好地应对跨域请求问题。
528 4
MapStruct - 生成空对象解决方案
MapStruct - 生成空对象解决方案
1880 0
|
Java 数据库连接 Spring
SpringBoot2 | BeanDefinition 注册核心类 ImportBeanDefinitionRegistrar 源码分析 (十)
SpringBoot2 | BeanDefinition 注册核心类 ImportBeanDefinitionRegistrar 源码分析 (十)
356 0
|
2月前
|
设计模式 算法 搜索推荐
Java 设计模式之策略模式:灵活切换算法的艺术
策略模式通过封装不同算法并实现灵活切换,将算法与使用解耦。以支付为例,微信、支付宝等支付方式作为独立策略,购物车根据选择调用对应支付逻辑,提升代码可维护性与扩展性,避免冗长条件判断,符合开闭原则。
391 35
|
9月前
|
Java 数据库 微服务
微服务——SpringBoot使用归纳——Spring Boot事务配置管理——事务相关
本文介绍Spring Boot事务配置管理,阐述事务在企业应用开发中的重要性。事务确保数据操作可靠,任一异常均可回滚至初始状态,如转账、购票等场景需全流程执行成功才算完成。同时,事务管理在Spring Boot的service层广泛应用,但根据实际需求也可能存在无需事务的情况,例如独立数据插入操作。
253 0
|
Java
Call to ‘super()‘ must be first statement in constructor body
文章解释了在Java中子类构造函数中调用父类构造函数时,必须首先调用`super()`,且不能有返回值。
219 0
Call to ‘super()‘ must be first statement in constructor body
|
前端开发 Java 调度
【JavaEE进阶】 拦截器(DispatcherServlet)源码简介
【JavaEE进阶】 拦截器(DispatcherServlet)源码简介
|
缓存 JavaScript 安全
MethodHandle方法句柄使用分享
JDK 1.7 引入了 `MethodHandle` 类,优化了之前的反射机制性能问题。`MethodHandle` 提供了一种更高效的方法调用机制,通过 `MethodType` 和 `Lookup` 对象实现。具体流程包括:创建 `MethodType` 获取方法签名,通过 `Lookup` 查找方法对应的 `MethodHandle`,最后调用方法。此外,通过 `ConstantCallSite` 进一步优化性能,利用其不变性特点减少运行时开销。实验结果显示,使用 `ConstantCallSite` 显著提升了方法调用速度。
262 3
MethodHandle方法句柄使用分享
|
设计模式
SpringMVC常见组件之DataBinder数据绑定器分析
SpringMVC常见组件之DataBinder数据绑定器分析
664 0
|
Java 关系型数据库 MySQL
1、Mybatis-Plus 创建SpringBoot项目
这篇文章是关于如何创建一个SpringBoot项目,包括在`pom.xml`文件中引入依赖、在`application.yml`文件中配置数据库连接,以及加入日志功能的详细步骤和示例代码。