使用 spring boot 和 spring-boot-maven-plugin 生成战争时排除 application.properties

Posted

技术标签:

【中文标题】使用 spring boot 和 spring-boot-maven-plugin 生成战争时排除 application.properties【英文标题】:Exclude application.properties when generating war using spring boot and spring-boot-maven-plugin 【发布时间】:2014-12-31 20:51:54 【问题描述】:

我正在使用 Spring Boot 开发一个 Web 应用程序,并且想要生成 war 而不是 jar。

使用此处描述的从 jar 到 war 的转换可以很好地工作:http://spring.io/guides/gs/convert-jar-to-war/

但我想将 application.properties 从战争中排除,因为我使用@PropertySource(value = "file:$OPENSHIFT_DATA_DIR/application.properties") 来获取生产环境的文件路径。

此方法在生成我的战争时有效,但在 eclipse 中我无法运行我的应用程序,因为 application.properties 根本没有复制到目标/类:

<build>
    <resources> 
        <resource> 
            <directory>src/main/resources</directory> 
            <excludes> 
                <exclude>application.properties</exclude> 
            </excludes> 
        </resource> 
     </resources> 
</build>

这个方法根本不行,我觉得spring-boot-maven-plugin不支持packagingExcludes:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration> 
                <packagingExcludes>WEB-INF/classes/application.properties</packagingExcludes> 
            </configuration> 
        </plugin>
    </plugins>
</build>

您还有其他建议吗?

谢谢

【问题讨论】:

我解决这个问题的方法是使用spring.config.location 参数覆盖打包的配置。例如,我在 Tomcat 的上下文文件中将其设置为指向我在生产环境中使用的配置文件。您是否尝试过这样做,或者这个解决方案不适合您?或者您也许可以通过使用不同的 Maven 构建配置文件进行开发和生产来实现您想要做的事情?我的意思是只有当您使用生产 Maven 配置文件打包您的应用程序时才会排除 application.properties ... 当我使用 maven 打包我的战争时,我只想排除 application.properties,其他一切正常。我不想在生成战争后删除 application.properties。 【参考方案1】:

在 Eclipse 中运行时,在 Run Configuration 中,您需要指定 Spring Boot 的属性路径:

--spring.config.location=$workspace_loc:/YOURPROYECTNAME/src/main/resources/

【讨论】:

【参考方案2】:

尝试使用以下解决方案。这将起作用:

<build>
    <resources>
         <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
            <excludes>
                <exclude>**/*.properties</exclude>
            </excludes>
        </resource>
    </resources>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

如果您使用上述解决方案,在 Eclipse IDE 中运行项目时,您可能会收到找不到属性文件的错误。要摆脱这种情况,您需要在作为配置运行时添加资源文件夹。(运行配置... -> 类路径 -> 用户条目 -> 高级... -> 添加文件夹)

【讨论】:

这会阻止 application.properties 被大多数开发人员想要的过滤,并且还会弄乱 Spring Boot 默认资源设置和过滤。更好的解决方案是修改 war 插件并排除任何属性文件。尝试过的&lt;packagingExcludes&gt;...&lt;/packagingExcludes&gt; 必须与maven-war-plugin 一起使用,而不是spring-boot-maven-plugin 插件。【参考方案3】:

尝试使用此解决方案:

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <version>$spring.version</version>
    <configuration>
        <addResources>false</addResources>
    </configuration>
</plugin>

false 将在您运行 mvn spring-boot:run 时保留属性

【讨论】:

【参考方案4】:

我从您的问题中了解到,您想使用 application.properties 进行开发。但是您不想将其用于生产。

我建议使用 Spring 配置文件 来实现这一点。 在你的属性文件中

    为开发创建配置文件。将您所有的开发属性放在它下面。 不要在属性文件中创建生产配置文件。 在开发时,将活动配置文件设置为开发,以便从 application.properties 文件加载属性。 在生产中运行时,将活动配置文件设置为生产。虽然 application.properties 将被加载到您的 WAR 中,但由于没有用于生产的配置文件,因此不会加载任何属性。

我使用 YML 做过类似的事情。我相信一定有办法使用.properties 文件来做同样的事情。

spring:
  profiles.active: development
--
spring:
  profiles: development
something:
  location: USA
  unit1: Test1
  unit2: Test2

您可以使用在运行时更改配置文件

-Dspring.profiles.active=production

【讨论】:

是和不是。如果您将这些配置文件属性文件存储在 src/main/resources 中,则无法从父类加载器加载它们(例如将它们放在 $TCHOME/lib 中),因为它们已经捆绑在 WAR 本身中【参考方案5】:

我添加的解决方案是解压我打包的war,删除文件application.properties并使用maven-antrun-plugin创建一个名为ROOT.war的新war并运行一些ant任务。

这是我在 pom.xml 中添加到我的插件中的:

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
    <execution>
        <id>package</id>
        <phase>package</phase>
        <configuration>
            <target>
                <unzip src="target/$artifactId-$version.$packaging" dest="target/ROOT/" />
                <delete file="target/ROOT/WEB-INF/classes/application.properties"/>
                <zip destfile="target/ROOT.war" basedir="target/ROOT" encoding="UTF-8"/>
                <delete dir="target/ROOT"/>
            </target>
        </configuration>
        <goals>
            <goal>run</goal>
        </goals>
    </execution>
</executions>
</plugin>

我将目标战争命名为 ROOT.war,因为我在 openshift PaaS 上使用 tomcat,所以我只需复制我的 ROOT.war 并推送到我的 openshift 存储库。就是这样

【讨论】:

恕我直言,正确答案。我需要稍加改动:我想包含application.properties,但我的个人资料中没有application-*.properties。而且因为我的 ANT 时代早已过去,我花了一段时间才弄清楚正确的语法,因此将其发布在这里:&lt;delete dir="target/ROOT/WEB-INF/classes/" includes="application-*.properties" /&gt; 这对我有用。我创建了两个单独的配置文件,每个配置文件都包含自己的构建,一个构建删除文件,另一个构建保留文件

以上是关于使用 spring boot 和 spring-boot-maven-plugin 生成战争时排除 application.properties的主要内容,如果未能解决你的问题,请参考以下文章

企业级spring-boot案例-Spring事件发布与监听

企业级spring-boot案例-Spring事件发布与监听

企业级spring-boot案例-Spring事件发布与监听

企业级spring-boot案例-Spring事件发布与监听

spring-boot项目需要单独安装Tomcat吗?

Spring Boot 日志处理你还在用Logback?