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

如何在科特林的Quarkus中使用CDI场注入?

晏炳
2023-03-14

我想在Quarkus中注入bean一个静态编程语言字段。示例文件看起来像

package org.example

import com.google.inject.Inject
import javax.enterprise.inject.spi.BeanManager
import javax.ws.rs.GET
import javax.ws.rs.Path

@Path("injectDemo")
open class InjectDemo @Inject constructor(val bm1: BeanManager) {

    @field:Inject
    protected open lateinit var bm2: BeanManager

    @GET
    fun demo() {
        println("bm1 $bm1")
        println("bm2 $bm2")
    }
}

构造函数参数注入工作正常,但字段bm2仍处于未初始化状态。

控制台输出:

bm1 io.quarkus.arc.impl.BeanManagerImpl@6b7ac97f
2020-05-21 03:45:11,670 ERROR [io.qua.ver.htt.run.QuarkusErrorHandler] (executor-thread-1) HTTP Request to /injectDemo failed, error id: ac118d6b-a26e-47e7-8c10-12e6a96e50ba-3: org.jboss.resteasy.spi.UnhandledException: kotlin.UninitializedPropertyAccessException: lateinit property bm2 has not been initialized
    at org.jboss.resteasy.core.ExceptionHandler.handleApplicationException(ExceptionHandler.java:106)
    at org.jboss.resteasy.core.ExceptionHandler.handleException(ExceptionHandler.java:372)
    at org.jboss.resteasy.core.SynchronousDispatcher.writeException(SynchronousDispatcher.java:216)
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:515)
    at org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:259)
    at org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:160)
    at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:362)
    at org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:163)
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:245)
    at io.quarkus.resteasy.runtime.standalone.RequestDispatcher.service(RequestDispatcher.java:73)
    at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.dispatch(VertxRequestHandler.java:123)
    at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.access$000(VertxRequestHandler.java:36)
    at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler$1.run(VertxRequestHandler.java:87)
    at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
    at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:2046)
    at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1578)
    at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1452)
    at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29)
    at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29)
    at java.base/java.lang.Thread.run(Thread.java:832)
    at org.jboss.threads.JBossThread.run(JBossThread.java:479)
Caused by: kotlin.UninitializedPropertyAccessException: lateinit property bm2 has not been initialized
    at org.example.InjectDemo.getBm2(InjectDemo.kt:12)
    at org.example.InjectDemo.demo(InjectDemo.kt:17)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
    at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:167)
    at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:130)
    at org.jboss.resteasy.core.ResourceMethodInvoker.internalInvokeOnTarget(ResourceMethodInvoker.java:621)
    at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTargetAfterFilter(ResourceMethodInvoker.java:487)
    at org.jboss.resteasy.core.ResourceMethodInvoker.lambda$invokeOnTarget$2(ResourceMethodInvoker.java:437)
    at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:362)
    at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:439)
    at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:400)
    at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:374)
    at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:67)
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:488)
    ... 17 more

有可能在科特林的Quarkus中使用CDI场注入吗?如果是,需要为注射设置什么才能工作?

我是从uberjar运行应用程序,而不是从本地图像运行。

jar包含生成的类org.example.InjectDemo_Bean包含一个方法create()的分解版本,该方法不显示任何注入到bm2字段的尝试:

    public InjectDemo create(CreationalContext var1) {
        Object var2 = this.injectProviderSupplier1.get();
        CreationalContextImpl var3 = CreationalContextImpl.child((InjectableReferenceProvider)var2, var1);
        Object var4 = ((InjectableReferenceProvider)var2).get((CreationalContext)var3);
        return new InjectDemo((BeanManager)var4);
    }

共有1个答案

赵同
2023-03-14

根据https://quarkus.io/guides/kotlin#cdi-使用kotlin注入kotlin注释反射未命中导致注入失败的目标注释。解决方案是添加fieldjavax。企业注射默认注释:

    @field:Default
    @field:Inject
    protected open lateinit var bm2: BeanManager
 类似资料:
  • 我目前正在使用静态编程语言在Quarkus中创建一个应用程序。我正在尝试使用RestEasy、Panache和Hibernate创建一个简单的用户endpoint。我现在的挑战是异常处理没有正确完成。当请求无效时,我想向用户显示正确且可理解的消息。 这是我的创建用户 POST 请求的用户资源: 这是我的用户实体: 为了完整起见,这是我的用户存储库: 当我确定请求有效时,创建用户确实有效。但我也想确

  • 我已经将正式用Java编写的JEE应用程序中的REST资源转换为Kotlin。该应用程序在Wildfly应用程序服务器中运行,使用Weld作为依赖项注入框架。 这是我想出的最终实现: setter用于测试目的。对于Mockito或其他可以设置私有字段的mocking框架,这不是必需的。 我在这个实现上遇到了一些问题: < li >我必须将类和所有方法更改为< code>open,以允许CDI容器为

  • 如何在使用Kotlin的Spring Boot中正确初始化ConfigurationProperties? 目前我喜欢下面的例子: 但是它看起来很丑陋,实际上不是一个iable,foo是常量ue,应该在启动期间初始化,将来不会改变。

  • 我有一个简单的Quarkus资源: 我试图将实例注入到我的资源中,但是我得到了一个。但是,如果我在上使用注释,那么一切都很好。是否有一种方法可以在不使用注释的情况下将类注入到我的资源中?换句话说,是否有一种方法可以使Quakus容器可以发现而不直接注释该类? 编辑:查看CDI文档,似乎可以使用带有注释的方法手动注册bean。但是,我不清楚哪个类应该包含带注释的方法) 另一个选择是使用Jandex索

  • 问题内容: 我正在学习具有C ++和Java背景的Kotlin。我期待下面的打印,不。我知道这对应到。默认实现不比较每个成员,即和吗?如果是这样,它会不会看到字符串值相等(因为再次映射到字符串值)?显然,我在Kotlin中还没有涉及平等与身份相关的问题。 问题答案: 您描述的默认实现仅适用于数据类。不适用于从中继承实现的常规类,只需使对象与自身相等即可。