@Bean: уникальное имя бина в подклассах - PullRequest
4 голосов
/ 15 января 2020

У меня есть абстрактный класс конфигурации в проекте на основе Spring 4. Класс выглядит примерно так:

public abstract class C<B> {
    @Bean
    public B b() {
        return a();
    }

    protected abstract B a();
}

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

Этот класс C расширен несколькими классами. Например:

@Configuration
public class E extends C<X> {

    @Override
    protected X a() { return new X(); }
}

@Configuration
public class F extends C<Y> {

    @Override
    protected Y a() { return new Y(); }
}

Цель состоит в том, чтобы каждый расширяющий класс мог создавать экземпляры и настраивать bean-компонент так, как он должен быть, и представлять экземпляр как Spring-компонент для инъекции в другие bean-компоненты. Другими словами, все поля должны иметь экземпляр компонента, внедренный в следующий компонент:

@Component
public class Bean {
    private final X x;
    private final Y y;

    public Bean(X x, Y y) {
        this.x = x;
        this.y = y;
    }
}

Проблема состоит в том, что компонент, созданный b(), всегда будет иметь имя b, которое означает, что даже если у меня более 1 расширения C, будет доступен только один из компонентов. В приведенном выше примере это будет означать, что поле x или y имеет значение null (или может вызвать исключение).

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

1 Ответ

1 голос
/ 15 января 2020

Действительно, без указания имени компонента он не сможет начать со следующего сообщения:

Компонент 'b', определенный в ресурсе пути класса

Вот способ, который противоречит интуиции, потому что, если расширитель подкласса не вызывает super.b(), то некоторые важные логики c никогда не будут выполнены.

Но ради ответа на ваш конкретный c вопрос :

C суперкласс

public abstract class C<B> {

  protected B b() {
   return a();
  }

  protected abstract B a();
}

Расширение подклассов

@Configuration
public class E extends C<X> {

  @Bean("X)// Bean name qualifier
  @Override
  protected X b() {
    return super.b();
  }

  @Override
  protected X a() {
    return new X();
  }
}


@Configuration
public class F extends C<Y> {

  @Bean("Y") // Bean name qualifier
  @Override
  protected Y b() {
    return super.b();
  }

  @Override
  protected Y a() {
    return new Y();
  }
}

Компонент Spring

@Component
public class Bean {
  private final X x;
  private final Y y;

  public Bean(X x, Y y) {
    this.x = x;
    this.y = y;
  }
}

Надеюсь, это поможет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...