@Service代替@Controller注解来标注到控制层的场景?

在SpringBoot开发中,@Controller@Service基本上是日常开发中使用的最频繁的两个注解。但你有没考虑过@Service代替@Controller注解来标注到控制层的场景?换言之,经过@Service标注的控制层能否实现将用户请求分发到服务层的功能?

前言

在SpringBoot开发中,@Controller注解用于标识一个控制器类,该类负责处理Web请求。而控制器类通常包含若干个方法,每个方法对应一个HTTP请求的处理逻辑。而控制器是MVC(Model-View-Controller)架构的一部分,其主要负责将用户请求分发到适当的服务层,并返回视图或响应数据。而@Service注解用于标识一个服务类,用以负责处理业务逻辑和与数据访问层交互。

相信对于大多数Java开发者来说@Controller@Service注解的使用都不算太难。但进一步,用@Service标注控制层能否达到和@Controller注解相同的功能呢?对于这个操作你可能会觉得很疯狂,并下意识的说出不可能。但事实果真如此吗?我们不妨先通过一个简单的例子来验证一下。

@Sercice代替@Controller

我们首先自定义一个ServiceController的控制层,其内部通过Autowired注解注入一个UserMapper,并通过userMapper来实现控制层与数据层的交互。具体代码如下:

ServiceController
@Service
@RequestMapping("/ts")
public class ServiceController {@Autowiredprivate UserMapper userMapper;@GetMapping("get-services")@ResponseBodypublic User getServices() {User user = userMapper.selectOne(Wrappers.lambdaQuery(User.class).eq(User::getUsername, "zhangSan"));return user;}
}

然后,通过PostMan发送一个Get请求,以请求 http://localhost:8080/ts/get-services 其返回内容如下 :

Date: Sun, 21 Jul 2024 02:37:39 GMT
Keep-Alive: timeout=60
Connection: keep-alive{"username": "zhangSan","id": 1,"type": null,"remark": "test1"
}

通过返回内容,不难看出我们的请求顺利到ServiceControllergetServices方法。也就是说我们完全可以用@Service来替代@Controller标注在控制层上!

揭秘背后原理

你可能会觉得@Service来替代@Controller这样的操作有的反常规,因为在学习SpringBoot时,从来也没有那个教程告诉我们@Service注解还有这样的骚操作。那@Service可以这样使用的背后原因到底是什么呢?

众所周知,@Service@Controller注解都能被Spring容器所加载,并注入到Spring容器中。我们以SpringBoot应用为例来分析其注入容器的全过程。

在分析之前我们首先明确一点,对于Spring而言其会根据配置(如 XML 文件或 @ComponentScan 注解)扫描指定的包及其子包,查找标记有 @Controller@Service@Repository@Component 的类。但对于Springboot应用而言,其并没有显示的使用XmL配置或@ComponentScan指定扫描路径的方式来加载对应路径下的Bean信息。

这背后的原因主要在于@SpringBootApplication 注解的使用,@SpringBootApplication其实是一个组合注解,其内部包括以下三个注解:

  • @EnableAutoConfiguration: 启用 Spring Boot 的自动配置机制。

  • @ComponentScan: 启用组件扫描,以便自动发现并注册 Spring 组件。

  • @Configuration: 表示这是一个 Spring 配置类。

在默认情况下,Spring Boot 会从主应用类所在的包开始进行组件扫描,这意味着只要 @Controller@Service 注解的类位于主应用类所在包及其子包中,它们就会被自动发现并注册到 Spring 容器中。

明白了SpringBoot对于Bean的加载逻辑后,我们再来深入到其内部来看。SpringBoot对于这部分Bean的加载流程如图所示:

当我们在main方法中执行SpringApplication.run时,其在run方法内容会完成Spring容器的创建,以及Bean的加载。具体来看,其在AbstractApplicationContext中的invokeBeanPostBeanFactoryPostProcessore时,会通过 ConfigurationClassPostProcessorpostProcessBeanDefinitionRegistry 方法加载路径下所有的bean名称信息,然后在finshBeanFactoryInitialization完成bean的实例化。而我们绕了这么一大圈就是皆在说明,被@Service@Controller所标注的类在SpringBoot框架中是如何一步步被注入到容器的。

进一步,笔者曾在揭秘@Controller内部方法与URL绑定的全流程中谈到,对于控制层内的方法,其会在AbstractHandlerMethodMapping中的 afterPropertiesSet()完成请求url与方法的映射绑定。更进一步,afterPropertiesSet的处理逻辑全部委托于于 getCandidateBeanNamesprocessCandidateBean两个方法。

getCandidateBeanNames 会获取当前容器中所有的bean 的名称集合,并筛选类中标有@Controller或者 @RequestMapping注解的类交给processCandidateBean处理,以完成请求url与方法的映射。

此时,我们不妨来回看我们一开始的ServiceController的样例代码:

@Service
@RequestMapping("/ts")
public class ServiceController {// ....省略内部细节信息
}

不难发现,其虽然没使用@Controller修饰,但其却被@RequestMapping注解信息,也就是说其能被processCandidateBean所处理,进而其也就能完成url和方法映射关系的维护。更进一步,当请求至DispatcherServlet时,SpringMVC变更通过其url信息,找到能处理相应请求的HandlerMethod。从而也就能完成url的处理以及视图的渲染。

事实上,只要你能确保Bean信息注入到容器,并且类信息上至少有@Controller或者 @RequestMapping注解,那便能在AbstractHandlerMethodMapping中所解析,然后完成url与方法的绑定!这也就是为什么我们一开始花费精力研究@Controller@Service 注入容器的原因。

总结

在 SpringBoot 开发中,@Controller@Service 是最常用的注解。通常,@Controller 用于标识控制器类,处理 Web 请求并将请求分发到服务层;而 @Service 用于标识服务类,处理业务逻辑。然而,如果用 @Service 来标注控制层是否可以实现与 @Controller 相同的功能呢?

答案是肯定的。只要类被 @Service 标注,并且包含 @RequestMapping 等注解,Spring Boot 依然能够将其作为控制器来处理请求并返回响应。这背后的原理在于 @Service@Controller 都能被 Spring 容器加载和注册,并且 @RequestMapping 注解能够使类的方法与 URL 映射,从而实现请求处理功能。

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

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

相关文章

【斯坦福CS144】Lab5

一、实验目的 在现有的NetworkInterface基础上实现一个IP路由器。 二、实验内容 在本实验中,你将在现有的NetworkInterface基础上实现一个IP路由器,从而结束本课程。路由器有几个网络接口,可以在其中任何一个接口上接收互联网数据报。路由…

搜狗翻译体验,2024四大翻译工具解析!

为了满足广大用户的需求,市面上涌现出了众多优秀的翻译工具,福昕在线翻译、福昕翻译客户端、海鲸AI翻译、搜狗翻译等。今天,我们就来对比一下这些翻译工具,看看它们各自的特点和优势。 福昕在线翻译:专业精准&#xf…

高效开发,低代码平台如何助力构建内部工具

Zoho Creator是低代码平台,助力快速构建内部工具,如审批、订单、销售管理等,提升生产力、客户满意度,并减轻管理负担。平台提供拖放界面、集成数据库等功能,入选Gartner低代码平台“魔力象限”。 一、什么是内部工具&a…

虚拟机没有网络怎么解决

CentOS7为例 进入虚拟网络编辑器 1.更改设置 2.选中NAT模式点击3点击移除网络 4添加网络,随便选一个 5.点开NAT设置,记住网关 6.DHCP设置,注意虚拟机设置ip必须在起始ip和结束ip范围内 进入虚拟机网络适配器,自定义选中第4步操作…

五、Python基础语法(程序的输入和输出)

一、输入 输入:输入就是获取键盘输入的数据,使用input()函数。代码会从上往下执行,当遇到input()函数,就会暂停执行,输入内容后,敲回车键,表示本次的输入结束。input函数得到的数据类型都是字符…

python none代表什么

python中None代表一个特殊的空值,即为一个空对象,没有任何的值。 一般用于assert,判断,函数无返回时的默认,具体如下: 1、assert断言: mylist [a, b, c] >>> assert len(mylist) is…

用包目录结构Python脚本,简陋而强大

模块清晰易于管理,模块代码以*.py脚本呈现,方便维护和扩展。 (笔记模板由python脚本于2024年10月09日 18:21:52创建,本篇笔记适合喜欢Python和编程的coder翻阅) 【学习的细节是欢悦的历程】 Python 官网:https://www.python.org/ …

java内存控制

Java 内存控制是一个相对复杂但至关重要的主题,它涉及到如何高效地管理Java应用程序中的内存资源。在Java中,内存管理主要由Java虚拟机(JVM)负责,包括内存的分配和回收。尽管如此,作为开发者,我…

Kali Linux中安装配置影音资源下载神器Amule

一、Debian系列Linux安装amule命令: sudo apt update sudo apt-get install amule amule-utils 二、配置Amule的要点: 1、首次运行Amule,提示是否下载服务器列表,点击是。 2、搜索选项的类型选择全球,类型的默认选项…

openwrt 配置4G网卡 simcom7600ce

文章目录 概述配置并烧录系统,实现识别4G模组编译选项配置修改usb的option.c文件编译源码,烧录固件 配置4G模组成为网卡设置4G模组驱动参数模组拨号添加网卡接口ping百度验证网络 开机启动脚本 概述 在mt7628芯片上,操作系统使用openwrt21.0…

每日OJ题_牛客_AB13【模板】拓扑排序_C++_Java

目录 牛客_AB13【模板】拓扑排序 题目解析 C代码 Java代码 牛客_AB13【模板】拓扑排序 【模板】拓扑排序_牛客题霸_牛客网 (nowcoder.com) 描述: 给定一个包含nn个点mm条边的有向无环图,求出该图的拓扑序。若图的拓扑序不唯一,输出任意合法…

【C++】面向对象之继承

不要否定过去,也不要用过去牵扯未来。不是因为有希望才去努力,而是努力了,才能看到希望。💓💓💓 目录 ✨说在前面 🍋知识点一:继承的概念及定义 •🌰1.继承的概念 •&…

小赢卡贷公益行:乡村振兴与多元公益并进

在金融科技的浪潮中,小赢卡贷不仅以其创新的金融产品和服务赢得了市场的广泛认可,更以其背后的公益之心,积极履行社会责任,传递着温暖与希望。小赢公益基金会,作为小赢卡贷社会责任的延伸,主要聚焦于乡村振…

衡石分析平台系统管理手册-智能运维之系统设置

系统设置​ HENGSHI 系统设置中展示了系统运行时的一些参数,包括主程序相关信息,Base URL、HTTP 代理、图表数据缓存周期、数据集缓存大小、租户引擎等相关信息。 主程序​ 系统设置中展示了主程序相关信息,这些信息是系统自动生成的&#…

springboot宿舍管理-计算机毕业设计源码40740

摘要 宿舍管理系统作为一种利用信息技术改善学生住宿管理的工具,在大学宿舍管理中具有重要的实际意义。本文通过对国内外研究现状的调查和总结,探讨了宿舍管理系统的论文主题、研究背景、研究目的、研究意义以及主要研究内容。 首先,宿舍管理…

心觉:购物选择困难症! 为什么你总是挑不出“最完美”的商品?

Hi,我是心觉,与你一起玩转潜意识、脑波音乐和吸引力法则,轻松掌控自己的人生! 挑战每日一省写作194/1000天 你有没有遇到过这样一种情况:打算买一款新的电子产品、家具或者衣服 但在网上和实体店翻来覆去&#xff0…

编译链接的过程发生了什么?

一:程序的翻译环境和执行环境 在 ANSI C 的任何一种实现中,存在两个不同的环境。 第 1 种是翻译环境,在这个环境中源代码被转换为可执行的机器指令。 第 2 种是执行环境,它用于实际执行代码 也就是说:↓ 1&#xff1…

ai免费写论文是原创吗?分享5款ai写作免费一键生成助手

在当今的学术研究和写作领域,AI技术的应用越来越广泛,尤其是在论文写作方面。许多AI写作工具声称能够一键生成高质量的论文,并且保证原创性。然而,这些工具是否真的能生成完全原创的论文,仍然是一个值得探讨的问题。 …

【动态规划-最长递增子序列(LIS)】【hard】力扣1671. 得到山形数组的最少删除次数

我们定义 arr 是 山形数组 当且仅当它满足&#xff1a; arr.length > 3 存在某个下标 i &#xff08;从 0 开始&#xff09; 满足 0 < i < arr.length - 1 且&#xff1a; arr[0] < arr[1] < … < arr[i - 1] < arr[i] arr[i] > arr[i 1] > … &g…

掌握甘特图,没有Excel也能轻松制作的技巧

甘特图是项目管理中常用工具&#xff0c;由亨利甘特发明。不擅长Excel者可用ZohoProjects等软件创建甘特图&#xff0c;其直观展示项目时间和任务&#xff0c;支持实时协作、工时管理等功能&#xff0c;广泛应用于各领域项目管理。 一、甘特图的由来 甘特图最初是由工程师和管…