V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
coderstory
V2EX  ›  Java

当基于 springnboot 的模块打包成 Jar 包时,项目的 yml 怎么样才能被读取?

  •  
  •   coderstory ·
    coderstory · 2022-01-20 15:15:40 +08:00 · 2456 次点击
    这是一个创建于 1032 天前的主题,其中的信息可能已经有所发展或是发生改变。

    现在有个 spring boot 项目

    <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    

    使用如上配置打包成一个普通的 jar 包

    D:.
    ├─cn
    │  └─bobmao
    │      └─pro
    │          └─runtime
    │              └─testweb10
    │                  └─dddd2
    │                      ├─controller
    │                      │  └─data
    │                      │      └─testweb10
    │                      │          └─fora
    │                      ├─data
    │                      │  └─entity
    │                      │      └─testweb10
    │                      │          └─fora
    │                      ├─jpaService
    │                      │  └─testweb10
    │                      │      └─fora
    │                      ├─repository
    │                      │  └─testweb10
    │                      │      └─fora
    │                      └─service
    └─META-INF
        └─maven
            └─cn.bobmao.pro.runtime.testweb10
                └─dddd2
    

    目录结构如上 application.yaml 在 jar 包的根目录内

    现在 jar 本地安装后,在一个新建的 spring boot 项目内使用,并修改 scanbasepackage 之类的注解扫描这个包中的 bean ,但是这个项目的 application.yaml 不清楚这么加载。因为打包后这个配置文件就在新项目 jar 包中的 lib 中的依赖 jar 内。

    一句话解释问题就是 springboot 项目如何依赖一个 springboot 打包出来的 jar ,且这个项目里的配置,bean 还能初始化。

    注意这个被依赖的项目是打包成 jar 后使用的,而不是塞源码到项目里。 这是一个低代码平台里的一个业务,用户开个 spring boot 项目(自定义模块)后上传,能被用户创建的模块(图形化设计的模块)使用。所以这种依赖关系不在仓库里。

    第 1 条附言  ·  2022-01-20 18:06:27 +08:00
    ```
    public class RuntimeApplication implements EnvironmentAware {


    private final String jarName = "dddd2-1.0.2.jar";

    public static void main(String[] args) {
    SpringApplication.run(RuntimeApplication.class, args);
    }

    @Override
    public void setEnvironment(@NotNull Environment environment) {
    try {
    Iterator<URL> urlIterator = getClass().getClassLoader().getResources("application.yaml").asIterator();
    while (urlIterator.hasNext()) {
    URL next = urlIterator.next();
    if (next.getPath().contains(jarName)) {
    YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean();
    yaml.setResources(new UrlResource(next));
    ((ConfigurableEnvironment) environment).getPropertySources().addLast(new PropertiesPropertySource("externalConfig", yaml.getObject()));
    }
    }
    } catch (IOException e) {
    log.error("yml 读取失败", e);
    }
    }
    }

    ```
    这是一个比较简单的解决方案 classloader.getResources 可以读取主 jar 和依赖 jar 里的东西
    读取后 塞到 propertySources 里 即可。
    此时 yml 已经读取但没有初始化任何 bean 可以解决我的问题
    8 条回复    2022-01-21 02:40:59 +08:00
    pierswu
        1
    pierswu  
       2022-01-20 15:45:07 +08:00
    springboot 项目如何依赖一个 springboot 打包出来的 jar ,且这个项目里的配置,bean 还能初始化。

    你可以看一下 spring boot starter ,是专门做这个事情的。

    那个 jar 模块的 application.yaml 是无效的,所以你在定义自己的属性时,要加上一些默认值。这点有没有更好的办法解决我没去研究,你可以自己再深入研究看看
    TyCoding
        2
    TyCoding  
       2022-01-20 16:40:10 +08:00
    把 yml 配置文件放到 jar 包外部,当前目录的 ./config/application.yml ,jar 启动后会优先读取 config 目录下的配置
    jorneyr
        3
    jorneyr  
       2022-01-20 16:40:32 +08:00
    SpringBoot 外部配置、优先级及配置详解: https://zhuanlan.zhihu.com/p/71555677
    hb0730
        4
    hb0730  
       2022-01-20 16:46:26 +08:00
    hb0730
        5
    hb0730  
       2022-01-20 16:48:36 +08:00
    dallaslu
        6
    dallaslu  
       2022-01-20 16:59:39 +08:00
    要不要试一下 appassembler-maven-plugin
    dallaslu
        7
    dallaslu  
       2022-01-20 17:01:19 +08:00
    啊,刚才没有读完。忽略 #6 吧
    xuanbg
        8
    xuanbg  
       2022-01-21 02:40:59 +08:00
    很简单,你想一下你依赖的第三方包,譬如 redis 所需要的 ip/port 等参数是怎么配置的就明白了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   6079 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 06:22 · PVG 14:22 · LAX 22:22 · JFK 01:22
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.