springboot 多模块情况下多配置文件问题

发布于 2022-09-07 12:35:44 字数 1181 浏览 13 评论 0

一个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文件引入项目,并且可以实现各模块配置文件相互独立,但有点问题:

  1. service配置文件格式必须为application-xxx.yml
  2. 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=============================================

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

围归者 2022-09-14 12:35:44

spring boot官网的EnvironmentPostProcessorExample,可以完美解决你的一切问题。
Spring Boot Reference Guide 2.1.1.RELEASE
76.3 Customize the Environment or ApplicationContext Before
It Starts

末骤雨初歇 2022-09-14 12:35:44

用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();
}
听闻余生 2022-09-14 12:35:44

第一种方法

试过在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(此种方法较好,推荐),代码如下

@Configuration
public 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加载对应配置文件

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文