注解详解系列 - @Conditional:条件化配置的利器

2024-06-22 12:20

本文主要是介绍注解详解系列 - @Conditional:条件化配置的利器,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

注解简介

在今天的注解详解系列中,我们将探讨@Conditional注解。@Conditional是Spring框架中的一个重要注解,用于根据特定条件来有选择性地创建bean。通过@Conditional注解,可以根据环境、配置或其他条件,动态地控制Spring应用程序中bean的创建过程。


注解定义

@Conditional注解用于根据特定条件来有选择性地创建bean。它通常与实现了Condition接口的类一起使用,以定义条件逻辑。以下是一个基本的示例:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;@Configuration
public class AppConfig {@Bean@Conditional(MyCondition.class)public MyService myService() {return new MyService();}
}

在这个示例中,myService方法返回的bean被定义为有条件地创建,Spring容器会根据MyCondition类的条件逻辑来决定是否创建该bean。


注解详解

@Conditional注解是Spring框架中用于条件化配置的注解。它的主要功能是根据特定条件来有选择性地创建bean,从而提供更灵活的配置选项。

@Conditional注解的作用包括:

  • 根据特定条件来有选择性地创建bean。
  • 支持环境、配置、系统属性、运行时条件等多种条件。
  • 提供更灵活和动态的bean创建机制。

@Conditional注解通常与@Configuration@Bean等注解一起使用,以标记需要条件化创建的bean。


使用场景

@Conditional注解广泛用于Spring应用程序中,用于根据环境、配置、系统属性或其他条件动态地控制bean的创建。例如,在不同的环境(开发、测试、生产)中,需要加载不同的配置或组件时,可以使用@Conditional注解进行条件化配置。


示例代码

以下是一个使用@Conditional注解的代码示例,展示了如何通过Spring根据特定条件来有选择性地创建bean:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;@Configuration
public class AppConfig {@Bean@Conditional(OnProductionCondition.class)public MyService myService() {return new MyService();}
}class MyService {public void doSomething() {System.out.println("Doing something in MyService");}
}class OnProductionCondition implements Condition {@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {Environment env = context.getEnvironment();String environment = env.getProperty("env");return "production".equals(environment);}
}

在这个示例中:

  • MyService类被定义为有条件地创建,只有在环境变量env的值为production时才会创建。
  • OnProductionCondition类实现了Condition接口,定义了匹配条件逻辑。

使用Spring Boot的条件注解

在Spring Boot项目中,可以使用一些预定义的条件注解,如@ConditionalOnProperty@ConditionalOnMissingBean@ConditionalOnClass等,来简化条件配置。以下是几个常用的条件注解示例:

  1. @ConditionalOnProperty

@ConditionalOnProperty注解用于根据配置文件中的属性来有选择性地创建bean。

import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class AppConfig {@Bean@ConditionalOnProperty(name = "feature.enabled", havingValue = "true")public FeatureService featureService() {return new FeatureService();}
}class FeatureService {public void execute() {System.out.println("FeatureService is enabled");}
}

在这个示例中,featureService bean只有在配置文件中feature.enabled属性为true时才会创建。

  1. @ConditionalOnMissingBean

@ConditionalOnMissingBean注解用于在容器中不存在某个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@ConditionalOnMissingBeanpublic MyService myService() {return new MyService();}
}class MyService {public void doSomething() {System.out.println("MyService is created because it is missing");}
}

在这个示例中,myService bean只有在容器中不存在相同类型的bean时才会创建。

  1. @ConditionalOnClass

@ConditionalOnClass注解用于在类路径中存在某个类时有选择性地创建bean。

import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class AppConfig {@Bean@ConditionalOnClass(name = "com.example.SomeClass")public MyService myService() {return new MyService();}
}class MyService {public void doSomething() {System.out.println("MyService is created because SomeClass is on the classpath");}
}

在这个示例中,myService bean只有在类路径中存在com.example.SomeClass类时才会创建。


常见问题

问题:如何定义自定义条件?

解决方案:自定义条件需要实现Condition接口,并在matches方法中定义条件逻辑。然后通过@Conditional注解指定自定义条件类。

import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;@Configuration
public class AppConfig {@Bean@Conditional(MyCustomCondition.class)public MyService myService() {return new MyService();}
}class MyService {public void doSomething() {System.out.println("MyService is created based on custom condition");}
}class MyCustomCondition implements Condition {@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {// 自定义条件逻辑return true;}
}

问题:如何在测试中使用@Conditional注解?

解决方案:可以通过设置环境变量、系统属性或配置文件来控制条件的匹配逻辑,从而在测试中验证条件配置。

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;@SpringBootTest
@ActiveProfiles("test")
public class MyServiceTest {@Autowired(required = false)private MyService myService;@Testpublic void testConditionalBeanCreation() {if (myService != null) {myService.doSomething();} else {System.out.println("MyService bean is not created");}}
}

小结

通过今天的学习,我们了解了@Conditional的基本用法和应用场景,以及如何在Spring Boot框架中使用条件注解进行条件化配置。明天我们将探讨另一个重要的Spring注解——@Profile


相关链接
  • Spring 官方文档
  • Spring 条件化配置
  • Spring Boot 条件注解

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

这篇关于注解详解系列 - @Conditional:条件化配置的利器的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1084271

相关文章

Spring Cloud:构建分布式系统的利器

引言 在当今的云计算和微服务架构时代,构建高效、可靠的分布式系统成为软件开发的重要任务。Spring Cloud 提供了一套完整的解决方案,帮助开发者快速构建分布式系统中的一些常见模式(例如配置管理、服务发现、断路器等)。本文将探讨 Spring Cloud 的定义、核心组件、应用场景以及未来的发展趋势。 什么是 Spring Cloud Spring Cloud 是一个基于 Spring

Linux 安装、配置Tomcat 的HTTPS

Linux 安装 、配置Tomcat的HTTPS 安装Tomcat 这里选择的是 tomcat 10.X ,需要Java 11及更高版本 Binary Distributions ->Core->选择 tar.gz包 下载、上传到内网服务器 /opt 目录tar -xzf 解压将解压的根目录改名为 tomat-10 并移动到 /opt 下, 形成个人习惯的路径 /opt/tomcat-10

uniapp接入微信小程序原生代码配置方案(优化版)

uniapp项目需要把微信小程序原生语法的功能代码嵌套过来,无需把原生代码转换为uniapp,可以配置拷贝的方式集成过来 1、拷贝代码包到src目录 2、vue.config.js中配置原生代码包直接拷贝到编译目录中 3、pages.json中配置分包目录,原生入口组件的路径 4、manifest.json中配置分包,使用原生组件 5、需要把原生代码包里的页面修改成组件的方

20.Spring5注解介绍

1.配置组件 Configure Components 注解名称说明@Configuration把一个类作为一个loC容 器 ,它的某个方法头上如果注册7@Bean , 就会作为这个Spring容器中的Bean@ComponentScan在配置类上添加@ComponentScan注解。该注解默认会扫描该类所在的包下所有的配置类,相当于之前的 <context:component-scan>@Sc

十四、观察者模式与访问者模式详解

21.观察者模式 21.1.课程目标 1、 掌握观察者模式和访问者模式的应用场景。 2、 掌握观察者模式在具体业务场景中的应用。 3、 了解访问者模式的双分派。 4、 观察者模式和访问者模式的优、缺点。 21.2.内容定位 1、 有 Swing开发经验的人群更容易理解观察者模式。 2、 访问者模式被称为最复杂的设计模式。 21.3.观察者模式 观 察 者 模 式 ( Obser

【操作系统】信号Signal超详解|捕捉函数

🔥博客主页: 我要成为C++领域大神🎥系列专栏:【C++核心编程】 【计算机网络】 【Linux编程】 【操作系统】 ❤️感谢大家点赞👍收藏⭐评论✍️ 本博客致力于知识分享,与更多的人进行学习交流 ​ 如何触发信号 信号是Linux下的经典技术,一般操作系统利用信号杀死违规进程,典型进程干预手段,信号除了杀死进程外也可以挂起进程 kill -l 查看系统支持的信号

IDEA配置Tomcat远程调试

因为不想把本地的Tomcat配置改乱或者多人开发项目想测试,本文主要是记录一下,IDEA使用Tomcat远程调试的配置过程,免得一段时间不去配置到时候忘记(毕竟这次是因为忘了,所以才打算记录的…) 首先在catalina.sh添加以下内容 JAVA_OPTS="-Dcom.sun.management.jmxremote=-Dcom.sun.management.jmxremote.port

SpringBoot集成Netty,Handler中@Autowired注解为空

最近建了个技术交流群,然后好多小伙伴都问关于Netty的问题,尤其今天的问题最特殊,功能大概是要在Netty接收消息时把数据写入数据库,那个小伙伴用的是 Spring Boot + MyBatis + Netty,所以就碰到了Handler中@Autowired注解为空的问题 参考了一些大神的博文,Spring Boot非controller使用@Autowired注解注入为null的问题,得到

Jitter Injection详解

一、定义与作用 Jitter Injection,即抖动注入,是一种在通信系统中人为地添加抖动的技术。该技术通过在发送端对数据包进行延迟和抖动调整,以实现对整个通信系统的时延和抖动的控制。其主要作用包括: 改善传输质量:通过调整数据包的时延和抖动,可以有效地降低误码率,提高数据传输的可靠性。均衡网络负载:通过对不同的数据流进行不同程度的抖动注入,可以实现网络资源的合理分配,提高整体传输效率。增

Java注解详细总结

什么是注解?         Java注解是代码中的特殊标记,比如@Override、@Test等,作用是:让其他程序根据注解信息决定怎么执行该程序。         注解不光可以用在方法上,还可以用在类上、变量上、构造器上等位置。 自定义注解  现在我们自定义一个MyTest注解 public @interface MyTest{String aaa();boolean bbb()