Как выполнить экстернализацию Spring Загрузите приложение application.properties в папку tomcat/lib
Мне нужна свободная конфигурация, развертываемая война, myapp1.war, которая может извлекать файлы конфигурации из папки tomcat/lib.
Поскольку у меня есть другие веб-приложения, сосуществующие на одном и том же Tomcat: myapp2.war, myapp3.war, мне нужен этот макет:
tomcat/lib/myapp1/application.properties
tomcat/lib/myapp2/application.properties
tomcat/lib/myapp3/application.properties
Таким образом, я могу создать военные файлы без каких-либо файлов свойств во время войны и развернуть их на любом сервере.
Я прочитал документацию Spring, но в ней объясняется, как установить местоположение при запуске как банку:
java -jar myapp.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties
Я не могу понять, как это сделать в случае нескольких сосуществующих военных файлов.
Я хотел бы знать, возможно ли это, или я должен отказаться от Spring загрузки и вернуться к традиционным приложениям Spring MVC.
Ответы
Ответ 1
Решением может быть загрузка application- {profile}.properties в виде аннотаций @PropertySource, как предполагает этот вопрос, но тогда система ведения журнала не будет работать, как вы можете видеть в документации.
Система ведения журнала инициализируется в начале жизненного цикла приложения, и поэтому такие свойства ведения журнала не будут найдены в файлах свойств, загружаемых с помощью аннотаций @PropertySource.
Это означает, что ваши свойства ведения журнала в application- {profile}.properties, например:
logging.config=classpath:myapp1/logback.xml
logging.path = /path/to/logs
logging.file = myapp1.log
будет проигнорировано, и система регистрации не будет работать.
Чтобы решить эту проблему, я использовал метод SpringApplicationBuilder.properties() для загрузки свойств в начале, когда приложение настроено. Там я установил "spring.config.location", используемый Spring Boot для загрузки всех application- {profile}.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 как "предоставленный". Кроме того, чтобы исключить все файлы свойств в src/main/resources/myapp1 из финальной войны и создать развертываемую войну без конфигурации:
<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
Теперь я могу создать конфигурацию без войны и поместить ее в папку apache-tomcat-7.0.59/webapps. Файлы свойств будут разрешаться с использованием classpath, независимо для каждого веб-приложения:
apache-tomcat-7.0.59/lib/myapp1
apache-tomcat-7.0.59/lib/myapp2
apache-tomcat-7.0.59/lib/myapp3
Ответ 2
С весны 4.2 и конфигурацией @Annotation и tomcat на linux serveur
В вашем классе приложения установите @PropertySource так:
@Configuration
@EnableWebMvc
@PropertySource(value = { "classpath:application-yourapp.properties"})
@ComponentScan(basePackages = "com.yourapp")
public class YourAppWebConfiguration extends WebMvcConfigurerAdapter {
...
}
Теперь вам просто нужно включить файл свойств в ваш classpath
В производстве
Разверните свои .war файлы (или что-нибудь еще) на tomcat и в любом случае поместите ваши application-yourapp.properties на свой рабочий компьютер. (например, в /opt/applyconfigfolder/application-yourapp.properties ")
Тогда в вашем tomcat (здесь tomcat 7) откройте 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
Если у вас уже есть определение пути к классу, вы можете добавить его
CLASSPATH=:/opt/applyconfigfolder:/yourpath1:/yourpath2:
Я не пробовал с windows но думаю проблем нет
В Dev (с затмением)
├src
| └main
| └ ....
└config
| └application-yourapp.properties
вместо src/main/resources/application-yourapp.properties
Теперь в eclipse добавьте вашу папку конфигурации в classpath, перейдите в "Run Configurations" вашего сервера Tomcat (или эквивалентный) и добавьте папку "Config" в записи пользователя.
![enter image description here]()
Итак, ваш application.properties находится вне приложения, и ваш проект отлично работает в среде разработчика.
Ответ 3
Даниэль Мора дал хорошее решение, но вместо Spring.config.location вы можете использовать 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:
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 предназначен для сторонних библиотек, а не для хранения свойств конфигурации для ваших веб-приложений. Поэтому я думаю, что лучшим решением будет добавить внешнюю папку в качестве дополнительной папки classpath, используя свойство shared.loader в conf/catalina.properties:
shared.loader = $ {catalina.base}/общие/конфигурации
Вы можете поместить свойства приложения app1.properties, app2.properties, ecc.. в apache-tomcat-7.0.59/shared/configurations.
Перед тем, как найти решение для переопределения метода настройки SpringBootServletInitializer от Daniel Mora, я решил добавить context.xml в src/main/webapp/META-INF со следующим содержимым:
<Context>
<Environment name="spring.config.name" value="myapp1" type="java.lang.String" override="false" description="define the property file for srping boot application"/>
</Context>