当前位置: 首页 > 知识库问答 >
问题:

在局部发育过程中用夸克注入不同的bean

桓瀚
2023-03-14

我读过这个帖子:https://quarkus.io/blog/quarkus-dependency-injection/。在这篇StackOverflow文章中也提到了这个过程:如何覆盖Quarkus中的CDI bean进行测试?。最后一篇文章说,“Create bean in test directory”。

我的问题略有不同。我想在“开发”时注入一个bean。在生产过程中,我希望注入默认bean。从文档上看,我看不出有什么办法让应用程序做出这种区分。

如果我有一个像这样的默认类:

@DefaultBean
@ApplicationScoped
class ProdProvider : SomeProvider {}
@Alternative
@Priority(1)
class DevProvider : SomeProvider {}

在一个例子中,我有一个credential provider类,它在本地开发时设置Google的PubSub仿真器。在生产中,我使用一个实现相同接口的类,但却是一个真正的凭据提供程序。但是,导致我提出这个问题的特定案例是一个实现一个方法的类:

@ApplicationScoped
class VaultLoginJwtProvider : LoginJwtProvider {
  @ConfigProperty(name = "vault.tokenPath")
  private val jwtPath: String? = null

  companion object {
    val logger: Logger = LoggerFactory.getLogger("VaultTokenProvider")
  }

  override fun getLoginJwt(): Optional<String> {
    logger.info("Using Vault Login JWT")

    return try {
      Optional.of(String(Files.readAllBytes(Paths.get(jwtPath))).trim { it <= ' ' })
    } catch (e: Exception) {
      logger.error("Could not read vault token at $jwtPath")
      logger.error(e.printStackTrace().toString())
      Optional.empty()
    }
  }
}

通过构造函数注入将该类注入到另一个类中:

@Singleton
class JwtServiceImpl(
  @RestClient val vaultClient: VaultClient,
  @Inject val loginJwtProvider: LoginJwtProvider
) {
  private var serviceJwt: String? = null

  companion object {
    val logger: Logger = LoggerFactory.getLogger("JwtServiceImpl")
  }

  private fun getLoginToken(): String? {
    val vaultLogin = VaultLogin(
      role = "user-service",
      jwt = loginJwtProvider.getLoginJwt().get()
    )

    val loginResponse = vaultClient.login(vaultLogin)

    return loginResponse.auth.clientToken
  }
}

我想在开发中注入更多的“模拟”类,它只返回一个静态字符串。我可以使用ProfileManager.getActiveProfile(),但这使我将开发问题混入了我的逻辑中。我不觉得这在我编译的生产代码中有任何位置。

共有1个答案

邵耀
2023-03-14

我的解决方案是在@javax.ws.rs.ext.Provider中自己创建最后一个bean。不像Micronaut@所要求的那么优雅,但好吧,它起作用了。

请注意,SomeProvider的实例不是一个“bean”,您必须自己关心生命周期(依赖注入、PostConstruct,没有PreDestroy,……)。

org.acme.someProvider.java

package org.acme;

import javax.enterprise.context.ApplicationScoped;

public interface SomeProvider {

  void providerMethod();

  @ApplicationScoped
  class ProdProviderRequirement {
    void foo() {}
  }

  class ProdProvider implements SomeProvider {

    private final ProdProviderRequirement prodProviderRequirement;

    ProdProvider(final ProdProviderRequirement prodProviderRequirement) {
      this.prodProviderRequirement = prodProviderRequirement;
    }

    @Override
    public void providerMethod() {
      prodProviderRequirement.foo();
    }
  }

  class DevProvider implements SomeProvider {
    @Override
    public void providerMethod() {}
  }
}
package org.acme;

import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Produces;
import javax.inject.Inject;
import javax.ws.rs.ext.Provider;
import org.acme.SomeProvider.DevProvider;
import org.acme.SomeProvider.ProdProvider;
import org.acme.SomeProvider.ProdProviderRequirement;

@Provider
class SomeProviderFactory {

  SomeProvider someProvider;

  @Inject
  SomeProviderFactory(final ProdProviderRequirement prodProviderRequirement) {
    final var someCondition = true;
    someProvider = someCondition ? new DevProvider() : new ProdProvider(prodProviderRequirement);
  }

  @Produces
  @ApplicationScoped
  SomeProvider someProvider() {
    return someProvider;
  }
}
 类似资料:
  • 我正在尝试使用Quarkus1.6.1.Final和OpenJDK11解决存储库模式的依赖注入问题。我想实现Inject with Interface,并给他们一些参数(如或)来指定具体类,但目前我有并且不确定如何修复它。 这里是我的代码部分。 UseCase类: 存储库接口: 我阅读并尝试了以下文章: 部分公文: 夸克-上下文和依赖注入https://quarkus.io/guides/cdi-

  • 我想在我的 Kotlin 资源文件中包含依赖项。但我不能。 我做了这个教程:https://quarkus.io/guides/rest-client-guide 但是,为了开始这个项目,我在我的项目中包含了扩展“kotlin”。 我的代码如下: 国家 国家服务 国家资源.kt 应用程序属性 错误: 有人能帮我吗? 谢谢

  • 在我们的夸克应用程序中,我们使用LDAP服务器来检索用户数据。简而言之,代码如下所示: 使用jre版本,一切都运行良好,但使用Quarkus原生,我得到ClassNotFoundExceptions。构建和启动是成功的,但调用应用程序不起作用。 现在例外是java。lang.ClassNotFoundException:javax。网ssl。SSLSocketFactory。我想知道quarkus

  • 我使用了著名的Dagger ViewModelFactory模式,以便能够为所有活动中的所有视图模型注入工厂。 我遇到的问题是,当我将工厂注入到匕首时失败了,因为我不打算使用的对象的提供者并不总是可访问的。他们不是因为包含提供者的模块没有添加。 例如,我有一个LogIn活动和一个SignUp活动,这是我为它们添加子组件的方式: 请注意,当我为SignUpActivity创建子组件时,我没有添加模块

  • 无法构建quarkus应用程序quarkus maven插件:2.10.0。最终[错误]由:java引起。io。IOException:无法为\target\quarkus app\quarkus\转换的字节码创建新文件系统。io上的jar[错误]。夸克斯。fs。util。ZipUtils。newZip(ZipUtils.java:133)[错误]位于io。夸克斯。部署。包装。步骤。JarResu

  • 对如何实现这一点有什么想法吗?我有一个编程解决方案,但更喜欢一个仅通过注释的解决方案