文章目录
- 条件注解是什么
- 有哪些条件注解
- 类条件注解
- Bean条件注解
- 属性条件注解
- 资源条件注解
- web应用条件注解
- SpEL( Spring Expression Language )表达式条件注解
- 其他条件注解
- 总结
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。
上篇文章我们在自定义starter中使用到了条件注解 @ConditionalOnMissingBean,那什么是条件注解呢?
条件注解是什么
条件注解是一种基于条件的注解,用于在应用程序中根据特定条件自动配置或排除某些组件。条件注解可以根据应用程序的环境、配置属性或其他条件来控制某些组件的注册和初始化。
有哪些条件注解
Springboot 提供了许多条件注解,主要分为7类:
类条件注解
类条件注解指的是根据指定的类来决定是否创建某个Bean的注解 ,这类注解有两个,分别为:
- @ConditionalOnClass:当类路径上存在指定的类时,创建Bean。
- @ConditionalOnMissingClass:当指定的类在类路径上不存在时,创建Bean。
@ConditionalOnClass
注解具有以下属性:
value
:要检查的类的Class类型数组。当数组中的类型存在时,条件成立。name
:与value
属性类似,指定要检查的类或接口的全限定名。当指定的类或接口存在时,条件成立。
@ConditionalOnMissingClass
只有一个value
属性,和@ConditionalOnClass
的value
属性作用相反。
用法如下:
@AutoConfiguration
public class MyAutoConfiguration {@Bean@ConditionalOnMissingClass("com.example.MyClass")public SomeService someService() {return new SomeService();}
}
在上述示例中,通过@ConditionalOnMissingClass
注解,当类com.example.MyClass
不存在时,才会创建SomeService
实例。
Bean条件注解
Bean条件注解指的是根据指定的Bean来决定是否创建某个Bean ,这类注解有两个,分别为:
- @ConditionalOnBean: 当指定的 Bean 在容器中存在时,条件才会成立,创建某个Bean。
- @ConditionalOnMissingBean:当容器中不存在指定类型的Bean时,创建某个Bean。
@ConditionalOnBean
注解具有以下属性:
-
value
:指定匹配的Bean 类型。可以使用单个Class对象作为值,或者使用一个Class数组来指定多个类。如果容器中存在其中任何一个 Bean,则条件满足。 -
type
:和value
属性类似,不同的是value
属性传的是Class类型数组,type
传的是对应的全限定名或者类名。 -
name
:指定匹配的Bean 名称。可以使用单个 Bean 名称字符串,也可以使用一个名称字符串数组来指定多个 Bean 名称。如果容器中存在其中任何一个 Bean,则条件满足。 -
parameterizedContainer
:指定一个参数化类型的容器,在检查 Bean 是否存在时,会检查容器中是否存在泛型类型的实现类的 Bean。例如:@ConditionalOnBean(parameterizedContainer = List.class)
会检查容器中是否存在类型为java.util.List
的 Bean。 -
annotation
:指定一个注解类型,在检查 Bean 是否存在时,会检查容器中是否存在被该注解标注的 Bean。 -
match
:指定匹配类型。默认为MatchType.ALL
,表示需要检查所有指定的 Bean 是否都存在。如果设置为MatchType.ANY
,则只要存在任何一个指定的 Bean,就可以满足条件。
其中value
和 name
二选一:value
和 name
两个属性是互斥的,只能选择其中一个来指定需要检查是否存在的 Bean。
@ConditionalOnMissingBean
注解除了有@ConditionalOnBean
注解所有的属性外,另外还多了两个属性:
ignored
:匹配时要忽略的Class类型数组。ignoredType
:匹配时要忽略的Class类型数组名称。
用法如下:
@AutoConfiguration
public class MyAutoConfiguration {@Bean@ConditionalOnMissingBeanpublic SomeService someService() {return new SomeService();}
}
在这段代码示例中,如果Spring容器中不包含 SomeService的Bean实例,ApplicationContext应用上下文才会创建名为 someService的Bean。
属性条件注解
属性条件注解指的是根据配置属性的值来决定是否创建某个Bean的注解 ,这类注解只有一个:
- @ConditionalOnProperty:当配置文件中指定属性存在或不存在时,创建某个Bean。
@ConditionalOnProperty
注解有以下属性:
name
:要匹配的属性的名称(必填属性),字符串数组,可以指定多个属性。通常是读取application.properties
或application.yml
文件中的属性值。havingValue
:要检查的属性的期望值,如果要检查的属性的值与该值相等,则条件成立(可选属性,默认为 “”)。matchIfMissing
:要检查的属性不存在时是否也要认为条件成立(可选属性,默认为 false)。prefix
:要检查的属性的前缀,即只有以指定前缀开头的属性才会被检查(可选属性,默认为空字符串)。value
:要检查的属性的值,可以用来代替name
和havingValue
属性(可选属性,默认为空字符串数组),value
可以同时指定多个要检查的属性的值,如果其中任意一个要检查的属性的值与期望值相等,则条件成立。
用法如下:
@ConditionalOnProperty(prefix = "spring", name = {"example.value"} , matchIfMissing = true , havingValue = "suncodernote")
class ExampleAutoConfiguration {
}
上面的示例的意思是,在启动时检查配置文件中前缀为spring
,名称为 example.value
的属性名,并且该属性的值是否是suncodernote
,即使没有匹配成功也可以加载类。
资源条件注解
资源条件注解指的是根据是否包含指定资源来决定是否创建某个Bean的注解 ,这类注解只有下面一个:
- @ConditionalOnResource:根据类路径上是否存在指定资源文件来决定是否创建某个Bean。
@ConditionalOnResource
注解只有一个属性:
resources
:指定需要检查的资源路径(必填),可以是相对于类路径的相对路径或绝对路径。
用法如下:
@ConditionalOnResource(resources = {"file:D:\\javassist-3.29.2-GA.jar" , "application.yml"})
class ExampleAutoConfiguration {
}
上面的示例的意思是,在启动时检查D盘是否有javassist-3.29.2-GA.jar
和classpath下是否有application.yml
,有的话就创建类。
web应用条件注解
web应用条件注解包括以下4个注解:
@ConditionalOnWebApplication
: 当应用程序是一个 Web 应用程序时,会创建某个Bean。@ConditionalOnNotWebApplication
:当应用程序不是一个 Web 应用程序时,会创建某个Bean。@ConditionalOnWarDeployment
:当应用程序以war包的形式部署时,会创建某个Bean。使用内嵌服务器时,会返回false,也就是不会创建某个Bean。@ConditionalOnNotWarDeployment
:当应用程序不以war包的形式部署时,会创建某个Bean。
上面4个注解中只有@ConditionalOnWebApplication
有属性,并且只有一个属性:
- type:web应用程序类型,有
ANY
、SERVLET
、REACTIVE
3个值可选,默认为ANY
。
SpEL( Spring Expression Language )表达式条件注解
SpEL表达式条件注解只有一个注解,那就是@ConditionalOnExpression
,它表示当指定的 SpEL 表达式结果为 true 时,条件才会成立。
@ConditionalOnExpression
只有一个属性:
- value:SpEL表达式,默认值true。如果条件满足,表达式应该返回true,否则返回false。
其他条件注解
除了以上这些注解外,还有一些其他的条件注解,这些注解都在 org.springframework.boot.autoconfigure.condition
包下
-
@ConditionalOnJava:判断当前运行的JVM版本是否符合指定的版本要求,当JVM版本为指定的版本范围时,将会触发实例化。
-
@ConditionalOnCheckpointRestore:用于指示一个配置类只在基于检查点的恢复可用时才会被加载。SpringBoot 在启动时检查是否启用了基于检查点的恢复。如果启用了基于检查点的恢复,那么带有该注解的配置类将会被加载并应用。否则,该配置类将不会被加载。在分布式系统中,检查点(Checkpoint) 是一种保存系统状态的方法,以便在系统故障或失败时可以恢复到之前的状态。
-
@ConditionalOnCloudPlatform:只有在指定的云平台运行程序时才会加载指定的Bean。
-
@ConditionalOnJndi:只有在 JNDI(Java Naming and Directory Interface) 存在的情况下,才会加载指定的 Bean。
-
@ConditionalOnSingleCandidate:当使用
@ConditionalOnSingleCandidate
注解标记一个Bean时,它会根据容器中是否存在指定类型的Bean来决定是否注册这个Bean。如果在容器中存在且只存在一个指定类型的Bean,则被@ConditionalOnSingleCandidate
注解标记的Bean将会被注册;如果不存在或存在多个指定类型Bean,则不会注册该Bean。这个注解在一些情况下非常有用,例如在多个实现类中选择一个默认的实现类,或者在只有一个数据源时配置默认的数据源等。通过使用@ConditionalOnSingleCandidate
注解,可以避免歧义性的自动装配问题,并确保只有在特定条件下才注册相关的Bean。 -
@ConditionalOnThreading:SpringBoot 3.2新增的一个注解,只有在使用特定类型的线程时创建 Bean。 特定类型的线程包括平台线程和虚拟线程。
总结
通过使用条件注解,可以轻松地根据应用程序的需求自定义配置。通常情况下,SpringBoot提供的条件注解已经足够使用,如果不满足的话我们可以自定义一个条件注解,下篇文章将介绍一下如何自定义一个条件注解。