首页 > 解决方案 > 在另一个实例变量中使用自动装配参数

问题描述

我有一个实现接口的服务。我现在想写一个映射器,基本上就是说,当我传入这个枚举类型时,使用那个服务。这就是我所拥有的

@Service
MyService implements Service {}


@Component
@RequiredArgsConstructor
MyMapper implements Mapper<Enum, Service> {

  private final MyService myService;

  private ImmutableMap<Enum, Service> MAPPER = ImmutableMap.<MyEnum, MyService>builder()
            .put(Enum.A, myService)
            .build();;

  @Override
  public Service map(Enum input) {
    return MAPPER.get(input);
  }
}

但是,这似乎行不通。我认为我不允许使用(自动装配的)实例变量来实例化另一个实例变量。

为了解决这个问题,我现在使用了单例模式。

@Service
MyService implements Service {}


@Component
@RequiredArgsConstructor
MyMapper implements Mapper<Enum, Service> {

  private final MyService myService;

  private ImmutableMap<Enum, Service> MAPPER = null;

  @Override
  public Service map(Enum input) {
    if(MAPPER == null){
      MAPPER = createMapper();
    }
    return MAPPER.get(input);
  }

  private ImmutableMap<Enum, Service> createMapper(){
    return ImmutableMap.<MyEnum, MyService>builder()
            .put(Enum.A, myService)
            .build();;
  }
}

这似乎可行,但我想知道是否有其他选择可以解决这个问题。

标签: javaspringautowired

解决方案


您遇到了关于最终变量的极端情况;即使它被标记为 final,映射的初始化语句在实例初始化块之前运行(否则这将很有用),实例初始化块在对变量进行赋值的构造函数体之前运行。

我不确定您为什么要创建一个映射只是为了保存一个单例值,但是您需要在构造函数体内分配映射。如果您出于某种原因真的想要此设置,我的建议是这样做:

private final Map<Enum, Service> MAPPER;

public MyMapper(MyService myService) {
    MAPPER = Map.of(Enum.A, myService);
}

推荐阅读