SpringBoot错误处理机制解析

news2025/1/9 16:17:32

SpringBoot错误处理----源码解析

文章目录

    • 1、默认机制
    • 2、使用@ExceptionHandler标识一个方法,处理用@Controller标注的该类发生的指定错误
      • 1).局部错误处理部分源码
      • 2).测试
    • 3、 创建一个全局错误处理类集中处理错误,使用==@ControllerAdvice==注解标注
      • 1).全局错误处理部分源码
      • 3).测试
    • 4、SpringMVC错误处理未能处理(上述处理不存在)
        • 1、SpringBoot中自动配置的错误处理机制,基于`ErrorMvcAutoConfiguration`自动配置实现
        • 2、` BasicErrorController`组件
        • 规则如下:
    • 5、自定义错误响应
    • 6、测试
        • 1、在项目的resources/templates/目录下创建一个error文件夹,放入4xx.html、5xx.html
        • 2、在项目的resources/templates/error文件夹中,再放入404.html、500.html
        • 3、浏览器先后测试上述情况

1、默认机制

SpringBoot错误处理的自动配置都在ErrorMvcAutoConfiguration中,两大核心机制:

  • 1.SpringBoot会自适应处理错误,响应页面或JSON数据

  • 2.SpringMVC的错误处理机制依然保留,MVC处理不了,才会交给SpringBoot进行处理。
    在这里插入图片描述(图片来自尚硅谷)

2、使用@ExceptionHandler标识一个方法,处理用@Controller标注的该类发生的指定错误

(默认只能处理这个类的该指定错误)

// @ExceptionHandler源码
@Target({ElementType.METHOD})     // 指定了该注解仅能用于方法
@Retention(RetentionPolicy.RUNTIME)   //指定了注解会在运行时保留,这允许通过反射在运行时获取对注解的访问
@Documented      //注解应该被包含在生成的 JavaDoc 文档中
@Reflective({ExceptionHandlerReflectiveProcessor.class}) 
public @interface ExceptionHandler {
    Class<? extends Throwable>[] value() default {};       
    //它定义了一个名为 value 的属性,其类型是一个 Class 数组,这个数组的元素必须是 Throwable 类或其子类。通过使用这个注解时,可以为 value 属性提供一个 Throwable 类型的数组
}

1).局部错误处理部分源码

@Controller         //适配服务端渲染    前后不分离模式开始
public class WelcomeController {
    //来到首页
    @GetMapping("/")
    public String index(){
        int i=10/0;    //制造错误
        return "index";
    }
    
    @ResponseBody     
    //返回的字符串应该直接作为 HTTP 响应体的内容,而不是作为视图名称解析。通常用于返回 JSON 或纯文本等非HTML内容
    @ExceptionHandler(Exception.class)   //传递到value数组中
    public String handleException(Exception e){
        return "Ohho~~~,原因:"+e.getMessage();
    }

}

2).测试

  • 1.启动项目,浏览器访问http://localhost:8080/

  • 2.测试结果(成功处理错误)
    在这里插入图片描述

3、 创建一个全局错误处理类集中处理错误,使用==@ControllerAdvice==注解标注

(这个类是集中处理所有@Controller 发生的错误)

//@ControllerAdvice源码
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component       //标记类为一个 Spring 组件
public @interface ControllerAdvice {
    @AliasFor(
        annotation = Component.class,
        attribute = "value"
    )
    String name() default "";

    @AliasFor("basePackages")
    String[] value() default {};

    @AliasFor("value")
    String[] basePackages() default {};

    Class<?>[] basePackageClasses() default {};

    Class<?>[] assignableTypes() default {};

    Class<? extends Annotation>[] annotations() default {};
}

1).全局错误处理部分源码

@ControllerAdvice        //这个类是集中处理所有@Controller发生的错误
public class GlobalExceptionHandler {
    @ResponseBody
    @ExceptionHandler(Exception.class)
    public String handleException(Exception e){
        return "Ohho~~~统一处理所有错误,原因:"+e.getMessage();
    }
}

###2).再创建一个类,使用@Controller注解标注

@Controller
public class HelloController {
    @GetMapping("/haha")
    public String haha(){
        int i = 10/0;        //制造错误
        return "index";
    }
}

3).测试

  • 1.启动项目,浏览器访问http://localhost:8080/
  • 2.测试结果(成功处理错误)就近原则,执行的是@Controller类中标注了@ExceptionHandler方法的处理
    在这里插入图片描述
  • 3.浏览器访问http://localhost:8080/haha全局错误处理类进行处理
    在这里插入图片描述

4、SpringMVC错误处理未能处理(上述处理不存在)

第一阶段的处理未解决,错误转发到/error,执行后续处理(图中第一阶段失效,第二阶段处理),以下测试过程中,注释掉上文中的全局和局部处理代码

1、SpringBoot中自动配置的错误处理机制,基于ErrorMvcAutoConfiguration自动配置实现

ErrorMvcAutoConfiguration自动装配类中,SpringBoot在底层写好一个 ==BasicErrorController==的组件,专门处理/error这个请求,部分源码如下:

@AutoConfiguration(before = WebMvcAutoConfiguration.class) //指定了该自动配置类在 WebMvcAutoConfiguration 之前进行配置
@ConditionalOnWebApplication(type = Type.SERVLET)    //只有在当前应用是一个 Servlet Web 应用时,这个自动配置才会生效
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class })   //只有当类路径中存在 Servlet 和 DispatcherServlet 时,这个自动配置才会生效
@EnableConfigurationProperties({ ServerProperties.class, WebMvcProperties.class }) //启用指定类的配置属性绑定
public class ErrorMvcAutoConfiguration {

	private final ServerProperties serverProperties; //注入了 ServerProperties 实例。这样的构造方法注入是为了获取应用程序的服务器配置

	public ErrorMvcAutoConfiguration(ServerProperties serverProperties) {
		this.serverProperties = serverProperties;  //注入 ServerProperties 实例
	}

    //容器中不存在 ErrorAttributes 类型的 Bean 时,才会创建并注册当前方法所返回的 Bean
	@Bean
	@ConditionalOnMissingBean(value = ErrorAttributes.class, search = SearchStrategy.CURRENT)
	public DefaultErrorAttributes errorAttributes() {
		return new DefaultErrorAttributes();
	}

    //在容器中不存在 ErrorController 类型的 Bean 时,才会创建并注册当前方法所返回的 Bean
	@Bean
	@ConditionalOnMissingBean(value = ErrorController.class, search = SearchStrategy.CURRENT)
	public BasicErrorController basicErrorController(ErrorAttributes errorAttributes,
			ObjectProvider<ErrorViewResolver> errorViewResolvers) {
		return new BasicErrorController(errorAttributes, this.serverProperties.getError(),
				errorViewResolvers.orderedStream().toList());
	}
    ...
}
2、 BasicErrorController组件

SpringBoot中默认的server.error.path=/error,即该类就是处理/error请求的,根据不同类型的请求,如果产生 HTML 内容的请求,匹配public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) 这个方法;否则其他请求类型,匹配public ResponseEntity<Map<String, Object>> error(HttpServletRequest request)方法。分别进行处理。(只会匹配其中一个,Spring MVC会尝试匹配与请求路径最匹配的RequestMapping)

  • 1.部分源码:
@Controller
@RequestMapping("${server.error.path:${error.path:/error}}")
public class BasicErrorController extends AbstractErrorController {
    	private final ErrorProperties errorProperties;

	/**
	 * Create a new {@link BasicErrorController} instance.
	 * @param errorAttributes the error attributes
	 * @param errorProperties configuration properties
	 */
	public BasicErrorController(ErrorAttributes errorAttributes, ErrorProperties errorProperties) {
		this(errorAttributes, errorProperties, Collections.emptyList());
	}

	/**
	 * Create a new {@link BasicErrorController} instance.
	 * @param errorAttributes the error attributes
	 * @param errorProperties configuration properties
	 * @param errorViewResolvers error view resolvers
	 */
	public BasicErrorController(ErrorAttributes errorAttributes, ErrorProperties errorProperties,
			List<ErrorViewResolver> errorViewResolvers) {
		super(errorAttributes, errorViewResolvers);
		Assert.notNull(errorProperties, "ErrorProperties must not be null");
		this.errorProperties = errorProperties;
	}

	@RequestMapping(produces = MediaType.TEXT_HTML_VALUE)   //请求类型为HTML 文本
	public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
		HttpStatus status = getStatus(request);
		Map<String, Object> model = Collections
			.unmodifiableMap(getErrorAttributes(request, getErrorAttributeOptions(request, MediaType.TEXT_HTML)));
		response.setStatus(status.value());
		ModelAndView modelAndView = resolveErrorView(request, response, status, model);
		return (modelAndView != null) ? modelAndView : new ModelAndView("error", model);
	}

	@RequestMapping
	public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
		HttpStatus status = getStatus(request);
		if (status == HttpStatus.NO_CONTENT) {
			return new ResponseEntity<>(status);
		}
		Map<String, Object> body = getErrorAttributes(request, getErrorAttributeOptions(request, MediaType.ALL));
		return new ResponseEntity<>(body, status);
	}
    ...
}
  • 2.匹配成功之后,错误页面解析的核心代码

    //1、解析错误的自定义视图地址
    ModelAndView modelAndView = resolveErrorView(request, response, status, model);
    //2、如果解析不到错误页面的地址,默认的错误页就是 error
    return (modelAndView != null) ? modelAndView : new ModelAndView("error", model);
    
  • 3.在ErrorMvcAutoConfiguration自动装配类中,SpringBoot在底层写好一个 ==DefaultErrorViewResolver==的组件,注入到了容器中

    	@Configuration(proxyBeanMethods = false)
    	@EnableConfigurationProperties({ WebProperties.class, WebMvcProperties.class })
    	static class DefaultErrorViewResolverConfiguration {
    
    		private final ApplicationContext applicationContext;
    
    		private final Resources resources;
    
    		DefaultErrorViewResolverConfiguration(ApplicationContext applicationContext, WebProperties webProperties) {
    			this.applicationContext = applicationContext;
    			this.resources = webProperties.getResources();
    		}
    
    		@Bean
    		@ConditionalOnBean(DispatcherServlet.class)
    		@ConditionalOnMissingBean(ErrorViewResolver.class)
    		DefaultErrorViewResolver conventionErrorViewResolver() {
    			return new DefaultErrorViewResolver(this.applicationContext, this.resources);
    		}
    
    	}
    
  • 4.在DefaultErrorViewResolver中定义了错误页的默认规则,功能如下:

    • 如果在类路径下,查看是否存在 error/错误码 的页面,存在就返回该视图;
    • 否则,去4个CLASSPATH_RESOURCE_LOCATIONS路径下,查看是否写了 error/错误码.html 的页面,存在则返回该视图;
    • 都不存在,则modelAndView=null;则判断是否有 error/4xx 或者 error/5xx 的页面,存在则返回该视图
    • 否则,去4个CLASSPATH_RESOURCE_LOCATIONS路径下,查看是否写了 error/4xx.html 或者 error/5xx.html 的页面,存在则返回该视图;
    public class DefaultErrorViewResolver implements ErrorViewResolver, Ordered {
        
        ...
            
        private static final Map<Series, String> SERIES_VIEWS;
    
    	static {
    		Map<Series, String> views = new EnumMap<>(Series.class);
    		views.put(Series.CLIENT_ERROR, "4xx");
    		views.put(Series.SERVER_ERROR, "5xx");
    		SERIES_VIEWS = Collections.unmodifiableMap(views);
    	}
        
        // 查看是否存在 error/错误码 的页面,存在就返回该视图
        // 不存在,则判断是否有  error/4xx  或者  error/5xx  的页面,存在则返回该视图
        @Override
    	public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) {
    		ModelAndView modelAndView = resolve(String.valueOf(status.value()), model);
    		if (modelAndView == null && SERIES_VIEWS.containsKey(status.series())) {
    			modelAndView = resolve(SERIES_VIEWS.get(status.series()), model);
    		}
    		return modelAndView;
    	}
    
        // 在类路径下,查看是否存在 error/错误码 的模板引擎,存在就返回该视图;
        // 否则去下面的4个CLASSPATH_RESOURCE_LOCATIONS路径下,查看是否写了  error/错误码.html 的页面,存在则返回该视图
    	private ModelAndView resolve(String viewName, Map<String, Object> model) {
    		String errorViewName = "error/" + viewName;
    		TemplateAvailabilityProvider provider = this.templateAvailabilityProviders.getProvider(errorViewName,
    				this.applicationContext);
    		if (provider != null) {
    			return new ModelAndView(errorViewName, model);
    		}
    		return resolveResource(errorViewName, model);
    	}
    
        //去下面的4个CLASSPATH_RESOURCE_LOCATIONS路径下,查看是否写了  error/错误码.html  的页面,存在则返回该视图
        //this.resources.getStaticLocations()
        //private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/META-INF/resources/",
    	//			"classpath:/resources/", "classpath:/static/", "classpath:/public/" };
    	private ModelAndView resolveResource(String viewName, Map<String, Object> model) {
    		for (String location : this.resources.getStaticLocations()) {
    			try {
    				Resource resource = this.applicationContext.getResource(location);
    				resource = resource.createRelative(viewName + ".html");
    				if (resource.exists()) {
    					return new ModelAndView(new HtmlResourceView(resource), model);
    				}
    			}
    			catch (Exception ex) {
    			}
    		}
    		return null;
    	}
        ...
    }
    
  • 5.在ErrorMvcAutoConfiguration自动装配类中,向容器中放入了一个默认名为error的视图,提供了默认的白页功能,如果上述都无法处理

    	@Configuration(proxyBeanMethods = false)
    	@ConditionalOnProperty(prefix = "server.error.whitelabel", name = "enabled", matchIfMissing = true)
    	@Conditional(ErrorTemplateMissingCondition.class)
    	protected static class WhitelabelErrorViewConfiguration {
    
    		private final StaticView defaultErrorView = new StaticView();
    
            //   注入了error视图
    		@Bean(name = "error")
    		@ConditionalOnMissingBean(name = "error")
    		public View defaultErrorView() {
    			return this.defaultErrorView;
    		}
    
    		// If the user adds @EnableWebMvc then the bean name view resolver from
    		// WebMvcAutoConfiguration disappears, so add it back in to avoid disappointment.
    		@Bean
    		@ConditionalOnMissingBean
    		public BeanNameViewResolver beanNameViewResolver() {
    			BeanNameViewResolver resolver = new BeanNameViewResolver();
    			resolver.setOrder(Ordered.LOWEST_PRECEDENCE - 10);
    			return resolver;
    		}
    
    	}
    

    默认的白页源码,就在类ErrorMvcAutoConfiguration中定义的

    private static class StaticView implements View {
    
    		private static final MediaType TEXT_HTML_UTF8 = new MediaType("text", "html", StandardCharsets.UTF_8);
    
    		private static final Log logger = LogFactory.getLog(StaticView.class);
    
    		@Override
    		public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response)
    				throws Exception {
    			if (response.isCommitted()) {
    				String message = getMessage(model);
    				logger.error(message);
    				return;
    			}
    			response.setContentType(TEXT_HTML_UTF8.toString());
    			StringBuilder builder = new StringBuilder();
    			Object timestamp = model.get("timestamp");
    			Object message = model.get("message");
    			Object trace = model.get("trace");
    			if (response.getContentType() == null) {
    				response.setContentType(getContentType());
    			}
    			builder.append("<html><body><h1>Whitelabel Error Page</h1>")
    				.append("<p>This application has no explicit mapping for /error, so you are seeing this as a fallback.</p>")
    				.append("<div id='created'>")
    				.append(timestamp)
    				.append("</div>")
    				.append("<div>There was an unexpected error (type=")
    				.append(htmlEscape(model.get("error")))
    				.append(", status=")
    				.append(htmlEscape(model.get("status")))
    				.append(").</div>");
    			if (message != null) {
    				builder.append("<div>").append(htmlEscape(message)).append("</div>");
    			}
    			if (trace != null) {
    				builder.append("<div style='white-space:pre-wrap;'>").append(htmlEscape(trace)).append("</div>");
    			}
    			builder.append("</body></html>");
    			response.getWriter().append(builder.toString());
    		}
    
    		private String htmlEscape(Object input) {
    			return (input != null) ? HtmlUtils.htmlEscape(input.toString()) : null;
    		}
    
    		private String getMessage(Map<String, ?> model) {
    			Object path = model.get("path");
    			String message = "Cannot render error page for request [" + path + "]";
    			if (model.get("message") != null) {
    				message += " and exception [" + model.get("message") + "]";
    			}
    			message += " as the response has already been committed.";
    			message += " As a result, the response may have the wrong status code.";
    			return message;
    		}
    
    		@Override
    		public String getContentType() {
    			return "text/html";
    		}
    
    	}
    
  • 6.在ErrorMvcAutoConfiguration自动装配类中,封装了JSON格式的错误信息(初始化了错误的类型、错误的状态码、路径、栈信息、时间戳等信息)

    @Bean
    @ConditionalOnMissingBean(value = ErrorAttributes.class, search = SearchStrategy.CURRENT)
    public DefaultErrorAttributes errorAttributes() {
        return new DefaultErrorAttributes();
    }
    
规则如下:
  • 1.解析一个错误页:

    • 如果发生了500、404、503、403 这些错误
        1. 如果有模板引擎,默认在 classpath:/templates/error/精确码.html
        1. 如果没有模板引擎,在静态资源文件夹下找 精确码.html
    • 如果匹配不到精确码.html这些精确的错误页,就去找5xx.html4xx.html模糊匹配
        1. 如果有模板引擎,默认在 classpath:/templates/error/5xx.html
        1. 如果没有模板引擎,在静态资源文件夹下找 5xx.html
  • 2.如果模板引擎路径templates下有 error.html页面,就直接渲染

5、自定义错误响应

​ 1) 自定义json响应:使用文章第2和第3部分介绍的,使用注解进行统一的异常处理

​ 2)自定义页面响应:根据第4部分介绍的规则,在对应的项目路径"classpath:/METAINF/resources/","classpath:/resources/","classpath:/static/", "classpath:/public/"或者模板引擎目录下,定义错误页面即可。

6、测试

1、在项目的resources/templates/目录下创建一个error文件夹,放入4xx.html、5xx.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
   4xx.html
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
5xx.html
</body>
</html>
2、在项目的resources/templates/error文件夹中,再放入404.html、500.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
404.html
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
500.html
</body>
</html>
3、浏览器先后测试上述情况
  • 1.访问一个不存在的路径;
  • 2.制造除0错误。

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

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

相关文章

【开源】基于Vue.js的软件学院思政案例库系统

文末获取源码&#xff0c;项目编号&#xff1a; S 070 。 \color{red}{文末获取源码&#xff0c;项目编号&#xff1a;S070。} 文末获取源码&#xff0c;项目编号&#xff1a;S070。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统管理员2.2 普通教师 三、系统展…

python程序将部分文件复制到指定目录

geotools-28.2中的lib一共有264个jar包&#xff0c;但我只想将部分100个左右jar包引导我的环境中&#xff0c;那个就需要从目录中找出想要的那100个jar&#xff0c;手动挑选太费时间&#xff0c;我简单的写了个小脚本来实现。 我将想要的jar文件名和路径存放到txt中&#xff0…

风控交易系统跟单系统资管软件都有哪些功能特点?

资管分仓软件的主要功能就是母账户可以添加子账号&#xff0c;并且设置出入金&#xff0c;手续费、保证金、风控等功能&#xff0c;同时监控端更可以直观的看子账户的交易情况直接折线图展示更加直观&#xff0c;在监控端的最高权限可以直接一键平仓子账户&#xff08;如果子账…

系列十三、SpringBoot的自动配置原理分析

一、概述 我们知道Java发展到现在功能十分的强大&#xff0c;生态异常的丰富&#xff0c;这里面离开不了Spring及其家族产品的支持&#xff0c;而作为Spring生态的明星产品Spring Boot可以说像王者一般的存在&#xff0c;那么的耀眼&#xff0c;那么的光彩夺目&#xff01;那么…

Optional源码分析(涉及Objects源码和Stream源码)

研究Optional源码之前先谈一谈Objects源码。 主要代码&#xff1a; ForceInlinepublic static <T> T requireNonNull(T obj) {if (obj null) {throw new NullPointerException();} else {return obj;}}ForceInlinepublic static <T> T requireNonNull(T obj, Str…

ES 快照到 S3 并从 Windows 共享目录恢复(qbit)

前言 业务需要将 Elasticsearch 快照到 AWS S3&#xff0c;再将快照拷贝到 Windows 系统&#xff0c;并恢复到 Elasticsearch。如下图所示&#xff1a; 环境 Elasticsearch 7.10.1 Windows Server 2019 Ubuntu 20.04 &#xff08;ES 宿主&#xff09; ES 集群1 安装 S3 插…

Python的文件的读写操作【侯小啾Python基础领航计划 系列(二十七)】

Python_文件的读写操作【侯小啾Python基础领航计划 系列(二十七)】 大家好,我是博主侯小啾, 🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔…

Go 语言中的函数调用。

更好的观看体验&#xff0c;请点击——函数调用 | YinKais Blog 本文将从函数的调用惯例和参数传递方法两个方面分别介绍函数执行的过程。 1、调用惯例 对于不同的编程语言&#xff0c; 它们在调用函数的时候往往都使用相同的语法&#xff1a; somefunction(arg0, arg1) 虽…

风变科技千万营收的AIGC项目,在Fanbook成功落地,专访风变科技CMO江育麟

在AIGC时代&#xff0c;创作生产力被下放到了每一位普通人身上&#xff0c;然后用户与AIGC应用之间还存在一定的认知与技术沟壑。 最近&#xff0c;【AIGC开放社区】注意到一款AIGC课程项目受到了相当的关注&#xff0c;让许多0基础的学员轻松地学会了使用AIGC技术的基本方法。…

Vxworks6.9的在线gdb调试(仿真内核和板载内核)

创作目的&#xff1a;归纳总结常用的技巧和方法&#xff0c;方便自己后续查阅重点节省时间。 一、仿真内核的gdb调试 1、新建DKM工程&#xff0c;选择sim的BSP包 2、DKM工程中添加c文件并编辑入口函数 3、新建vxworks远端系统 4、显示系统起来之后进行加载.out 5、选择Debug模…

Python的模块与库,及if __name__ == ‘__main__语句【侯小啾Python基础领航计划 系列(二十四)】

Python的模块与库,及if name == ‘__main__语句【侯小啾Python基础领航计划 系列(二十四)】 大家好,我是博主侯小啾, 🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔…

Java基础之数组拷贝

Arrays.copyOf 详解 copyOf是Arrays类下面的一个方法,用于拷贝各种数组 以整型数组为例&#xff1a;int [ ] copyOf(int [ ]array,int newLength);第一个参数是想要拷贝到数组&#xff0c;第二个参数是新拷贝得到的数组的大小&#xff08;不一定非得和原始数组大小一样&…

RT-Thread 内存管理

在计算机系统中&#xff0c;通常存储空间可以分为两种&#xff1a;内部存储空间和外部存储空间。 内部存储空间通常访问速度比较快&#xff0c;能够按照变量地址随机访问&#xff0c;也就是我们通常所说的RAM&#xff08;随机存储器&#xff09;&#xff0c;可以把它理解为电脑…

Java多线程技术二:线程间通信——join()方法的使用

1 概述 在很多情况下&#xff0c;主线程创建并启动子线程&#xff0c;如果子线程中要进行大量的耗时运算&#xff0c;主线程往往将早于子线程结束&#xff0c;这时如果主线程想等待子线程执行完成后再结束&#xff0c;例如子线程处理一个数据&#xff0c;主线程要取到这个数据中…

WordPress免费插件大全清单【2023最新】

WordPress已经成为全球范围内最受欢迎的网站建设平台之一。要让您的WordPress网站更具功能性、效率性&#xff0c;并提供卓越的用户体验&#xff0c;插件的选择与使用变得至关重要。 WordPress插件的作用 我们先理解一下插件在WordPress生态系统中的作用。插件是一种能够为Wo…

【PyTorch】softmax回归

文章目录 1. 模型与代码实现1.1. 模型1.2. 代码实现 2. Q&A 1. 模型与代码实现 1.1. 模型 背景 在分类问题中&#xff0c;模型的输出层是全连接层&#xff0c;每个类别对应一个输出。我们希望模型的输出 y ^ j \hat{y}_j y^​j​可以视为属于类 j j j的概率&#xff0c;然…

计算机网络入侵检测技术研究

摘 要 随着网络技术的发展&#xff0c;全球信息化的步伐越来越快&#xff0c;网络信息系统己成为一个单位、一个部门、一个行业&#xff0c;甚至成为一个关乎国家国计民生的基础设施&#xff0c;团此&#xff0c;网络安全就成为国防安全的重要组成部分&#xff0c;入侵检测技术…

线程的使用1

1. 创建一个线程 1.1 创建线程练习 线程实际上是应用层的概念&#xff0c;在 Linux 内核中&#xff0c;所有的调度实体都被称为任务 (task) &#xff0c; 他们之间的区别是&#xff1a;有些任务自己拥有一套完整的资源&#xff0c;而有些任务彼此之间共享一套资源 对此函数的使…

机器学习深度学学习分类模型中常用的评价指标总结记录与代码实现说明

在机器学习深度学习算法模型大开发过程中&#xff0c;免不了要对算法模型进行对应的评测分析&#xff0c;这里主要是总结记录分类任务中经常使用到的一些评价指标&#xff0c;并针对性地给出对应的代码实现&#xff0c;方便读者直接移植到自己的项目中。 【混淆矩阵】 混淆矩阵…

多模块下MyBatis官方生成器

MyBatis官方生成器 1. 依赖插件 创建generator模块 在父模块中进行版本管理 <dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.6</version> </dependency><dependency><g…