gpt4 book ai didi

cdi - 根据 Quarkus 中的应用程序属性注入(inject)不同的实现

转载 作者:行者123 更新时间:2023-12-02 18:29:09 26 4
gpt4 key购买 nike

我有一个有两个实现的 Repository 接口(interface)。一个从本地存储的 CSV 文件读取数据,而另一个从 Amazon Dynamo DB 读取数据。我希望能够根据应用程序属性或自定义构建配置文件在我正在使用的实现之间切换。我通常会在运行时使用工厂来检索正确的类,但如果可能的话,我想通过注入(inject)来实现。

我使用 Spring boot 发现了一个类似的问题,但找不到适用于 Quarkus 的等效问题 Spring choose bean implementation at runtime

我还尝试实现一个配置类,类似于此处文档中的配置类,但还是不太顺利。 https://quarkus.io/guides/cdi-reference#default_beans

感觉好像我遗漏了一些明显的东西,所以非常感谢任何指示。

这是我的类的一个简单示例:

@ApplicationScoped
public class ExampleService {

@Inject
ExampleRepository repository;

public List<Data> retrieveData() {
return repository.retrieveData();
}
}
public interface ExampleRepository {
List<Data> retrieveData();
}
@ApplicationScoped
public class DynamoRepository implements ExampleRepository {

@Override
public List<Data> retrieveData() {
//Get Data from DynamoDb
}
}
@ApplicationScoped
public class CsvRepository implements ExampleRepository {
@Inject
CsvBeanHandler csvBeanHandler;
@Inject
LocalFileReader fileReader;

@Override
public List<Data> retrieveData() {
// Get data from CSV
}
}

目前我的 application.yml 中还有以下内容:

com:
example:
application:
storage-type: 'CSV' # OR AMAZON_DYNAMO_DB

最佳答案

看起来他们已经将此直接添加到文档中:

https://quarkus.io/guides/cdi-reference#declaratively-choose-beans-that-can-be-obtained-by-programmatic-lookup

我觉得贴了这么多有点内疚,但这是 SO 方式。

我可以补充一点,它不像 Guice 的“绑定(bind)”;两个类都将被实例化,但只会注入(inject)一个。同样与 Guice 不同的是,您不能注入(inject)接口(interface)(或者我做错了)——您必须使用 Instance 执行如下所示的操作。就我个人而言,我只是使用构造函数注入(inject),然后将 Instance 包装器的值放入 final 字段中,所以我不会为额外的步骤而哭泣。我确实想念 Modules ala Guice 可能带来的强大功能和显式绑定(bind),但这里的简单性有其自身的值(value)。

5.16. Declaratively Choose Beans That Can Be Obtained by Programmatic Lookup

It is sometimes useful to narrow down the set of beans that can beobtained by programmatic lookup via javax.enterprise.inject.Instance.Typically, a user needs to choose the appropriate implementation of aninterface based on a runtime configuration property.

Imagine that we have two beans implementing the interfaceorg.acme.Service. You can’t inject the org.acme.Service directlyunless your implementations declare a CDI qualifier. However, you caninject the Instance instead, then iterate over allimplementations and choose the correct one manually. Alternatively,you can use the @LookupIfProperty and @LookupUnlessPropertyannotations. @LookupIfProperty indicates that a bean should only beobtained if a runtime configuration property matches the providedvalue. @LookupUnlessProperty, on the other hand, indicates that a beanshould only be obtained if a runtime configuration property does notmatch the provided value.

@LookupIfProperty Example

 interface Service {
String name();
}

@LookupIfProperty(name = "service.foo.enabled", stringValue = "true")
@ApplicationScoped
class ServiceFoo implements Service {

public String name() {
return "foo";
}
}

@ApplicationScoped
class ServiceBar implements Service {

public String name() {
return "bar";
}
}

@ApplicationScoped
class Client {

@Inject
Instance<Service> service;

void printServiceName() {
// This will print "bar" if the property "service.foo.enabled" is NOT set to "true"
// If "service.foo.enabled" is set to "true" then service.get() would result in an AmbiguousResolutionException
System.out.println(service.get().name());
}
}

关于cdi - 根据 Quarkus 中的应用程序属性注入(inject)不同的实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69670132/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com