在另一个实例变量中使用自动装配参数

Using an autowired parameter in another instance variable

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

@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();;
  }
}

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

您运行正在考虑最终变量的边缘情况;即使它被标记为最终的,映射的初始化语句 运行s 在实例初始化程序块之前(否则会有用),运行 在对变量进行赋值的构造函数主体之前。

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

private final Map<Enum, Service> MAPPER;

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

对于这个问题,服务定位器最适合。

我的枚举:-

public enum MyEnum {
    A,
    B
}

创建服务并使用名称 "A" 和 "B"(您的枚举名称为字符串):-

 @Service("A")
 MyService1 implements Service {}

 @Service("B")
 MyService2 implements Service {}

创建MyMapper界面:-

public interface MyMapper {

    Service map(MyEnum myEnum);

}

配置 ServiceLocatorFactoryBean :-

@Bean
public ServiceLocatorFactoryBean serviceLocatorFactoryBean(){
    ServiceLocatorFactoryBean bean = new ServiceLocatorFactoryBean();
    bean.setServiceLocatorInterface(MyMapper.class);
    return bean;
}

开始使用:-

@Autowired
MyMapper mapper;