Spring @RequestMapping 工作原理

Spring @RequestMapping 工作原理

配置基础启动类及Controller类

@SpringBootApplication
public class DemoServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoServiceApplication.class, args);
    }
}
@RestController
public class HelloController {

    @PatchMapping("/hello")
    // above statement is a shortcut for below statement
    // @RequestMapping(value = "/hello", method = RequestMethod.PATCH)
    public ResponseData hello() {
        return ResponseData.success(null);
    }

    @PutMapping ("/hello")
	// above statement is a shortcut for below statement
	// @RequestMapping(value = "/hello", method = RequestMethod.PUT)
    public ResponseData hello2() {
        return ResponseData.success(null);
    }
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@RequestMapping(method = RequestMethod.PATCH)
public @interface PatchMapping {
	// ...
}

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@RequestMapping(method = RequestMethod.PUT)
public @interface PutMapping {
	// ...
}

请求验证

$ curl -X PUT http://localhost:8080/hello

在这里插入图片描述

package jakarta.servlet.http;

public abstract class HttpServlet extends GenericServlet {
	// ...
	
	/**
	 * Dispatches client requests to the protected service method. There's no need to override this method.
	 * ...
	 */
    @Override
    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {

        HttpServletRequest request;
        HttpServletResponse response;

        try {
            request = (HttpServletRequest) req;
            response = (HttpServletResponse) res;
        } catch (ClassCastException e) {
            throw new ServletException(lStrings.getString("http.non_http"));
        }
        service(request, response);
    }
    
    // ...
    
	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        String method = req.getMethod();

        if (method.equals(METHOD_GET)) {
        	// ..
	        doGet(req, resp);
            // ...
        } else if (method.equals(METHOD_HEAD)) {
        	// ..
	        doHead(req, resp);
        } else if (method.equals(METHOD_POST)) {
            doPost(req, resp);
        } else if (method.equals(METHOD_PUT)) {
            doPut(req, resp);
        } else if (method.equals(METHOD_DELETE)) {
            doDelete(req, resp);
        } else if (method.equals(METHOD_OPTIONS)) {
            doOptions(req, resp);
        } else if (method.equals(METHOD_TRACE)) {
            doTrace(req, resp);
        } else {
            // Note that this means NO servlet supports whatever
            // method was requested, anywhere on this server.
        }
    }
    // ...
}
package org.springframework.web.servlet;

public abstract class HttpServletBean extends HttpServlet implements EnvironmentCapable, EnvironmentAware {
	// ...
	// no override service(), subclass `FrameworkServlet` will implement this method
	// ...
}
package org.springframework.web.servlet;

public abstract class FrameworkServlet extends HttpServletBean implements ApplicationContextAware {

	// ...
	private static final Set<String> HTTP_SERVLET_METHODS =
			Set.of("DELETE", "HEAD", "GET", "OPTIONS", "POST", "PUT", "TRACE");
	// ...
	
	/**
	 * Override the parent class implementation in order to intercept requests
	 * using PATCH or non-standard HTTP methods (WebDAV).
	 */
	@Override
	protected void service(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		if (HTTP_SERVLET_METHODS.contains(request.getMethod())) {
			super.service(request, response);
		} // PATCH is missing, so process will go here
		else {
			processRequest(request, response);
		}
	}
	// ...

	@Override
	protected final void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		processRequest(request, response);
	}

	/**
	 * Delegate POST requests to {@link #processRequest}.
	 * @see #doService
	 */
	@Override
	protected final void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		processRequest(request, response);
	}

	/**
	 * Delegate PUT requests to {@link #processRequest}.
	 * @see #doService
	 */
	@Override
	protected final void doPut(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		processRequest(request, response);
	}

	/**
	 * Delegate DELETE requests to {@link #processRequest}.
	 * @see #doService
	 */
	@Override
	protected final void doDelete(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		processRequest(request, response);
	}

	/**
	 * Delegate OPTIONS requests to {@link #processRequest}, if desired.
	 * <p>Applies HttpServlet's standard OPTIONS processing otherwise,
	 * and also if there is still no 'Allow' header set after dispatching.
	 * @see #doService
	 */
	@Override
	protected void doOptions(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		if (this.dispatchOptionsRequest || CorsUtils.isPreFlightRequest(request)) {
			processRequest(request, response);
			if (response.containsHeader(HttpHeaders.ALLOW)) {
				// Proper OPTIONS response coming from a handler - we're done.
				return;
			}
		}

		// Use response wrapper in order to always add PATCH to the allowed methods
		super.doOptions(request, new HttpServletResponseWrapper(response) {
			@Override
			public void setHeader(String name, String value) {
				if (HttpHeaders.ALLOW.equals(name)) {
					value = (StringUtils.hasLength(value) ? value + ", " : "") + HttpMethod.PATCH.name();
				}
				super.setHeader(name, value);
			}
		});
	}

	/**
	 * Delegate TRACE requests to {@link #processRequest}, if desired.
	 * <p>Applies HttpServlet's standard TRACE processing otherwise.
	 * @see #doService
	 */
	@Override
	protected void doTrace(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		if (this.dispatchTraceRequest) {
			processRequest(request, response);
			if ("message/http".equals(response.getContentType())) {
				// Proper TRACE response coming from a handler - we're done.
				return;
			}
		}
		super.doTrace(request, response);
	}

	/**
	 * Process this request, publishing an event regardless of the outcome.
	 * <p>The actual event handling is performed by the abstract
	 * {@link #doService} template method.
	 */
	protected final void processRequest(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		long startTime = System.currentTimeMillis();
		Throwable failureCause = null;

		LocaleContext previousLocaleContext = LocaleContextHolder.getLocaleContext();
		LocaleContext localeContext = buildLocaleContext(request);

		RequestAttributes previousAttributes = RequestContextHolder.getRequestAttributes();
		ServletRequestAttributes requestAttributes = buildRequestAttributes(request, response, previousAttributes);

		WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
		asyncManager.registerCallableInterceptor(FrameworkServlet.class.getName(), new RequestBindingInterceptor());

		initContextHolders(request, localeContext, requestAttributes);

		try {
			doService(request, response);
		}
		catch (ServletException | IOException ex) {
			failureCause = ex;
			throw ex;
		}
		catch (Throwable ex) {
			failureCause = ex;
			throw new ServletException("Request processing failed: " + ex, ex);
		}

		finally {
			resetContextHolders(request, previousLocaleContext, previousAttributes);
			if (requestAttributes != null) {
				requestAttributes.requestCompleted();
			}
			logResult(request, response, failureCause, asyncManager);
			publishRequestHandledEvent(request, response, startTime, failureCause);
		}
	}
	
	// ...
	protected abstract void doService(HttpServletRequest request, HttpServletResponse response) throws Exception;
	// ...
}
package org.springframework.web.servlet;

public class DispatcherServlet extends FrameworkServlet {
	// ...
	@Override
	protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
		// ...
		try {
			doDispatch(request, response);
		}
		finally {
			// ...
		}
		// ...
	}
	
	// ...
	
	/**
	 * Process the actual dispatching to the handler.
	 * The handler will be obtained by applying the servlet's HandlerMappings in order. 
	 * The HandlerAdapter will be obtained by querying the servlet's installed HandlerAdapters to find the first that supports the handler class. 
	 * All HTTP methods are handled by this method. It's up to HandlerAdapters or handlers themselves to decide which methods are acceptable.
	 */	 
	@SuppressWarnings("deprecation")
	protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
		// ...
		try {
		// ...
			try {
				// ...
				// Determine handler for the current request.
				// important here
				mappedHandler = getHandler(processedRequest);
				// ...
				// Determine handler adapter for the current request.
				HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
				// ...
				// Actually invoke the handler.
				mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

				if (asyncManager.isConcurrentHandlingStarted()) {
					return;
				}

				applyDefaultViewName(processedRequest, mv);
				mappedHandler.applyPostHandle(processedRequest, response, mv);
			}
			// catch()
		} 
		//catch()
	}
	
	// ...
	
	/**
	 * Return the HandlerExecutionChain for this request.
	 * <p>Tries all handler mappings in order.
	 */
	@Nullable
	protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
		if (this.handlerMappings != null) {
			for (HandlerMapping mapping : this.handlerMappings) {
				HandlerExecutionChain handler = mapping.getHandler(request);
				if (handler != null) {
					return handler;
				}
			}
		}
		return null;
	}

	// ...
}		
this.handlerMappings = {ArrayList@7649}  size = 5
	 0 = {RequestMappingHandlerMapping@6913} 
	 1 = {BeanNameUrlHandlerMapping@7828} 
	 2 = {RouterFunctionMapping@7829} 
	 3 = {SimpleUrlHandlerMapping@7830} 
	 4 = {WelcomePageHandlerMapping@7831} 

展开 0 = {RequestMappingHandlerMapping@6913}

 mappingRegistry = {AbstractHandlerMethodMapping$MappingRegistry@6921} 
	 registry = {HashMap@7840}  size = 5
		  {RequestMappingInfo@7864} "{GET [/api/tutorials]}" -> {AbstractHandlerMethodMapping$MappingRegistration@7865} 
		  {RequestMappingInfo@7866} "{ [/error], produces [text/html]}" -> {AbstractHandlerMethodMapping$MappingRegistration@7867} 
		  {RequestMappingInfo@7868} "{PATCH [/hello]}" -> {AbstractHandlerMethodMapping$MappingRegistration@7869} 
		  {RequestMappingInfo@7870} "{ [/error]}" -> {AbstractHandlerMethodMapping$MappingRegistration@7871} 
		  {RequestMappingInfo@7872} "{PUT [/hello]}" -> {AbstractHandlerMethodMapping$MappingRegistration@7873} 
	 pathLookup = {LinkedMultiValueMap@7841}  size = 3
		  "/api/tutorials" -> {ArrayList@7852}  size = 1
		  "/hello" -> {ArrayList@7854}  size = 2
		  "/error" -> {ArrayList@7856}  size = 2

在这里插入图片描述

package org.springframework.web.servlet.handler;

public abstract class AbstractHandlerMapping extends WebApplicationObjectSupport
		implements HandlerMapping, Ordered, BeanNameAware {
	// ...
	
	/**
	 * Look up a handler for the given request, falling back to the default
	 * handler if no specific one is found.
	 * @param request current HTTP request
	 * @return the corresponding handler instance, or the default handler
	 * @see #getHandlerInternal
	 */
	@Override
	@Nullable
	public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
		Object handler = getHandlerzInternal(request);
		if (handler == null) {
			handler = getDefaultHandler();
		}
		if (handler == null) {
			return null;
		}
		// Bean name or resolved handler?
		if (handler instanceof String handlerName) {
			handler = obtainApplicationContext().getBean(handlerName);
		}

		// Ensure presence of cached lookupPath for interceptors and others
		if (!ServletRequestPathUtils.hasCachedPath(request)) {
			initLookupPath(request);
		}

		HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);

		if (logger.isTraceEnabled()) {
			logger.trace("Mapped to " + handler);
		}
		else if (logger.isDebugEnabled() && !DispatcherType.ASYNC.equals(request.getDispatcherType())) {
			logger.debug("Mapped to " + executionChain.getHandler());
		}

		if (hasCorsConfigurationSource(handler) || CorsUtils.isPreFlightRequest(request)) {
			CorsConfiguration config = getCorsConfiguration(handler, request);
			if (getCorsConfigurationSource() != null) {
				CorsConfiguration globalConfig = getCorsConfigurationSource().getCorsConfiguration(request);
				config = (globalConfig != null ? globalConfig.combine(config) : config);
			}
			if (config != null) {
				config.validateAllowCredentials();
			}
			executionChain = getCorsHandlerExecutionChain(request, executionChain, config);
		}

		return executionChain;
	}

	// ...
}
package org.springframework.web.servlet.mvc.method;
public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMethodMapping<RequestMappingInfo> {
	// ..
	
	@Override
	@Nullable
	protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
		// ...
		return super.getHandlerInternal(request);
		// ...
	}
	
	// ...	
}
package org.springframework.web.servlet.handler;

public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMapping implements InitializingBean {
	// ...
	
	@Override
	@Nullable
	protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
		String lookupPath = initLookupPath(request);
		this.mappingRegistry.acquireReadLock();
		try {
			HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);
			return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null);
		}
		finally {
			this.mappingRegistry.releaseReadLock();
		}
	}
	// ...

	@Nullable
	protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {
		List<Match> matches = new ArrayList<>();
		List<T> directPathMatches = this.mappingRegistry.getMappingsByDirectPath(lookupPath);
		if (directPathMatches != null) {
			addMatchingMappings(directPathMatches, matches, request);
		}
		if (matches.isEmpty()) {
			addMatchingMappings(this.mappingRegistry.getRegistrations().keySet(), matches, request);
		}
		if (!matches.isEmpty()) {
			Match bestMatch = matches.get(0);
			if (matches.size() > 1) {
				Comparator<Match> comparator = new MatchComparator(getMappingComparator(request));
				matches.sort(comparator);
				bestMatch = matches.get(0);
				if (logger.isTraceEnabled()) {
					logger.trace(matches.size() + " matching mappings: " + matches);
				}
				if (CorsUtils.isPreFlightRequest(request)) {
					for (Match match : matches) {
						if (match.hasCorsConfig()) {
							return PREFLIGHT_AMBIGUOUS_MATCH;
						}
					}
				}
				else {
					Match secondBestMatch = matches.get(1);
					if (comparator.compare(bestMatch, secondBestMatch) == 0) {
						Method m1 = bestMatch.getHandlerMethod().getMethod();
						Method m2 = secondBestMatch.getHandlerMethod().getMethod();
						String uri = request.getRequestURI();
						throw new IllegalStateException(
								"Ambiguous handler methods mapped for '" + uri + "': {" + m1 + ", " + m2 + "}");
					}
				}
			}
			request.setAttribute(BEST_MATCHING_HANDLER_ATTRIBUTE, bestMatch.getHandlerMethod());
			handleMatch(bestMatch.mapping, lookupPath, request);
			return bestMatch.getHandlerMethod();
		}
		else {
			return handleNoMatch(this.mappingRegistry.getRegistrations().keySet(), lookupPath, request);
		}
	}
	// ...
}

查看looupPath

lookupPath="/hello"
this.mappingRegistry = {AbstractHandlerMethodMapping$MappingRegistry@6921} 
	 registry = {HashMap@7840}  size = 5
		  {RequestMappingInfo@7864} "{GET [/api/tutorials]}" -> {AbstractHandlerMethodMapping$MappingRegistration@7865} 
		  {RequestMappingInfo@7866} "{ [/error], produces [text/html]}" -> {AbstractHandlerMethodMapping$MappingRegistration@7867} 
		  {RequestMappingInfo@7868} "{PATCH [/hello]}" -> {AbstractHandlerMethodMapping$MappingRegistration@7869} 
		  {RequestMappingInfo@7870} "{ [/error]}" -> {AbstractHandlerMethodMapping$MappingRegistration@7871} 
		  {RequestMappingInfo@7872} "{PUT [/hello]}" -> {AbstractHandlerMethodMapping$MappingRegistration@7873} 
	 pathLookup = {LinkedMultiValueMap@7841}  size = 3
		  "/api/tutorials" -> {ArrayList@7852}  size = 1
		  "/hello" -> {ArrayList@7854}  size = 2
		  "/error" -> {ArrayList@7856}  size = 2

directPathMatches

List<T> directPathMatches = this.mappingRegistry.getMappingsByDirectPath(lookupPath);
directPathMatches = {ArrayList@7854}  size = 2
	 0 = {RequestMappingInfo@7872} "{PUT [/hello]}"
	 1 = {RequestMappingInfo@7868} "{PATCH [/hello]}"
package org.springframework.web.method;

public class HandlerMethod {
	// ...
	public HandlerMethod createWithResolvedBean() {
		Object handler = this.bean;
		// default would go here
		if (this.bean instanceof String beanName) {
			Assert.state(this.beanFactory != null, "Cannot resolve bean name without BeanFactory");
			handler = this.beanFactory.getBean(beanName);
		}
		return new HandlerMethod(this, handler);
	}
	// ...
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

单元测试用例到底该如何设计?

目录 前言 使用参数方法创建测试用例 使用执行路径方法创建测试用例 总结 前言 最近一些大公司在进行去测试化的操作&#xff0c;这一切的根源大概可以从几年前微软一刀切砍掉所有内部正式的测试人员开始说起&#xff0c;当时微软内部的测试工程师有一部分转职成了开发工程…

【数据结构常见七大排序(三)上】—交换排序篇【冒泡排序】And【快速排序】

目录 前言 1.冒泡排序 1.1冒泡排序动图 1.2冒泡排序源代码 1.3冒泡排序的特性总结 2.快速排序&#x1f451; 2.1hoare版本实现思想 排序前 排序中 排序后 2.2hoare版本快排源代码 2.3分析先走 情况1&#x1f947; 情况2&#x1f948; 前言 交换类排序两个常见的排…

嵌入式工程师常用的软件工具推荐

前言&#xff1a;常言道&#xff1a;工欲善其事&#xff0c;必先利其器。作为一名合格的嵌入式工程师&#xff0c;日常可能需要接触和处理各种奇奇怪怪的问题&#xff0c;这时候一款高适配性的工具将会令工作效率大大提升。作者根据个人的实际使用情况与粉丝的客观感受&#xf…

紧跟国家“新能源+”模式!涂鸦智慧能源方案助力夏季用电节能提效

“今天的你是几分熟&#xff1f;” 今年夏天&#xff0c;高温来得比往年更早&#xff0c;五六月份就提前开启了滚滚热浪模式&#xff0c;京津冀和山东等地最高气温也一度突破了历史极值。在提前到来的高温“烤”验下&#xff0c;全社会供电能力面临着极大挑战。 中国电力网预…

完整的电商平台后端API开发总结

对于开发一个Web项目来说&#xff0c;无论是电商还是其他品类的项目&#xff0c;注册与登录模块都是必不可少的&#xff1b;注册登录功能也是我们在日常生活中最长接触的&#xff0c;对于这个业务场景的需求与逻辑大概是没有什么需要详细介绍的&#xff0c;市面上常见的邮箱注册…

PSP - Jackhmmer 搜索 EMBL 序列数据库的相似序列

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/131817060 EMBL (European Molecular Biology Laboratory&#xff0c;欧洲分子生物实验室)&#xff1a;EMBL 数据库是一个由欧洲生物信息学研究所…

第六届字节跳动青训营报录比(宣传大使)

统计 前端基础卷&#xff1a;105 前端基础班&#xff1a;120-22(笔试不过基础班&#xff0c;宣传大使奖励进入&#xff09;98 前端进阶卷&#xff1a;77 前端进阶班&#xff1a;18-216 后端基础卷&#xff1a;151 后端基础班&#xff1a;220 后端进阶卷&#xff1a;133 后端进…

LeetCode·每日一题·1851. 包含每个查询的最小区间·优先队列(小顶堆)

题目 示例 思路 离线查询&#xff1a; 输入的结果数组queries[]是无序的。如果我们按照输入的queries[]本身的顺序逐个查看&#xff0c;时间复杂度会比较高。 于是&#xff0c;我们将queries[]数组按照数值大小&#xff0c;由小到大逐个查询&#xff0c;这种方法称之为离线查询…

《微服务架构设计模式》第十二章 部署微服务应用

内容总结自《微服务架构设计模式》 部署微服务应用 一、部署模式分类二、编程语言特定的发布包格式1、概述2、利弊 三、将服务部署为虚拟机1、概览2、利弊 四、将服务部署为容器1、概述2、利弊3、K8S部署 五、Serverless部署1、概述2、利弊3、示例 六、总结 一、部署模式分类 …

视频融合平台EasyCVR级联后上级平台播放失败的问题排查与优化

EasyCVR视频融合平台基于云边端智能协同架构&#xff0c;具有强大的数据接入、处理及分发能力&#xff0c;平台可提供视频监控直播、云端录像、云存储、录像检索与回看、智能告警、平台级联、云台控制等视频能力与服务&#xff0c;可支持多协议、多类型的海量设备接入与分发。 …

7、PHP语法要点2

1、or 和 ||&#xff0c;&& 和 and 都是逻辑运算符&#xff0c;效果一样&#xff0c;但是其优先级却不一样。&&、||的优先级在赋值运算符之前&#xff0c;or和and在赋值运算符之后。 2、字符串变量及数组可以在echo输出时双引号内、双引号外均可引用&#xff…

Meta提出全新参数高效微调方案,仅需一个RNN,Transformer模型GPU使用量减少84%!

近来&#xff0c;随着ChatGPT和GPT-4模型的不断发展&#xff0c;国内外互联网大厂纷纷推出了自家的大语言模型&#xff0c;例如谷歌的PaLM系列&#xff0c;MetaAI的LLaMA系列&#xff0c;还有国内公司和高校推出的一些大模型&#xff0c;例如百度的文心一言&#xff0c;清华的C…

迅镭激光赋能工程机械,客户连续复购激光加工设备达双赢!

工程机械是装备制造业的重要组成部分&#xff0c;当前&#xff0c;我国已成为门类齐全、规模庞大、基础坚实、竞争力强的工程机械设备制造大国。 随着工程机械产业正在全面向智能化、绿色化转型&#xff0c;激光加工成为推动工程机械产业转型升级的重要工具&#xff0c;越来越多…

CS162 11-12 调度与死锁

调度 overview 1.FCFS 可以利用好cache缓存&#xff0c;减少上下文切换。 2.很直观&#xff0c;贪心&#xff0c;可以减少平均的响应时间 3 4. 5.等待调度的时间是平均的 6.优先级翻转&#xff0c;和优先级捐赠 解决 cfs中的调度 死锁 四个必要不充分条件 银行家算法&…

《深度学习推荐系统》笔记

目录 一、推荐系统是什么1.作用和意义2.推荐系统的架构2.1 逻辑架构2.2 技术架构 二、传统的推荐系统方法1. 协同过滤算法1.1 userCF&&ItemCF1.3 矩阵分解算法 2. 逻辑回归算法3. 因子分解机3.1 POLY2模型3.2 FM模型3.3 FFM模型3.4 小结 4. 组合模型4.1 GBDTLR组合模型…

数学建模-多元线性回归分析

回归分析介绍和分类 数据分类及数据的来源 线性回归 四种模型的解释、虚拟变量的设置以及交互项的解释 3个定量&#xff0c;7个定类插入&#xff0c;表格&#xff0c;包含标题&#xff0c;标题换黑色 可以右键&#xff0c;复制表格&#xff0c;excel中设置三线表 ,gen(A)是参数…

Linux 部署Vue+Spring Boot项目

部署Vue Spring Boot项目 安装redis wget http://download.redis.io/releases/redis-4.0.8.tar.gz tar -zxvf redis-4.0.8.tar.gz yum install gcc-c make make install如果出现下面的问题&#xff1a; yum install tcl make testredis-server myconifg/redis.conf输入客户端…

WordPress作为可扩展的企业级解决方案

网络商业世界就像一片汪洋大海&#xff0c;大型企业是大海中最大的鱼。然而&#xff0c;只因为你比其他人都大&#xff0c;并不意味着你不能逆流而上。相反&#xff0c;企业业务面临的挑战更大&#xff0c;对网站的技术要求更高。 多年来&#xff0c;大型公司通常依赖最昂贵的…

不用显示器,不用鼠标和键盘,让我们用主机远程访问OK3588的桌面

不用显示器&#xff0c;不用鼠标和键盘&#xff0c;让我们用主机远程访问OK3588的桌面 MobaXterm软件介绍串口终端运行命令MobaXterm访问开发板 MobaXterm软件介绍 MobaXterm是一款增强型终端软件&#xff0c;对于Windows平台上的程序员、网络管理员和开发者是一款极其优秀的工…

用 pesq 给 torchaudio 读取的音频数据打分

用torchaudio读取的音频文件&#xff0c;在输入pesq之前需要进行格式处理与转换。 import torchaudio from pesq import pesq# 读取音频文件 audio_clean, src torchaudio.load(./audio/NOIZEUS/clean/sp01.wav) audio_0dB, sr0 torchaudio.load(./audio/NOIZEUS/bable/0dB/…