springboot 自定义listener 添加环境变量。 抄的springboot项目去掉了一些不用的jar包后包 No Value Bound 错误排查。
1. 自定义listener 实现 ApplicationListener<ApplicationEnvironmentPreparedEvent>, Ordered (如果要设置优先级可以实现Ordered接口,注意order值越小优先级越高)
public class MyListener implements ApplicationListener<ApplicationEnvironmentPreparedEvent>, Ordered { @Override public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) { Map<String, Object> bootstrapMap = new HashMap<>(); bootstrapMap.put("spring.config.name", "bootstrap"); event.getEnvironment().getPropertySources().addLast(new MapPropertySource("bootstrap", bootstrapMap)); } @Override public int getOrder() { return Ordered.HIGHEST_PRECEDENCE + 1; } }
2. 启动类 addListener(new MyListener()) 即可。
问题: 抄的springboot项目去掉了一些不用的jar包后包 No Value Bound 错误排查。
看错误: No Value Bound , 具体没截图,发现是spring.dataousrce.xx 参数没有读取到。检查项目配置及apollo 没有问题。
查看debug日志,发现读取了另外一个项目的配置,项目名yy,全局搜索关于yy的配置文件,在一个jar包中找到application.properties 。
本项目有配置文件,名为 bootstrap.yml 。为什么原项目会读取bootstrap.yml作为项目配置,而新项目则是已application.properties 为项目配置。
grpc:
server:
port: 8080
spring:
application:
name: xx (application.properties 中该项为 yy)
profiles:
active: dev
debug代码发现 ConfigFileApplicationListener 读取配置文件:
private Set<String> getSearchNames() { if (this.environment.containsProperty(CONFIG_NAME_PROPERTY)) { String property = this.environment.getProperty(CONFIG_NAME_PROPERTY); return asResolvedSet(property, null); } return asResolvedSet(ConfigFileApplicationListener.this.names, DEFAULT_NAMES); }
其中 CONFIG_NAME_PROPERTY = spring.config.name 如果环境变量中有配置,则优先使用该名称读取配置文件,否则默认为 application。
扩展1:配置文件路径的优先级问题
// Note the order is from least to most specific (last one wins)private static final String DEFAULT_SEARCH_LOCATIONS = "classpath:/,classpath:/config/,file:./,file:./config/";
扩展2:不仅可以指定配置文件名,还能指定路径。
The 'spring.config.name' property can be used to specify an alternative name to load
* and the 'spring.config.location' property can be used to specify alternative search
* locations or specific files.
应该是老项目指定了spring.config.name , 发现老项目引入了springcloud, 定义了BootstrapApplicationListener 。