|
| 1 | +很多时候我们需要将一些常用的配置信息比如阿里云oss配置、发送短信的相关信息配置等等放到配置文件中。 |
| 2 | + |
| 3 | +下面我们来看一下 Spring 为我们提供了哪些方式帮助我们从配置文件中读取这些配置信息。 |
| 4 | + |
| 5 | +`application.yml` 内容如下: |
| 6 | + |
| 7 | +```yaml |
| 8 | +wuhan2020: 2020年初武汉爆发了新型冠状病毒,疫情严重,但是,我相信一切都会过去!武汉加油!中国加油! |
| 9 | + |
| 10 | +my-profile: |
| 11 | + name: Guide哥 |
| 12 | + email: koushuangbwcx@163.com |
| 13 | + |
| 14 | +library: |
| 15 | + location: 湖北武汉加油中国加油 |
| 16 | + books: |
| 17 | + - name: 天才基本法 |
| 18 | + description: 二十二岁的林朝夕在父亲确诊阿尔茨海默病这天,得知自己暗恋多年的校园男神裴之即将出国深造的消息——对方考取的学校,恰是父亲当年为她放弃的那所。 |
| 19 | + - name: 时间的秩序 |
| 20 | + description: 为什么我们记得过去,而非未来?时间“流逝”意味着什么?是我们存在于时间之内,还是时间存在于我们之中?卡洛·罗韦利用诗意的文字,邀请我们思考这一亘古难题——时间的本质。 |
| 21 | + - name: 了不起的我 |
| 22 | + description: 如何养成一个新习惯?如何让心智变得更成熟?如何拥有高质量的关系? 如何走出人生的艰难时刻? |
| 23 | + |
| 24 | +``` |
| 25 | + |
| 26 | +### 1.通过 `@value` 读取比较简单的配置信息 |
| 27 | + |
| 28 | +使用 `@Value("${property}")` 读取比较简单的配置信息: |
| 29 | + |
| 30 | +```java |
| 31 | +@Value("${wuhan2020}") |
| 32 | +String wuhan2020; |
| 33 | +``` |
| 34 | + |
| 35 | +> **需要注意的是 `@value`这种方式是不被推荐的,Spring 比较建议的是下面几种读取配置信息的方式。** |
| 36 | +
|
| 37 | +### 2.通过`@ConfigurationProperties`读取并与 bean 绑定 |
| 38 | + |
| 39 | +> **`LibraryProperties` 类上加了 `@Component` 注解,我们可以像使用普通 bean 一样将其注入到类中使用。** |
| 40 | +
|
| 41 | +```java |
| 42 | + |
| 43 | +import lombok.Getter; |
| 44 | +import lombok.Setter; |
| 45 | +import lombok.ToString; |
| 46 | +import org.springframework.boot.context.properties.ConfigurationProperties; |
| 47 | +import org.springframework.context.annotation.Configuration; |
| 48 | +import org.springframework.stereotype.Component; |
| 49 | + |
| 50 | +import java.util.List; |
| 51 | + |
| 52 | +@Component |
| 53 | +@ConfigurationProperties(prefix = "library") |
| 54 | +@Setter |
| 55 | +@Getter |
| 56 | +@ToString |
| 57 | +class LibraryProperties { |
| 58 | + private String location; |
| 59 | + private List<Book> books; |
| 60 | + |
| 61 | + @Setter |
| 62 | + @Getter |
| 63 | + @ToString |
| 64 | + static class Book { |
| 65 | + String name; |
| 66 | + String description; |
| 67 | + } |
| 68 | +} |
| 69 | + |
| 70 | +``` |
| 71 | + |
| 72 | +这个时候你就可以像使用普通 bean 一样,将其注入到类中使用: |
| 73 | + |
| 74 | +```java |
| 75 | +package cn.javaguide.readconfigproperties; |
| 76 | + |
| 77 | +import org.springframework.beans.factory.InitializingBean; |
| 78 | +import org.springframework.boot.SpringApplication; |
| 79 | +import org.springframework.boot.autoconfigure.SpringBootApplication; |
| 80 | + |
| 81 | +/** |
| 82 | + * @author shuang.kou |
| 83 | + */ |
| 84 | +@SpringBootApplication |
| 85 | +public class ReadConfigPropertiesApplication implements InitializingBean { |
| 86 | + |
| 87 | + private final LibraryProperties library; |
| 88 | + |
| 89 | + public ReadConfigPropertiesApplication(LibraryProperties library) { |
| 90 | + this.library = library; |
| 91 | + } |
| 92 | + |
| 93 | + public static void main(String[] args) { |
| 94 | + SpringApplication.run(ReadConfigPropertiesApplication.class, args); |
| 95 | + } |
| 96 | + |
| 97 | + @Override |
| 98 | + public void afterPropertiesSet() { |
| 99 | + System.out.println(library.getLocation()); |
| 100 | + System.out.println(library.getBooks()); } |
| 101 | +} |
| 102 | +``` |
| 103 | + |
| 104 | +控制台输出: |
| 105 | + |
| 106 | +``` |
| 107 | +湖北武汉加油中国加油 |
| 108 | +[LibraryProperties.Book(name=天才基本法, description........] |
| 109 | +``` |
| 110 | + |
| 111 | +### 3.通过`@ConfigurationProperties`读取并校验 |
| 112 | + |
| 113 | +我们先将`application.yml`修改为如下内容,明显看出这不是一个正确的 email 格式: |
| 114 | + |
| 115 | +```yaml |
| 116 | +my-profile: |
| 117 | + name: Guide哥 |
| 118 | + email: koushuangbwcx@ |
| 119 | +``` |
| 120 | +
|
| 121 | +>**`ProfileProperties` 类没有加 `@Component` 注解。我们在我们要使用`ProfileProperties` 的地方使用`@EnableConfigurationProperties`注册我们的配置bean:** |
| 122 | + |
| 123 | + ```java |
| 124 | +import lombok.Getter; |
| 125 | +import lombok.Setter; |
| 126 | +import lombok.ToString; |
| 127 | +import org.springframework.boot.context.properties.ConfigurationProperties; |
| 128 | +import org.springframework.stereotype.Component; |
| 129 | +import org.springframework.validation.annotation.Validated; |
| 130 | +
|
| 131 | +import javax.validation.constraints.Email; |
| 132 | +import javax.validation.constraints.NotEmpty; |
| 133 | +
|
| 134 | +/** |
| 135 | + * @author shuang.kou |
| 136 | + */ |
| 137 | +@Getter |
| 138 | +@Setter |
| 139 | +@ToString |
| 140 | +@ConfigurationProperties("my-profile") |
| 141 | +@Validated |
| 142 | +public class ProfileProperties { |
| 143 | + @NotEmpty |
| 144 | + private String name; |
| 145 | +
|
| 146 | + @Email |
| 147 | + @NotEmpty |
| 148 | + private String email; |
| 149 | + |
| 150 | + //配置文件中没有读取到的话就用默认值 |
| 151 | + private Boolean handsome = Boolean.TRUE; |
| 152 | +
|
| 153 | +} |
| 154 | + ``` |
| 155 | + |
| 156 | +具体使用: |
| 157 | + |
| 158 | +```java |
| 159 | +package cn.javaguide.readconfigproperties; |
| 160 | +
|
| 161 | +import org.springframework.beans.factory.InitializingBean; |
| 162 | +import org.springframework.beans.factory.annotation.Value; |
| 163 | +import org.springframework.boot.SpringApplication; |
| 164 | +import org.springframework.boot.autoconfigure.SpringBootApplication; |
| 165 | +import org.springframework.boot.context.properties.EnableConfigurationProperties; |
| 166 | +
|
| 167 | +/** |
| 168 | + * @author shuang.kou |
| 169 | + */ |
| 170 | +@SpringBootApplication |
| 171 | +@EnableConfigurationProperties(ProfileProperties.class) |
| 172 | +public class ReadConfigPropertiesApplication implements InitializingBean { |
| 173 | + private final ProfileProperties profileProperties; |
| 174 | +
|
| 175 | + public ReadConfigPropertiesApplication(ProfileProperties profileProperties) { |
| 176 | + this.profileProperties = profileProperties; |
| 177 | + } |
| 178 | +
|
| 179 | + public static void main(String[] args) { |
| 180 | + SpringApplication.run(ReadConfigPropertiesApplication.class, args); |
| 181 | + } |
| 182 | +
|
| 183 | + @Override |
| 184 | + public void afterPropertiesSet() { |
| 185 | + System.out.println(profileProperties.toString()); |
| 186 | + } |
| 187 | +} |
| 188 | +
|
| 189 | +``` |
| 190 | + |
| 191 | +因为我们的邮箱格式不正确,所以程序运行的时候就报错,根本运行不起来,保证了数据类型的安全性: |
| 192 | + |
| 193 | +```visual basic |
| 194 | +Binding to target org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'my-profile' to cn.javaguide.readconfigproperties.ProfileProperties failed: |
| 195 | +
|
| 196 | + Property: my-profile.email |
| 197 | + Value: koushuangbwcx@ |
| 198 | + Origin: class path resource [application.yml]:5:10 |
| 199 | + Reason: must be a well-formed email address |
| 200 | +``` |
| 201 | + |
| 202 | +我们把邮箱测试改为正确的之后再运行,控制台就能成功打印出读取到的信息: |
| 203 | + |
| 204 | +``` |
| 205 | +ProfileProperties(name=Guide哥, email=koushuangbwcx@163.com, handsome=true) |
| 206 | +``` |
| 207 | +
|
| 208 | +### 4.`@PropertySource`读取指定 properties 文件 |
| 209 | +
|
| 210 | +```java |
| 211 | +import lombok.Getter; |
| 212 | +import lombok.Setter; |
| 213 | +import org.springframework.beans.factory.annotation.Value; |
| 214 | +import org.springframework.context.annotation.PropertySource; |
| 215 | +import org.springframework.stereotype.Component; |
| 216 | +
|
| 217 | +@Component |
| 218 | +@PropertySource("classpath:website.properties") |
| 219 | +@Getter |
| 220 | +@Setter |
| 221 | +class WebSite { |
| 222 | + @Value("${url}") |
| 223 | + private String url; |
| 224 | +} |
| 225 | +``` |
| 226 | + |
| 227 | +使用: |
| 228 | + |
| 229 | +```java |
| 230 | +@Autowired |
| 231 | +private WebSite webSite; |
| 232 | + |
| 233 | +System.out.println(webSite.getUrl());//https://javaguide.cn/ |
| 234 | + |
| 235 | +``` |
| 236 | + |
| 237 | +### 5.题外话:Spring加载配置文件的优先级 |
| 238 | + |
| 239 | +Spring 读取配置文件也是有优先级的,直接上图: |
| 240 | + |
| 241 | +<img src="https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-11/read-config-properties-priority.jpg" style="zoom:50%;" /> |
| 242 | + |
| 243 | +更对内容请查看官方文档:https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-external-config |
| 244 | + |
| 245 | +> 本文源码: |
0 commit comments