SpringBoot中的条件装配方法

 更新时间:2024年08月29日 09:34:42   作者:思静语  
在实际的项目开发中,我们往往需要根据不同的环境做出不同的配置,例如:在开发环境下,我们会使用内存数据库以便快速启动服务并进行开发调试,在test环境、生产环境,会使用对应环境的数据库,这篇文章主要介绍了SpringBoot中的条件装配方法,需要的朋友可以参考下

在实际的项目开发中,我们往往需要根据不同的环境做出不同的配置,例如:在开发环境下,我们会使用内存数据库以便快速启动服务并进行开发调试,在test环境、生产环境,会使用对应环境的数据库。
如果我们的应用程序可以根据自身的环境做一些这样的适配,那么我们的程序开发无疑将更加灵活、高效。
在过去的应用程序开发中,我们常常会将这些环境变量写在某个指定的配置文件中,每次服务器启动的时候,会读取服务器中指定的配置文件,从而实现根据不同的环境,应用程序能做出对应的适配。
但是这样的工作,对于运维来说,非常苦逼,尤其是应用程序到达50个以上的时候,会非常不好维护,每次上线改配置~
当我们在使用SpringBoot来开发应用程序的时候,这些工作量将大大简化。
SpringBoot为开发者提供了三种可选的条件装配方式。
● Profile
● Conditional
● ConditionalOnProperty
在Spring Boot中,条件装配(Conditional Bean Configuration)是指根据特定的条件来决定是否创建或装配某个Bean。以下是几种常用的条件装配方式及其代码示例:
Spring提供的条件装配@Conditional,灵活性非常强,但是具体判断逻辑还需要我们自己实现,比较麻烦。
实际上,Spring Boot为开发者提供了很多使用起来更简单的条件注解,例如:
● ConditionalOnProperty:如果有指定的配置,条件生效
● ConditionalOnBean:如果有指定的Bean,条件生效
● ConditionalOnMissingBean:如果没有指定的Bean,条件生效
● ConditionalOnMissingClass:如果没有指定的Class,条件生效
● ConditionalOnWebApplication:在Web环境中条件生效
● ConditionalOnExpression:根据表达式判断条件是否生效

Profile

SpringBoot 为应用程序提供了Profile这一概念,用来表示不同的环境。例如,我们分别定义开发、测试和生产这3个环境
dev:开发环境
test:测试环境
production:生产环境
以上传文件为例,在开发环境下,我们将文件上传到本地,而在测试环境、生产环境,我们将文件上传到云端服务商。

1、首先编写两套上传服务
/**
● 上传文件到本地
● @since 2021-06-13
 */
public class FileUploader implements Uploader { @Override
 public String upload(File file) {
 //上传文件到本地,并返回绝对路径
 return null;
 }
}
/**
● 上传文件到OSS
● @since 2021-06-13
 */
public class OSSUploader implements Uploader { @Override
 public String upload(File file) {
 //上传文件到云端,并返回绝对路径
 return null;
 }
}

2、然后编写一个服务配置类,根据不同的环境,创建不同的实现类

@Configuration
public class AppConfig {
@Bean
@Profile("dev")
public Uploader initFileUploader() {
    System.out.println("初始化一个上传到本地的bean");
    return new FileUploader();
}
@Bean
@Profile("!dev")
public Uploader initOSSUploader() {
    System.out.println("初始化一个上传到云端的bean");
    return new OSSUploader();
}
}

3、最后,运行程序
在运行程序时,加上JVM参数-Dspring.profiles.active=dev就可以指定以dev环境启动。
如果当前的Profile设置为dev,则Spring容器会调用initFileUploader()创建FileUploader,否则,调用initOSSUploader()创建OSSUploader。
注意:@Profile(“!dev”)表示非dev环境。
当然,你还可以在application.properties文件中加上如下配置,一样可以指定环境进行运行。

spring.profiles.active=dev

1. @Conditional 注解

@Conditional允许基于自定义条件进行装配。
代码示例:

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

自定义条件:

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
public class MyCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        // 判断条件,返回true表示创建该bean
        return true; // 可以根据环境变量、系统属性等来判断
        // return "true".equalsIgnoreCase(context.getEnvironment().getProperty("enable.sms"));
    }
}

2. @ConditionalOnProperty 注解

根据配置文件中的属性值决定是否装配某个Bean。
代码示例:

import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyConfig {
    @Bean
    @ConditionalOnProperty(name = "feature.enabled", havingValue = "true")
    public MyService myService() {
        return new MyService();
    }
}

配置文件:

eature:
  enabled: true

@ConditionalOnClass 注解
如果某个类在类路径上存在,则装配相应的Bean。
代码示例:

import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyConfig {
    @Bean
    @ConditionalOnClass(name = "com.example.SomeClass")
    public MyService myService() {
        return new MyService();
    }
}

4. @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 MyConfig {
    @Bean
    @ConditionalOnMissingBean
    public MyService myService() {
        return new MyService();
    }
}

5. @ConditionalOnBean 注解

如果容器中存在某个特定的Bean,则装配当前的Bean。
代码示例:

import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyConfig {
    @Bean
    @ConditionalOnBean(name = "someOtherBean")
    public MyService myService() {
        return new MyService();
    }
}

6. @ConditionalOnExpression 注解

根据SpEL表达式的结果来决定是否装配Bean。
代码示例:

import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyConfig {
    @Bean
    @ConditionalOnExpression("${feature.enabled:true} == true")
    public MyService myService() {
        return new MyService();
    }
}

这些注解帮助你根据不同的条件动态地装配Bean,使得Spring Boot应用更加灵活和可配置。

到此这篇关于SpringBoot中的条件装配方法的文章就介绍到这了,更多相关SpringBoot条件装配内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 详解重试框架Spring retry实践

    详解重试框架Spring retry实践

    spring retry是从spring batch独立出来的一个能功能,主要实现了重试和熔断。这篇文章主要介绍了详解重试框架Spring retry实践,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-05-05
  • Spring中Transactional注解使用的心得(推荐)

    Spring中Transactional注解使用的心得(推荐)

    这篇文章主要介绍了Spring中Transactional注解使用的心得,事务是用来控制数据的ACID特性的,用于保证数据的正确性和完整性,需要的朋友可以参考下
    2022-10-10
  • Guava Retryer实现接口重试的示例

    Guava Retryer实现接口重试的示例

    本文主要介绍了Guava Retryer实现接口重试的示例,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-12-12
  • Java使用JDBC连接数据库的实现方法

    Java使用JDBC连接数据库的实现方法

    这篇文章主要介绍了Java使用JDBC连接数据库的实现方法,包括了详细的加载步骤以及完整实现示例,需要的朋友可以参考下
    2014-09-09
  • 详解Spring Boot 项目部署到heroku爬坑

    详解Spring Boot 项目部署到heroku爬坑

    这篇文章主要介绍了详解Spring Boot 项目部署到heroku爬坑,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-08-08
  • Java中五种不同方法的创建对象

    Java中五种不同方法的创建对象

    本文为大家详细介绍了在Java中5种不同创建对象的方法和实例代码,感兴趣的小伙伴们可以参考一下
    2016-07-07
  • 利用Java8 Optional类优雅如何地解决空指针问题

    利用Java8 Optional类优雅如何地解决空指针问题

    这篇文章主要给大家介绍了关于如何利用Java8 Optional类优雅解决空指针问题的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • java 终止线程的4种方式小结

    java 终止线程的4种方式小结

    本文主要介绍了java终止线程的4种方式小结,包含布尔标志位,interrupt()方法,stop()方法和Thread.interrupt()方法,具有一定的参考价值,感兴趣的可以了解一下
    2024-05-05
  • Java+Freemarker实现根据XML模板文件生成Word文档

    Java+Freemarker实现根据XML模板文件生成Word文档

    这篇文章主要为大家详细介绍了Java如何使用Freemarker实现根据XML模板文件生成Word文档,文中的示例代码讲解详细,感兴趣的小伙伴可以学习一下
    2023-11-11
  • Java格式化输出printf()解读

    Java格式化输出printf()解读

    这篇文章主要介绍了Java格式化输出printf()解读,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-09-09

最新评论