英文:
Looking up and selecting the correct interface implementation based on enum value in Spring Boot
问题
Spring Boot这里。我有一个接口:
```java
public interface AnalyticsService {
AnalyticsResult analyze(AnalyticsRequest request);
}
我有几十个针对这个接口的不同实现,每个实现都需要被标记为 @Service
:
@Service
public class FizzAnalyticsService implements AnalyticsService {
@Override
public AnalyticsResult analyze(AnalyticsRequest request) {
// ...
}
}
@Service
public class BuzzAnalyticsService implements AnalyticsService {
@Override
public AnalyticsResult analyze(AnalyticsRequest request) {
// ...
}
}
// ... 等等(几十个)
我想创建一个枚举,比如说 AnalyticsType
:
public enum AnalyticsType {
FIZZ,
BUZZ,
...(几十个)
}
然后以某种方式将每个枚举值映射/绑定到不同的 AnalyticsService
实现,以便“客户类”可以在运行时选择正确的实现,类似于:
@Service
public class SomeService {
@Autowired
private FizzAnalyticsService fizzAnalyticsService;
@Autowired
private BuzzAnalyticsService buzzAnalyticsService;
// ... 等等
public void doSomething(AnalyticsType type, AnalyticsRequest request) {
AnalyticsService analyticsService = ???(按 'type' 查找)
AnalyticsResult result = analyticsService.analyze(request);
}
}
在Spring Boot中,如何处理这种类型的查找是什么合适的解决方案?
<details>
<summary>英文:</summary>
Spring Boot here. I have an interface:
public interface AnalyticsService {
AnalyticsResult analyze(AnalyticsRequest request);
}
I have dozens of different impls for this interface, each of which needs to be a `@Service`:
@Service
public class FizzAnalyticsService implements AnalyticsService {
@Override
public AnalyticsResult analyze(AnalyticsRequest request) {
// ...
}
}
@Service
public class BuzzAnalyticsService implements AnalyticsService {
@Override
public AnalyticsResult analyze(AnalyticsRequest request) {
// ...
}
}
// ... etc. (dozens)
I would like to create an `enum`, say, `AnalyticsType`:
public enum AnalyticsType {
FIZZ,
BUZZ,
... (dozens)
}
And somehow map/bind each enum value to a different `AnalyticsService` impl, such that a "client class" could select the correct impl at runtime, something like:
@Service
public class SomeService {
@Autowired
private FizzAnalyticsService fizzAnalyticsService;
@Autowired
private BuzzAnalyticsService buzzAnalyticsService;
// ... etc.
public void doSomthing(AnalyticsType type, AnalyticsRequest request) {
AnalyticsService analyticsService = ??? (lookup by 'type')
AnalyticsResult result = analyticsService.analyze(request);
}
}
What's the appropriate solution to do this type of lookup in Spring Boot?
</details>
# 答案1
**得分**: 1
以下是代码部分的翻译:
```java
public enum AnalyticsType {
FIZZ,
BUZZ
}
public class AnalyticsRequest {
// 数据
}
public class AnalyticsResult {
// 数据
}
public interface AnalyticsService {
boolean supportsType(AnalyticsType analyticsType);
AnalyticsResult analyze(AnalyticsRequest request);
}
@Service
public class FizzAnalyticsService implements AnalyticsService {
@Override
public boolean supportsType(final AnalyticsType analyticsType) {
return AnalyticsType.FIZZ == analyticsType;
}
@Override
public AnalyticsResult analyze(final AnalyticsRequest request) {
return null;
}
}
@Service
public class BuzzAnalyticsService implements AnalyticsService {
@Override
public boolean supportsType(final AnalyticsType analyticsType) {
return AnalyticsType.BUZZ == analyticsType;
}
@Override
public AnalyticsResult analyze(final AnalyticsRequest request) {
return null;
}
}
@Service
public class SomeService {
private final List<AnalyticsService> analyticsServices;
public SomeService(final List<AnalyticsService> analyticsServices) {
this.analyticsServices = analyticsServices;
}
public void doSomthing(AnalyticsType type, AnalyticsRequest request) {
AnalyticsService analyticsService = analyticsServices.stream()
.filter(as -> as.supportsType(type))
.findFirst()
.orElseThrow(() -> new RuntimeException("Type %s doesn't support analytics".formatted(type)));
AnalyticsResult result = analyticsService.analyze(request);
}
}
英文:
will something like this help you? You should be able to inject all services of same type to a collection and then by some criteria filter out those which you want.
public enum AnalyticsType {
FIZZ,
BUZZ
}
public class AnalyticsRequest {
// data
}
public class AnalyticsResult {
// data
}
public interface AnalyticsService {
boolean supportsType(AnalyticsType analyticsType);
AnalyticsResult analyze(AnalyticsRequest request);
}
@Service
public class FizzAnalyticsService implements AnalyticsService {
@Override
public boolean supportsType(final AnalyticsType analyticsType) {
return AnalyticsType.FIZZ == analyticsType;
}
@Override
public AnalyticsResult analyze(final AnalyticsRequest request) {
return null;
}
}
@Service
public class BuzzAnalyticsService implements AnalyticsService {
@Override
public boolean supportsType(final AnalyticsType analyticsType) {
return AnalyticsType.BUZZ == analyticsType;
}
@Override
public AnalyticsResult analyze(final AnalyticsRequest request) {
return null;
}
}
@Service
public class SomeService {
private final List<AnalyticsService> analyticsServices;
public SomeService(final List<AnalyticsService> analyticsServices) {
this.analyticsServices = analyticsServices;
}
public void doSomthing(AnalyticsType type, AnalyticsRequest request) {
AnalyticsService analyticsService = analyticsServices.stream()
.filter(as -> as.supportsType(type))
.findFirst()
.orElseThrow(() -> new RuntimeException("Type %s doesn't support analytics".formatted(type)))
AnalyticsResult result = analyticsService.analyze(request);
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论