spring 从application.properties中获取参数的四种方式

在Spring Boot中,自定义一个Starter时,从application.properties中获取参数主要有以下几种方法:

  1. 使用@Value注解
    这是最常用的方法之一,通过@Value注解可以直接将application.properties中的属性值注入到Spring管理的Bean中。
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;@Component
public class MyService {@Value("${my.starter.property}")private String myProperty;public void printProperty() {System.out.println("My Property: " + myProperty);}
}

在application.properties中配置:

my.starter.property=Hello, Spring Boot!
  1. 使用@ConfigurationProperties注解
    如果需要绑定一组相关的属性,可以使用@ConfigurationProperties注解。这种方式更适合管理一组配置属性,并且支持类型安全和默认值。

首先,定义一个配置类:

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;@Component
@ConfigurationProperties(prefix = "my.starter")
public class MyStarterProperties {private String property;// Getter and Setterpublic String getProperty() {return property;}public void setProperty(String property) {this.property = property;}
}

在application.properties中配置:

properties
my.starter.property=Hello, Spring Boot!
然后,在需要使用这些属性的地方注入MyStarterProperties:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
public class MyService {private final MyStarterProperties properties;@Autowiredpublic MyService(MyStarterProperties properties) {this.properties = properties;}public void printProperty() {System.out.println("My Property: " + properties.getProperty());}
}
  1. 使用Environment接口
    通过Environment接口,可以动态地获取配置属性。这种方式适用于需要灵活获取配置属性的场景。
import org.springframework.core.env.Environment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
public class MyService {private final Environment environment;@Autowiredpublic MyService(Environment environment) {this.environment = environment;}public void printProperty() {String myProperty = environment.getProperty("my.starter.property");System.out.println("My Property: " + myProperty);}
}
  1. 使用@PropertySource注解
    如果需要从自定义的配置文件中加载属性,可以使用@PropertySource注解。

首先,定义一个自定义的配置文件my-starter.properties:

properties
my.starter.property=Hello, Custom Property Source!
然后,在配置类中使用@PropertySource注解:

import org.springframework.context.annotation.PropertySource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;@Component
@PropertySource("classpath:my-starter.properties")
public class MyService {@Value("${my.starter.property}")private String myProperty;public void printProperty() {System.out.println("My Property: " + myProperty);}
}

总结
以上四种方法都可以用于从application.properties中获取参数,选择哪种方法取决于具体的需求和场景:

@Value注解:适合简单的单个属性注入。
@ConfigurationProperties注解:适合绑定一组相关的属性,提供类型安全和默认值。
Environment接口:适合需要动态获取配置属性的场景。
@PropertySource注解:适合从自定义的配置文件中加载属性。

@Value 注解和 Environment 接口在 Spring Boot 中都可以用于从 application.properties 获取单个参数,但它们在实现方式、使用场景和功能特点上存在显著区别。以下是对两者的具体比较:
在这里插入图片描述

当提到“属性在运行时才确定或需要动态查询”时,这主要涉及到在应用程序运行过程中,根据某些条件或上下文来动态决定需要获取的配置属性值。这种情况下,Environment 接口相比 @Value 注解具有显著的优势。下面我将通过具体的场景和示例来详细说明这一区别。
  1. 动态属性查询的场景
    场景1:多环境配置
    假设你的应用程序需要在不同的环境(如开发、测试、生产)中运行,并且每个环境都有不同的配置属性。例如,数据库连接字符串、API 端点等。在运行时,你可能需要根据当前环境来动态选择正确的配置属性。

使用 @Value 注解的问题:
如果你使用 @Value 注解,你需要在编译时就为每个可能的属性值都声明注解,或者为每个环境创建不同的配置类。这不仅增加了代码的复杂性,而且当环境配置发生变化时,还需要修改和重新编译代码。
使用 Environment 接口的优势:
你可以在运行时通过 Environment 接口查询当前环境的配置属性。例如,你可以根据系统属性(如 spring.profiles.active)或外部配置(如环境变量)来动态决定查询哪个属性。
场景2:用户自定义配置
假设你的应用程序允许用户自定义某些配置属性,这些属性在应用程序启动时或运行过程中由用户提供。例如,用户可能希望自定义日志级别、缓存大小等。

使用 @Value 注解的问题:
由于 @Value 注解需要在编译时确定属性名,因此无法直接支持用户自定义的配置属性。你需要在代码中硬编码所有可能的属性名,或者使用其他复杂的机制来处理用户自定义配置。
使用 Environment 接口的优势:
你可以通过 Environment 接口动态查询用户提供的配置属性。用户可以通过配置文件、命令行参数、环境变量等方式提供配置属性,你的应用程序可以在运行时动态获取这些属性值。
2. 示例代码
使用 Environment 接口实现多环境配置

import org.springframework.core.env.Environment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
public class DatabaseConfig {private final Environment environment;@Autowiredpublic DatabaseConfig(Environment environment) {this.environment = environment;}public String getDatabaseUrl() {// 根据当前环境动态查询数据库连接字符串String activeProfile = environment.getProperty("spring.profiles.active");if ("dev".equals(activeProfile)) {return environment.getProperty("database.url.dev");} else if ("prod".equals(activeProfile)) {return environment.getProperty("database.url.prod");} else {throw new IllegalStateException("Unknown environment: " + activeProfile);}}
}

在 application.properties 或 application-dev.properties、application-prod.properties 中配置:

application-dev.properties

database.url.dev=jdbc:mysql://localhost:3306/dev_db
# application-prod.properties
database.url.prod=jdbc:mysql://prod-server:3306/prod_db

使用 Environment 接口实现用户自定义配置

import org.springframework.core.env.Environment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
public class AppConfig {private final Environment environment;@Autowiredpublic AppConfig(Environment environment) {this.environment = environment;}public int getCacheSize() {// 动态查询用户自定义的缓存大小String cacheSizeStr = environment.getProperty("app.cache.size", "100"); // 默认值为100try {return Integer.parseInt(cacheSizeStr);} catch (NumberFormatException e) {throw new IllegalArgumentException("Invalid cache size: " + cacheSizeStr, e);}}
}

用户可以通过以下方式之一提供 app.cache.size 属性:

在 application.properties 中配置:
properties
app.cache.size=200
通过命令行参数启动应用程序:
bash
java -jar myapp.jar --app.cache.size=300
通过环境变量设置:
bash
export APP_CACHE_SIZE=400
java -jar myapp.jar
(注意:环境变量名通常需要转换为大写,并用下划线替换点号,具体取决于你的应用程序如何解析环境变量)
3. 总结
@Value 注解:适用于属性在编译时已知且固定的场景,如静态配置属性。它提供了类型安全和 SpEL 表达式支持,但灵活性较低,不适合动态查询。
Environment 接口:适用于属性在运行时才确定或需要动态查询的场景,如多环境配置、用户自定义配置等。它提供了更高的灵活性和可配置性,但需要手动进行类型转换和错误处理。
因此,当属性在运行时才确定或需要动态查询时,Environment 接口是更合适的选择

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/184.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2025华东杯B题华东杯数学建模思路代码成品讲解工序安排问题

完整内容请看文章最下面的推广群 我将展示完整的文章、代码和结果 工序安排问题 摘要 本文研究的核心是制造业中的工序安排优化问题,源自实际生产管理中常见的资源分配挑战。问题背景设定为一家拥有100名工人和三条相同服装生产线的成衣制造厂,涉及裁…

Solon Cloud Gateway 补充

说明 在「使用 Solon Cloud Gateway 替换Spring Cloud Gateway 」的文章中,有评论说不知道响应式。当时看的是 Solon Cloud Gateway 使用响应式接口,由 Solon-Rx 来实现,是基于 reactive-streams 封装的 RxJava 极简版。目前仅一个接口 Com…

腾讯云CodeBuddy初体验

我正在参加CodeBuddy「首席试玩官」内容创作大赛,本文所使用的 CodeBuddy 免费下载链接:腾讯云代码助手 CodeBuddy - AI 时代的智能编程伙伴”; 最近AI编程很火,据说我司程序员现在每天可以准点下班,AI起到了很大的作…

K8S - 命名空间实战 - 从资源隔离到多环境管理

引言 在传统的物理机或虚拟机环境中,不同业务应用共享资源,容易导致权限冲突、资源争用和管理混乱。Kubernetes 通过 命名空间(Namespace)实现资源逻辑隔离,将集群划分为多个虚拟子集群,从而解决以下问题&…

《多端统一的终极答案:X5内核增强版的渲染优化全解析》

跨端应用的需求呈爆发式增长,无论是电商购物、社交互动,还是金融理财类应用,都期望能够在不同平台上为用户提供一致且流畅的体验。而在这一过程中,跨端渲染技术成为了关键瓶颈。腾讯X5内核增强版的出现,犹如一道曙光&a…

1.5 点云数据获取方式——双目立体相机

图1-5-1 双目立体相机 双目相机通过模拟人眼立体视觉,利用两个摄像头的视差信息计算物体深度,进而生成 3D 点云,具有成本低、体积小、信息丰富等优势,成为中

JavaScript高级进阶(五)

操作节点属性 设置属性&#xff08;先找属性再操作&#xff09; setAttribute()方法添加指定的属性&#xff0c;并为其赋指定的值 语法&#xff1a; element.setAttribute(attributename/属性名,attributevalue/属性值) 例: <style> .box{ width: 200px; height: 200p…

数据结构每日一题day13(链表)★★★★★

题目描述&#xff1a;采用尾插法在头指针L处建立一个带头结点的单链表,输入-1表示结束结果返回建立的单链表。 算法思想&#xff1a; 1.初始化链表&#xff1a;创建一个头结点&#xff08;不存储实际数据&#xff09;&#xff0c;头指针 L 指向该头结点。初始时&#xff0c;头…

第十六届蓝桥杯 2025 C/C++组 破解信息

目录 题目&#xff1a; 题目描述&#xff1a; 题目链接&#xff1a; 思路&#xff1a; 思路详解&#xff1a; 代码&#xff1a; 代码详解&#xff1a; 题目&#xff1a; 题目描述&#xff1a; 题目链接&#xff1a; P12344 [蓝桥杯 2025 省 B/Python B 第二场] 破解信息…

【Linux网络】深入解析I/O多路转接 - Select

&#x1f4e2;博客主页&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;博客仓库&#xff1a;https://gitee.com/JohnKingW/linux_test/tree/master/lesson &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &…

MongoDB的下载安装与启动

MongoDB的下载安装与启动&#xff0c; 一、MongoDB下载安装 1. 官网下载 打开官网&#xff1a;https://www.mongodb.com/try/download/community选择&#xff1a; 版本&#xff08;Version&#xff09;&#xff1a;选最新版或者根据需要选旧版。平台&#xff08;OS&#xff0…

Docker 容器虚拟化技术和自动化部署

Docker 容器虚拟化技术和自动化部署 一、Docker 核心组件1.1 Docker 引擎1.2 Docker 镜像1.3 Docker 容器1.4 Docker 仓库 二、Docker 环境安装清华镜像安装 三、Docker 基本操作3.1 镜像管理3.1.1 查看本地镜像 docker images3.1.2 添加镜像标签 docker tag3.1.3 查看镜像信息…