配置文件属性注入到java


前言


一、@Value注解

ps:动态配置参数配置,解耦,以下答案系gpt回答。

定义@Value 注解是 Spring Framework 中用于注入配置值的一个注解。它通常用于将属性值注入到 Spring 管理的 Bean 中。@Value 可以从多种源获取值,包括配置文件、系统属性、环境变量等。

主要用法

  1. 注入配置文件中的属性值

    在 Spring Boot 应用中,通常会使用 application.propertiesapplication.yml 文件来定义配置。可以通过 @Value 注解将这些配置值注入到 Bean 中。例如:

    # application.properties
    myapp.timeout=5000
    
    # application.yml
    myapp:
      timeout: 5000
    
    @Component
    public class MyService {
        @Value("${myapp.timeout}")
        private int timeout;
    
        // 使用 timeout 属性
    }
    

    在这个示例中,timeout 变量将被注入 application.propertiesapplication.yml 文件中的 myapp.timeout 属性值。

  2. 注入默认值

    @Value 还允许定义默认值,当配置值不可用时,使用默认值。例如:

    @Component
    public class MyService {
        @Value("${myapp.timeout:3000}") // 默认值为 3000
        private int timeout;
    
        // 使用 timeout 属性
    }
    

说明 :在上面的例子中,如果 application.yml 文件中包含 myapp.exampleValue,那么 exampleValue将被设置为 Hello World。如果 application.yml 文件中没有配myapp.exampleValue,则exampleValue 会被设置为 default value,不会抛出异常。

  1. 注入表达式结果

    @Value 注解支持 Spring Expression Language (SpEL) 表达式,可以动态计算注入值。例如:

    @Component
    public class MyService {
        @Value("#{T(java.lang.Math).random() * 100}")
        private double randomValue;
    
        // 使用 randomValue 属性
    }
    

    在这个示例中,randomValue 会被注入一个 0 到 100 之间的随机数。

  2. 注入环境变量或系统属性

    @Value 也可以用来注入环境变量或系统属性。例如:

    @Component
    public class MyService {
        @Value("#{systemProperties['user.home']}")
        private String userHome;
    
        // 使用 userHome 属性
    }
    

    这个示例将系统属性 user.home 注入到 userHome 变量中。

注意事项

  • 类型转换:Spring 会自动进行类型转换,如果注入的值与字段类型不匹配,可能会导致类型转换异常。确保配置值的类型与目标字段类型兼容。

  • 使用场景:虽然 @Value 注解很强大,但对于复杂的配置管理,考虑使用 @ConfigurationProperties 注解,它允许将配置映射到一个配置类中,并提供了更丰富的功能和更好的结构化支持。

二、@ConfigurationProperties注解

对于更复杂的配置场景,Spring 推荐使用 @ConfigurationProperties 注解,它允许将配置属性绑定到一个 POJO 类中,从而更方便地管理和使用配置。如下所示:

1. 在 application.yml 中定义集合

假设你要在 application.yml 文件中定义一个城市列表和一个地图(字典):

myapp:
  cities:
    - London
    - New York
    - Tokyo

  config:
    setting1: value1
    setting2: value2

2. 创建一个配置类

你需要创建一个配置类,使用 @ConfigurationProperties 注解,并在类中定义集合属性。这里我们将创建一个 MyAppProperties 类。

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

import java.util.List;
import java.util.Map;

@Data
@Configuration
@RefreshScope    
@ConfigurationProperties(prefix = "myapp")  // 指定前缀
public class MyAppProperties {

    private List<String> cities;      // 用于存储城市列表
    private Map<String, String> config; // 用于存储配置键值对

   
}

3. 使用注入的属性

在你的应用中,你可以通过 @Autowired 注解将上面的配置类注入到其他 Bean 中,并使用它的属性:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class MyService {

    private final MyAppProperties myAppProperties;

    @Autowired
    public MyService(MyAppProperties myAppProperties) {
        this.myAppProperties = myAppProperties;
    }

    public void printCities() {
        System.out.println("Cities: " + myAppProperties.getCities());//集合
    }

    public void printConfig() {
        System.out.println("Config: " + myAppProperties.getConfig());//map
    }
}

4. 启用配置属性功能

Spring Boot 应用的主类上,确保包含 @EnableConfigurationProperties 注解,这通常是默认启用的,但在某些情况下需要明确添加。

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

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

5. 运行应用

当你运行这个 Spring Boot 应用时,MyService 中的 printCitiesprintConfig 方法将打印从 application.yml 中注入的城市列表和配置字典。

总结

通过上述方式,你可以方便地在 Spring Boot 应用中通过注解将 YAML 文件中的集合属性注入到 Java 类中。这种方法使得配置更加整洁且容易管理。

三 、扩展

1**Spring Boot 启动过程

SpringApplication 初始化**:启动时,`SpringApplication` 类创建并配置上下文。

2. **加载 `application.properties` 或 `application.yml`**:配置文件中的属性被加载到环境中。

3. **创建 `ApplicationContext`**:通过 `SpringApplication.run()` 创建 `ApplicationContext`。

4. **创建和配置 Bean**:在 `ApplicationContext` 创建过程中,Spring 扫描、实例化并配置 Beans5. **属性注入**- **`@Value` 注解**:首先处理通过 `@Value` 注解的属性注入。
   - **`@ConfigurationProperties` 注解**:随后注入 `@ConfigurationProperties` 注解的类中的属性。

6. **执行 BeanPostProcessors**:在 Bean 初始化之前,执行 `BeanPostProcessor` 的 `postProcessBeforeInitialization` 方法。

7. **初始化 Bean**:执行 Bean 的初始化方法(例如 `@PostConstruct`)。

8. **执行 BeanPostProcessors**:在 Bean 初始化之后,执行 `BeanPostProcessor` 的 `postProcessAfterInitialization` 方法。

9. **完成上下文刷新**:上下文完全准备好后,应用启动完成。

此过程确保在应用启动时,所有的配置和属性都会被正确地加载和注入到相应的 Beans 中。

`@RefreshScope` 是 Spring Cloud 提供的一个注解,主要用于支持动态刷新配置。当使用 Spring Cloud Config 进行外部配置管理时,添加此注解的 Bean 可以在运行时通过 `/actuator/refresh` 端点获取最新的配置信息。

2**@RefreshScope**

使用场景

  • 当你需要从外部配置源(如 Git、SVN 或其他配置存储)动态更新配置而无需重启整个应用时,@RefreshScope 是非常有用的。
  • 适用于配置中心管理的应用,尤其是在微服务架构中,当需要更新配置信息而不想停掉服务时。

示例

  1. 添加依赖

    pom.xml 中添加 Spring Cloud 相关依赖:

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-config</artifactId>
    </dependency>
    
  2. 定义配置类

    创建一个配置类,并在需要动态刷新的地方使用 @RefreshScope 注解:

    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.cloud.context.config.annotation.RefreshScope;
    import org.springframework.stereotype.Component;
    
    @Component
    @RefreshScope
    public class MyConfig {
    
        @Value("${myapp.exampleValue:default value}")
        private String exampleValue;
    
        public String getExampleValue() {
            return exampleValue;
        }
    }
    
  3. 创建 REST 控制器

    创建一个控制器,在应用中调用配置值:

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class MyController {
    
        @Autowired
        private MyConfig myConfig;
    
        @GetMapping("/value")
        public String getValue() {
            return myConfig.getExampleValue();
        }
    }
    
  4. 刷新配置

    启动应用后,通过访问 /actuator/refresh 端点即可刷新配置,这需要在 application.yml 中启用 actuator:

    management:
      endpoints:
        web:
          exposure:
            include: refresh
    

刷新流程

  • 当配置更改时,修改外部配置源并调用 /actuator/refresh 端点,Spring 会重新加载与 @RefreshScope 注解的 Bean 相关的配置信息。

  • 此时,下次访问 MyController 中的 /value 端点时,会返回最新的配置信息,而不需要重启应用。

小结

@RefreshScope 提供了一种优雅的方式来动态管理和刷新配置,显著提高了微服务架构中的灵活性和可维护性。通过它,可以确保应用在运行时能够持续迭代和适应变化的配置需求。

  • 23
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值