【Java】springboot 多模块情况下多配置文件问题
一个springboot的项目,使用mavan管理,希望做成模块化划分
例如分为service、admin-web、front-web、interface,每个模块为一个独立的maven项目
service为最底层公共服务,提供业务逻辑处理,数据库存储等
其他三个为控制层,提供页面展示、接口等
现在问题:每一个模块都有自己的配置文件application.yml,整合的时候怎么将两个文件合并,例如,启动admin-web时,加载service中的application.yml
大致项目结构如下:
例如数据库配置文件放在service的yml中,页面thymeleaf相关配置放在web的yml中,web依赖于service,目前在web的yml中使用spring.profiles.include 可以将service中,对应yml文件引入项目,并且可以实现各模块配置文件相互独立,但有点问题:
- service配置文件格式必须为application-xxx.yml
- web的yml中必须显示的配置include值
问题:是否能在service中提供一个@Configuration,能将service中yml的属性值注入到spring容器中,而不再需要在web的yml中显示引入service的yml文件,这样的话只需要在web的pom中依赖service就可以了,配置文件不需要做处理
项目代码:
https://gitee.com/soft_xiang/...
数据库为公网测试库,随时删数据,不要乱来
====2018.06.19更新=============================================
分模块配置文件加载问题已初步解决,参见我的回答,推荐第二种方法
第二种方法引起的多环境配置文件加载问题暂未解决,走过路过的都帮忙看一下
====2018.06.19更新 end=============================================
回答
spring boot官网的EnvironmentPostProcessorExample,可以完美解决你的一切问题。
Spring Boot Reference Guide 2.1.1.RELEASE
76.3 Customize the Environment or ApplicationContext Before
It Starts
用application.yml配置无非也是生产bean, 比如你示例代码中application-module1-service.yml
:
spring: datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://140.143.26.196:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&autoReconnect=true
username: test
可以在编码中这样去实现:
@Bean@Primary
public DataSource dataSource() {
return DataSourceBuilder
.create()
.username("")
.password("")
.url("")
.driverClassName("")
.build();
}
第一种方法
试过在module1-service中添加自定义datasource(只支持properties,Yml可能能实现,但还不太会写),可以实现(此种方式不清楚是否会影响原来spring datasource机制,对spring原理不熟)
代码如下:
@Component@ConfigurationProperties(prefix = "spring.datasource")
@PropertySource("classpath:service-jdbc.properties")
public class MyDataSourceProperties {
private String url;
...
}
@EnableConfigurationProperties(MyDataSourceProperties.class)public class MyDataSourceConfig {
@Autowired
private MyDataSourceProperties myDataSourceProperties;
@Bean
@Primary
public DataSource dataSource() {
return DataSourceBuilder.create(myDataSourceProperties.getClassLoader()).type(myDataSourceProperties.getType()).driverClassName(myDataSourceProperties.determineDriverClassName()).url(myDataSourceProperties.determineUrl()).username(myDataSourceProperties.determineUsername()).password(myDataSourceProperties.determinePassword()).build();
}
}
完整代码:https://gitee.com/soft_xiang/...
第二种方法
在module1-service中自定义properties bean(此种方法较好,推荐),代码如下
@Configurationpublic class ServiceConfig {
@Bean
public static PropertySourcesPlaceholderConfigurer properties() {
PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean();
yaml.setResources(new ClassPathResource("application-module1-service.yml"));
configurer.setProperties(yaml.getObject());
return configurer;
}
}
由第二种用法引起的新的问题:
项目中如果存在多环境配置文件,如application-module1-service-dev.yml/application-module1-service-test.yml/application-module1-service/-release.yml时,怎样根据module1-web中配置的spring.profiles.active加载对应的配置文件?
思路为在加载文件时使用SpringContextUtil获取配置文件中的active,在properties()中根据active加载文件
代码如下:
SpringContextUtil.java
@Order(Integer.MIN_VALUE)@Component
public class SpringContextUtil implements ApplicationContextAware {
private static ApplicationContext context = null;
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
this.context = applicationContext;
}
/// 获取当前环境
public static String getActiveProfile() {
return context.getEnvironment().getActiveProfiles()[0];
}
/// 获取当前环境
public static String[] getActiveProfiles() {
return context.getEnvironment().getActiveProfiles();
}
}
ServiceConfig
@Bean public static PropertySourcesPlaceholderConfigurer properties() {
PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
String path = "application-module1-service.yml";
try {
String profile = SpringContextUtil.getActiveProfile();
if (StringUtils.isNotBlank(profile)) {
path = "application-module1-service-" + profile + ".yml";
}
}catch (NullPointerException e){
e.printStackTrace();
System.out.println("SpringContextUtil...未加载...");
}
YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean();
yaml.setResources(new ClassPathResource(path));//File引入
configurer.setProperties(yaml.getObject());
return configurer;
}
完整代码:https://gitee.com/soft_xiang/...
然而这里会有循环依赖问题
运行代码会有
SpringContextUtil...未加载...
没有实现根据active加载对应配置文件
以上是 【Java】springboot 多模块情况下多配置文件问题 的全部内容, 来源链接: utcz.com/a/87078.html