在Spring Boot中根据枚举值查找并选择正确的接口实现

huangapple go评论70阅读模式
英文:

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 &quot;client class&quot; 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 &#39;type&#39;)
    AnalyticsResult result = analyticsService.analyze(request);

}

}


What&#39;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&lt;AnalyticsService&gt; analyticsServices;

    public SomeService(final List&lt;AnalyticsService&gt; analyticsServices) {
        this.analyticsServices = analyticsServices;
    }

    public void doSomthing(AnalyticsType type, AnalyticsRequest request) {
        AnalyticsService analyticsService = analyticsServices.stream()
                .filter(as -&gt; as.supportsType(type))
                .findFirst()
                .orElseThrow(() -&gt; new RuntimeException(&quot;Type %s doesn&#39;t support analytics&quot;.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&lt;AnalyticsService&gt; analyticsServices;

    public SomeService(final List&lt;AnalyticsService&gt; analyticsServices) {
        this.analyticsServices = analyticsServices;
    }

    public void doSomthing(AnalyticsType type, AnalyticsRequest request) {

        AnalyticsService analyticsService = analyticsServices.stream()
                .filter(as -&gt; as.supportsType(type))
                .findFirst()
                .orElseThrow(() -&gt; new RuntimeException(&quot;Type %s doesn&#39;t support analytics&quot;.formatted(type)))
        AnalyticsResult result = analyticsService.analyze(request);

    }
}

huangapple
  • 本文由 发表于 2023年2月24日 01:53:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/75548553.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定