@Bean public TestBean testBean() { TestBean testBean = new TestBean(); testBean.setName(env.getProperty(“testbean.name”));
return testBean;
} }
17)SpringApplication.setDefaultProperties 设置的参数
下面来用一个Demo 说下:
import org.springframework.stereotype.*;
import org.springframework.beans.factory.annotation.*;
@Component
public class MyBean {
@Value(“${name}”)
private String name;
// …
}
-
你可以使用 classpath 下的application.yml来配置name= laowang
-
可以使用一个外部的application.yml 来设置一个name = laoli 覆盖上一个配置 (当前name 获取的话是laoli)
-
在可以使用java -jar app.jar --name=“Spring” 再来覆盖上一个配置 (当前name获取的话是 Spring)
Spring Boot 配置文件也支持通配符的方式来加载,比如使用 spring.config.additional-location和spring.config.location来加载配置的时候就可以使用通配符加载多个文件。
2、配置随机属性
========
随机属性的注入其实是通过RandomValuePropertySource 来实现的,它可以帮我们来产生integers、 longs、 uuid、strings 的随机值。这个对于我们平时进行一些测试案例还是很实用的。
//可以配置在application.yml
my.secret=${random.value}
my.number=${random.int}
my.bignumber=${random.long}
my.uuid=${random.uuid}
my.number.less.than.ten=${random.int(10)}
my.number.in.range=${random.int[1024,65536]}
3、命令行属性
=======
我们可以使用 java -jar --server.port=9000的方式将命令行参数server.port 添加到我们应用的Environment,可以使用@Value等方式获取。正常情况下命令行添加的属性优先级是咱们优先级高的。
如果你不想将命令行的属性添加到应用的Environment中,那你可以配置SpringApplication.setAddCommandLineProperties(false)就行了。
其实使用命令行加载最多的可能就是–javaagent 这个属性了,对于现在的公司,APM监控那是必不可少的。我们也可以通过命令参数的配置来临时的加载一些属性进行测试使用。
4、应用加载配置文件
==========
其实上面已经说过了,这里再重新提一下。SpringApplication 会从application.yml里面加载属性配置,并将他们添加到Spring 的Environment中供我们使用。优先级如下,高优先级覆盖低的(这里放个原版,可以自己尝试理解下):
-
A /config subdirectory of the current directory
-
The current directory
-
A classpath /config package
-
The classpath root
如果你不喜欢配置文件叫做application.properties,也可以使用spring.config.name来进行配置。也可以使用spring.config.location 来指定配置加载路径。
举例说明:
//修改我的配置文件叫myproject
java -jar myproject.jar --spring.config.name=myproject
//换一个地方来加载我得配置文件
java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties
因为spring.config.name 和 spring.config.location 配置是用来确定应用需要加载哪些属性的,所以需要尽可能早的加载。一般都是使用系统环境变量、系统参数、命令行加载的方式进行使用。
默认的配置加载路径如下,安装优先级从高到低排序(file:./config/ 优先级最高),所以在使用加载的时候一定要注意:
-
file:./config/
-
file:./config/*/
-
file:./
-
classpath:/config/
-
classpath:/
5、占位符的使用
========
在application.properties 我们可以使用占位符来进行属性的动态加载
比如我们可以借助maven 的profile 在打包的时候动态的对环境参数进行替换(比如替换mysql 、redis等域名)
上几个例子:
//简单的使用
app.name=MyAppapp.description=${app.name} is a Spring Boot application
//配合命令行参数使用,如参数增加 --port=9000 来代替–server.port=9000,那在配置文件中我们就可以配置server.port=${port:8080}
注意一点:
如果你的POM 里面集成了spring-boot-starter-parent ,那么默认的maven-resources-plugins插件会使用@maven.token@来代替${maven.token}。这么做其实是为了防止和Spring的占位符产生冲突,所以如果我们使用maven 的profile 或者其他的来动态替换application.properties 内部的属性,请使用 @name@.
6、YAML文件进行多环境配置
===============
1) 配置文件使用
在application.yml中,你可以使用spring.profiles 来激活你想加载的环境配置内容。
例子:
server:
address: 192.168.1.100
spring:
profiles: development
server:
address: 127.0.0.1
spring:
profiles: production & eu-central
server:
address: 192.168.1.120
在上面的例子中,如果我们激活development 那server.address 就是127.0.0.1。如果production & eu-central 被激活,那server.address 就是192.168.1.120。如果这三个我都没激活,那server.address 就是192.168.1.100,环境配置直接使用—来隔离开。
注意:spring.profiles 这个属性可以是一个名字,也可以是一个表达式。
2)@Profile注解使用
我们很多时候会遇到组件动态选择的问题,比如我有多种的权限接入方式或者数据源选择性激活。但我又不想来来回回写点if else,那么@Profile就是一个神器了,他的到来使我们的代码更加的灵活多变。
比如我们重写一个属于源配置:
//第一个
@Configuration@Profile(“development”)
public class StandaloneDataConfig { @Bean public DataSource dataSource() { return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.HSQL) .addScript(“classpath:com/bank/config/sql/schema.sql”)
.addScript(“classpath:com/bank/config/sql/test-data.sql”)
.build(); }}//第二个@Configuration@Profile(“production”)
public class JndiDataConfig { @Bean(destroyMethod=“”)
public DataSource dataSource() throws Exception { Context ctx = new InitialContext(); return (DataSource) ctx.lookup(“java:comp/env/jdbc/datasource”);
}}
这样,我们就可以根据不同的配置来激活不同的逻辑了,如果再能搭配上远程配置中心,那就更美丽了。
7、YAML的问题
=========
1) YAML有很多优点,那必然也是有一丢丢的小毛病的。那就是YAML文件默认不能使用@PropertySource注解来进行配置加载。如果你不想进行多余的改造,那就老实的建一个properties文件用吧。
2)在YAML中配置多环境配置信息有的时候会有奇奇怪怪的问题,比如下面的:
application-dev.yml
server:
port: 8000
spring:
profiles: “!test”
security:
user:
password: “secret”
如果此时我启动应用的时候加载了–spring.profiles.active=dev ,那我正常是应该得到security.user.password = secret,但真实的情况却不是这样。
因为我们在配置文件名上使用了xxx-dev.yml,这时候当应用加载的时候就会直接找到application-dev.yml文件.而这时我们配置文件内的多环境配置就失效了。
所以在多环境配置使用的时候,我们要不然就选择xxx-dev.yml、xxx-pro.yml 这种方式,要不然就选择在一个文件内配置多环境。二者只能选一个,以免出现恶心人的问题。
8、对象属性绑定
========
有时候我们会有一组相同类型的属性需要加载,如果使用@Value 那真是累死人。这里Spring Boot为我们提供了一个便捷的方式,我们可以使用一个类对所需要的变量进行统一的配置加载。
举个例子:
//属性类
package com.example;import java.net.InetAddress;import java.util.ArrayList;import java.util.Collections;import java.util.List;import org.springframework.boot.context.properties.ConfigurationProperties;@ConfigurationProperties(“acme”)
public class AcmeProperties { private boolean enabled;
private InetAddress remoteAddress;
private final Security security = new Security();
public boolean isEnabled() { … } public void setEnabled(boolean enabled) { … } public InetAddress getRemoteAddress() { … } public void setRemoteAddress(InetAddress remoteAddress) { … } public Security getSecurity() { … } public static class Security { private String username;
private String password;
private List roles = new ArrayList<>(Collections.singleton(“USER”));
public String getUsername() { … } public void setUsername(String username) { … } public String getPassword() { … } public void setPassword(String password) { … } public List getRoles() { … } public void setRoles(List roles) { … } }}
这时我在application.yml中配置如下属性,Spring Boot就会帮助我们直接将属性绑定到AcmeProperties类中
acme.enabled =false
acme.remote-address=127.0.0.1
acme.security.username=xxx
因为 @EnableConfigurationProperties 只是帮助我们进行声明,在实际使用上我们需要配合**@Configuration**,比如下面的配置,这样配置完后我们就可以使用@Resource 进行属性注入了。
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(AcmeProperties.class)
public class MyConfiguration {}
9、宽松的绑定规则
=========
上面聊了@ConfigurationProperties 可以帮助我们进行对象属性绑定,其实在Spring Boot中为我们提供了相当宽松的绑定规则。
比如context-path绑定到 contextPath属性,PORT绑定到 port属性,下面继续搞个Demo。
@ConfigurationProperties(prefix=“acme.my-project.person”)
public class OwnerProperties {
private String firstName;
public String getFirstName() {
return this.firstName;
} public void setFirstName(String firstName) {
this.firstName = firstName;
}}
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。*
[外链图片转存中…(img-LX7RQm3e-1715612254538)]
[外链图片转存中…(img-Hwf0pZLu-1715612254538)]
[外链图片转存中…(img-t7XiWx1W-1715612254539)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!