Spring系统学习 - AOP之基于注解的AOP和XML的AOP

上一篇我们围绕了AOP中代理模式的使用,这篇我们将主要围绕AOP的相关术语介绍,以及重点围绕基于注解的AOP进行相关知识的概述和使用说明。

AOP的相关术语

  1. 切面(Aspect):切面是一个模块化的横切关注点,它包含了一组通知和切点。通常,切面用于定义横切关注点的行为,如日志记录、事务管理等。
    在这里插入图片描述

  2. 通知(Advice):通知是切面在特定切点上执行的动作。在 Spring AOP 中,有以下几种类型的通知:

    • 前置通知(Before Advice):在目标方法执行之前执行。
    • 后置通知(After Advice):在目标方法执行之后执行,无论目标方法是否抛出异常。
    • 返回通知(After Returning Advice):在目标方法成功执行并返回结果后执行。
    • 异常通知(After Throwing Advice):在目标方法抛出异常后执行。
    • 环绕通知(Around Advice):在目标方法执行前后都执行,并可以控制目标方法的执行。
      在这里插入图片描述
  3. 切点(Pointcut):切点是指在应用程序中选择连接点的表达式。它定义了哪些方法或类应该被通知所影响。切点使用表达式语言来匹配连接点。

  4. 连接点(Join Point):连接点是在应用程序执行过程中可以插入切面的点。它可以是方法调用、方法执行、异常抛出等。
    在这里插入图片描述

  5. 引入(Introduction):引入允许向现有的类添加新的方法或属性。它允许在不修改现有类的情况下,向类添加新的功能。

  6. 目标对象(Target Object):目标对象是被通知的对象,它包含了切面所要应用的方法。

  7. 代理(Proxy):代理是一个对象,它包装了目标对象,并拦截对目标对象的访问。代理可以在目标对象的方法执行前后添加额外的逻辑。

  8. 织入(Weaving):织入是将切面应用到目标对象并创建新的代理对象的过程。织入可以在编译时、类加载时或运行时进行。(可以称之为横切关注点)

在这里插入图片描述
这些术语的作用:

  1. 提供统一的概念和术语:术语提供了一套统一的概念和术语,使开发人员能够更好地理解和沟通。通过使用共同的术语,可以减少误解和混淆,提高团队协作效率。
  2. 定义和描述 AOP 的各个组成部分:术语用于定义和描述 AOP 的各个组成部分,如切面、通知、切点等。它们提供了一种标准的方式来描述和理解 AOP 的概念和实现。
  3. 指导开发人员理解和使用 Spring AOP 框架:术语帮助开发人员理解和使用 Spring AOP 框架。通过熟悉和理解这些术语,开发人员可以更好地使用 Spring AOP 提供的功能和特性,实现横切关注点的处理。
  4. 促进知识共享和学习:术语作为一种共享的语言,促进了知识的共享和学习。开发人员可以通过使用相同的术语来交流和分享经验,从而加深对 Spring AOP 的理解和应用。

基于注解的AOP

基于注解的 AOP 是一种使用注解来定义切面和通知的方式。在传统的基于 XML 配置的 AOP 中,切面和通知的定义通常是通过 XML 配置文件来完成的,而基于注解的 AOP 则使用注解来实现这些定义,使得配置更加简洁和直观。

在这里插入图片描述

  • 动态代理(InvocationHandler):JDK原生的实现方式,需要被代理的目标类必须实现接口。因为这个技术要求代理对象和目标对象实现同样的接口(兄弟两个拜把子模式)。

  • cglib:通过继承被代理的目标类(认干爹模式)实现代理,所以不需要目标类实现接口。

  • AspectJ:本质上是静态代理,将代理逻辑“织入”被代理的目标类编译得到的字节码文件,所以最终效果是动态的。weaver就是织入器。Spring只是借用了AspectJ中的注解。

常见的注解:

  • @Aspect:用于定义切面类,标识该类为切面。
  • @Before:用于定义前置通知,在目标方法执行之前执行。
  • @After:用于定义后置通知,在目标方法执行之后执行,无论目标方法是否抛出异常。
  • @AfterReturning:用于定义返回通知,在目标方法成功执行并返回结果后执行。
  • @AfterThrowing:用于定义异常通知,在目标方法抛出异常后执行。
  • @Around:用于定义环绕通知,在目标方法执行前后都执行,并可以控制目标方法的执行。

案例

导入相关依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>SSM</artifactId><groupId>com.miaow</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>Spring-AOP</artifactId><description>Spring的AOP学习</description><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.1</version><scope>test</scope></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.20</version></dependency><!--        引入AOP,实际上就是spring-aspect会帮我传递过来aspectjweaver--><dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>5.3.8</version></dependency></dependencies></project>

创建接口实现注解横切

public interface Calculator {int add(int i, int j);int sub(int i, int j);int mul(int i, int j);int div(int i, int j);}
@Component
public class CalculatorImpl implements Calculator {@Overridepublic int add(int i, int j) {int result = i + j;System.out.println("方法内部,result:"+result);return result;}@Overridepublic int sub(int i, int j) {int result = i - j;System.out.println("方法内部,result:"+result);return result;}@Overridepublic int mul(int i, int j) {int result = i * j;System.out.println("方法内部,result:"+result);return result;}@Overridepublic int div(int i, int j) {int result = i / j;System.out.println("方法内部,result:"+result);return result;}
}
@Component
@Aspect //将当前组件标识为切面
public class LoggerAspect {@Pointcut("execution(* com.miaow.aspect.CalculatorImpl.*(..))")public void pointCut(){}//@Before("execution(public int com.miaow.aspect.CalculatorImpl.add(int, int))")//@Before("execution(* com.miaow.aspect.CalculatorImpl.*(..))")@Before("pointCut()")public void beforeAdviceMethod(JoinPoint joinPoint) {//获取连接点所对应方法的签名信息Signature signature = joinPoint.getSignature();//获取连接点所对应方法的参数Object[] args = joinPoint.getArgs();System.out.println("LoggerAspect,方法:"+signature.getName()+",参数:"+ Arrays.toString(args));}@After("pointCut()")public void afterAdviceMethod(JoinPoint joinPoint){//获取连接点所对应方法的签名信息Signature signature = joinPoint.getSignature();System.out.println("LoggerAspect,方法:"+signature.getName()+",执行完毕");}/*** 在返回通知中若要获取目标对象方法的返回值* 只需要通过@AfterReturning注解的returning属性* 就可以将通知方法的某个参数指定为接收目标对象方法的返回值的参数*/@AfterReturning(value = "pointCut()", returning = "result")public void afterReturningAdviceMethod(JoinPoint joinPoint, Object result){//获取连接点所对应方法的签名信息Signature signature = joinPoint.getSignature();System.out.println("LoggerAspect,方法:"+signature.getName()+",结果:"+result);}/*** 在异常通知中若要获取目标对象方法的异常* 只需要通过AfterThrowing注解的throwing属性* 就可以将通知方法的某个参数指定为接收目标对象方法出现的异常的参数*/@AfterThrowing(value = "pointCut()", throwing = "ex")public void afterThrowingAdviceMethod(JoinPoint joinPoint, Throwable ex){//获取连接点所对应方法的签名信息Signature signature = joinPoint.getSignature();System.out.println("LoggerAspect,方法:"+signature.getName()+",异常:"+ex);}//使用了环绕通知就不需要使用上述四种通知,如果选择上面的四种通知,那么就不需要选择下面的环绕通知@Around("pointCut()")//环绕通知的方法的返回值一定要和目标对象方法的返回值一致public Object aroundAdviceMethod(ProceedingJoinPoint joinPoint){Object result = null;try {System.out.println("环绕通知-->前置通知");//表示目标对象方法的执行result = joinPoint.proceed();System.out.println("环绕通知-->返回通知");} catch (Throwable throwable) {throwable.printStackTrace();System.out.println("环绕通知-->异常通知");} finally {System.out.println("环绕通知-->后置通知");}return result;}}
/*** 这段代码定义了一个名为 ValidateAspect 的 Aspect,它使用 @Order 注解将其优先级设置为 1,并使用 @Before 注解定义一个前置通知方法。*/
@Component
@Aspect
@Order(1)  //order=1值越小,优先级越高
public class ValidateAspect {//@Before("execution(* com.miaow.aspect.CalculatorImpl.*(..))")@Before("com.miaow.aspect.LoggerAspect.pointCut()")public void beforeMethod(){System.out.println("ValidateAspect-->前置通知");}}

在Spring 配置文件中添加下述代码

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"><!--基于注解的AOP的实现:1、将目标对象和切面交给IOC容器管理(注解+扫描)2、开启AspectJ的自动代理,为目标对象自动生成代理3、将切面类通过注解@Aspect标识--><!--    扫码component文件--><context:component-scan base-package="com.miaow.aspect"></context:component-scan><!--    启用基于注解AOP,否则实现不了--><aop:aspectj-autoproxy />
</beans>

测试类:

    @Testpublic void test2(){//先获取IOCApplicationContext context = new ClassPathXmlApplicationContext("spring-aop.xml");//当我们使用AOP之后无法直接获取对象,只能通过动态代理的获取com.miaow.aspect.Calculator calculator =  context.getBean(com.miaow.aspect.Calculator.class);
//        calculator.add(1,2);
//        calculator.sub(1,2);
//        calculator.mul(1,2);calculator.div(1,2);}

运行结果:

ValidateAspect-->前置通知
环绕通知-->前置通知
LoggerAspect,方法:div,参数:[1, 2]
方法内部,result:0
LoggerAspect,方法:div,结果:0
LoggerAspect,方法:div,执行完毕
环绕通知-->返回通知
环绕通知-->后置通知

补充说明AOP中的切面优先级

相同目标方法上同时存在多个切面时,切面的优先级控制切面的内外嵌套顺序。

  • 优先级高的切面:外面
  • 优先级低的切面:里面

在这里插入图片描述

在基于注解的 AOP 中,切面的优先级可以通过以下方式进行控制:

  • @Order 注解:可以在切面类上使用 @Order 注解来指定切面的优先级。@Order 注解的值越小,优先级越高。如果多个切面都使用了 @Order 注解,则优先级较高的切面将先于优先级较低的切面执行。
@Aspect
@Order(1)
public class MyAspect1 {// ...
}@Aspect
@Order(2)
public class MyAspect2 {// ...
}
  • 实现 Ordered 接口:可以让切面类实现 Ordered 接口,并实现其中的 getOrder() 方法来指定切面的优先级。getOrder() 方法返回的值越小,优先级越高。
@Aspect
public class MyAspect implements Ordered {// ...@Overridepublic int getOrder() {return 1;}
}
  • @Order 和 Ordered 接口的组合使用:可以同时使用 @Order 注解和实现 Ordered 接口的方式来控制切面的优先级。当切面类既使用了 @Order 注解,又实现了 Ordered 接口时,@Order 注解的优先级高于 Ordered 接口的 getOrder() 方法返回值。
@Aspect
@Order(1)
public class MyAspect implements Ordered {// ...@Overridepublic int getOrder() {return 2;}
}

需要注意的是,切面的优先级仅在多个切面同时应用于同一个连接点时才会起作用。如果切面应用于不同的连接点,优先级的设置将不会生效。

了解基于XML的AOP操作

在基于 XML 的 Spring AOP 中,切面和通知的定义通常是通过 XML 配置文件来完成的。以下是基于 XML 的 Spring AOP 的配置步骤:

  1. 定义切面类:创建一个切面类,其中包含了切面的逻辑和通知的定义。
  2. 创建 XML 配置文件:创建一个 XML 配置文件,用于定义切面和通知的关系。
  3. 配置切面和通知:在 XML 配置文件中,使用 <aop:config> 元素来配置切面和通知。
  4. 定义切点:使用 <aop:pointcut> 元素来定义切点,切点用于匹配连接点。
  5. 配置通知:使用 <aop:advisor> 元素来配置通知,将切面和切点关联起来。
  6. 引入其他配置:根据需要,可以在 XML 配置文件中引入其他的配置,如引入目标对象、引入代理等。

在这里插入图片描述

基于XML的AOP操作展示

public interface Calculator {int add(int i, int j);int sub(int i, int j);int mul(int i, int j);int div(int i, int j);}
@Component
public class CalculatorImpl implements Calculator {@Overridepublic int add(int i, int j) {int result = i + j;System.out.println("方法内部,result:"+result);return result;}@Overridepublic int sub(int i, int j) {int result = i - j;System.out.println("方法内部,result:"+result);return result;}@Overridepublic int mul(int i, int j) {int result = i * j;System.out.println("方法内部,result:"+result);return result;}@Overridepublic int div(int i, int j) {int result = i / j;System.out.println("方法内部,result:"+result);return result;}
}
@Component
@Aspect //将当前组件标识为切面
public class LoggerAspect {public void pointCut(){}public void beforeAdviceMethod(JoinPoint joinPoint) {//获取连接点所对应方法的签名信息Signature signature = joinPoint.getSignature();//获取连接点所对应方法的参数Object[] args = joinPoint.getArgs();System.out.println("LoggerAspect,方法:"+signature.getName()+",参数:"+ Arrays.toString(args));}public void afterAdviceMethod(JoinPoint joinPoint){//获取连接点所对应方法的签名信息Signature signature = joinPoint.getSignature();System.out.println("LoggerAspect,方法:"+signature.getName()+",执行完毕");}/*** 在返回通知中若要获取目标对象方法的返回值* 只需要通过@AfterReturning注解的returning属性* 就可以将通知方法的某个参数指定为接收目标对象方法的返回值的参数*/public void afterReturningAdviceMethod(JoinPoint joinPoint, Object result){//获取连接点所对应方法的签名信息Signature signature = joinPoint.getSignature();System.out.println("LoggerAspect,方法:"+signature.getName()+",结果:"+result);}/*** 在异常通知中若要获取目标对象方法的异常* 只需要通过AfterThrowing注解的throwing属性* 就可以将通知方法的某个参数指定为接收目标对象方法出现的异常的参数*/public void afterThrowingAdviceMethod(JoinPoint joinPoint, Throwable ex){//获取连接点所对应方法的签名信息Signature signature = joinPoint.getSignature();System.out.println("LoggerAspect,方法:"+signature.getName()+",异常:"+ex);}public Object aroundAdviceMethod(ProceedingJoinPoint joinPoint){Object result = null;try {System.out.println("环绕通知-->前置通知");//表示目标对象方法的执行result = joinPoint.proceed();System.out.println("环绕通知-->返回通知");} catch (Throwable throwable) {throwable.printStackTrace();System.out.println("环绕通知-->异常通知");} finally {System.out.println("环绕通知-->后置通知");}return result;}}
@Component
public class ValidateAspect {public void beforeMethod(){System.out.println("ValidateAspect-->前置通知");}}

XML文件配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context" xmlns:c="http://www.springframework.org/schema/c"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"><context:component-scan base-package="com.miaow.xml"></context:component-scan><aop:config >
<!--        将IOC容器的bean设置为切面 @Component 自动将我们标记的类设置为类名小字母开头-->
<!--        设置一个共同的切入点表达式--><aop:pointcut id="pointCut" expression="execution(* com.miaow.xml.CalculatorImpl.*(..))"/><aop:aspect ref="loggerAspect"><aop:before method="beforeAdviceMethod" pointcut-ref="pointCut"></aop:before><aop:after method="afterAdviceMethod" pointcut-ref="pointCut"></aop:after><aop:after-returning method="afterReturningAdviceMethod" returning="result" pointcut-ref="pointCut"></aop:after-returning><aop:after-throwing method="afterThrowingAdviceMethod" throwing="ex" pointcut-ref="pointCut"></aop:after-throwing><aop:around method="aroundAdviceMethod" pointcut-ref="pointCut"></aop:around></aop:aspect><!--    设置优先级--><aop:aspect ref="validateAspect" order="1"><aop:before method="beforeMethod" pointcut-ref="pointCut"></aop:before></aop:aspect></aop:config>
</beans>

测试类

public class AOPByXMLTest {@Testpublic void testAop(){ApplicationContext context = new ClassPathXmlApplicationContext("Spring-aop-xml.xml");Calculator calculator = (Calculator) context.getBean(Calculator.class);calculator.add(1,2);}
}
ValidateAspect-->前置通知
LoggerAspect,方法:add,参数:[1, 2]
环绕通知-->前置通知
方法内部,result:3
环绕通知-->返回通知
环绕通知-->后置通知
LoggerAspect,方法:add,结果:3
LoggerAspect,方法:add,执行完毕

通过 aop:config 元素配置了切面和通知,使用 aop:pointcut 元素定义了切点,使用 aop:before、aop:after、aop:after-returning、aop:after-throwing、aop:around 元素配置了不同类型的通知。

通过基于 XML 的配置,可以灵活地定义和配置切面和通知,实现对目标对象的横切关注点的处理。

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

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

相关文章

Vue3框架搭建:vue+vite+pina+typescript

一、使用vue-create创建一个vue3项目 仓库地址&#xff1a;GitHub - buguniao5213/LuArch: Front-end architecture 官方地址&#xff1a;GitHub - vuejs/create-vue: &#x1f6e0;️ The recommended way to start a Vite-powered Vue project 原始目录结构如下&#xff1…

ASP.NET MVC Lock锁的测试

思路&#xff1a;我们让后台Thread.Sleep一段时间&#xff0c;来模拟一个耗时操作&#xff0c;而这个时间可以由前台提供。 我们开启两个或以上的页面&#xff0c;第一个耗时5秒(提交5000)&#xff0c;第二个耗时1秒(提交1000)。 期望的测试结果&#xff1a; 不加Lock锁&…

胡克定律(Hooke‘s Law)

胡克定律&#xff08;Hooke’s Law&#xff09; flyfish 在一个简单的阻尼振动系统中&#xff0c;力可以分为多个组成部分&#xff0c;其中包括弹力、阻力等。胡克定律 描述了弹力与位移之间的关系&#xff0c;是研究弹簧系统中弹力的基础。 胡克定律&#xff08;Hooke’s L…

192.168.1.1路由器管理系统使用教程

节选自&#xff1a;192.168.1.1路由器管理系统-厂商有哪些-如何使用-无法登录原因-苏州稳联 什么是 192.168.1.1 路由器管理系统&#xff1f; 192.168.1.1 是大多数家庭路由器的默认 IP 地址&#xff0c;用于访问路由器的管理控制台。通过这个管理系统&#xff0c;用户可以配…

【多媒体】Java实现MP4和MP3音视频播放器【JavaFX】【更多功能的播放器】【音视频播放】

在Java中播放视频可以使用多种方案&#xff0c;最常见的是通过Swing组件JFrame和JLabel来嵌入JMF(Java Media Framework)或Xuggler。不过&#xff0c;JMF已经不再被推荐使用&#xff0c;而Xuggler是基于DirectX的&#xff0c;不适用于跨平台。而且上述方案都需要使用第三方库。…

websockt初始化,创建一个webSocket示例

写文思路&#xff1a; 以下主要从几个方面着手写websocket相关&#xff0c;包括以下&#xff1a;什么是webSocket&#xff0c;webSocket的优点和劣势&#xff0c;webSocket工作原理&#xff0c;webSocket握手示例&#xff0c;如何使用webSocket(使用webSocket的一个示例)&#…

2024中国大学专业排名:生态、地理、草业、林学、资环

生态学、林学、地理科学、草业科学、农业资源与环境、大气科学、农学、地球化学、水土保持与荒漠化防治、自然地理与资源环境、地理信息科学、应用气象学共12个专业。 一、生态学 二、林学 三、地理科学 四、草业科学 五、农业资源与环境 六、大气科学 七、农学 八、地球化学 九…

Memcached 介绍与详解及在Java Spring Boot项目中的使用与集成

Memcached 介绍 Memcached 是一种高性能的分布式内存对象缓存系统&#xff0c;主要用于加速动态Web应用以减少数据库负载&#xff0c;从而提高访问速度和性能。作为一个开源项目&#xff0c;Memcached 被广泛应用于许多大型互联网公司&#xff0c;如Facebook、Twitter 和 YouT…

精准注入:掌握Conda包依赖注入的艺术

精准注入&#xff1a;掌握Conda包依赖注入的艺术 引言 在复杂的软件开发和数据分析项目中&#xff0c;依赖管理是确保项目顺利运行的关键。Conda作为功能强大的包管理器&#xff0c;不仅能够处理Python包的依赖&#xff0c;还支持高级的依赖注入技术&#xff0c;允许开发者更…

【《无主之地3》风格角色渲染在Unity URP下的实现_角色渲染(第四篇) 】

文章目录 概要描边问题外秒变分叉解决办法1:测试效果如下:外秒变分叉解决办法2:URP管线下PBR渲染源码关键词解释:完整shader代码如下:URP管线下二次元皮肤渲染源码URP管线下二次元头发渲染源码简要介绍文章的目的、主要内容和读者将获得的知识。 概要 提示:《无主之地3》…

希喂、鲜朗和牧野奇迹主食冻干怎么样?第一次喂冻干哪款更好

我是个宠物医生&#xff0c;每天很长时间都在跟猫猫狗狗打交道&#xff0c;送到店里来的猫猫状态几乎是一眼就能看出来&#xff0c;肥胖、肝损伤真是现在大部分家养猫正面临的&#xff0c;靠送医治疗只能减缓无法根治&#xff0c;根本在于铲屎官的喂养方式。 从业这几年&#…

js前端GBK(url)编码解码简单实现

baidu了一堆&#xff0c;发现基本都需要下载并调用第三方组件&#xff0c;嫌麻烦&#xff0c;最后找到这篇文章&#xff1a;https://www.cnblogs.com/index-html/p/js-str-to-gbk-ultra-lite.html 在他的基础上完善了该方法&#xff0c;调用方式&#xff1a; decStr2 GBKenco…

SuperMap GIS基础产品FAQ集锦(20240709)

一、SuperMap iDesktopX 问题1&#xff1a;请问针对iDesktopX地质体建模功能的数据组织格式相关问题请教哪位同事? 11.1.1 【解决办法】“地质体构建”功能可依据多个地质点数据集实现对地质体的构建&#xff0c;构建地质体中点图层的顺序对应实际地层由高到低。可参考官方博…

全能型CAE/CFD建模工具SimLab 详解Part1: Geomtry,轻松集成力学、电磁学、疲劳优化等功能

SimLab的建模功能 SimLab集成了结构力学&#xff0c;流体力学&#xff0c;电磁学&#xff0c;疲劳和优化等功能&#xff0c;是全能型的CAE / CFD建模工具。 具有强大的几何、网格编辑功能&#xff0c;能够快速的清理复杂模型&#xff0c;减少手动修复的工作量&#xff0c;提高…

考研数学什么时候开始强化?如何保证进度不掉队?

晚了。我是实在人&#xff0c;不给你胡乱吹&#xff0c;虽然晚了&#xff0c;但相信我&#xff0c;还有的救。 实话实说&#xff0c;从七月中旬考研数一复习完真的有点悬&#xff0c;需要超级高效快速... 数二的时间也有点紧张... 中间基本没有试错的时间&#xff0c;让你换…

【linux】内核文件创建以及写文件

在测试创建文件时&#xff0c;测试发现需要提升内存访问权限到 KERNEL_DS。内核使用系统调用参数肯定是内核空间&#xff0c;为了不让这些系统调用检查参数所以必须设置set_fs(KERNEL_DS)才能使用该系统调用。记录一下 #include <linux/kernel.h> #include <linux/mo…

使用zip命令压缩大文件并分割,再合并成单个文件的操作指南

在处理大型文件&#xff08;如超过100GB的文件&#xff09;时&#xff0c;直接进行压缩和传输可能会遇到存储或网络带宽的限制。为了更有效地管理这些文件&#xff0c;我们可以先将它们使用zip命令进行压缩&#xff0c;然后使用split命令将压缩后的文件分割成多个较小的部分&am…

linux宝塔负载状态100%解决办法

宝塔面板负载状态显示100% 接着使用top命令查看了一下&#xff0c;发现cpu利用率很低&#xff0c;load却很高 通过使用 ps -axjf命令查看是否存在D状态进程 D 状态是指不可中断的睡眠状态&#xff0c;该状态的进程无法被 kill&#xff0c;也无法自行退出&#xff0c;只能通过恢…

使用各向异性滤波器和图像处理方法进行脑肿瘤检测(MATLAB)

医学图像分割一直以来都是计算机辅助诊断领域的研究热点。在医学图像的处理和分析中&#xff0c;对图像中感兴趣区域的准确分割尤其关键。要对感兴趣区域进行分类识别&#xff0c;首先要从图像中把感兴趣区域精确分割出来&#xff0c;然后有针对性地对感兴趣区域提取特征并分类…