1. 前言
在 spring boot 中,条件注解(conditional 注解) 是一种强大的功能,允许我们根据某些条件动态地注册或跳过特定的 bean。其中,@conditionalonbean 是最常用的条件注解之一,它的作用是:当 spring 容器中存在指定的 bean 时,当前 bean 才会被注册。
本篇文章将详细介绍 @conditionalonbean 的使用场景、原理,并提供多个示例帮助理解。
2. @conditionalonbean 作用与基本用法
2.1 @conditionalonbean 的作用
@conditionalonbean 主要用于以下场景:
- 按需加载 bean:只有在某个 bean 存在时,另一个 bean 才会被创建。
- 模块化设计:某些功能模块需要依赖特定 bean 才能启用,例如 仅当某个组件存在时,自动配置才会生效。
- 避免 bean 冲突:如果某个 bean 依赖其他 bean,则可使用
@conditionalonbean确保它不会因缺少依赖而加载失败。
2.2 基本用法
示例:当 datasource bean 存在时,才创建 myservice bean
import org.springframework.boot.autoconfigure.condition.conditionalonbean;
import org.springframework.context.annotation.bean;
import org.springframework.context.annotation.configuration;
import javax.sql.datasource;
@configuration
public class myconfig {
@bean
public datasource datasource() {
// 这里模拟 datasource 实例,实际可用 hikaridatasource、druid 等
return new fakedatasource();
}
@bean
@conditionalonbean(datasource.class) // 仅当 datasource 存在时,才创建 myservice
public myservice myservice() {
return new myservice();
}
}
class myservice {
public myservice() {
system.out.println("myservice 被创建");
}
}
class fakedatasource implements datasource {
// 这里可以模拟 datasource 方法
}执行结果:
myservice 被创建
如果 datasource() 方法被注释掉,则 myservice 不会被创建。
3. @conditionalonbean 详解
@conditionalonbean 提供了多个属性,可以更加灵活地控制 bean 的创建。
3.1 value 和 type 属性(指定 bean 类型)
用于指定某种类型的 bean 存在时,当前 bean 才会被注册。
@bean
@conditionalonbean(value = datasource.class) // 仅当 datasource 存在时生效
public myrepository myrepository() {
return new myrepository();
}等效于:
@bean
@conditionalonbean(type = "javax.sql.datasource") // 使用全限定类名
public myrepository myrepository() {
return new myrepository();
}区别:
value:直接使用 class 类型,编译时检查更安全。type:使用字符串,可用于避免某些类找不到(如可选依赖)。
3.2 name 属性(指定 bean 名称)
用于 指定某个 bean 名称是否存在 来决定当前 bean 是否加载。
@bean
@conditionalonbean(name = "custombean") // 仅当名为 custombean 的 bean 存在时注册
public mycomponent mycomponent() {
return new mycomponent();
}3.3 annotation 属性(指定 bean 需要标注的注解)
可以指定某些 bean 是否包含特定注解,如果包含,则当前 bean 才会被注册。
@bean
@conditionalonbean(annotation = repository.class) // 仅当存在 @repository 注解的 bean 时生效
public myservice myservice() {
return new myservice();
}3.4 search 属性(搜索范围)
默认情况下,@conditionalonbean 只会在 当前应用上下文 中查找 bean,而不会查找 父上下文(即 spring boot 的 applicationcontext 层级)。
search 选项可以指定搜索范围:
all:在所有父子applicationcontext中搜索。current(默认):仅搜索当前applicationcontext。
@bean
@conditionalonbean(value = datasource.class, search = searchstrategy.all) // 在所有上下文中搜索
public myservice myservice() {
return new myservice();
}4.@conditionalonbean 使用场景
场景 1:按需加载数据库相关 bean
如果应用程序中 使用了数据库,则提供一个 databaseservice,否则不创建:
@bean
@conditionalonbean(datasource.class)
public databaseservice databaseservice() {
return new databaseservice();
}场景 2:启用某些自动配置
spring boot 的 spring-boot-autoconfigure 模块大量使用 @conditionalonbean 来控制自动配置。例如:
只有当 dispatcherservlet 存在时,spring mvc 相关的自动配置才会生效。
@configuration
@conditionalonbean(dispatcherservlet.class)
public class mvcautoconfiguration {
// 仅当 dispatcherservlet 存在时,spring mvc 配置生效
}场景 3:可选依赖的组件
有时,某些功能是可选的,比如当 redis 组件存在时,才创建缓存管理器:
@bean
@conditionalonbean(name = "redistemplate") // 只有当 redistemplate 存在时才加载
public cachemanager cachemanager() {
return new rediscachemanager();
}5. @conditionalonbean vs @conditionalonmissingbean
| 注解 | 作用 |
|---|---|
@conditionalonbean | 当指定 bean 存在时,才注册当前 bean |
@conditionalonmissingbean | 当指定 bean 不存在时,才注册当前 bean |
示例:
@bean
@conditionalonmissingbean(datasource.class) // 仅当 datasource 不存在时才创建
public datasource defaultdatasource() {
return new defaultdatasource();
}6. 结论
在 spring boot 中,@conditionalonbean 可以帮助我们根据 是否存在特定 bean 来 动态注册 bean,广泛用于 按需加载、自动配置 等场景。
总结:
✅ 指定 bean 类型:@conditionalonbean(datasource.class)
✅ 指定 bean 名称:@conditionalonbean(name = "custombean")
✅ 指定 bean 注解:@conditionalonbean(annotation = repository.class)
✅ 搜索范围:@conditionalonbean(search = searchstrategy.all)
你在项目中用过 @conditionalonbean 吗?欢迎留言分享你的经验!🚀
到此这篇关于spring boot 中的 @conditionalonbean 注解详解的文章就介绍到这了,更多相关spring boot @conditionalonbean 注解内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论