#java #spring #configuration #spring-annotations
#java #spring #конфигурация #spring-аннотации
Вопрос:
Я пытаюсь создать приложение, которое использует аннотации Spring для импорта конфигураций. Для этого вопроса я сузил его до двух файлов. Класс Startup:
package core;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Slf4j
@Configuration
@Import(ConfigSettings.class)
public class Startup {
public static void main (String args[]) {
log.info("main class");
}
}
и настройки конфигурации
ядро пакета;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
@Slf4j
@Configuration
@ComponentScan({"connections", "filter"})
@PropertySource({"classpath:config/${env.config:dev}.application.properties"})
public class ConfigSettings {
public ConfigSettings() {
log.info("Constructor ConfigSettings");
}
}
Я ожидал, что результат будет:
[INFO]Constructor ConfigSettings
[INFO]main class
Но он показывает только mainclass. Похоже, что конструктор настроек конфигурации вообще не вызывается. Я ожидаю, что он вызовет ее из-за аннотации импорта.
Кто-нибудь может объяснить, что происходит не так? Заранее благодарю вас!
Комментарии:
1. Почему.
@Import
имеет значение только в контексте / области действия Spring,ApplicationContext
вы просто запускаетеmain
метод.2. Ваш
main
метод не имеет ничего общего с контейнером Spring. Поэтому вы не можете ожидать, что она загрузит контекст Spring и классы конфигурации.
Ответ №1:
Лучше всего заставить класс config возвращать объект config, содержащий ваши значения. Обычно я не стремлюсь добавлять всеобъемлющий объект конфигурации, но у меня есть файл конфигурации для каждого компонента (базы данных, контроллеров и т.д.).
Затем вы можете вернуть сконфигурированный объект как компонент и позволить spring внедрить его. Если бы я должен был создать конфигурационный файл для RestTemplate (в качестве простого примера):
@Service
public class RestClientConfig {
@Value("${your.config.value}")
private String yourValue;
private final RestTemplate restTemplate = new RestTemplate();
@Bean
public RestTemplate restTemplate() {
// Configure it, using your imported values
// ...
return restTemplate;
}
}
Однако main
метод находится за пределами контейнера spring, и вы не сможете загрузить его таким образом, но с помощью вышеупомянутого метода вы можете вызвать настроенный компонент непосредственно там, где вам нужно его использовать.
Комментарии:
1. Спасибо! Мне трудно понять, что делают контейнеры, но я думаю, что теперь это начинает иметь смысл. Просто проверьте, правильно ли я понял: причина, по которой это не сработало, заключалась в том, что у меня был мой основной метод вне моего контейнера Spring, и поэтому он не мог его загрузить. С помощью обходного пути (например, этого или applicationcontext) компоненты настраиваются без необходимости в main в контейнере Spring? Это правильно? Спасибо, что уделили мне время!
2. «С помощью обходного пути (подобного этому или applicationcontext) компоненты настраиваются без необходимости в main в контейнере Spring?» Закрыть; если вы используете Spring, это обернет ваше приложение в контейнер spring, но при этом для настройки используются классы, которые находятся в контексте приложения, таким образом, spring сможет их увидеть и создаст зависимости для вас.