@ConfigurationProperties和@ConditionalOnProperties的理解与使用

在SpringBoot中为了降低耦合度,简化开发,有很多方便的注解,其中@COnfigurationProperties和@ConditionalOnProperties就只个人觉得比较好用的组件中的两个

@ConfigurationProperties的用法

这个注解可以根据配置文件中的配置绑定相关属性到有这个注解的类上

其中有四个静态方法


	@AliasFor("prefix")
	String value() default "";
	
	@AliasFor("value")
	String prefix() default "";

	boolean ignoreInvalidFields() default false;

	boolean ignoreUnknownFields() default true;

其中 value() 和prefix()的功能是一样的,只能使用一个,就是我们在配置文件中的前缀,

ignoreInvalidFields(),是否忽略不合法的Field,默认为false,也就是说这个Field的类型如果不匹配,那么启动就会报错

ignoreUnknownFields()是否忽略位置的Field,默认为true,也就是说在对应的类中如果没有找到这个field,程序也不会报错,
使用的时候会有三种方式使用,一般在项目中选择其一就可以了,
1. 和@Service或者@Component之类的注解一起同时使用在类上,如下

@Data
@Service
@ConfigurationProperties(prefix =LouisBootProperties.PREFIX)
public class LouisBootProperties {

    static final String PREFIX = "louis.boot";
    
    private int bootTime;
    
    private String appName;
    
    private int port;
}

2. 在@Configuration,中注入一个新@Bean

@Data
@ConfigurationProperties(prefix =LouisBootProperties.PREFIX)
public class LouisBootProperties {

    static final String PREFIX = "louis.boot";

    private int bootTime;

    private String appName;

    private int port;

}
@Configuration
public class BootConfig {
    @Bean
    public LouisBootProperties louisBootProperties() {
        return new LouisBootProperties();
    }
}

3. 在@Configuration类上使用@EnableConfigurationProperties(LouisBootProperties.class)


@Data
@ConfigurationProperties(prefix =LouisBootProperties.PREFIX)
public class LouisBootProperties {

    static final String PREFIX = "louis.boot";

    private int bootTime;

    private String appName;

    private int port;



}

@Configuration
@EnableConfigurationProperties(LouisBootProperties.class)
public class BootConfig {
}

这三种方式中任意一种方式都可以。
我的配置文件application.properties中的配置如下

louis.boot.port=9999
louis.boot.app-name=LOUIS-server
louis.boot.boot-time=1984

需要注意的是我们的属性一般是驼峰命名法,在配置文件中需要将中间的大写字母换成 "-"加小写字母,不过使用驼峰的方式也是一样的,能够加载出来
Controller类在最下面,

最后结果为


{
    "message": "success",
    "code": 200,
    "result": {
        "bootTime": 1984,
        "appName": "LOUIS-server",
        "port": 9999
    }
}

以上三种方式任选一种都是这种结果,如果不选,那么启动会报错(主要原因是@Autowired中的类Spring没有找到的原因,去掉Autowire则不会报错)

有时候我们在项目中不单单只用@ConfigurationProperties,还会和@Conditionl系列配合使用,特别是在Configuration类中,这里介绍一下@ConditionalOnProperty

@ConditionalOnProperty的用法

@ConditionalOnPropertiy 是基于@Conditional的,不懂的可以网上百度,这里简单讲讲

@Conditional 说直白点就是在不同的条件下使用不同的Bean,@Conditional中只有一个参数,如下

Class<? extends Condition>[] value();

这个参数是接收一个实现了Cndition接口的Class数组
而Condition 是一个函数式接口只有一个方法matchs,传入两个参数,返回boolean类型

boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);

也就是说@ConDitional中的参数会有一个返回值,如果返回true,我们注解上的组件,就会被加载,否则,Spring则不加载我们注解的组件。
同理,@ConditionalOnPropertiy就是在配置文件找到我们自定义了配置,找到了就返回true,我们注解的组件就会被加载(一般是Configuration类就会生效),否则就不会加载我们注解的组件

Spring Boot中基于@Conditional的注解还有很多,譬如说ConditionalOnMissingClassConditionalOnExpression等都是同等道理的

@ConditionalOnProperty的用法很简单,它有五个静态方法,代码如下

    String[] value() default {};


	String prefix() default "";


	String[] name() default {};

	String havingValue() default "";

	
	boolean matchIfMissing() default false;

其中 value()name()的用法是一样的,只能使用一个,系统在加载的时候会在配置文件中找value()或者name()中的值,如果有就返回true,没有就返回false,

prefix(),就是要找的name()的前缀,

havingValue():如果从配置文件中找到的name()中的值如果和havingValue()中的值一样,就返回true,否则就返回false,
matchIfMissing(),如果没有找到name()中的值就返回false(默认的,我们可以修改)

最后如果返回的值为false,那么我们注解的类就不会生效,否则就生效

示例代码如下

和@ConfigurationProperties中的代码配套阅读效果更佳

/**
*这个properties我使用@Service的方式
*/
@Data
@Service
@ConfigurationProperties(prefix =LouisBootProperties.PREFIX)
public class LouisBootProperties {

    static final String PREFIX = "louis.boot";

    private int bootTime;

    private String appName;

    private int port;

    public int getBootTime() {
        return bootTime;
    }
}

/**
 *这个里面我在配置文件中shiyong@Bean的方式
 */
@Data
@ConfigurationProperties(prefix =BootLouisProperties.PREFIX)
public class BootLouisProperties {

    static final String PREFIX = "boot.louis";

    private String boot;

    private String louis;

    private long time;

    private int port;
}

/**
*配置类
*/
@ConditionalOnProperty(prefix = "louis.config",name = "app-config",havingValue = "app-config")
@Configuration
public class BootConfig {
    
    @Bean
    public BootLouisProperties bootLouisProperties() {
        return new BootLouisProperties();
    }
}

/**
 * controller类
 */
@RestController
public class ConfigController {

    @Autowired
    private LouisBootProperties bootProperties;

    @Autowired(required = false)
    private BootLouisProperties bootLouisProperties;

    @GetMapping("/louis/boot")
    public ResponseData getProperties() {
        return new ResponseData<>(bootProperties);
    }
    @GetMapping("/boot/louis")
    public ResponseData getBootLouisProperties() {
        return new ResponseData<>(bootLouisProperties);
    }
}

配置文件

louis.boot.port=9999
louis.boot.app-name=LOUIS-server
louis.boot.boot-time=1984
boot.louis.boot=boot
boot.louis.louis=louis
boot.louis.time=990990
boot.louis.port=582
louis.config.app-config=zhangsan

运行/boot/louis结果为

{
    "message": "success",
    "code": 200,
    "result": null
}

运行/louis/boot结果为

{
    "message": "success",
    "code": 200,
    "result": {
        "bootTime": 1984,
        "appName": "LOUIS-server",
        "port": 9999
    }
}

说明我们刚才讲解时正确的,BootConfig类是没有生效的

  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
@ConfigurationProperties 和 @Value 可以混合使用,但需要注意以下几点: 1. 需要在类上添加 @ConfigurationProperties 注解,并指定前缀,用于将配置文件中的属性值注入到类的属性中。 2. 在需要使用 @Value 注解的属性上添加该注解,并指定属性的名称,用于将指定的属性值注入到该属性中。 3. 如果使用 @Value 注解的属性在配置文件中没有对应的值,则会报错,因此需要设置默认值或者使用 required 属性来避免报错。 4. 如果使用 @Value 注解的属性和 @ConfigurationProperties 注解指定的属性名称相同,则 @Value 注解的属性值会覆盖 @ConfigurationProperties 注解指定的属性值。 下面是一个示例代码: ```java @ConfigurationProperties(prefix = "example") public class ExampleProperties { private String name; private int age; // 省略 getter 和 setter 方法 @Override public String toString() { return "ExampleProperties{" + "name='" + name + '\'' + ", age=" + age + '}'; } } @Component public class ExampleComponent { @Value("${example.name:defaultName}") private String name; @Autowired private ExampleProperties properties; public void printProperties() { System.out.println("name from @Value: " + name); System.out.println("name from @ConfigurationProperties: " + properties.getName()); System.out.println("age from @ConfigurationProperties: " + properties.getAge()); } } ``` 在上面的示例中,ExampleProperties使用 @ConfigurationProperties 注解指定了前缀为 example,用于将配置文件中以 example 开头的属性值注入到该类的属性中。ExampleComponent 类中使用 @Value 注解指定了属性 name 的值,并使用 @Autowired 注解将 ExampleProperties 类注入到该类中。在 printProperties 方法中,分别输出了从 @Value 和 @ConfigurationProperties 中获取的属性值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值