ZetCode

Spring Boot 条件 Bean

最后修改于 2023 年 7 月 18 日

Spring Boot 条件 Bean 教程展示了如何基于条件将 Bean 注册到 Spring Boot 应用上下文。

Spring Boot 是一个流行的应用程序框架,用于在 Java、Kotlin 或 Groovy 中创建企业应用程序。

@Conditional

@Conditional 注解表明,只有当所有指定的条件都匹配时,组件才会被注册到应用上下文中。如果一个 @Configuration 类用 @Conditional 标记,那么与该类关联的所有 @Bean 方法、@Import 注解和 @ComponentScan 注解都将受到这些条件的约束。

Spring 提供了大量的开箱即用的条件注解,包括 @ConditionalOnClass, @ConditionalOnMissingBean, @ConditionalOnBean, @ConditionalOnProperty, @ConditionalOnNotWebApplication@ConditionalOnExpression

Spring Boot 条件 Bean 示例

在下面的应用中,我们有两个 Bean 是基于条件注册的。

build.gradle
...
src
├── main
│   ├── java
│   │   └── com
│   │       └── zetcode
│   │           ├── Application.java
│   │           ├── bean
│   │           │   ├── GenericMessage.java
│   │           │   ├── MessageBean.java
│   │           │   └── WelcomeMessage.java
│   │           ├── conf
│   │           │   └── AppConf.java
│   │           └── MyRunner.java
│   └── resources
│       └── application.properties
└── test
    └── java

这是 Spring Boot 应用程序的项目结构。

build.gradle
plugins {
    id 'org.springframework.boot' version '3.1.1'
    id 'io.spring.dependency-management' version '1.1.0'
    id 'java'
}

group = 'com.zetcode'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter'
}

这是 build.gradle 文件。

com/zetcode/bean/MessageBean.java
package com.zetcode.bean;

public interface MessageBean {

    String getMessage();
}

这是 MessageBean

com/zetcode/bean/GenericMessage.java
package com.zetcode.bean;

public record GenericMessage(String message) implements MessageBean {

}

这是一个用于通用消息的 GenericMessage

com/zetcode/bean/WelcomeMessage.java
package com.zetcode.bean;

public record WelcomeMessage(String message) implements MessageBean {

}

WelcomeMessage 适用于欢迎消息。

com/zetcode/conf/AppConf.java
package com.zetcode.conf;

import com.zetcode.bean.GenericMessage;
import com.zetcode.bean.WelcomeMessage;
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 AppConf {

    @Bean
    @ConditionalOnProperty(name="welcomebean.enabled", havingValue="true")
    public WelcomeMessage welcomeBeanBean() {

        return new WelcomeMessage("Welcome!");
    }

    @Bean
    @ConditionalOnMissingBean(WelcomeMessage.class)
    public GenericMessage messageBean() {

        return new GenericMessage("Today is a beautiful day.");
    }
}

AppConf 中,我们定义了两个基于条件的 Bean。

@Bean
@ConditionalOnProperty(name="welcomebean.enabled", havingValue="true")
public WelcomeMessage welcomeBeanBean() {

    return new WelcomeMessage("Welcome!");
}

通过 @ConditionalOnProperty,只有当 welcomebean.enabled 属性设置为 true 时,才会注册 WelcomeMessage Bean。

@Bean
@ConditionalOnMissingBean(WelcomeMessage.class)
public GenericMessage messageBean() {

    return new GenericMessage("Today is a beautiful day.");
}

GenericMessage 的注册条件是 WelcomeMessage 没有被注册。

resources/application.properties
spring.main.banner-mode=off
welcomebean.enabled=true

application.properties 文件中,我们定义了 welcomebean.enabled 属性。

com/zetcode/MyRunner.java
package com.zetcode;

import com.zetcode.bean.MessageBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

@Component
public class MyRunner implements CommandLineRunner {

    private final MessageBean messageBean;

    @Autowired
    public MyRunner(MessageBean messageBean) {
        this.messageBean = messageBean;
    }

    @Override
    public void run(String... args) throws Exception {

        System.out.println(messageBean.message());
    }
}

MyRunner 中,我们自动装配一个消息 Bean 并打印消息。根据 welcomebean.enabled 属性,我们要么获得欢迎消息,要么获得通用消息。

com/zetcode/Application.java
package com.zetcode;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

`Application` 设置了 Spring Boot 应用程序。

$ ./gradlew bootRun
...
Welcome!

我们运行应用程序。

在本文中,我们使用了条件 Bean。

作者

我叫 Jan Bodnar,是一位充满激情的程序员,拥有丰富的编程经验。自 2007 年以来,我一直在撰写编程文章。迄今为止,我撰写了超过 1,400 篇文章和 8 本电子书。我拥有超过十年的编程教学经验。

列出 所有 Spring Boot 教程