【Spring Boot】详解条件注解以及条件拓展注解@Conditional与@ConditionalOnXxx
Spring
@Conditional
Spring 4.0+提供的注解。作用是给需要装载的Bean增加一个条件判断。只有满足条件才会装在到IoC容器中。而这个条件可以由自己去完成的,可以通过重写Condition接口重写matches()方法去实现自定义的逻辑。所以说这个注解增加了对Bean装载的灵活性。
源码
可以看出来首先可以修饰在类、接口、枚举以及方法上。并且可以接收一个或多个实现Condition接口的类。

那么在Condition接口中只有一个返回布尔类型的matches()方法。从这个单词也看得出来这是匹配的意思,所以就是匹配校验Bean是否可以被加载进IoC容器中。Determine if the condition matches(确定条件是否匹配)。

实战代码
以下先建两个Bean类、一个条件类、一个配置类、以及测试Main类。需要注意的是条件类中的参数并不是Spring的上下文ApplicationContext,所以其内容需要设置在-vm options中。至于这个-vm [options]中的options可以通过DOS窗口输入Java就可以看到有什么选项了。
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Animal {private String name;private String sex;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Person {private String name;private Integer age;
}
public class PersonCondition implements Condition {/*** @param context 上下文* @param metadata 注解元信息*/@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {// 通过条件上下文获取环境中的配置文件信息String property = context.getEnvironment().getProperty("spring.createBean");if(null == property) {return false;}return property.contains("person");}
}
public class AnimalCondition implements Condition {/*** @param context 上下文* @param metadata 注解元信息*/@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {// 通过条件上下文获取环境中的配置文件信息String property = context.getEnvironment().getProperty("spring.createBean");if(null == property) {return false;}return property.contains("animal");}
}
public class ConditionalTest {public static void main(String[] args) {// 通过Spring上下文ApplicationContext传入配置类获取其中的Bean描述并输出ApplicationContext applicationContext = new AnnotationConfigApplicationContext(ConditionalConfig.class);Arrays.stream(applicationContext.getBeanDefinitionNames()).forEach(System.out::println);}
}
测试结果

SpringBoot
关于@ConditionalOnXxx注解是在SpringBoot中拓展出来的,是原先Spring框架中没有存在的注解。那么以下就逐一去了解每个注解的作用。需要说的是这些注解全部都可以注解在类、接口、枚举和方法上。

从上图可以发现有十三种是@ConditionalOnXxx。其中就不了解@ConditionalOnCloudPlatform与@ConditionOnJndi这两个注解了。
上面的扩展注解我们可以简单的分为以下几类:
- Bean作为条件:@ConditionalOnBean、@ConditionalOnMissingBean、@ConditionalOnSingleCandidate。
- 类作为条件:@ConditionalOnClass、@ConditionalOnMissingClass。
- SpEL表达式作为条件:@ConditionalOnExpression。
- Java版本作为条件: @ConditionalOnJava
- 配置属性作为条件:@ConditionalOnProperty。
- 资源文件作为条件:@ConditionalOnResource。
- 是否Web应用作为判断条件:@ConditionalOnWebApplication、@ConditionalOnNotWebApplication。
条件为Bean的情况
@ConditionalOnBean
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional({OnBeanCondition.class})
public @interface ConditionalOnBean {/*** 需要作为条件的类的Class对象数组*/Class<?>[] value() default {};/*** 需要作为条件的类的Name, Class.getName()*/String[] type() default {};/*** (用于指定注解修饰的Bean)条件所需的注解类*/Class<? extends Annotation>[] annotation() default {};/*** Spring容器中Bean的名字*/String[] name() default {};/*** 搜索容器层级,当前容器,父容器*/SearchStrategy search() default SearchStrategy.ALL;/*** 可能在其泛型参数中包含指定Bean类型的其他类*/Class<?>[] parameterizedContainer() default {};
}
源码中的属性就不一一展示测试了,这里就测试value于name即可,value传入的是Class类型。而这个注解的含义很简单:如果IoC容器中存在该注解中value属性对应的Bean,那么就加载被该注解注解的Bean。否则不加载。测试代码采用上面Spring目录下的测试结果中的代码。这里主要展示配置类中的逻辑。
@Configuration
public class ConditionalConfig {@Beanpublic Person person() {return new Person();}@Bean@ConditionalOnBean(Person.class)//@ConditionalOnBean(name = "com.gok.entity.Person")public Animal animal() {return new Animal();}
}

这里需要注意的是,Spring加载Bean是在配置类中自上而下加载的,所以说如果person()与animal()两个方法换位置的话Animal是不会被加载到IoC容器中的,因为在它加载时Person还没被加载入IoC容器。
@ConditionalOnMissingBean
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnBeanCondition.class)
public @interface ConditionalOnMissingBean {/*** 需要作为条件的类的Class对象数组*/Class<?>[] value() default {};/*** 需要作为条件的类的Name, Class.getName()*/String[] type() default {};/*** 匹配Bean的时候需要忽视的Class对象数组,一般是父类* @ConditionalOnMissingBean(value = JdbcFactory.class, ignored = MySqlDefaultFactory.class)*/Class<?>[] ignored() default {};/*** 匹配Bean的时候需要忽视的类的Name, Class.getName()*/String[] ignoredType() default {};/*** (用于指定注解修饰的Bean)条件所需的注解类*/Class<? extends Annotation>[] annotation() default {};/*** Spring容器中Bean的名字*/String[] name() default {};/*** 搜索容器层级,当前容器,父容器*/SearchStrategy search() default SearchStrategy.ALL;/*** 可能在其泛型参数中包含指定Bean类型的其他类*/Class<?>[] parameterizedContainer() default {};
}
理解了上面注解的作用,那这个注解就游刃有余了,miss单词意为错过、没有的意思。所以这个注解的作用就是:如果IoC容器中不存在该注解中value属性对应的Bean,那么就加载被该注解注解的Bean。否则不加载。
@Configuration
public class ConditionalConfig {@Beanpublic Person person() {return new Person();}@Bean@ConditionalOnMissingBean(Person.class)//@ConditionalOnMissingBean(name = "com.gok.entity.Person")public Animal animal() {return new Animal();}
}
@ConditionalOnSingleCandidate
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnBeanCondition.class)
public @interface ConditionalOnSingleCandidate {/*** 需要作为条件的类的Class对象*/Class<?> value() default Object.class;/*** 需要作为条件的类的Name, Class.getName()*/String type() default "";/*** 搜索容器层级,当前容器,父容器*/SearchStrategy search() default SearchStrategy.ALL;
}
此注解从单词single与candidate可以得出是单个候选人的意思。大致可以猜测是存在相同类型的Bean的话只会对单个有效。我尝试将其放到person02()上,还是一样将这两个Bean加载到了IoC当中,但是放在第一个person01()上,导致person01没有被加载到IoC容器当中。所以此Bean的作用就是:如果当指定Bean在容器中只有一个,或者虽然有多个但是指定首选Bean的时候则生效。即同类型的Bean中,首选Bean无法被加载入IoC容器中。
@Configuration
public class ConditionalConfig {@Bean@ConditionalOnSingleCandidatepublic Person person01() {return new Person();}@Beanpublic Person person02() {return new Person();}
}
条件为类的情况
@ConditionalOnClass
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnClassCondition.class)
public @interface ConditionalOnClass {/*** 需要作为条件的类的Class对象数组*/Class<?>[] value() default {};/*** 需要作为条件的类的Name, Class.getName()*/String[] name() default {};
}
这个其实和@ConditionalOnBean类似,但是那个注解是在IoC容器中或者是类全限定名找是否存在该Spring Bean。而@ConditionalOnClas是在IoC容器中或者是类全限定名找到是否存在该类。如果存在就加载,不存在就不加载到IoC容器中。
@ConditionalMissingClass
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional({OnClassCondition.class})
public @interface ConditionalOnMissingClass {/*** 需要作为条件的类的Name, Class.getName()*/String[] value() default {};
}
与@ConditionalOnClass相反。会在这里一起展示代码以及测试的结果。Plant类是真实存在的,所以说person01被加载到IoC容器中,而person02没有被加载到IoC当中。
@Configuration
public class ConditionalConfig {@Bean@ConditionalOnClass(Animal.class)public Person person01() {return new Person();}@Bean@ConditionalOnMissingClass("com.gok.entity.Animal")public Person person02() {return new Person();}
}

条件为SpEL表达式的情况
@ConditionalOnExpression
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD })
@Documented
@Conditional(OnExpressionCondition.class)
public @interface ConditionalOnExpression {/*** 要作为条件的SpEL表达式*/String value() default "true";
}
这个注解就是用来判断该Bean是否符合SpEL表达式,至于什么是SpEL表达式就自行百度学习了,就不多放篇幅去详细说明了。这里我设置person01为true,而person02为false。
@Configuration
public class ConditionalConfig {@Bean@ConditionalOnExpression("true")public Person person01() {return new Person();}@Bean@ConditionalOnExpression("false")public Person person02() {return new Person();}
}
条件为Java的情况
@ConditionalOnJava
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnJavaCondition.class)
public @interface ConditionalOnJava {/*** 比较方式,Range.EQUAL_OR_NEWER:当前版本等于或高于、Range.OLDER_THAN:当前版本老于,越早的版本越老*/ConditionalOnJava.Range range() default ConditionalOnJava.Range.EQUAL_OR_NEWER;/*** 指定JAVA版本*/JavaVersion value();/*** Range options.*/public static enum Range {/*** Equal to, or newer than the specified {@link JavaVersion}.*/EQUAL_OR_NEWER,/*** Older than the specified {@link JavaVersion}.*/OLDER_THANprivate Range() {}}
}
此注解用来判断当前运行环境的Java版本是多少。符合范围内的条件才会加载Bean。
@Configuration
public class ConditionalConfig {@Bean@ConditionalOnJava(JavaVersion.EIGHT)public Person person01() {return new Person();}@Bean@ConditionalOnJava(JavaVersion.NINE)public Person person02() {return new Person();}
}


条件为配置条件的情况
@ConditionalOnProperty
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD })
@Documented
@Conditional(OnPropertyCondition.class)
public @interface ConditionalOnProperty {/*** 对应property名称的值*/String[] value() default {};String[] name() default {};/*** property名称的前缀,可有可无*/String prefix() default "";/*** 与name组合使用,比较获取到的属性值与havingValue给定的值是否相同,相同才加载配置*/String havingValue() default "";/*** 缺少该property时是否可以加载。如果为true,没有该property也会正常加载;反之报错*/boolean matchIfMissing() default false;
}
此注解用于条件配置中读取peoperties文件中的信息。本人测试读取yml无效,需要在配置类上多添加个@PropertySource注解读取文件才能够使用配置条件注解。
# application.properties中的内容
com.gok.test=true
com.gok.password=123456
@Configuration
// 读取properties文件的方式 可以配合@Value注解读取详细信息
@PropertySource(value = "classpath:application.properties", encoding = "UTF-8")
//@PropertySources({@PropertySource(value = "classpath:application.properties", encoding = "UTF-8")})
public class ConditionalConfig {@Bean@ConditionalOnProperty("com.gok.test")public Person person01() {return new Person();}@Bean@ConditionalOnProperty(name = "com.gok.test")public Person person02() {return new Person();}@Bean@ConditionalOnProperty("com.gok.password")public Person person03() {return new Person();}@Bean@ConditionalOnProperty(name = "com.gok.password", havingValue = "123456")public Person person04() {return new Person();}@Bean@ConditionalOnProperty(name = "com.gok.password", havingValue = "123456789")public Person person05() {return new Person();}@Bean@ConditionalOnProperty(value = "com.gok.password=123456", matchIfMissing = true)public Person person06() {return new Person();}@Bean// 这里要注意如果要使用prefix前缀的话 必须带上name或者value// 或者会报错:The name or value attribute of @ConditionalOnProperty must be specified// 以下拼接即为:是否存在com.gok.password这个属性@ConditionalOnProperty(prefix = "com.gok", name = "password")public Person person07() {return new Person();}
}
条件为资源条件的情况
@ConditionalOnResource
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnResourceCondition.class)
public @interface ConditionalOnResource {/*** 要作为判断条件的资源文件名称 @ConditionalOnResource(resources = ”mybatis.xml”)*/String[] resources() default {};
}
查询指定的资源,不仅仅可以查找classpath下的文件,还可以用来查找外部资源是否存在。
@Configuration
public class ConditionalConfig {@Bean@ConditionalOnResource(resources = "https://www.baidu.com")public Person person01() {return new Person();}@Bean@ConditionalOnResource(resources = "classpath:application.properties")public Person person02() {return new Person();}@Bean@ConditionalOnResource(resources = "https://www.baiduhaha.com")public Person person03() {return new Person();}
}
条件为Web应用的情况
@ConditionalOnWebApplication
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnWebApplicationCondition.class)
public @interface ConditionalOnWebApplication {/*** 需要作为条件的Web应用程序的必需类型*/ConditionalOnWebApplication.Type type() default ConditionalOnWebApplication.Type.ANY;/*** Available application types.*/public static enum Type {/*** 任何web应用都将匹配*/ANY,/*** 仅基于servlet的Web应用程序将匹配*/SERVLET,/*** 仅基于反应式的Web应用程序将匹配*/REACTIVE;private Type() {}}
}
判断当前是否为Web项目/Web环境。主要就是从是否有导入Web的依赖。这里简单介绍以下三种不同情况的依赖引入情况。
<!-- 无Web容器 -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- 使用Tomcat/Servlet Web容器 -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 使用Netty 响应式的Web容器 -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
@ConditionalOnNotWebApplication
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional({OnWebApplicationCondition.class})
public @interface ConditionalOnNotWebApplication {
}
参考文章
https://www.cnblogs.com/dusucyy/p/16609736.html
@ConditionalOnBean详解_你就像甜甜的益达的博客-CSDN博客a
相关文章:
【Spring Boot】详解条件注解以及条件拓展注解@Conditional与@ConditionalOnXxx
Spring Conditional Spring 4.0提供的注解。作用是给需要装载的Bean增加一个条件判断。只有满足条件才会装在到IoC容器中。而这个条件可以由自己去完成的,可以通过重写Condition接口重写matches()方法去实现自定义的逻辑。所以说这个注解增加了对Bean装载的灵活性。…...
Android 12 源码分析 —— 应用层 一(SystemUI准备篇)
Android 12 源码分析 —— 应用层一(SystemUI准备篇) 在接下来的时间中,将会使用Pixel 3(blueline)作为研究对象,选用AOSP的android-12.0.0_r34分支作源代码。 先从android的应用层进行探析,然后慢慢深入android的fr…...
记录 MySQL 如何开启已有的定时任务
1.首先,确保你已经在MySQL的配置文件my.ini中启用了事件调度器。在[mysqld]部分添加event_schedulerON,然后保存文件并重启MySQL服务。这将启用MySQL的事件调度器功能。 但如果是线上业务不能停也可以在该数据库中输入 -- 开启事件计划程序 SET GLOBAL …...
三种生成树(STP,RSTP,MSTP)的基本配置(自我理解)
目录 一、为什么要使用生成树(STP): 二、由于设备冗余而导致的问题: 广播风暴: 三、802.1D生成树基本配置 四、802.1D生成树实验 实验拓扑: 实验配置: 配置完成后,在SW8上观察现象&…...
FRP内网穿透,配置本地电脑作为服务器
FRP内网穿透,配置本地电脑作为服务器 下载FRP服务端客户端 参考链接: https://www.it235.com/实用工具/内网穿透/pierce.html https://www.cnblogs.com/007sx/p/17469301.html 由于没有公网ip,所以尝试内网穿透将本地电脑作为服务器ÿ…...
Linux基础指令
本文已收录至《Linux知识与编程》专栏! 作者:ARMCSKGT 演示环境:CentOS 7 目录 前言 正文 查看当前用户whoami 查看当前目录路径pwd 清理屏幕clear 查看目录下文件指令ls 进入目录指令cd 以树状结构显示目录文件tree 创建普通文件指…...
基于GRU门控循环网络的时间序列预测matlab仿真,对比LSTM网络
目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 LSTM: GRU 2.算法运行软件版本 matlab2022a 3.部分核心程序 %构建GRU网络模型 layers [ ...sequenceInputLayer(N_feature)gruLayer(N_hidden)f…...
windows上ffmpeg如何录制双屏幕中的一个屏幕上的视频
首先,如何在window上安装ffmpeg自己查找scoop安装ffmpeg. 如题: 如果你有两个屏幕,如何让ffmpeg来录制其中的一个屏幕的视频呢。 很简单,首先你要查看另外一个屏幕的分辨率: 第一步:进入系统中 第二步&am…...
使用Python搭建服务器公网展示本地电脑文件
文章目录 1.前言2.本地http服务器搭建2.1.Python的安装和设置2.2.Python服务器设置和测试 3.cpolar的安装和注册3.1 Cpolar云端设置3.2 Cpolar本地设置 4.公网访问测试5.结语 1.前言 Python作为热度比较高的编程语言,其语法简单且语句清晰,而且python有…...
Java IO流(五)Netty实战[TCP|Http|心跳检测|Websocket]
Netty入门代码示例(基于TCP服务) Server端 package com.bierce.io.netty.simple; import io.netty.bootstrap.ServerBootstrap; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.*; import io.netty.channel.nio.NioEventLoopGro…...
C#基础进阶
C#基础进阶 泛型 http://www.runoob.com/csharp/csharp-generic.html 匿名函数 http://www.runoob.com/csharp/csharp-anonymous-methods.html 扩展方法 https://blog.csdn.net/u011127019/article/details/54728886 https://docs.microsoft.com/zh-cn/dotnet/csharp/pr…...
Java:ArrayList集合、LinkedList(链表)集合的底层原理及应用场景
ArrayList集合的底层原理及应用场景 LinkedList(链表)集合的底层原理及应用场景 单向链表 增加数据 删除数据 双向链表 LinkedList的应用场景之一:可以用来设计队列 入队 出队 LinkedList的应用场景之一:可以用来设计栈 压栈(push),addFirst…...
【Python】json文件的读取
文章目录 1. json简介2.json的使用规范3.json文件的书写4.json文件的读取 1. json简介 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,常用于将结构化数据进行传输和存储。它基于JavaScript语法,但可以被多种编程…...
专用杂凑函数的消息鉴别码算法学习记录
声明 本文是学习github5.com 网站的报告而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 范围 GB/T 15852的本部分规定了三种采用专用杂凑函数的消息鉴别码算法。这些消息鉴别码算法可用作数据完整性检验,检验数据是否被非授权地改变。同样…...
Golang使用消息队列(RabbitMQ)
最近在使用Golang做了一个网盘项目(类似百度网盘),这个网盘项目有一个功能描述如下:用户会删除一个文件到垃圾回收站,回收站的文件有一个时间期限,比如24h,24h后数据库中记录和oss中文件会被删除…...
Apache Spark远程代码执行漏洞(CVE-2023-32007)漏洞复现
漏洞描述 Apache Spark是美国阿帕奇(Apache)基金会的一款支持非循环数据流和内存计算的大规模数据处理引擎。 Apache Spark 3.4.0之前版本存在命令注入漏洞,该漏洞源于如果ACL启用后,HttpSecurityFilter中的代码路径可以允许通过…...
春秋云镜 :CVE-2020-21650(MyuCMS后台rce)
一、题目 靶标介绍: MyuCMS开源内容管理系统,采用ThinkPHP开发而成的社区商城聚合,插件,模板,轻便快捷容易扩展 其2.2版本中admin.php/config/add方法存在任意命令执行漏洞. 进入题目: exp: url/index.p…...
测试框架pytest教程(7)实现 xunit 风格的setup
pytest支持setup和teardown,对于使用unittest和nose框架的用户来说对这些很熟悉,但是在pytest可以使用功能更强大的fixture来实现固定装置。 模块级别 如果单个模块中有多个测试函数和测试类,您可以选择实现以下固定方法,这些方…...
用队列实现栈
目录 题目题目要求示例 解答方法一、实现思路时间复杂度和空间复杂度代码 方法二、实现思路时间复杂度和空间复杂度代码 方法三、实现思路时间复杂度和空间复杂度代码 总结 题目 用队列实现栈 题目要求 题目链接 示例 解答 方法一、 使用两个队列来实现栈。 实现思路 题…...
Anolis 8.6 下 Redis 7.2.0 集群搭建和配置
Redis 7.2.0 搭建和集群配置 一.Redis 下载与单机部署1.Redis 下载2.虚拟机配置3.Redis 单机源码安装和测试4.Java 单机连接测试1.Pom 依赖2.配置文件3.启动类4.配置类5.单元测试6.测试结果 二.Redis 集群部署1.主从1.从节点配置2.Java 测试 2.哨兵1.哨兵节点配置2.复制一个哨兵…...
linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...
【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...
React19源码系列之 事件插件系统
事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...
高等数学(下)题型笔记(八)空间解析几何与向量代数
目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...
Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...
C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...
PAN/FPN
import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...
20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...





