Yaml 语法
该部分基于菜鸟教程 https://www.runoob.com/w3cnote/yaml-intro.html
yaml 概述
YAML 是 “YAML Ain’t a Markup Language”(YAML
不是一种标记语言)的递归缩写。在开发的这种语言时,YAML
的意思其实是:“Yet Another Markup Language”(仍是一种标记语言)。
YAML
是一种人类可读的数据序列化标准,常用于配置文件、数据交换、API规范等场景。它的设计目标是既能被人类轻松阅读和编写,又能被机器有效解析。
YAML
的语法和其他高级语言类似,并且可以简单表达清单、散列表,标量等数据形态。它使用空白符号缩进和大量依赖外观的特色,特别适合用来表达或编辑数据结构、各种配置文件、倾印调试内容、文件大纲(例如:许多电子邮件标题格式和YAML非常接近)。
YAML 的配置文件后缀为 .yml,如:application.yml
。
YAML 的主要特点:
- 人类可读性强,语法简洁直观
- 使用缩进表示层级结构,避免了XML的标签冗余
- 支持丰富的数据类型
- 跨语言支持,几乎所有编程语言都有对应的解析库
- 配置文件后缀为
.yml
或 .yaml
基本语法
- 大小写敏感 -
Name
和 name
是不同的键
- 使用缩进表示层级关系 - 类似Python的语法风格
- 缩进只允许使用空格,不允许使用Tab -
这是YAML的强制要求
- 缩进的空格数量不限 - 但同一层级必须左对齐
- 冒号后必须跟空格 -
key: value
,不能写成key:value
- 井号表示注释 -
# 这是注释
数据类型
YAML 支持以下几种数据类型:
YAML 对象
对象键值对使用冒号结构表示 key:
value,冒号后面要加一个空格。
也可以使用 key:{key1: value1, key2: value2, …}。
还可以使用缩进表示层级关系;
1 2 3 4 5
| user: name: Alice age: 30 email: alice@example.com
|
1 2 3 4 5 6 7 8 9 10 11 12
| company: name: Tech Corp address: street: 123 Main St city: San Francisco country: USA employees: - name: Alice position: Developer - name: Bob position: Designer
|
较为复杂的对象格式,可以使用问号加一个空格代表一个复杂的
key,配合一个冒号加一个空格代表一个 value:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| "user name": John "api-key": abc123 "@context": "https://schema.org"
? [key1, key2] : value_for_complex_key
? name: complex_object_key type: identifier : result: success data: processed
|
意思即对象的属性是一个数组
[complexkey1,complexkey2],对应的值也是一个数组
[complexvalue1,complexvalue2]
而且还支持一种行内映射的形式
1 2 3
| user: {name: Alice, age: 30, city: "New York"} coordinates: {x: 10, y: 20, z: 5}
|
YAML 数组
以 - 开头的行表示构成一个数组:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| languages: - Python - JavaScript - Go - Rust
projects: - name: Project A languages: - Python - Django status: active - name: Project B languages: - JavaScript - React status: completed
|
YAML 支持多维数组,可以使用行内表示:
1 2 3 4
| numbers: [1, 2, 3, 4, 5] colors: ["red", "green", "blue"] mixed: [1, "hello", true, null]xxxxxxxxxx4 1
|
多维序列
数据结构的子成员是一个数组,则可以在该项下面缩进一个空格。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| matrix: - [1, 2, 3] - [4, 5, 6] - [7, 8, 9]
matrix_nested: - - 1 - 2 - 3 - - 4 - 5 - 6
|
一个相对复杂的例子:
1 2 3 4 5 6 7 8 9
| companies: - id: 1 name: company1 price: 200W - id: 2 name: company2 price: 500W
|
意思是 companies 属性是一个数组,每一个数组元素又是由 id、name、price
三个属性构成。
数组也可以使用流式(flow)的方式表示:
1
| companies: [{id: 1,name: company1,price: 200W},{id: 2,name: company2,price: 500W}]
|
复合结构
数组和对象可以构成复合结构,例:
1 2 3 4 5 6 7 8 9
| languages: - Ruby - Perl - Python websites: YAML: yaml.org Ruby: ruby-lang.org Python: python.org Perl: use.perl.org
|
转换为 json 为:
1 2 3 4 5 6 7 8 9
| { languages: [ 'Ruby', 'Perl', 'Python'], websites: { YAML: 'yaml.org', Ruby: 'ruby-lang.org', Python: 'python.org', Perl: 'use.perl.org' } }
|
纯量
纯量是最基本的,不可再分的值,包括:
- 字符串
- 布尔值
- 整数
- 浮点数
- Null
- 时间
- 日期
使用一个例子来快速了解纯量的基本使用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| boolean: - TRUE - FALSE float: - 3.14 - 6.8523015e+5 int: - 123 - 0b1010_0111_0100_1010_1110 null: nodeName: 'node' parent: ~ string: - 哈哈 - 'Hello world' - newline newline2 date: - 2018-02-17 datetime: - 2018-02-17T15:02:31+08:00
|
引用
锚点和引用是YAML中避免重复配置的强大功能。它类似于编程中的变量定义和使用。
- 锚点(Anchor):使用
&
符号定义,相当于给一段配置起个名字
- 引用(Reference):使用
*
符号引用,相当于使用之前定义的配置
- 合并(Merge):使用
<<
符号,将引用的内容合并到当前位置
简单值的引用
1 2 3 4 5 6 7 8 9 10 11 12 13
| database_host: &db_host "localhost" cache_host: &cache_host "redis.example.com"
services: api: database_url: *db_host cache_url: *cache_host worker: database_url: *db_host cache_url: *cache_host
|
相当于
1 2 3 4 5 6 7 8 9 10 11 12
| database_host: "localhost" cache_host: "redis.example.com"
services: api: database_url: "localhost" cache_url: "redis.example.com" worker: database_url: "localhost" cache_url: "redis.example.com"
|
对象的引用和合并
&
用来建立锚点(defaults),<<
表示合并到当前数据,***** 用来引用锚点。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| default_database: &db_defaults driver: postgresql port: 5432 pool_size: 10 timeout: 30 ssl: true
development: database: <<: *db_defaults host: localhost name: dev_database
production: database: <<: *db_defaults host: prod.db.com name: prod_database ssl: false
|
解析结果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| default_database: driver: postgresql port: 5432 pool_size: 10 timeout: 30 ssl: true
development: database: driver: postgresql port: 5432 pool_size: 10 timeout: 30 ssl: true host: localhost name: dev_database
production: database: driver: postgresql port: 5432 pool_size: 10 timeout: 30 ssl: false host: prod.db.com name: prod_database
|
数组的引用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| common_dependencies: &common_deps - lodash - moment - axios
basic_tools: &basic_tools - webpack - babel
frontend_project: dependencies: *common_deps
backend_project: dependencies: - express - *common_deps - mongoose
fullstack_project: dependencies: - react - *common_deps - *basic_tools - typescript
|
相当于
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| backend_project: dependencies: - express - lodash - moment - axios - mongoose
fullstack_project: dependencies: - react - lodash - moment - axios - webpack - babel - typescript
|
多个锚点的组合使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| database_config: &db_config driver: mysql charset: utf8mb4 pool_min: 5 pool_max: 20
cache_config: &cache_config provider: redis ttl: 3600 max_memory: "512mb"
logging_config: &log_config level: info format: json rotation: daily
microservices: user_service: <<: *db_config <<: *cache_config <<: *log_config port: 8001 order_service: <<: *db_config <<: *log_config port: 8002 payment_service: <<: *db_config <<: *cache_config port: 8003 level: debug
|
相当于
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| microservices: user_service: driver: mysql charset: utf8mb4 pool_min: 5 pool_max: 20 provider: redis ttl: 3600 max_memory: "512mb" level: info format: json rotation: daily port: 8001
order_service: driver: mysql charset: utf8mb4 pool_min: 5 pool_max: 20 level: info format: json rotation: daily port: 8002
|
yaml 的多文档支持
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| --- name: Document 1 type: config data: key1: value1 key2: value2
--- name: Document 2 type: data items: - item1 - item2 - item3
...
|
标签和类型转换
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| integer_value: !!int "123" float_value: !!float "456.789" string_value: !!str 123 boolean_value: !!bool "yes"
custom_object: !MyClass property1: value1 property2: value2
binary_data: !!binary | R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5 OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+ +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC
|
Spring Boot 管理配置文件
注入配置文件
yaml文件更强大的地方在于,他可以给我们的实体类直接注入匹配值,它允许开发者以声明式的方式配置应用程序
Spring
Boot支持将YAML配置文件中的属性值自动注入到Java类中,主要通过以下几种方式实现:
使用@Value注解与配置文件占位符
@Value
注解可以直接用于字段、方法参数和构造器参数,以注入配置文件中的值。它适用于简单的配置项。
1 2 3 4 5 6 7
| server: port: 8080 app: name: MyApplication version: 1.0.0 author: ergoutree
|
properties 也可以这样
1 2 3 4
| server.port=8080 app.name=MyApplication app.version=1.0.0 app.author=ergoutree
|
Java类示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| @Component public class AppInfoService { @Value("${app.name}") private String appName; @Value("${app.version}") private String version; @Value("${server.port}") private int serverPort; @Value("${app.description:这是一个Spring Boot应用}") private String description; public void printAppInfo() { System.out.println("应用名称: " + appName); System.out.println("版本: " + version); System.out.println("端口: " + serverPort); System.out.println("描述: " + description); } }
|
@Value("${app.name}")
会自动将YAML中的
app.name
值注入到 appName
字段
- 支持嵌套属性,如
server.port
- 可以设置默认值,语法是
${key:defaultValue}
@ConfigurationProperties:
@ConfigurationProperties 是
Spring Boot 中的一个注解,用于将配置文件中的属性值绑定到 Java Bean
上。提供了一种更类型安全的方式来处理配置。这种方式适合注入一组相关的配置属性,更加优雅和类型安全。
通常,这个注解用于将外部属性文件中的属性值映射到应用程序的配置类中,以便在整个应用程序中方便地访问和使用这些属性。
这个注解通常与 @Configuration
(声明是一个配置类) 或
@Component
(声明是一个bean)一起使用,将配置属性绑定到一个特定的
Java Bean,然后以便让 Spring 容器识别并管理这个 Bean。
通过在类上使用
@ConfigurationProperties
,可以将属性文件中的键与 Java Bean
的字段或属性进行映射。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| database: host: localhost port: 3306 username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver connection-timeout: 30000 max-connections: 10
email: smtp: host: smtp.qq.com port: 587 username: example@qq.com password: your-password from: noreply@example.com templates: welcome: welcome-template.html reset-password: reset-password-template.html
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| @Component @ConfigurationProperties(prefix = "database") @Data public class DatabaseProperties { private String host; private int port; private String username; private String password; private String driverClassName; private long connectionTimeout; private int maxConnections; }
@Component @ConfigurationProperties(prefix = "email") @Data public class EmailProperties { private Smtp smtp = new Smtp(); private String from; private Map<String, String> templates = new HashMap<>(); @Data public static class Smtp { private String host; private int port; private String username; private String password; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| @Service public class EmailService { private final EmailProperties emailProperties; public EmailService(EmailProperties emailProperties) { this.emailProperties = emailProperties; } public void sendEmail() { System.out.println("SMTP主机: " + emailProperties.getSmtp().getHost()); System.out.println("SMTP端口: " + emailProperties.getSmtp().getPort()); System.out.println("发件人: " + emailProperties.getFrom()); System.out.println("欢迎模板: " + emailProperties.getTemplates().get("welcome")); } }
|
说明:
@ConfigurationProperties(prefix = "database")
会将所有以 database
开头的配置映射到该类
- 支持嵌套对象,如
email.smtp
会映射到
EmailProperties.Smtp
类
- 支持集合类型,如
Map templates
- 需要提供标准的getter/setter方法(可使用Lombok简化)
在Spring
Boot的启动类或配置类上添加@EnableConfigurationProperties
注解来启用@ConfigurationProperties
支持
对于Spring Boot 2.2及以上版本,这一步通常是可选的,因为Spring
Boot会自动配置
Environment方式
在Spring
Boot中,Environment
抽象是Spring框架提供的一个接口,它允许你访问配置属性以及应用程序的环境。虽然Environment
不是一个专门用于注入配置的方式(像@Value
或@ConfigurationProperties
那样),但它可以在某些情况下非常有用,特别是当你需要访问低级别的配置信息或进行条件化配置时。
Environment
接口提供了多种方法来获取配置属性,包括通过键名(key)直接访问和通过解析占位符(placeholders)来访问。
也就是说,读取环境变量,但是不仅仅读取环境变量它会从多个配置源读取配置,包括但不限于:
- .环境变量(Operating System Environment Variables)
- 系统属性(System Properties)
- 配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| @Component public class EnvironmentService { private final Environment environment; public EnvironmentService(Environment environment) { this.environment = environment; } public void demonstrateEnvironment() { String appName = environment.getProperty("app.name"); Integer serverPort = environment.getProperty("server.port", Integer.class); String description = environment.getProperty("app.description", "默认描述"); System.out.println("应用名称: " + appName); System.out.println("服务端口: " + serverPort); System.out.println("应用描述: " + description); String[] activeProfiles = environment.getActiveProfiles(); System.out.println("激活的Profile: " + Arrays.toString(activeProfiles)); if (environment.containsProperty("database.url")) { System.out.println("数据库URL: " + environment.getProperty("database.url")); } } }
|
Environment 接口的常用方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| @Service public class ConfigurationService { private final Environment env; public ConfigurationService(Environment env) { this.env = env; } public void demonstrateEnvironmentMethods() { String stringValue = env.getProperty("app.name"); Integer intValue = env.getProperty("server.port", Integer.class); Boolean boolValue = env.getProperty("app.debug", Boolean.class); String valueWithDefault = env.getProperty("app.title", "默认标题"); Integer portWithDefault = env.getProperty("custom.port", Integer.class, 9090); try { String requiredValue = env.getRequiredProperty("app.name"); System.out.println("必需属性: " + requiredValue); } catch (IllegalStateException e) { System.out.println("必需属性不存在: " + e.getMessage()); } boolean hasProperty = env.containsProperty("app.version"); String[] activeProfiles = env.getActiveProfiles(); String[] defaultProfiles = env.getDefaultProfiles(); boolean acceptsDev = env.acceptsProfiles("dev"); boolean acceptsDevOrTest = env.acceptsProfiles("dev", "test"); System.out.println("字符串值: " + stringValue); System.out.println("整数值: " + intValue); System.out.println("布尔值: " + boolValue); System.out.println("带默认值: " + valueWithDefault); System.out.println("端口带默认值: " + portWithDefault); System.out.println("包含版本属性: " + hasProperty); System.out.println("激活的Profile: " + Arrays.toString(activeProfiles)); System.out.println("默认Profile: " + Arrays.toString(defaultProfiles)); System.out.println("接受dev Profile: " + acceptsDev); System.out.println("接受dev或test Profile: " + acceptsDevOrTest); } }
|
Environment
提供了对配置属性的广泛访问,但它不是类型安全的。若需要类型安全的配置绑定,建议使用@ConfigurationProperties
。
Environment
还提供了对活动 profiles
的访问,这在进行条件化配置时非常有用。
当你需要访问 Spring Boot 的 application.properties 或
application.yml 文件中的配置时,Environment
是一个很好的选择,但它也可以访问其他来源的配置,如命令行参数、JNDI、servlet上下文参数等。
@Configuration注解+@Bean
(还可以加@Import引入三方)
先用@Configuration
标记一个类作为配置类,相当于 XML
中的<beans>
标签
- 配置类会被 Spring 容器扫描并处理。
- 配置类中的
@Bean
方法会被容器调用以创建和管理 Bean。
- 配置类本身也是一个 Bean,可以被其他组件注入。
然后用@Bean
标记其中的方法,返回一个对象并注册为 Spring
容器中的 Bean。
- 方法名默认作为 Bean
的名称(可通过
name
属性指定其他名称)。
- 可以指定 Bean 的作用域(如
@Scope("prototype")
)。
- 可以通过
@DependsOn
指定依赖关系。
之后不同的地方就是,使用@Import
导入其他配置类,将它们的
Bean 定义合并到当前配置中。
- 引入第三方库的配置类。
- 模块化配置,将相关配置分散到多个类中。
- 导入没有使用
@Configuration
注解的普通类(会被当作配置类处理)。
这是基础配置类与 Bean 定义
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;
@Configuration public class AppConfig {
@Bean public MyService myService() { return new MyServiceImpl(); }
@Bean(name = "customDataSource") public DataSource dataSource() { return DataSourceBuilder.create() .url("jdbc:mysql://localhost:3306/mydb") .username("root") .password("password") .build(); } }
|
在这之上,我们就可以使用@Import
引入其他配置类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import;
@Configuration @Import({DatabaseConfig.class, SecurityConfig.class}) public class AppConfig { }
@Configuration public class DatabaseConfig { @Bean public DataSource dataSource() { } }
@Configuration public class SecurityConfig { @Bean public AuthenticationManager authenticationManager() { } }
|
使用 @PropertySources
@PropertySources
是@PropertySource
的容器注解,用于同时指定多个配置文件源。
创建多个自定义配置文件
1 2 3 4 5 6 7 8 9 10 11 12
| custom.app.name=自定义应用 custom.app.version=2.0.0 custom.database.driver=mysql custom.cache.enabled=true custom.cache.ttl=3600
business.module.user=用户管理模块 business.module.order=订单处理模块 business.feature.payment=true business.feature.notification=false
|
使用@PropertySource
的配置类示例
基本用法,指定了使用 custom.properties
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| @Configuration @PropertySource("classpath:custom.properties") public class CustomConfiguration { @Autowired private Environment env; @Bean public CustomAppProperties customAppProperties() { CustomAppProperties props = new CustomAppProperties(); props.setName(env.getProperty("custom.app.name")); props.setVersion(env.getProperty("custom.app.version")); props.setDatabaseDriver(env.getProperty("custom.database.driver")); props.setCacheEnabled(env.getProperty("custom.cache.enabled", Boolean.class, false)); props.setCacheTtl(env.getProperty("custom.cache.ttl", Integer.class, 1800)); return props; } }
@Data public class CustomAppProperties { private String name; private String version; private String databaseDriver; private boolean cacheEnabled; private int cacheTtl; }
|
@PropertySources
多文件配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| @Configuration @PropertySources({ @PropertySource("classpath:custom.properties"), @PropertySource("classpath:business.properties"), @PropertySource(value = "classpath:optional.properties", ignoreResourceNotFound = true), @PropertySource(value = "file:${user.home}/app-config.properties", ignoreResourceNotFound = true) }) public class MultiplePropertySourcesConfiguration { @Autowired private Environment env; @Bean public ApplicationSettings applicationSettings() { ApplicationSettings settings = new ApplicationSettings(); settings.setAppName(env.getProperty("custom.app.name")); settings.setAppVersion(env.getProperty("custom.app.version")); settings.setCacheEnabled(env.getProperty("custom.cache.enabled", Boolean.class)); settings.setUserModule(env.getProperty("business.module.user")); settings.setOrderModule(env.getProperty("business.module.order")); settings.setPaymentEnabled(env.getProperty("business.feature.payment", Boolean.class)); return settings; } @PostConstruct public void printConfiguration() { System.out.println("=== 配置信息 ==="); System.out.println("应用名称: " + env.getProperty("custom.app.name")); System.out.println("应用版本: " + env.getProperty("custom.app.version")); System.out.println("用户模块: " + env.getProperty("business.module.user")); System.out.println("订单模块: " + env.getProperty("business.module.order")); System.out.println("缓存启用: " + env.getProperty("custom.cache.enabled")); System.out.println("支付功能: " + env.getProperty("business.feature.payment")); } }
@Data public class ApplicationSettings { private String appName; private String appVersion; private String userModule; private String orderModule; private Boolean cacheEnabled; private Boolean paymentEnabled; }
|
- 加载多个配置文件:通过
@PropertySources
注解可以声明加载多个配置文件。
classpath:
前缀表示从类路径加载。
file:
前缀表示从文件系统加载,支持使用环境变量(如${user.home}
)。
- 加载顺序:配置文件按声明顺序加载,后加载的文件会覆盖前面文件中同名的属性(例如,如果
app-config.properties
和custom.properties
都有custom.app.name
属性,将使用app-config.properties
中的值)。
- 可选文件:通过
ignoreResourceNotFound = true
指定可选文件,如果文件不存在则忽略(如optional.properties
和用户主目录下的配置文件)。
条件化属性源
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| @Configuration public class ConditionalPropertySourceConfiguration { @Configuration @Profile("dev") @PropertySources({ @PropertySource("classpath:dev.properties"), @PropertySource("classpath:dev-database.properties") }) static class DevConfiguration { } @Configuration @Profile("prod") @PropertySources({ @PropertySource("classpath:prod.properties"), @PropertySource("classpath:prod-database.properties") }) static class ProdConfiguration { } @Configuration @Profile("test") @PropertySource("classpath:test.properties") static class TestConfiguration { } }
|
@Profile
注解:根据激活的环境(如dev
、prod
、test
)选择性加载配置类。
@PropertySource
注解:然后加载特定环境的配置文件。实现环境配置分离
使用
@ImportResource
加载 XML 配置文件
如果你有传统的 Spring XML 配置文件,需要在 Spring Boot 中加载。
1 2 3 4 5 6 7 8 9
| <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="myService" class="com.example.MyService"> <property name="message" value="Hello from XML!"/> </bean> </beans>
|
1 2 3 4 5 6 7 8 9 10 11
| import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.ImportResource;
@SpringBootApplication @ImportResource("classpath:applicationContext.xml") public class MyApp { public static void main(String[] args) { SpringApplication.run(MyApp.class, args); } }
|
Spring
Boot 中的 application.properties 与 application.yaml
其实SpringBoot的配置文件有.properties和.yml两种形式,两种配置文件的效果类似,只不过是格式不同而已
SpringBoot使用一个全局的配置文件 , 配置文件名称是固定的
- application.properties
- 语法:使用
key=value
格式,用
.
分隔层级。
- 简单直接,适合简单配置。
- 支持占位符引用(如
${app.name}
)。
- 不支持复杂的嵌套结构(需重复前缀)。
application.yaml
/
application.yml
- 语法:使用
key: value
格式,通过缩进表示层级。
- 结构清晰,适合复杂配置(减少重复前缀)。
- 支持列表、对象嵌套。
- 更易读,尤其对于多层次配置。
注意:
当properties和yml同时存在时,properties的优先级会比yml高
两种文件都是用#
注释,yml
的优点在于可以省去一下重复代码
在properties文件里面的.
连接在yml文件里面全部换成
:
进行连接,并且每一级之间必须换行,在第二级开始应该进行几个空格的缩进,如果是同级的就不需要进行缩进
properties 文件和 yml
文件优先级:
Spring Boot
对配置文件的加载遵循特定的顺序和优先级,总结如下:
单文件优先级
相同类型文件:
高优先级位置的文件覆盖低优先级位置的文件。
优先级从高到低:
命令行参数(如 --server.port=8081
)。
```bash java -jar app.jar –server.port=8081
–spring.profiles.active=prod 1 2 3 4 5 6 7 8 9 10 11 12
| - 直接在启动应用时传入的参数
- 格式:`--属性名=值`
- 优先级最高,会覆盖所有其他配置
2. 环境变量(如 `SERVER_PORT=8081`)。
```bash export SERVER_PORT=8081 export SPRING_PROFILES_ACTIVE=prod
|
操作系统级别的环境变量
Spring Boot会自动将环境变量转换为配置属性
命名规则:大写字母,用下划线分隔
SPRING_APPLICATION_JSON
环境变量(JSON
格式配置)。
1
| export SPRING_APPLICATION_JSON='{"server.port":8081,"logging.level.root":"DEBUG"}'
|
java:comp/env
JNDI 属性。
1 2 3
| Context ctx = new InitialContext(); ctx.bind("java:comp/env/server.port", "8081");
|
- 主要用于Java EE环境
- 通过JNDI(Java命名和目录接口)设置的属性
Java 系统属性(System.getProperties()
)。
1
| java -Dserver.port=8081 -jar app.jar
|
- 通过
-D
参数设置的JVM系统属性
- 也可以在代码中通过
System.setProperty()
设置
RandomValuePropertySource
(随机值,如
random.*
)。
1 2 3 4
| my.secret=${random.value} my.number=${random.int} my.uuid=${random.uuid}
|
- Spring Boot内置的随机值生成器
- 用于生成随机配置值
应用外部的 application-{profile}.properties
或
.yaml
(如
config/application.properties
)。
1 2 3 4 5
| project/ ├── app.jar ├── config/ │ ├── application-dev.properties # 外部Profile配置 │ └── application-prod.properties
|
- 位于jar包外部的带环境标识的配置文件
- 通常放在
config/
目录下
- 优先级高于应用内部的同类文件
应用内部的 application-{profile}.properties
或
.yaml
(如
src/main/resources/application-dev.properties
)。
1 2 3 4
| src/main/resources/ ├── application.properties ├── application-dev.properties # 内部Profile配置 └── application-prod.properties
|
- 打包在jar内的带环境标识的配置文件
- 位于
src/main/resources/
目录
应用外部的 application.properties
或
.yaml
。
1 2 3 4
| project/ ├── app.jar ├── config/ │ └── application.properties # 外部通用配置
|
- jar包外部的通用配置文件
- 不带
profile
后缀的配置文件
应用内部的 application.properties
或
.yaml
(最低优先级)。
1 2
| src/main/resources/ └── application.properties # 内部通用配置,优先级最低
|
- 打包在jar内的通用配置文件
- 优先级最低,最容易被其他配置覆盖
同路径下
.properties
与 .yaml
的优先级
- 当
application.properties
和
application.yaml
同时存在于同一位置时
.properties
文件优先级更高,会覆盖
.yaml
中的同名属性。
- 示例
- 若
application.properties
包含
server.port=8080
,而 application.yaml
包含
server.port=8081
,则最终端口为 8080。
不同路径下的配置文件
- 外部配置 > 内部配置
- 位于应用外部(如
config/
目录)的配置文件优先级高于应用内部(src/main/resources
)的配置文件。
特定环境配置(application-{profile}.properties
)
- 特定环境配置 > 通用配置:
- 激活的环境配置(如
application-dev.properties
)会覆盖通用配置(application.properties
)。
- 若同时存在
application-dev.properties
和
application-dev.yaml
,则 .properties
仍优先。
场景 |
优先级顺序(高 → 低) |
同类型文件 |
外部 > 内部,特定环境 > 通用环境 |
同路径下 .properties vs .yaml |
.properties > .yaml |
特定环境配置 |
application-{profile}.properties >
application.properties |