Spring-MVC 源码分析--DispatcherServlet 初始化

文章目录

  • 前言
  • 一、DispatcherServlet 概念以及作用:
  • 二、请求分发器 HandleMapping :
    • 2.1 HandleMapping 的概念及其作用:
    • 2.2 HandleMapping 的三种默认实现
      • 2.2.1 HandleMapping 实现的时机:
      • 2.2.2 RequestMappingHandlerMapping作用 :
      • 2.2.3 BeanNameUrlHandlerMapping 作用:
      • 2.2.4 RouterFunctionMapping 作用:
  • 三、HandlerAdapter 介绍接作用 :
    • 3.1 HandlerAdapter 的作用:
    • 3.1 HandlerAdapter的几种默认实现:
      • 3.1.1 .HttpRequestHandlerAdapter
      • 3.1.2 .SimpleControllerHandlerAdapter
      • 3.1.3 .RequestMappingHandlerAdapter
      • 3.1.4 .HandlerFunctionAdapter
  • 总结


前言

我们知道一个http 请求到达服务端后是通过DispatcherServlet 进行请求的分发,而分发的逻辑具体就是要找到这个请求合适的HandleMapping 来处理,那么HandleMapping 是什么,它是怎么根据请求路径判断 哪个HandleMapping 来处理请求呢,HandleMapping 分发请求后,怎么完成对方法参数的解析,又是如何将方法的返回值给封装成浏览器需要的对象?


一、DispatcherServlet 概念以及作用:

DispatcherServlet 是 Spring MVC 框架的核心组件之一,它是一个前端控制器(Front Controller)。

DispatcherServlet 充当了统一的请求处理器和请求调度中心的角色。当一个 HTTP 请求发起到应用程序时,它首先被 DispatcherServlet 接收并处理。DispatcherServlet 根据请求的特征和配置的规则,将请求分配给合适的处理器来进行处理,并将处理结果返回给客户端。

DispatcherServlet 的主要功能包括:

  1. 请求的接收和解析:DispatcherServlet 接收并解析 HTTP 请求,包括请求的 URL、参数、头信息等。

  2. HandlerMapping:DispatcherServlet 使用一个或多个 HandlerMapping 来决定请求应该由哪个处理器来处理。HandlerMapping 根据请求的 URL 和其他条件,将请求映射到相应的处理器(即控制器)。

  3. HandlerAdapter:DispatcherServlet 使用一个或多个 HandlerAdapter 来适配不同类型的处理器。HandlerAdapter 将处理器适配成统一的处理器方法的调用方式,以便进行统一的处理和返回结果。

  4. 视图解析和渲染:DispatcherServlet 使用视图解析器(ViewResolver)来解析处理器返回的逻辑视图名,并将其渲染为最终的响应结果。可以是HTML、JSON、XML等不同格式的响应。

  5. 异常处理和错误页面:DispatcherServlet 提供了处理请求过程中发生的异常和错误的机制。它可以捕获并处理异常,并将错误信息渲染为指定的错误页面或其他响应。

通过配置和定制 DispatcherServlet,可以灵活地控制请求的处理流程,进行拦截、验证、权限控制等操作,从而实现灵活、可扩展的 Web 应用程序,通过对DispatcherServlet 初始化实际上就是对HandlerMapping ,HandlerAdapter 的初始化。

可见一个DispatcherServlet 的bean 完成了http 请求的全部流程,想要知晓它的工作情况,就需要对它内部的几个组件进行分析

二、请求分发器 HandleMapping :

2.1 HandleMapping 的概念及其作用:

在 Spring MVC 中,HandlerMapping 是用于决定请求的 URL 应该由哪个处理器(Handler)来处理的组件。

当 DispatcherServlet 接收到一个 HTTP 请求时,它会委托一个或多个 HandlerMapping 来找到适合处理该请求的处理器。它会遍历注册的 HandlerMapping 实现,根据配置和请求的特征来确定最匹配的处理器。

HandlerMapping 提供了多种实现,以适应不同的 URL 映射策略,常见的实现包括:

RequestMappingHandlerMapping:基于注解的 URL 映射,通过扫描带有@RequestMapping 注解的控制器(Handler)类和方法,将它们映射为请求路径。
SimpleUrlHandlerMapping:RouterFunctionMapping是Spring WebFlux框架中的一个关键组件,用于将HTTP请求映射到对应的处理器函数(Handler Function)。
BeanNameUrlHandlerMapping:将请求的 URL 与 bean 的名称进行映射。
通过配置多个 HandlerMapping,可以根据不同的 URL 映射策略来选择适合的处理器。在多个 HandlerMapping 都找不到适合的处理器时,可以根据配置选择做进一步的处理,如显示自定义的错误页面或返回特定的响应。

由此可见HandleMapping 主要功能就是通过对请求的路径解析,然后交由具体HandlerMapping 实现类完成处理的,但是平时我们在项目中,并没有自定义 HandlerMapping ,实际上spring-mvc 中有默认的HandlerMapping 实现可以让我们直接使用;

2.2 HandleMapping 的三种默认实现

2.2.1 HandleMapping 实现的时机:

DispatcherServlet的onRefresh方法在Spring容器刷新(refresh)的过程中被调用。具体的执行时机如下:

  • 当Spring容器启动时,会初始化并加载配置文件,创建并初始化各个bean,并完成依赖注入等操作。
  • 当Spring容器初始化完毕后,会调用DispatcherServlet的init方法进行初始化。
  • 在DispatcherServlet的init方法中,会调用父类FrameworkServlet的initServletBean方法。
  • 在initServletBean方法中,会调用onRefresh方法,用于处理Spring容器刷新的操作。
  • 在onRefresh方法中,会初始化并准备DispatcherServlet所需要的各个组件,包括HandlerMapping、HandlerAdapter、ViewResolver等。
  • 完成组件的初始化后,DispatcherServlet即可接收并处理请求。
  • 需要注意的是,onRefresh方法的执行时机是在Spring容器初始化完毕后,并在DispatcherServlet初始化的过程中调用的。在onRefresh方法执行之前,Spring容器已经完成了bean的创建和初始化操作。

DispatcherServlet 中的 onRefresh 方法:

protected void onRefresh(ApplicationContext context) {
this.initStrategies(context);
}protected void initStrategies(ApplicationContext context) {this.initMultipartResolver(context);this.initLocaleResolver(context);this.initThemeResolver(context);// HandlerMapping 的初始化this.initHandlerMappings(context);// HandlerAdapter的初始化this.initHandlerAdapters(context);this.initHandlerExceptionResolvers(context);this.initRequestToViewNameTranslator(context);this.initViewResolvers(context);this.initFlashMapManager(context);
}

接下来主要对HandlerMapping 默认的三种实现方式进行分析;

2.2.2 RequestMappingHandlerMapping作用 :

它主要是对 @RequestMapping 注解的解析,因为其父类AbstractHandlerMethodMapping 实现了InitializingBean 接口所以在对RequestMappingHandlerMapping 进行依赖注入完成后 会调用 afterPropertiesSet 方法

 public void afterPropertiesSet() {// 初始化一些类型的解析this.config = new RequestMappingInfo.BuilderConfiguration();this.config.setPatternParser(this.getPathPatternParser());this.config.setContentTypeResolver(this.getContentTypeResolver());// 扫描解析@RequestMapping super.afterPropertiesSet();
}

调用父类 AbstractHandlerMethodMapping 的 afterPropertiesSet 方法:

public void afterPropertiesSet() {this.initHandlerMethods();int total = this.getHandlerMethods().size();if (this.logger.isTraceEnabled() && total == 0 || this.logger.isDebugEnabled() && total > 0) {this.logger.debug(total + " mappings in " + this.formatMappingName());}}protected void initHandlerMethods() {// 获取spring 容器中所哟的beanString[] beanNames = this.obtainApplicationContext().getBeanNamesForType(Object.class);String[] var2 = beanNames;int var3 = beanNames.length;for(int var4 = 0; var4 < var3; ++var4) {String beanName = var2[var4];if (!beanName.startsWith("scopedTarget.")) {Class<?> beanType = null;// 遍历每个beantry {// 获取bean 的类型beanType = this.obtainApplicationContext().getType(beanName);} catch (Throwable var8) {if (this.logger.isTraceEnabled()) {this.logger.trace("Could not resolve type for bean '" + beanName + "'", var8);}}// 如果改bean 被 Controller 或者  RequestMapping 注解修饰 则为http 请求处理类if (beanType != null && this.isHandler(beanType)) {// 对类中的方法进行收集this.detectHandlerMethods(beanName);}}}this.handlerMethodsInitialized(this.getHandlerMethods());}

其中 this.isHandler 进行当前bean 的类的注解判断:

protected boolean isHandler(Class<?> beanType) {return AnnotatedElementUtils.hasAnnotation(beanType, Controller.class) || AnnotatedElementUtils.hasAnnotation(beanType, RequestMapping.class);
}

在看下对于类中方法的收集:

protected void detectHandlerMethods(final Object handler) {// 获取bean 的class 类型Class<?> handlerType = handler instanceof String ? this.obtainApplicationContext().getType((String)handler) : handler.getClass();if (handlerType != null) {Class<?> userType = ClassUtils.getUserClass(handlerType);// 获取到加了RequestMapping  注解的方法Map<Method, T> methods = MethodIntrospector.selectMethods(userType, (method) -> {return this.getMappingForMethod(method, userType);});if (this.logger.isTraceEnabled()) {this.logger.trace(this.formatMappings(userType, methods));} else if (this.mappingsLogger.isDebugEnabled()) {this.mappingsLogger.debug(this.formatMappings(userType, methods));}// 遍历方法 然后进行注册,方便后续 通过http 请求路径 来筛选 HandlerMappingmethods.forEach((method, mapping) -> {Method invocableMethod = AopUtils.selectInvocableMethod(method, userType);this.registerHandlerMethod(handler, invocableMethod, mapping);});}}

对于类中加了RequestMapping 注解方法的收集:

 @Nullableprotected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {// info 不为null 则说明增加了 RequestMapping   注解RequestMappingInfo info = this.createRequestMappingInfo(method);if (info != null) {//RequestMappingInfo typeInfo = this.createRequestMappingInfo(handlerType);if (typeInfo != null) {info = typeInfo.combine(info);}Iterator var5 = this.pathPrefixes.entrySet().iterator();while(var5.hasNext()) {Map.Entry<String, Predicate<Class<?>>> entry = (Map.Entry)var5.next();if (((Predicate)entry.getValue()).test(handlerType)) {String prefix = (String)entry.getKey();if (this.embeddedValueResolver != null) {prefix = this.embeddedValueResolver.resolveStringValue(prefix);}info = RequestMappingInfo.paths(new String[]{prefix}).options(this.config).build().combine(info);break;}}}return info;}

RequestMappingInfo info 对象的获取:

 @Nullable
private RequestMappingInfo createRequestMappingInfo(AnnotatedElement element) {// 获取到方法上的RequestMapping 注解对象RequestMapping requestMapping = (RequestMapping)AnnotatedElementUtils.findMergedAnnotation(element, RequestMapping.class);RequestCondition<?> condition = element instanceof Class ? this.getCustomTypeCondition((Class)element) : this.getCustomMethodCondition((Method)element);// 有RequestMapping  注解则封装为 RequestMappingInfo  返回,否则直接返回nullreturn requestMapping != null ? this.createRequestMappingInfo(requestMapping, condition) : null;
}

2.2.3 BeanNameUrlHandlerMapping 作用:

主要是对bean 的名称以"/" 的进行处理,其父类ApplicationObjectSupport 实现了ApplicationContextAware 接口所以在对BeanNameUrlHandlerMapping 进行初始化之后会调用initApplicationContext 方法:
AbstractDetectingUrlHandlerMapping 的initApplicationContext 方法

 public void initApplicationContext() throws ApplicationContextException {super.initApplicationContext();// 对bean 进行筛选this.detectHandlers();}protected void detectHandlers() throws BeansException {ApplicationContext applicationContext = this.obtainApplicationContext();// 获取spring 中所有的beanString[] beanNames = this.detectHandlersInAncestorContexts ? BeanFactoryUtils.beanNamesForTypeIncludingAncestors(applicationContext, Object.class) : applicationContext.getBeanNamesForType(Object.class);String[] var3 = beanNames;int var4 = beanNames.length;// 依次遍历for(int var5 = 0; var5 < var4; ++var5) {String beanName = var3[var5];// 如果bean 的名称 以 / 开头 则进行收集String[] urls = this.determineUrlsForHandler(beanName);if (!ObjectUtils.isEmpty(urls)) {// registerHandler 对筛选的bean 进行收集:this.registerHandler(urls, beanName);}}if (this.mappingsLogger.isDebugEnabled()) {this.mappingsLogger.debug(this.formatMappingName() + " " + this.getHandlerMap());} else if (this.logger.isDebugEnabled() && !this.getHandlerMap().isEmpty() || this.logger.isTraceEnabled()) {this.logger.debug("Detected " + this.getHandlerMap().size() + " mappings in " + this.formatMappingName());}}

determineUrlsForHandler 判断bean:BeanNameUrlHandlerMapping 下的determineUrlsForHandler

protected String[] determineUrlsForHandler(String beanName) {List<String> urls = new ArrayList();if (beanName.startsWith("/")) {// bean 的名称以  / 开头urls.add(beanName);}String[] aliases = this.obtainApplicationContext().getAliases(beanName);String[] var4 = aliases;int var5 = aliases.length;for(int var6 = 0; var6 < var5; ++var6) {String alias = var4[var6];if (alias.startsWith("/")) {urls.add(alias);}}return StringUtils.toStringArray(urls);
}

2.2.4 RouterFunctionMapping 作用:

主要 解析 Spring WebFlux 框架中通过RouterFunctions 中绑定关系的解析,因为RouterFunctionMapping 实现了InitializingBean 接口所以在完成对其依赖注入后会调用afterPropertiesSet 方法

public void afterPropertiesSet() throws Exception {if (CollectionUtils.isEmpty(this.messageReaders)) {ServerCodecConfigurer codecConfigurer = ServerCodecConfigurer.create();this.messageReaders = codecConfigurer.getReaders();}if (this.routerFunction == null) {// 收集routerFunction this.initRouterFunctions();}if (this.routerFunction != null) {RouterFunctions.changeParser(this.routerFunction, this.getPathPatternParser());}}

routerFunction 的收集


protected void initRouterFunctions() {// 获取所有的RouterFunction 类型的bean List<RouterFunction<?>> routerFunctions = this.routerFunctions();// 进行合并后赋值给routerFunction  属性 private RouterFunction<?> routerFunction;this.routerFunction = (RouterFunction)routerFunctions.stream().reduce(RouterFunction::andOther).orElse((Object)null);this.logRouterFunctions(routerFunctions);
}private List<RouterFunction<?>> routerFunctions() {return (List)this.obtainApplicationContext().getBeanProvider(RouterFunction.class).orderedStream().map((router) -> {return router;}).collect(Collectors.toList());
}

介绍完了HandlerMapping 的三种默认实现,接下来再来看下 另外一个组件HandlerAdapter;

三、HandlerAdapter 介绍接作用 :

3.1 HandlerAdapter 的作用:

HandlerAdapter 是 Spring MVC 框架中的一个关键组件,它的作用是将请求交给合适的处理器进行处理,并对处理结果进行适配,以便正确返回给客户端。

HandlerAdapter 的主要作用包括:

  1. 选择合适的处理器:根据请求的特征和配置的规则,HandlerAdapter 从多个处理器中选择合适的处理器来处理请求。例如,根据请求的URL路径、请求方法、请求参数等进行选择。

  2. 适配处理器的方法:不同的处理器(Controller)可能使用不同的处理方法来处理请求。HandlerAdapter负责将请求适配到处理器的特定方法,并调用该方法处理请求。HandlerAdapter 确保处理器方法的参数正确绑定到请求的数据和上下文信息上。

  3. 处理结果的适配:处理器方法执行完毕后,得到的处理结果可能是一个逻辑视图名、模型对象或者其他类型的对象。HandlerAdapter 负责将处理结果适配成对应的视图对象、响应格式等,以便返回给客户端。

  4. 异常处理:当处理器方法执行过程中发生异常时,HandlerAdapter 负责捕获和处理异常。它可以根据配置的异常处理策略,将异常信息适配成对应的错误响应,并正确返回给客户端。

通过适配不同类型的处理器和处理器方法,HandlerAdapter 将请求和处理器解耦,并提供统一的请求处理流程。它使得开发者可以更加专注于业务逻辑的编写,而无需关注请求的细节和适配处理。

HandlerAdapter 是 Spring MVC 框架中负责选择合适的处理器、适配处理方法并处理结果的关键组件,它实现了请求和处理器的解耦和适配,以实现统一的请求处理流程和结果返回。

HandlerAdapter 是 Spring MVC 框架中的一个关键组件,它的作用是将请求交给合适的处理器进行处理,并对处理结果进行适配,以便正确返回给客户端。

HandlerAdapter 的主要作用包括:

  1. 选择合适的处理器:根据请求的特征和配置的规则,HandlerAdapter 从多个处理器中选择合适的处理器来处理请求。例如,根据请求的URL路径、请求方法、请求参数等进行选择。

  2. 适配处理器的方法:不同的处理器(Controller)可能使用不同的处理方法来处理请求。HandlerAdapter负责将请求适配到处理器的特定方法,并调用该方法处理请求。HandlerAdapter 确保处理器方法的参数正确绑定到请求的数据和上下文信息上。

  3. 处理结果的适配:处理器方法执行完毕后,得到的处理结果可能是一个逻辑视图名、模型对象或者其他类型的对象。HandlerAdapter 负责将处理结果适配成对应的视图对象、响应格式等,以便返回给客户端。

  4. 异常处理:当处理器方法执行过程中发生异常时,HandlerAdapter 负责捕获和处理异常。它可以根据配置的异常处理策略,将异常信息适配成对应的错误响应,并正确返回给客户端。

通过适配不同类型的处理器和处理器方法,HandlerAdapter 将请求和处理器解耦,并提供统一的请求处理流程。它使得开发者可以更加专注于业务逻辑的编写,而无需关注请求的细节和适配处理。

HandlerAdapter 是 Spring MVC 框架中负责选择合适的处理器、适配处理方法并处理结果的关键组件,它实现了请求和处理器的解耦和适配,以实现统一的请求处理流程和结果返回。平常开发中我们也没有自定义 HandlerAdapter 的实现,使用的最多的还是spring-mvc 提供的几种默认实现,下面看下它的几种默认实现:

3.1 HandlerAdapter的几种默认实现:

3.1.1 .HttpRequestHandlerAdapter

HttpRequestHandlerAdapter:用于适配实现了HttpRequestHandler接口的处理器。HttpRequestHandler是一种比较底层的处理器类型,需要开发者自己实现处理逻辑。HttpRequestHandlerAdapter负责调用其handleRequest()方法执行逻辑。

3.1.2 .SimpleControllerHandlerAdapter

SimpleControllerHandlerAdapter:用于适配实现了Controller接口的处理器。Controller是一种较早版本的处理器类型,需要实现handleRequest()方法,返回一个ModelAndView对象。SimpleControllerHandlerAdapter将调用处理器的handleRequest()方法,并将其返回的ModelAndView适配成所需的视图结果。

3.1.3 .RequestMappingHandlerAdapter

RequestMappingHandlerAdapter:用于适配带有@RequestMapping注解的Controller类。它支持将请求参数绑定到方法参数、处理方法返回值的适配,并负责调用处理方法执行请求处理逻辑。

3.1.4 .HandlerFunctionAdapter

HandlerFunctionAdapter 是 Spring WebFlux 框架中的一个默认 HandlerAdapter 实现,用于适配 HandlerFunction。HandlerFunction 是一种用于处理请求的函数式接口,它接收一个 ServerRequest 对象,返回一个 Mono 对象,用于表示异步的响应结果。


总结

DispatcherServlet 的初始化主要是对请求分布的bean HandlerMapping 和负责请求参数解析,方法调用及方法返回值解析的HandlerAdapter 组成,后续的文章会分析 HandlerAdapter 对于请求方法的参数解析,方法的调用,以及返回值的包装返回;

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用小程序实现App灰度测试的好处

灰度测试&#xff08;Gray Testing&#xff09;是一种软件测试策略&#xff0c;也被称为渐进性测试或部分上线测试。在灰度测试中&#xff0c;新的软件版本或功能并非一次性推送给所有用户&#xff0c;而是仅在一小部分用户中进行测试。这可以帮助开发团队逐步暴露新功能或版本…

Linux Kernel KDB KGDB 实体机内核调试

内核编译配置 CONFIG_DEBUG_INFOy # 编译debug infoCONFIG_MAGIC_SYSRQy # 功能编译开关 CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE0x1 # 默认开启项 默认存在 /proc/sysrq-trigger CONFIG_MAGIC_SYSRQ_SERIALy # 串行sysrq &…

vscode如何开发微信小程序?(保姆级教学)

1.安装“微信小程序开发工具”扩展 2.安装“vscode weapp api”扩展 3.安装“vscode wxml”扩展 4.安装“vscode-wechat”扩展 5.在终端执行命令&#xff1a; vue create -p dcloudio/uni-preset-vue uniapp-test uniapp-test就是我这里的项目名称了 6.如果遇到了这个错误&a…

KBU1010-ASEMI功率整流器件KBU1010

编辑&#xff1a;ll KBU1010-ASEMI功率整流器件KBU1010 型号&#xff1a;KBU1010 品牌&#xff1a;ASEMI 封装&#xff1a;KBU-4 特性&#xff1a;插件、整流桥 最大平均正向电流&#xff1a;10A 最大重复峰值反向电压&#xff1a;1000V 恢复时间&#xff1a;&#xff…

C++多态(2) ——抽象类与final、override关键字

C多态(2) ——抽象类与final、override关键字_c class final-CSDN博客

紫光展锐T820与飞桨完成I级兼容性测试 助推端侧AI融合创新

近日&#xff0c;紫光展锐高性能5G SoC T820与百度飞桨完成I级兼容性测试&#xff08;基于Paddle Lite工具&#xff09;。测试结果显示&#xff0c;双方兼容性表现良好&#xff0c;整体运行稳定。这是紫光展锐加入百度“硬件生态共创计划”后的阶段性成果。 本次I级兼容性测试完…

Vue 条件渲染 v-if

v-if 指令&#xff1a;用于控制元素的显示或隐藏。 执行条件&#xff1a;当条件为 false 时&#xff0c;会将元素从 DOM 中删除。 应用场景&#xff1a;适用于显示隐藏切换频率较低的场景。 语法格式&#xff1a; <div v-if"数据">内容</div> 基础用…

ros2 学习03-开发工具vscode 插件配置

VSCode插件配置 为了便于后续ROS2的开发与调试&#xff0c;我们还可以安装一系列插件&#xff0c;无限扩展VSCode的功能。 中文语言包 Python插件 C插件 CMake插件 vscode-icons ROS插件 Msg Language Support Visual Studio IntelliCode URDF Markdown All in One VSCode支持的…

技术探秘:在RISC Zero中验证FHE——由隐藏到证明:FHE验证的ZK路径(1)

1. 引言 开源代码实现见&#xff1a; https://github.com/hashcloak/fhe_risc0_zkvm&#xff08;Rust&#xff09;https://github.com/weikengchen/vfhe-profiled&#xff08;Rust&#xff09;https://github.com/l2iterative/vfhe0&#xff08;Rust&#xff09; L2IV Resea…

两点云相减并保存结果的C++代码实现

C中实现两个点云相减并保存相减结果&#xff0c;可以使用点云库&#xff08;PCL, Point Cloud Library&#xff09;。代码示例展示了如何进行点云相减&#xff0c;并将结果保存为一个新的点云文件。 这个例子使用了PCL中的pcl::KdTreeFLANN来查找一个点云中的点在另一个点云中…

虚拟磁盘扩容

看了acrn内部的磁盘制作、扩容脚本,学习一下 #!/bin/bash # Copyright (C) 2020-2022 Intel Corporation. # SPDX-License-Identifier: BSD-3-Clausebuild_dir="$PWD/build" cloud_image="${build_dir}/focal-server-cloudimg-amd64.img" cloud_image_ur…

基于AT89C52单片机的计算器设计与仿真

点击链接获取Keil源码与Project Backups仿真图&#xff1a; https://download.csdn.net/download/qq_64505944/88637995?spm1001.2014.3001.5503 源码获取 B 源码仿真图课程设计51 摘 要 计算器一般是指“电子计算器”,能进行数学运算的手持机器&#xff0c;拥有集成电路芯…

整合SpringSecurity

目录 前言 数据库设计 用户表 角色表 用户角色表 权限表 角色权限表 插入数据 表的实体类 用户表实体类 角色表实体类 权限表实体类 mapper层接口 UserMapper RoleMapper AuthorityMapper 封装登录信息 统一响应结果 上下文相关类 jwt令牌工具类 依赖导入…

2023.12.17 关于 Redis 的特性和应用场景

目录 引言 Redis 特性 内存中存储数据 可编程性 可扩展性 持久化 支持集群 高可用性 Redis 优势 Redis 用作数据库 Redis 相较于 MySQL 优势 Redis 相较于 MySQL 劣势 Redis 用作缓存 典型场景 Redis 存储 session 信息 Redis 用作消息队列 初心 消息队列的…

Skywalking系列之最新版9.2.0-JavaAgent本地构建

MAC 10.15.7IDEA 2021.2skywalking-agent 9.2.0-SNAPSHOTJDK 17/21 (最新的代码要看最新的要求&#xff0c;注意不能使用JDK8&#xff0c;会构建失败)Maven 3.6.0 关于本地构建JavaAgent源码 1、获取源码&#xff0c;加载submodule 分步执行&#xff1a; git clone https:/…

智能优化算法应用:基于适应度相关算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于适应度相关算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于适应度相关算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.适应度相关算法4.实验参数设定5.算法…

构建高效统一的音视频联动融合通信调度平台

在信息技术日益高度发展的今天&#xff0c;越来越多的企业或者组织机构重视如何提高内外部的工作效率&#xff0c;但由于传统的通信方式如电话、邮件、短信、传真等方式无法满足企业高效、快速的沟通要求&#xff0c;因此需要一个可以将各种通信方式结合在一起的通信系统来满足…

动态规划 - 740. 删除并获得点数(C#和C实现)

动态规划 - 740. 删除并获得点数(C#和C实现) 题目描述 给你一个整数数组 nums &#xff0c;你可以对它进行一些操作。 每次操作中&#xff0c;选择任意一个 nums[i] &#xff0c;删除它并获得 nums[i] 的点数。之后&#xff0c;你必须删除每个等于 nums[i] - 1 或 nums[i] …

驭见大模型 智领新征程丨泰迪智能科技荣登2023年度广东省人工智能应用项目风云榜

12月15日&#xff0c;由广东省科学技术厅、广东省工业和信息化厅、广东省人力资源和社会保障厅、广东省政务服务数据管理局、广东省科学技术协会指导&#xff0c;广东省人工智能产业协会主办的2023年粤港澳大湾区人工智能产业大会正式举办&#xff0c;大会以“驭见大模型、智领…

静态独享专线IP怎么设置?使用静态IP怎么上网

随着互联网的普及和发展&#xff0c;越来越多的人开始使用电脑上网。在上网的过程中&#xff0c;IP地址是每个设备与互联网连接的唯一标识。而静态IP地址则是指固定不变的IP地址&#xff0c;它可以让您的电脑在每次连接互联网时都能够获得相同的IP地址&#xff0c;这对于一些需…