Java 如何将 Spring Boot application.properties 外部化到 tomcat/lib 文件夹
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31017064/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to externalize Spring Boot application.properties to tomcat/lib folder
提问by Daniel Mora
I need a configuration free, deployable war, myapp1.war that can retrieve the configuration files from the tomcat/lib folder. As I have other web applications coexisting on the same Tomcat: myapp2.war, myapp3.war, I need this layout:
我需要一个可以从 tomcat/lib 文件夹中检索配置文件的免费配置、可部署的战争 myapp1.war。由于我在同一个 Tomcat 上共存了其他 Web 应用程序:myapp2.war、myapp3.war,因此我需要以下布局:
tomcat/lib/myapp1/application.properties
tomcat/lib/myapp2/application.properties
tomcat/lib/myapp3/application.properties
This way I can build the war files without any properties files inside the war and deploy on any server.
这样我就可以在没有任何属性文件的情况下构建战争文件并部署在任何服务器上。
I have read the Spring documentationbut it explains how to set the location when running as a jar:
我已阅读Spring 文档,但它解释了如何在作为 jar 运行时设置位置:
java -jar myapp.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties
I cannot figure out how to do this for the case of multiple coexisting war files.
对于多个共存的战争文件,我无法弄清楚如何做到这一点。
I would like to know if this is possible or should I give up on Spring Boot and go back to the traditional Spring MVC applications.
我想知道这是否可行,或者我应该放弃 Spring Boot 并回到传统的 Spring MVC 应用程序。
采纳答案by Daniel Mora
A solution could be to load application-{profile}.properties as @PropertySource annotations as this questionsuggests, but then the logging system wont work, as you can see in the documentation.
一个解决方案可能是将 application-{profile}.properties 加载为 @PropertySource 注释,正如这个问题所暗示的那样,但是日志系统将无法工作,正如您在文档中看到的那样。
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.
日志系统在应用程序生命周期的早期初始化,因此在通过 @PropertySource 注释加载的属性文件中将找不到这样的日志属性。
This means that your logging properties in application-{profiles}.properties like:
这意味着 application-{profiles}.properties 中的日志记录属性如下:
logging.config=classpath:myapp1/logback.xml
logging.path = /path/to/logs
logging.file = myapp1.log
will be ignored and the logging system wont work.
将被忽略,日志系统将无法工作。
To solve this I have used the SpringApplicationBuilder.properties() method to load properties at the beginning, when the application is configured. There I set the 'spring.config.location' used by Spring Boot to load all the application-{profiles}.properties:
为了解决这个问题,我使用 SpringApplicationBuilder.properties() 方法在开始时加载属性,当应用程序被配置时。在那里我设置了 Spring Boot 使用的“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;
}
}
Then I have moved the properties files from src/main/resources to src/main/resources/myapp1
然后我将属性文件从 src/main/resources 移动到 src/main/resources/myapp1
.
├src
| └main
| └resources
| └myapp1
| └application.properties
| └application-development.properties
| └logback.xml
└─pom.xml
In the pom.xml I have to set the scope of embedded tomcat libraries as "provided". Also, to exclude all properties files in src/main/resources/myapp1 from the final war and generate a configuration free, deployable war:
在 pom.xml 中,我必须将嵌入式 tomcat 库的范围设置为“提供”。此外,要从最终战争中排除 src/main/resources/myapp1 中的所有属性文件,并生成一个无配置、可部署的战争:
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<packagingExcludes>
**/myapp1/
</packagingExcludes>
</configuration>
</plugin>
Then in Tomcat I have
然后在Tomcat中我有
├apache-tomcat-7.0.59
└lib
├─myapp1
| └application.properties
| └logback.xml
└─myapp2
└application.properties
└logback.xml
Now I can generate the configuration free war and drop it into the apache-tomcat-7.0.59/webapps folder. Properties files will be resolved using the classpath, independently for each webapp:
现在我可以生成配置免费战争并将其放入 apache-tomcat-7.0.59/webapps 文件夹中。属性文件将使用类路径解析,对于每个 web 应用程序都是独立的:
apache-tomcat-7.0.59/lib/myapp1
apache-tomcat-7.0.59/lib/myapp2
apache-tomcat-7.0.59/lib/myapp3
回答by amdev
With Spring 4.2 and @Annotation config and tomcat on linux serveur
在 Linux 服务器上使用 Spring 4.2 和 @Annotation 配置和 tomcat
In your Application class set the @PropertySource like that :
在您的 Application 类中,像这样设置 @PropertySource :
@Configuration
@EnableWebMvc
@PropertySource(value = { "classpath:application-yourapp.properties"})
@ComponentScan(basePackages = "com.yourapp")
public class YourAppWebConfiguration extends WebMvcConfigurerAdapter {
...
}
Now you just need to include the property file in your classpath
现在您只需要在类路径中包含属性文件
In production
生产中
Deploy your .war files ( or anything ) on tomcat, and put your application-yourapp.properties anyway on your production machine. ( for exemple in /opt/applyconfigfolder/application-yourapp.properties" )
在 tomcat 上部署你的 .war 文件(或任何东西),然后把你的 application-yourapp.properties 放在你的生产机器上。(例如在 /opt/applyconfigfolder/application-yourapp.properties” 中)
Then in your tomcat ( here tomcat 7 ) open bin\catalina.sh
然后在你的 tomcat(这里是 tomcat 7)中打开 bin\catalina.sh
You have this line
你有这条线
# 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=
Just add the path of the folder which contains application.properties
只需添加包含 application.properties 的文件夹的路径
CLASSPATH=:/opt/applyconfigfolder
If you have already some classpath define you can add it
如果您已经定义了一些类路径,则可以添加它
CLASSPATH=:/opt/applyconfigfolder:/yourpath1:/yourpath2:
I haven't try with windows but I think there is no problem
我还没有尝试过 windows 但我认为没有问题
In Dev ( with eclipse )
在开发中(使用 eclipse )
├src
| └main
| └ ....
└config
| └application-yourapp.properties
instead of src/main/resources/application-yourapp.properties
代替 src/main/resources/application-yourapp.properties
Now in eclipse add your config folder to classpath, go to "Run Configurations" of your tomcat server ( or equivalent ) and add the folder Config to User Entries
现在在 Eclipse 中将您的配置文件夹添加到类路径,转到您的 tomcat 服务器(或等效的)的“运行配置”并将文件夹配置添加到用户条目
Ok that's it, your application.properties is out of the application and your project run perfectly in dev environment.
好的,就是这样,您的 application.properties 在应用程序之外,您的项目在开发环境中完美运行。
回答by Salvatore Iamundo
Daniel Mora gave a good solution but instead of using spring.config.location you can use 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), so you can have different properties file for different web apps in the same tomcat/lib directory:
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),因此您可以在同一个 tomcat/lib 目录中为不同的 Web 应用程序设置不同的属性文件:
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;
}
}
I think that the lib directory is for third party libraries not for storing configuration properties for your web apps. So I think that a better solution is to add an external folder as additional classpath folder using shared.loader property in conf/catalina.properties:
我认为 lib 目录用于第三方库,而不是用于存储 Web 应用程序的配置属性。所以我认为更好的解决方案是使用 conf/catalina.properties 中的 shared.loader 属性添加一个外部文件夹作为额外的类路径文件夹:
shared.loader=${catalina.base}/shared/configurations
shared.loader=${catalina.base}/shared/configurations
You can put your application properties app1.properties, app2.properties, ecc.. in apache-tomcat-7.0.59/shared/configurations.
您可以将应用程序属性 app1.properties、app2.properties、ecc.. 放在 apache-tomcat-7.0.59/shared/configurations 中。
Before finding Daniel Mora solution of overridding configure method of SpringBootServletInitializer my solution was to add a context.xml in src/main/webapp/META-INF with this content:
在找到覆盖 SpringBootServletInitializer 的配置方法的 Daniel Mora 解决方案之前,我的解决方案是在 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>