Компонент условной загрузки Spring Boot

я запускаю проект весенней загрузки, и я пытаюсь условно загрузить некоторые bean-компоненты. У меня есть следующий файл конфигурации:

application:
    components:
        componentA:
            - ex1
              ex2
              ex3
        componentB:
            - ex1
              ex2
              ex3
        componentC:
            - ex1
              ex2
              ex3
    use: componentA

и следующие классы конфигурации

@Configuration
@ConfigurationProperties(prefix = "application.components")
@Primary
@Getter
@Setter
@NoArgsConstrutor
public class MainConfig
{
    private List<ComponentAConfig> componentA = new ArrayList<ComponentAConfig>();
    private List<ComponentBConfig> componentB = new ArrayList<ComponentBConfig>();
    private List<ComponentCConfig> componentC = new ArrayList<ComponentCConfig>();

}
@Getter
@Setter
@NoArgsConstrutor
public abstract class ComponentConfig
{
    private String ex1;
    private String ex2;
    private String ex3;
}
@Configuration
@ConditionalOnProperty(prefix = "application", name = "use", havingValue = "componentA")
public class ComponentAConfig extends ComponentConfig
{
    
}
@Configuration
@ConditionalOnProperty(prefix = "application", name = "use", havingValue = "componentB")
public class ComponentBConfig extends ComponentConfig
{
    
}
@Configuration
@ConditionalOnProperty(prefix = "application", name = "use", havingValue = "componentC")
public class ComponentCConfig extends ComponentConfig
{
    
}

Несмотря на то, что у меня есть @ConditionalOnProperty, определенный для каждого класса конфигурации, он все равно загружает их все. Как я могу загрузить только список компонентов A и игнорировать остальные 2? Спасибо

Не могли бы вы предоставить ссылку на полный пример проекта, чтобы мы могли его попробовать? Кажется, это работает при копировании в мой проект.

Gobanit 06.11.2022 19:12

О, теперь я понял, что вы пытаетесь сделать... И я думаю, что это не может работать таким образом.

Gobanit 06.11.2022 19:15

Я думаю, вы неправильно используете конфигурацию. В классе MainConfig вы хотите заполнить поля свойствами приложения. В то же время вы аннотировали классы компонентов как @Configuration, что странно, поскольку я ожидал, что они будут классами POJO. Или, если это конфигурации и их существование должно быть условным, зачем там MainConfig? Наверное, я не очень понимаю, чего вы хотите достичь.

Gobanit 06.11.2022 19:21
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
3
61
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Думаю, я бы сделал так. (Отредактировано на основе более позднего комментария)

Класс части конфигурации:

@Data
@NoArgsConstructor
public class ComponentConfigPart {
    private String ex1;
    private String ex2;
    private String ex3;
}

Базовый класс для бина

@Data
public abstract class ComponentConfig {
    private List<ComponentConfigPart> parts = new ArrayList<>();

    @PostConstruct
    public void init() {
        System.out.println("Created instance of " + this.getClass().getSimpleName());
        System.out.println("Created " + this);
    }
}

Класс ComponentA

@Component
@ConfigurationProperties(prefix = "application.components.a")
@ConditionalOnProperty(prefix = "application", name = "use", havingValue = "componentA")
@ToString(callSuper = true)
public class ComponentAConfig extends ComponentConfig {
    
}

Класс ComponentB:

@Component
@ConfigurationProperties(prefix = "application.components.b")
@ConditionalOnProperty(prefix = "application", name = "use", havingValue = "componentB")
@ToString(callSuper = true)
public class ComponentBConfig extends ComponentConfig {

}

и MainConfig, который хочет получить «выбранный» компонент:

@Configuration
public class MainConfig {

    @Autowired
    private ComponentConfig config;

    @PostConstruct
    public void init() {
        System.out.println("MainConfig has autowired class of " + config.getClass().getSimpleName());
    }
}

Теперь свойства такие:

application:
  components:
    a:
      parts:
        - ex1: a
          ex2: aa
          ex3: aaa
        - ex1: a2
          ex2: aa2
          ex3: aaa2
    b:
      parts:
        - ex1: b
          ex2: bb
          ex3: bbb
        - ex1: b2
          ex2: bb2
          ex3: bbb2
  use: componentA

И результаты в журналах консоли:

Created instance of ComponentAConfig
Created ComponentAConfig(super=ComponentConfig(parts=[ComponentConfigPart(ex1=a, ex2=aa, ex3=aaa), ComponentConfigPart(ex1=a2, ex2=aa2, ex3=aaa2)]))
MainConfig has autowired class of ComponentAConfig

Точно так же, если свойства похожи на:

application:
  components:
    a:
      parts:
        - ex1: a
          ex2: aa
          ex3: aaa
        - ex1: a2
          ex2: aa2
          ex3: aaa2
    b:
      parts:
        - ex1: b
          ex2: bb
          ex3: bbb
        - ex1: b2
          ex2: bb2
          ex3: bbb2
  use: componentB

Результат:

Created instance of ComponentBConfig
Created ComponentBConfig(super=ComponentConfig(parts=[ComponentConfigPart(ex1=b, ex2=bb, ex3=bbb), ComponentConfigPart(ex1=b2, ex2=bb2, ex3=bbb2)]))
MainConfig has autowired class of ComponentBConfig

Это то поведение, которое я ищу, но каждый компонент должен представлять собой список, подобный этому:

application:
  components:
    componentA:
        - ex1
          ex2
          ex3
        - ex1
          ex2
          ex3
    componentB:
        - ex1
          ex2
          ex3
        - ex1
          ex2
          ex3
    componentC:
        - ex1
          ex2
          ex3
        - ex1
          ex2
          ex3
use: componentA

Вот почему у меня был класс MainConfig с каждым списком.

Я обновил ответ, так что он ближе к вашей цели.

Gobanit 06.11.2022 20:33

Другие вопросы по теме