Конфигурация импорта аннотаций Spring не вызывалась

#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 сможет их увидеть и создаст зависимости для вас.