如何外部化 Spring 启动 application.properties 到 tomcat/lib 文件夹
How to externalize Spring Boot application.properties to tomcat/lib folder
我需要一个免费的、可部署的配置 war、myapp1.war,它可以从 tomcat/lib 文件夹中检索配置文件。
因为我有其他网络应用程序共存于同一个 Tomcat: myapp2.war, myapp3.war, 我需要这个布局:
tomcat/lib/myapp1/application.properties
tomcat/lib/myapp2/application.properties
tomcat/lib/myapp3/application.properties
这样我就可以在 war 中构建没有任何属性文件的 war 文件并部署到任何服务器上。
我已阅读 Spring documentation 但它解释了如何在 运行 作为 jar 时设置位置:
java -jar myapp.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties
对于多个 war 文件共存的情况,我不知道如何做到这一点。
我想知道这是否可行,或者我应该放弃 Spring 启动并返回到传统的 Spring MVC 应用程序。
一种解决方案是将 application-{profile}.properties 作为 @PropertySource 注释加载,如此 question suggests, but then the logging system wont work, as you can see in the documentation。
The logging system is initialized early in the application lifecycle
and as such logging properties will not be found in property files
loaded via @PropertySource annotations.
这意味着您在 application-{profiles}.properties 中的日志属性如下:
logging.config=classpath:myapp1/logback.xml
logging.path = /path/to/logs
logging.file = myapp1.log
将被忽略,日志系统将无法工作。
为了解决这个问题,我在配置应用程序时使用 SpringApplicationBuilder.properties() 方法在开始时加载属性。在那里我设置 Spring 使用的 'spring.config.location' 引导加载所有应用程序-{profiles}.properties:
public class Application extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder springApplicationBuilder) {
return springApplicationBuilder
.sources(Application.class)
.properties(getProperties());
}
public static void main(String[] args) {
SpringApplicationBuilder springApplicationBuilder = new SpringApplicationBuilder(Application.class)
.sources(Application.class)
.properties(getProperties())
.run(args);
}
static Properties getProperties() {
Properties props = new Properties();
props.put("spring.config.location", "classpath:myapp1/");
return props;
}
}
然后我将属性文件从 src/main/resources 移动到 src/main/resources/myapp1
.
├src
| └main
| └resources
| └myapp1
| └application.properties
| └application-development.properties
| └logback.xml
└─pom.xml
在 pom.xml 中,我必须将嵌入式 tomcat 库的范围设置为 "provided"。
此外,要从最终 war 中排除 src/main/resources/myapp1 中的所有属性文件,并生成一个免费的、可部署的配置 war:
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<packagingExcludes>
**/myapp1/
</packagingExcludes>
</configuration>
</plugin>
然后在Tomcat我有
├apache-tomcat-7.0.59
└lib
├─myapp1
| └application.properties
| └logback.xml
└─myapp2
└application.properties
└logback.xml
现在我可以免费生成配置 war 并将其放入 apache-tomcat-7.0.59/webapps 文件夹中。属性文件将使用类路径解析,独立于每个 webapp:
apache-tomcat-7.0.59/lib/myapp1
apache-tomcat-7.0.59/lib/myapp2
apache-tomcat-7.0.59/lib/myapp3
使用 Spring 4.2 和 @Annotation 配置以及 linux 服务器上的 tomcat
在您的应用程序中 class 像这样设置 @PropertySource :
@Configuration
@EnableWebMvc
@PropertySource(value = { "classpath:application-yourapp.properties"})
@ComponentScan(basePackages = "com.yourapp")
public class YourAppWebConfiguration extends WebMvcConfigurerAdapter {
...
}
现在您只需将 属性 文件包含在您的 class 路径
中
生产中
在 tomcat 上部署您的 .war 文件(或任何文件),并将您的应用程序 yourapp.properties 无论如何放在您的生产机器上。 (例如 /opt/applyconfigfolder/application-yourapp.properties" )
然后在你的tomcat(这里tomcat7)打开bin\catalina.sh
你有这条线
# Ensure that any user defined CLASSPATH variables are not used on startup,
# but allow them to be specified in setenv.sh, in rare case when it is needed.
CLASSPATH=
只需添加包含application.properties
的文件夹的路径
CLASSPATH=:/opt/applyconfigfolder
如果您已经定义了一些class路径,您可以添加它
CLASSPATH=:/opt/applyconfigfolder:/yourpath1:/yourpath2:
我没试过 windows 但我认为没有问题
开发中(使用 eclipse)
├src
| └main
| └ ....
└config
| └application-yourapp.properties
而不是src/main/resources/application-yourapp.properties
现在在 Eclipse 中将您的配置文件夹添加到 class 路径,转到 tomcat 服务器(或等效服务器)的 "Run Configurations" 并将文件夹 Config 添加到用户条目
好的,就是这样,您的 application.properties 已脱离应用程序,您的项目 运行 在开发环境中非常完美。
Daniel Mora 提供了一个很好的解决方案,但您可以使用 spring.config.name (https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-application-property-files) 而不是使用 spring.config.location,因此您可以在同一个文件中为不同的 Web 应用程序设置不同的属性文件tomcat/lib目录:
public class Application extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder springApplicationBuilder) {
return springApplicationBuilder
.sources(Application.class)
.properties(getProperties());
}
public static void main(String[] args) {
SpringApplicationBuilder springApplicationBuilder = new SpringApplicationBuilder(Application.class)
.sources(Application.class)
.properties(getProperties())
.run(args);
}
static Properties getProperties() {
Properties props = new Properties();
props.put("spring.config.name", "myapp1");
return props;
}
}
我认为 lib 目录用于第三方库,而不是用于存储 Web 应用程序的配置属性。
所以我认为更好的解决方案是在 conf/catalina.properties:
中使用 shared.loader 属性 添加一个外部文件夹作为附加类路径文件夹
shared.loader=${catalina.base}/shared/configurations
您可以将您的应用程序属性 app1.properties、app2.properties、ecc.. 放在 apache-tomcat-7.0.59/shared/configurations 中。
在找到 Daniel Mora 覆盖 SpringBootServletInitializer 配置方法的解决方案之前,我的解决方案是在 src/main/webapp/META-INF 中添加一个 context.xml,内容如下:
<Context>
<Environment name="spring.config.name" value="myapp1" type="java.lang.String" override="false" description="define the property file for srping boot application"/>
</Context>
我需要一个免费的、可部署的配置 war、myapp1.war,它可以从 tomcat/lib 文件夹中检索配置文件。 因为我有其他网络应用程序共存于同一个 Tomcat: myapp2.war, myapp3.war, 我需要这个布局:
tomcat/lib/myapp1/application.properties
tomcat/lib/myapp2/application.properties
tomcat/lib/myapp3/application.properties
这样我就可以在 war 中构建没有任何属性文件的 war 文件并部署到任何服务器上。
我已阅读 Spring documentation 但它解释了如何在 运行 作为 jar 时设置位置:
java -jar myapp.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties
对于多个 war 文件共存的情况,我不知道如何做到这一点。
我想知道这是否可行,或者我应该放弃 Spring 启动并返回到传统的 Spring MVC 应用程序。
一种解决方案是将 application-{profile}.properties 作为 @PropertySource 注释加载,如此 question suggests, but then the logging system wont work, as you can see in the documentation。
The logging system is initialized early in the application lifecycle and as such logging properties will not be found in property files loaded via @PropertySource annotations.
这意味着您在 application-{profiles}.properties 中的日志属性如下:
logging.config=classpath:myapp1/logback.xml
logging.path = /path/to/logs
logging.file = myapp1.log
将被忽略,日志系统将无法工作。
为了解决这个问题,我在配置应用程序时使用 SpringApplicationBuilder.properties() 方法在开始时加载属性。在那里我设置 Spring 使用的 'spring.config.location' 引导加载所有应用程序-{profiles}.properties:
public class Application extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder springApplicationBuilder) {
return springApplicationBuilder
.sources(Application.class)
.properties(getProperties());
}
public static void main(String[] args) {
SpringApplicationBuilder springApplicationBuilder = new SpringApplicationBuilder(Application.class)
.sources(Application.class)
.properties(getProperties())
.run(args);
}
static Properties getProperties() {
Properties props = new Properties();
props.put("spring.config.location", "classpath:myapp1/");
return props;
}
}
然后我将属性文件从 src/main/resources 移动到 src/main/resources/myapp1
.
├src
| └main
| └resources
| └myapp1
| └application.properties
| └application-development.properties
| └logback.xml
└─pom.xml
在 pom.xml 中,我必须将嵌入式 tomcat 库的范围设置为 "provided"。 此外,要从最终 war 中排除 src/main/resources/myapp1 中的所有属性文件,并生成一个免费的、可部署的配置 war:
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<packagingExcludes>
**/myapp1/
</packagingExcludes>
</configuration>
</plugin>
然后在Tomcat我有
├apache-tomcat-7.0.59
└lib
├─myapp1
| └application.properties
| └logback.xml
└─myapp2
└application.properties
└logback.xml
现在我可以免费生成配置 war 并将其放入 apache-tomcat-7.0.59/webapps 文件夹中。属性文件将使用类路径解析,独立于每个 webapp:
apache-tomcat-7.0.59/lib/myapp1
apache-tomcat-7.0.59/lib/myapp2
apache-tomcat-7.0.59/lib/myapp3
使用 Spring 4.2 和 @Annotation 配置以及 linux 服务器上的 tomcat
在您的应用程序中 class 像这样设置 @PropertySource :
@Configuration
@EnableWebMvc
@PropertySource(value = { "classpath:application-yourapp.properties"})
@ComponentScan(basePackages = "com.yourapp")
public class YourAppWebConfiguration extends WebMvcConfigurerAdapter {
...
}
现在您只需将 属性 文件包含在您的 class 路径
中生产中
在 tomcat 上部署您的 .war 文件(或任何文件),并将您的应用程序 yourapp.properties 无论如何放在您的生产机器上。 (例如 /opt/applyconfigfolder/application-yourapp.properties" )
然后在你的tomcat(这里tomcat7)打开bin\catalina.sh
你有这条线
# Ensure that any user defined CLASSPATH variables are not used on startup,
# but allow them to be specified in setenv.sh, in rare case when it is needed.
CLASSPATH=
只需添加包含application.properties
的文件夹的路径CLASSPATH=:/opt/applyconfigfolder
如果您已经定义了一些class路径,您可以添加它
CLASSPATH=:/opt/applyconfigfolder:/yourpath1:/yourpath2:
我没试过 windows 但我认为没有问题
开发中(使用 eclipse)
├src
| └main
| └ ....
└config
| └application-yourapp.properties
而不是src/main/resources/application-yourapp.properties
现在在 Eclipse 中将您的配置文件夹添加到 class 路径,转到 tomcat 服务器(或等效服务器)的 "Run Configurations" 并将文件夹 Config 添加到用户条目
好的,就是这样,您的 application.properties 已脱离应用程序,您的项目 运行 在开发环境中非常完美。
Daniel Mora 提供了一个很好的解决方案,但您可以使用 spring.config.name (https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-application-property-files) 而不是使用 spring.config.location,因此您可以在同一个文件中为不同的 Web 应用程序设置不同的属性文件tomcat/lib目录:
public class Application extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder springApplicationBuilder) {
return springApplicationBuilder
.sources(Application.class)
.properties(getProperties());
}
public static void main(String[] args) {
SpringApplicationBuilder springApplicationBuilder = new SpringApplicationBuilder(Application.class)
.sources(Application.class)
.properties(getProperties())
.run(args);
}
static Properties getProperties() {
Properties props = new Properties();
props.put("spring.config.name", "myapp1");
return props;
}
}
我认为 lib 目录用于第三方库,而不是用于存储 Web 应用程序的配置属性。 所以我认为更好的解决方案是在 conf/catalina.properties:
中使用 shared.loader 属性 添加一个外部文件夹作为附加类路径文件夹shared.loader=${catalina.base}/shared/configurations
您可以将您的应用程序属性 app1.properties、app2.properties、ecc.. 放在 apache-tomcat-7.0.59/shared/configurations 中。
在找到 Daniel Mora 覆盖 SpringBootServletInitializer 配置方法的解决方案之前,我的解决方案是在 src/main/webapp/META-INF 中添加一个 context.xml,内容如下:
<Context>
<Environment name="spring.config.name" value="myapp1" type="java.lang.String" override="false" description="define the property file for srping boot application"/>
</Context>