注解详解系列 - @ConditionalOnMissingBean:条件性地定义Bean

注解简介

在今天的注解详解系列中,我们将探讨@ConditionalOnMissingBean注解。@ConditionalOnMissingBean是Spring Boot提供的一个注解,用于在特定条件下定义Bean。通过@ConditionalOnMissingBean注解,可以在只有当指定类型的Bean不存在时才创建一个新的Bean,这对于配置覆盖和自定义Bean特别有用。


注解定义

@ConditionalOnMissingBean注解用于在Spring上下文中没有指定类型的Bean时,才创建当前Bean。以下是一个基本的示例:

import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig {

    @Bean
    @ConditionalOnMissingBean
    public MyService myService() {
        return new MyServiceImpl();
    }
}

在这个示例中,如果Spring上下文中不存在MyService类型的Bean,那么myService方法将创建一个新的MyServiceImpl实例。


注解详解

@ConditionalOnMissingBean注解的主要功能是控制Bean的创建条件。它常用于以下场景:

  • 默认配置:为应用程序提供默认的Bean配置,允许用户在需要时覆盖。
  • 模块化设计:在模块化应用程序中,根据实际情况有选择地加载Bean。
  • 自定义扩展:允许用户在不修改原始配置的情况下,自定义和扩展应用程序。

使用场景

@ConditionalOnMissingBean注解广泛应用于Spring Boot应用程序中,特别是在自动配置和模块化设计中。例如,可以在自动配置类中使用该注解,以便用户在需要时提供自己的实现。


示例代码

以下是一个使用@ConditionalOnMissingBean注解的代码示例,展示了如何在Spring Boot应用程序中条件性地定义Bean:

服务接口和实现

public interface MyService {
    void performTask();
}

public class MyServiceImpl implements MyService {
    @Override
    public void performTask() {
        System.out.println("Default MyService implementation");
    }
}

public class CustomMyServiceImpl implements MyService {
    @Override
    public void performTask() {
        System.out.println("Custom MyService implementation");
    }
}

自动配置类

import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyServiceAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public MyService myService() {
        return new MyServiceImpl();
    }
}

自定义配置类

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class CustomConfig {

    @Bean
    public MyService customMyService() {
        return new CustomMyServiceImpl();
    }
}

在这个示例中:

  • 如果没有提供自定义的MyService实现,Spring将使用默认的MyServiceImpl
  • 如果用户提供了自定义的CustomMyServiceImpl,Spring将使用该自定义实现。

高级用法

条件性地定义多个Bean

可以为多个Bean定义条件。例如:

@Configuration
public class AdvancedConfig {

    @Bean
    @ConditionalOnMissingBean(name = "firstBean")
    public MyService firstService() {
        return new FirstServiceImpl();
    }

    @Bean
    @ConditionalOnMissingBean(name = "secondBean")
    public MyService secondService() {
        return new SecondServiceImpl();
    }
}

在这个示例中,firstServicesecondService将根据它们各自的条件性定义来创建。

结合其他条件注解

可以将@ConditionalOnMissingBean与其他条件注解结合使用。例如:

import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class CombinedConfig {

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(name = "app.feature.enabled", havingValue = "true")
    public MyService featureService() {
        return new FeatureServiceImpl();
    }
}

在这个示例中,只有当app.feature.enabled属性为true且没有其他MyService类型的Bean时,才会创建FeatureServiceImpl


常见问题

问题:如何在测试中验证@ConditionalOnMissingBean的行为?

解决方案:可以在测试中使用不同的配置类来验证@ConditionalOnMissingBean的行为。例如:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.ContextConfiguration;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

@SpringBootTest
@ContextConfiguration(classes = {MyServiceAutoConfiguration.class, ConditionalOnMissingBeanTest.TestConfig.class})
public class ConditionalOnMissingBeanTest {

    @Autowired
    private MyService myService;

    @Test
    public void testConditionalOnMissingBean() {
        assertTrue(myService instanceof CustomMyServiceImpl);
    }

    @Configuration
    static class TestConfig {
        @Bean
        public MyService customMyService() {
            return new CustomMyServiceImpl();
        }
    }
}

在这个测试示例中,通过在测试配置中提供自定义的MyService实现,可以验证@ConditionalOnMissingBean的行为。


小结

通过今天的学习,我们了解了@ConditionalOnMissingBean注解的基本用法和应用场景,以及如何在Spring Boot应用程序中条件性地定义Bean。明天我们将探讨另一个重要的Spring注解——@ConditionalOnProperty


相关链接
  • Spring Boot 官方文档
  • Spring Conditional 注解

希望这个示例能帮助你更好地理解和应用@ConditionalOnMissingBean注解。如果有任何问题或需要进一步的帮助,请随时告诉我。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

zabbix-server的搭建

zabbix-server的搭建 部署 zabbix 服务端(192.168.99.180) rpm -ivh https://mirrors.aliyun.com/zabbix/zabbix/5.0/rhel/7/x86_64/zabbix-release-5.0-1.el7.noarch.rpm cd /etc/yum.repos.d sed -i s#http://repo.zabbix.com#https://mirrors.aliyun.com/zabbix# zabbix.r…

关于FPGA对 DDR4 (MT40A256M16)的读写控制 4

关于FPGA对 DDR4 (MT40A256M16)的读写控制 4 语言 :Verilg HDL 、VHDL EDA工具:ISE、Vivado、Quartus II 关于FPGA对 DDR4 (MT40A256M16)的读写控制 4一、引言二、DDR4 SDRAM设备中模式寄存器重要的模式寄存…

Arduino - LED 矩阵

Arduino - LED 矩阵 Arduino - LED Matrix LED matrix display, also known as LED display, or dot matrix display, are wide-used. In this tutorial, we are going to learn: LED矩阵显示器,也称为LED显示器,或点阵显示器,应用广泛。在…

“Hello, World!“ 历史由来

布莱恩W.克尼汉(Brian W. Kernighan)—— Unix 和 C 语言背后的巨人 布莱恩W.克尼汉在 1942 年出生在加拿大多伦多,他在普林斯顿大学取得了电气工程的博士学位,2000 年之后取得普林斯顿大学计算机科学的教授教职。 1973 年&#…

C++ | Leetcode C++题解之第203题移除链表元素

题目: 题解: class Solution { public:ListNode* removeElements(ListNode* head, int val) {struct ListNode* dummyHead new ListNode(0, head);struct ListNode* temp dummyHead;while (temp->next ! NULL) {if (temp->next->val val) {…

小柴冲刺软考中级嵌入式系统设计师系列一、计算机系统基础知识(1)嵌入式计算机系统概述

flechazohttps://www.zhihu.com/people/jiu_sheng 小柴冲刺嵌入式系统设计师系列总目录https://blog.csdn.net/qianshang52013/article/details/139975720?spm1001.2014.3001.5501 根据IEEE(国际电气电子工程师协会)的定义,嵌入式系统是&q…

Linux高并发服务器开发(六)线程

文章目录 1. 前言2 线程相关操作3 线程的创建4 进程数据段共享和回收5 线程分离6 线程退出和取消7 线程属性(了解)8 资源竞争9 互斥锁9.1 同步与互斥9.2 互斥锁 10 死锁11 读写锁12 条件变量13 生产者消费者模型14 信号量15 哲学家就餐 1. 前言 进程是C…

哪吒汽车,正在等待“太乙真人”的拯救

文丨刘俊宏 在360创始人、哪吒汽车股东周鸿祎近日连续且着急的“督战”中,哪吒汽车(下简称哪吒)终究还是顶不住了。 6月26日,哪吒通过母公司合众新能源在港交所提交了IPO文件,急迫地希望成为第五家登陆港股的造车新势力…

uniapp中实现瀑布流 短视频页面展示

直接上干货 第一部分为结构 <swiper class"list" :currentindex change"swiperchange" scrolltolower"onReachBottom"><swiper-item style"overflow: scroll;" v-for"(item,index) in 2" :key"index"&g…

DataV大屏组件库

DataV官方文档 DataV组件库基于Vue &#xff08;React版 (opens new window)&#xff09; &#xff0c;主要用于构建大屏&#xff08;全屏&#xff09;数据展示页面即数据可视化&#xff0c;具有多种类型组件可供使用&#xff1a; 源码下载

Golang | Leetcode Golang题解之第204题计数质数

题目&#xff1a; 题解&#xff1a; func countPrimes(n int) int {primes : []int{}isPrime : make([]bool, n)for i : range isPrime {isPrime[i] true}for i : 2; i < n; i {if isPrime[i] {primes append(primes, i)}for _, p : range primes {if i*p > n {break}…

智能交通(1)——杭州交通数据集

赛题简介 在本地赛题中&#xff0c;参赛团队需要在平台提供的仿真交通场景下&#xff0c;通过算法模型驱动交通信号灯&#xff0c;以在各种交通状况&#xff08;高峰期、雨天等&#xff09;下都能最大程度地服务车辆&#xff0c;使其在模拟环境中获得综合最大得分。 数据集 …

Docker 部署 MariaDB 数据库 与 Adminer 数据库管理工具

文章目录 MariaDBmariadb.cnf开启 binlog Adminerdocker-compose.ymlAdminer 连接 MariaDB MariaDB MariaDB是一个流行的开源关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;它是MySQL的一个分支和替代品。 官网&#xff1a;https://mariadb.com/镜像&#xff…

GPU算力是什么,哪些行业需要用到GPU算力?

近两年&#xff0c;计算能力已成为推动各行各业发展的关键因素。而GPU&#xff08;图形处理器&#xff09;算力&#xff0c;作为现代计算技术的重要分支&#xff0c;正逐渐在多个领域展现出其强大的潜力和价值。尚云将简要介绍GPU算力的定义和基本原理&#xff0c;并探讨其在哪…

对于CDA一级考试该咋准备??!

一、了解考试内容和结构 CDA一级考试主要涉及的内容包括&#xff1a;数据分析概述与职业操守、数据结构、数据库基础与数据模型、数据可视化分析与报表制作、Power BI应用、业务数据分析与报告编写等。 CDA Level Ⅰ 认证考试大纲:https://edu.cda.cn/group/4/thread/174335 …

从架构设计的角度分析ios自带网络库和AFNetworking

总结&#xff08;先说明文章分析出的一些‘认知’&#xff09; 从本文中&#xff0c;我们可以总结出一些框架设计上的“认知”&#xff1a; 对于通用的常规配置信息方面的设计&#xff0c;我们可以通过定义一个“类似于NSURLSessionConfiguration、NSURLRequest”的类来完成设…

Python | Leetcode Python题解之第203题移除链表元素

题目&#xff1a; 题解&#xff1a; # Definition for singly-linked list. # class ListNode: # def __init__(self, val0, nextNone): # self.val val # self.next next class Solution:def removeElements(self, head: ListNode, val: int) -> Li…

ArkTS自定义组件

一、自定义组件基本结构 // 定义自定义组件 ButtonCom.ets Component export struct BtnCom{State msg: string "按钮";build() {Row(){Text(this.msg).onClick(() > {this.msg "测试"})}} } // 引入自定义组件 import {BtnCom} from "./Butto…

[Go Web] Kratos 使用的简单总结

文章目录 1.Kratos 简介2.传输协议3.日志4.错误处理5.配置管理6.wire 1.Kratos 简介 Kratos并不绑定于特定的基础设施&#xff0c;不限定于某种注册中心&#xff0c;或数据库ORM等&#xff0c;所以您可以十分轻松地将任意库集成进项目里&#xff0c;与Kratos共同运作。 API -&…

正版软件 | R-Drive Image:数据安全守护者,您的智能备份专家

在数字化时代&#xff0c;数据安全的重要性不言而喻。R-Drive Image 是一款功能强大的备份和恢复软件&#xff0c;为您提供了全面的解决方案&#xff0c;确保您的数据安全无忧。 精确备份&#xff0c;全面保护 R-Drive Image 能够创建硬盘驱动器的逐字节副本&#xff0c;无论是…