使用Spring Boot @Service自动连接的泛型反向查找



Spring Boot &这里是Java 11。我有一个抽象基类:

public abstract class AbstractBurninator {
// ...
}

和一些子类,如:

public class FizzBurninator extends AbstractBurninator {}
public class BuzzBurninator extends AbstractBurninator {}
public class FoobazBurninator extends AbstractBurninator {}

但是除了这三个子类之外,它还有更多的子类。我也有一个接口:

public interface DoesThings<B extends AbstractBurninator> {
void doAllTheThings(B burninator, String payload);
}

所以接口的每个实现必须指定它所操作的AbstractBurninator子类。因此我有:

  • public class DoesFizzThings implements DoesThings<FizzBurninator> {}
  • public class DoesBuzzThings implements DoesThings<BuzzBurninator> {}
  • public class DoesFoobazThings imlpements DoesThings<FoobazBurninator> {}
  • 等。

我现在有一个Spring Boot服务(用@Service注释),它与所有List<DoesThings>的列表自动连接。在该服务内部,我有一个方法,它将推断(从某些逻辑)并实例化一个AbstractBurninator子类,然后它需要查找与之相关的DoesThings实现。因此,如果它推断出FizzBurninator的实例,我希望它从autowired列表中选择DoesFizzThings实例:

@Service
public class BurninationService {
@Autowired
private List<DoesThings> thingDoers;
public void hahaha(Whistlefeather wf) {
// use 'wf' and other stateful data to infer a subclassed instance of 'AbstractBurninator':
AbstractBurninator burninator = inferSomehow();
// TODO: how to figure out which item of 'thingDoers' matches 'burninator'?

}

TBD查找的简单而优雅的方法是什么?I可以注入一个映射:

private Map<AbstractBurninator,DoesThings> thingDoers;

但这似乎没有必要,因为每个DoesThing都有1且只有1对应的AbstractBurninator。什么好主意吗?这可能可以用直接的Java泛型完成,但我猜Spring有一些漂亮的实用程序可以在这里提供帮助。

如果您愿意将Spring上下文连接到您的服务中,您可以这样做(受这个SO接受的答案的启发)

private <T extends AbstractBurninator> DoesThings<T> getSomeBurn(Class<T> clazz) {
String[] arr = ctx.getBeanNamesForType(ResolvableType.forClassWithGenerics(DoesThings.class, clazz));
if (arr.length == 1) {
return (DoesThings<T>) ctx.getBean(arr[0]);
} else {
throw new IllegalArgumentException("No burninator found");
}
}

这是一个漂亮的"未检查的铸型"。警告。此外,根据我的经验,连接应用程序上下文表明存在设计问题,并且肯定会使测试复杂化。

相关内容

  • 没有找到相关文章

最新更新