【@ConfigurationProperties注解的用处】

介绍

@ConfigurationProperties 是 Spring 框架中的一个注解,用于将配置文件中的属性映射到 Java 对象的字段上。它的主要用途是简化配置文件与 Java 对象之间的映射过程,使得配置更加方便、可读,并提供类型安全的属性访问。

用途和特性

  • 属性映射: 将配置文件中的属性映射到 Java 对象的字段上。这样,可以通过在 Java 类中定义字段来组织和访问应用程序的配置。

  • 类型安全: 通过在 Java 类型上使用注解,可以实现类型安全的属性访问。如果配置文件中的属性与 Java 类型不匹配,Spring 在启动时会报错,提前发现配置错误。

  • 嵌套属性: 支持将配置文件中的属性嵌套到 Java 对象的嵌套字段中,使得可以更结构化地组织配置信息。

  • 多环境支持: 可以通过在注解中指定 prefix 属性,将不同环境下的配置信息分组,从而实现多环境配置。

  • 默认值: 可以为字段设置默认值,如果配置文件中没有相应的属性,将使用默认值。

  • 动态刷新: 在 Spring Boot 中,@ConfigurationProperties 还支持动态刷新,当配置发生变化时,可以通过 @RefreshScope 注解实现动态刷新,而不需要重启应用程序。

  • 属性验证: 可以使用 @Validated 注解结合 JSR 303 标准的验证注解,对配置属性进行验证。

示例如下:

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "myapp")
public class MyAppProperties {
    
    

    private String appName;
    private int maxConnections;
    // other properties...

    // getters and setters...
}

在上面的例子中,@ConfigurationProperties 注解指定了 prefix 属性为 “myapp”,表示配置文件中的属性应该以 “myapp” 为前缀。例如,配置文件中的属性可以是 myapp.appName 和 myapp.maxConnections。这些属性将被映射到 MyAppProperties 类的相应字段上。

与@Value的区别

@ConfigurationProperties 和 @Value 是 Spring 中用于获取配置信息的两种不同方式

  1. 类型安全:

@ConfigurationProperties 提供了类型安全的配置绑定。你可以创建一个 Java 类,将配置属性映射到该类的字段上,Spring 会自动将配置文件中的值绑定到相应的字段,而且会进行类型转换。如果类型不匹配,Spring 会在启动时报错。
@Value 是基于 SpEL(Spring Expression Language)的,它是一个字符串表达式,不提供类型安全性。你需要手动进行类型转换,并且如果类型不匹配,可能会导致运行时错误。

  1. 多属性绑定:

@ConfigurationProperties 支持将多个属性绑定到一个类中,使得配置更加结构化,适用于组织复杂的配置信息。
@Value 一般用于单一属性的注入,较难组织复杂的配置信息。

  1. 适用场景:

@ConfigurationProperties 适用于大量配置属性、多个相关配置属性的情况,尤其是复杂的配置信息。
@Value 适用于简单的属性注入,对于少量的配置项。

最大的区别在于第一点类型安全上
使用 @ConfigurationProperties 时,可以将配置文件中的属性直接映射到一个 Java 类的字段上。Spring 在启动时会尝试将配置文件中的值转换为字段声明的类型。如果类型不匹配,Spring 会在启动时检测到并报告错误。这种类型检查是在应用程序启动时进行的,有助于提前发现配置错误,而不是在运行时发生意外行为。

其次就是可以通过java类管理配置属性,对于配置属性较多情况下可以使其更加统一

@value的优点体现在对于两个关系不大的配置上,比如有myapp.aaa.ccc.bbb=1myapp.qqq=2这样的两个配置
如果使用@ConfigurationProperties注解,需要嵌套方式去获取内容,如下:

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "myapp")
public class MyAppProperties {
    
    
    private final AAA aaa = new AAA();
    private int qqq;

    public static class AAA {
    
    
        private final CCC ccc = new CCC();

        public static class CCC {
    
    
            private int bbb;

            public int getBbb() {
    
    
                return bbb;
            }

            public void setBbb(int bbb) {
    
    
                this.bbb = bbb;
            }
        }

        public CCC getCcc() {
    
    
            return ccc;
        }
    }

    public AAA getAaa() {
    
    
        return aaa;
    }

    public int getQqq() {
    
    
        return qqq;
    }

    public void setQqq(int qqq) {
    
    
        this.qqq = qqq;
    }
}

结论

结合@ConfigurationProperties的优点,我们在约定配置文件时,相同的业务配置尽量有统一的前缀和减少嵌套(通过下划线或者横杠映射类的驼峰命名),不同的业务配置有不同的prefix。这样便于使用一个配置类管理。示例如下:
在这里插入图片描述

补充

补充一些其他类似的spring注解

  • @ConditionalOnproperity
    @ConditionalOnProperty 是 Spring Boot 中的一个条件注解,用于根据配置属性的值来决定是否要启用某个配置类、Bean 或组件。这个注解在以下场景中特别有用:

特定配置开关: 你可以使用 @ConditionalOnProperty 来根据配置文件中的某个属性值来决定是否启用某个配置。例如,只有在配置文件中设置了特定的属性时,某个Bean 或配置类才会生效。

@Configuration
@ConditionalOnProperty(name = "myapp.feature.enabled", havingValue = "true")
public class MyFeatureConfiguration {
    
    
    // 配置类的内容...
}

myapp.feature.enabled=true,这样配置类 MyFeatureConfiguration 就会在属性 myapp.feature.enabled 的值为 true 时生效。

  • @ConditionalOnMissingBean
    @ConditionalOnMissingBean 是 Spring Boot 中的一个条件注解,用于在特定的 Bean 还不存在时启用某个配置类、Bean 或组件。这个注解在以下场景中特别有用:

默认实现: 当你有一个接口或抽象类有多个实现时,可以使用 @ConditionalOnMissingBean 注解来提供一个默认的实现。如果容器中已经有了某个实现的 Bean,那么就不会再创建这个默认实现的 Bean。

@Service
public class DefaultMyService implements MyService {
    
    
    // 默认实现的内容...
}

@Service
@ConditionalOnMissingBean(MyService.class)
public class CustomMyService implements MyService {
    
    
    // 自定义实现的内容...
}

在这个例子中,如果容器中已经有了类型为 MyService 的 Bean(例如 DefaultMyService),那么 CustomMyService 就不会被创建。如果没有,就会创建 CustomMyService。

插件化扩展: 当你提供一种插件机制,允许开发者在应用程序中注册自定义实现时,可以使用 @ConditionalOnMissingBean。这样,如果用户自己定义了实现,就使用用户的实现;否则,使用默认实现。

@Configuration
public class MyConfig {
    
    

    @Bean
    @ConditionalOnMissingBean
    public MyPlugin myPlugin() {
    
    
        return new DefaultMyPlugin();
    }
}

在这个例子中,如果容器中已经有了 MyPlugin 类型的 Bean,那么 myPlugin 方法就不会创建新的 Bean;否则,它会创建一个默认的 DefaultMyPlugin Bean。

猜你喜欢

转载自blog.csdn.net/qq_40454136/article/details/134811444