В Spring и Micronaut есть очень лаконичные способы внедрения различных bean-компонентов в зависимости от среды / профиля, в котором выполняется приложение. Я пытаюсь сделать то же самое с Quarkus.
Я читал этот пост: https://quarkus.io/blog/quarkus-dependency-injection/. И этот процесс упоминается в этой статье StackOverflow: Как я могу переопределить компонент CDI в Quarkus для тестирования? . В этом последнем посте говорится: «создайте бин в тестовом каталоге».
Моя проблема немного другая. Я хотел бы ввести боб, когда в «разработке». В производстве я бы хотел, чтобы вводился компонент по умолчанию. Из документов я не вижу способа, чтобы приложение делало это различие.
Если у меня есть класс по умолчанию, подобный этому:
@DefaultBean
@ApplicationScoped
class ProdProvider : SomeProvider {}
И я хочу переопределить его следующим образом this:
@Alternative
@Priority(1)
class DevProvider : SomeProvider {}
Как сделать так, чтобы это происходило только в режиме разработки?
В одном случае у меня есть класс провайдера учетных данных, который настраивает эмулятор 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
}
}
I Вы хотели бы добавить больше «ложного» класса в процессе разработки, который просто возвращает строку stati c. Я мог бы использовать ProfileManager.getActiveProfile()
, но это смешало меня с проблемами разработки в моей логике c. И я не чувствую, что это имеет место в моем скомпилированном рабочем коде.
Это возможно в Micronaut с использованием аннотации @Requires(env = ["dev", "test"])
. Я кратко рассмотрел использование @Produces
, но документы Oracle EE показались мне немного трудными для получения asp. Если это решение, я покопаюсь.