@Bean:子类中唯一的bean名称

Lás*_*zki 5 java spring spring-boot

我在基于 Spring 4 的项目中有一个抽象配置类。这个类看起来像这样:

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

    protected abstract B a();
}
Run Code Online (Sandbox Code Playgroud)

当然,这不是实际的课程,但是让我们使用这个理论课程,它涉及真正有问题的课程中最重要的部分。

该类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(); }
}
Run Code Online (Sandbox Code Playgroud)

目标是让每个扩展类按照预期的方式实例化和设置 bean,并将实例公开为 Spring bean,以便注入到其他 bean 中。换句话说,所有字段都应该在以下 bean 中注入一个 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是,创建的 bean 的b()名称始终为b,这意味着即使我有 1 个以上的 扩展名C,也只有一个 bean 可用。在上面的示例中,这意味着x, 或y字段为空(或者会抛出异常)。

如何为这些 bean 提供唯一的名称,以便所有扩展都C可以公开其自己的 bean 实例而不会重叠?

小智 1

事实上,如果不指定 bean 名称,它将无法启动并显示以下消息:

bean 'b',在类路径资源中定义

这是一种违反直觉的方法,因为如果子类扩展器不调用super.b(),那么一些重要的逻辑将永远不会被执行。

但为了回答你的具体问题:

C超类

public abstract class C<B> {

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

  protected abstract B a();
}
Run Code Online (Sandbox Code Playgroud)

扩展子类

@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();
  }
}
Run Code Online (Sandbox Code Playgroud)

弹簧组件

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

  public Bean(X x, Y y) {
    this.x = x;
    this.y = y;
  }
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助