【问题标题】:Load Maven depencencies defined on profiles加载配置文件上定义的 Maven 依赖项
【发布时间】:2021-10-30 00:23:22
【问题描述】:

我正在构建一个具有 2 种不同情况的演示应用程序,第一种是开发,第二种是生产。 这是我的 pom.xml

... (version, name, etc)
    <properties>
        <java.version>11</java.version>
        <spring-cloud.version>2020.0.3</spring-cloud.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <!--DEFAULT PROFILE-->
        <env>development</env>
    </properties>

    <dependencies>
        ... (lombok, junit, swagger, datarest, datatest, web, webmvc...)

    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <filters>
            <filter>src/main/resources/${env}.yml</filter>
        </filters>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
                <includes>
                    <include>*.yml</include>
                    <include>*.xml</include>
                    <include>*.properties</include>
                </includes>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <profiles>
        <profile>
            <id>development</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <properties>
                <start-class>com.central.CentralApplication</start-class>
                <env>development</env>
            </properties>

            <dependencies>

                <dependency>
                    <groupId>com.h2database</groupId>
                    <artifactId>h2</artifactId>
                    <scope>runtime</scope>
                </dependency>

                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-data-jpa</artifactId>
                </dependency>

                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-jdbc</artifactId>
                </dependency>

            </dependencies>
        </profile>

        <profile>
            <id>production</id>
            <activation>
                <property>
                    <name>production</name>
                </property>
            </activation>

            <properties>
                <env>production</env>
                <start-class>com.central.CentralApplicationProd</start-class>
            </properties>

            <dependencies>

                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-netflix-eureka-client</artifactId>
                    <version>3.0.3</version>
                    <scope>compile</scope>
                </dependency>

                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
                    <version>3.0.3</version>
                </dependency>

                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-starter-openfeign</artifactId>
                    <version>3.0.3</version>
                </dependency>

                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
                    <version>2.2.9.RELEASE</version>
                </dependency>

                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-actuator</artifactId>
                </dependency>

            </dependencies>
        </profile>
    </profiles>

</project>

pom 中似乎没有问题,但是当我尝试创建生产所需的 main 时,它找不到 Eureka 和 Feign 依赖项(@EnableEurekaClient 和 @EnableFeignClients)。另一方面,如果我更改 &lt;activeByDefault&gt;true&lt;/activeByDefault&gt; 并将其放入生产配置文件中,它会加载其依赖项,但显然不会加载开发项。

编码时如何加载这两个依赖项? 我的方法错了吗?

提前致谢!

【问题讨论】:

  • 如果你做mvn -Pdesarrollo,production编译会发生什么
  • 您不应该为不同的环境创建不同的工件。您应该创建 1 个工件。您有一个 Spring Boot 应用程序,只需在运行时提供必要的信息。
  • Antoniossss,如果我运行该命令(我忘记将配置文件 id 更改为开发,所以我运行的命令是 mvn -Pdevelopment,production)它说留下了一个参数。我做错了什么?
  • Deinum 先生/女士,很抱歉,但我认为我不了解您(我是 Spring 的新手)。工件是什么意思?
  • Artefacts 表示 maven 构建的输出。在您的情况下,人工制品是包含应用程序的 jar 文件。 @M.Deinum 正确建议的是为所有环境生成单个二进制工件(== 相同的 jar 文件)并通过配置参数更改其行为。

标签: java spring spring-boot maven spring-mvc


【解决方案1】:

如果您有 Spring Boot 应用程序,则不应为任何依赖项定义任何配置文件。

如果您需要为 dev 提供不同的配置,您应该使用 spring 配置文件。这意味着您可以定义像application.properties(也适用于.yml)或application-dev.properties 这样的文件,可以简单地通过--spring.profiels.active=dev 激活意味着激活application-dev.properties

此外,如果您只需要 h2 数据库进行测试,您应该简单地使用 &lt;scope&gt;test&lt;/scope&gt;

这看起来很奇怪,您在 prod 配置文件中定义了 spring-boot-starter-actuator 依赖项,但没有为 dev 定义。

另一件事是您已经定义了&lt;start-class&gt;com.central.CentralApplication&lt;/start-class&gt;,默认情况下它是通过包含@SpringBootApplication 注释的类定义的。这意味着您只有一个用于该目的的类,对于哪个环境等都没有关系。

我强烈建议阅读 Spring Boot 文档等。 问题是为什么不同时定义两者。

我还看到您在 spring-boot-maven-plugin 配置中明确排除了 lombok。这意味着通常你没有正确定义 lombok 的依赖范围。

如果您使用 bom 导入,最好自己定义依赖项的版本。否则,您可能会有版本混合,这可能会导致问题。

最后一个建议是永远不要使用配置文件来使用不同的依赖项。

https://docs.spring.io/spring-boot/docs/current/reference/html/

【讨论】:

  • 感谢您的回答!这不仅在问题的范围内非常有帮助,而且对于我不知道的其他一些问题也很有帮助。 h2 依赖项只是在 dev 中,因为它应该替换对另一个服务的调用。在那种情况下,我不应该用测试范围来定义它,对吧?就主要而言,我有 2 个(都带有@SpringBootApplication,一个用于开发(没有 Eureka 和没有 Feign 注释)和一个用于生产(带有那些)。这也错了吗?我将检查 lombok 依赖项。关于bom 进口,它们是什么?对不起菜鸟问题
  • 如果你真的有两个主要的应用程序,你应该制作一个包含三个模块的多模块构建。公共代码,app1 + eureka 和 app2 没有.. 这很清楚。 H2 会替代对另一个服务的调用吗?嘲讽?正在测试中?
  • eureka 是一个服务发现的东西,据我所知..所以为什么不在 dev 中使用它的问题呢?
  • 我知道这可能很奇怪。但想法是在开发中通过 RabbitMQ 进行 2 个服务通信(只有这 2 个服务)和在生产中,将其更改为 Kafka 并有 3 个服务,其中一个调用“新”来检查参数,而不是检查它本身就像在 dev 中一样(这就是需要 H2 db 的原因)。这就是为什么 Eureka(和 Feign)应该只在生产中而不是在开发中以及为什么 h2 应该在开发中的原因。对不起,如果这很奇怪,对我来说也是如此,但这是要求
【解决方案2】:

您应该将共享依赖项放在 pom 文件主要部分的配置文件标签之外。您代码中的 Java 类需要此依赖项。

如果你想在不同的环境中实现不同的逻辑,我建议你在Spring configuration files上使用不同的配置文件。

【讨论】:

猜你喜欢
  • 2011-05-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-07
  • 1970-01-01
  • 1970-01-01
  • 2012-07-10
相关资源
最近更新 更多