Java 将单例bean注入到请求范围的JAX-RS资源中

Java 将单例bean注入到请求范围的JAX-RS资源中,java,jakarta-ee,singleton,jax-rs,cdi,Java,Jakarta Ee,Singleton,Jax Rs,Cdi,我试图将一个单例bean注入到我的请求范围的JAX-RS资源中。我注意到我的Singleton构造函数在每个请求上都被调用,这显然不是期望的行为。我的代码构件如下所示:- JAX-RS资源 @Path("/thing") @ManagedBean public class ThingResource { //This is desired to be Singleton @Inject @RedisThingDb private ThingDb thingDb;

我试图将一个单例bean注入到我的请求范围的JAX-RS资源中。我注意到我的Singleton构造函数在每个请求上都被调用,这显然不是期望的行为。我的代码构件如下所示:-

JAX-RS资源

@Path("/thing")
@ManagedBean
public class ThingResource {

    //This is desired to be Singleton
    @Inject
    @RedisThingDb
    private ThingDb thingDb;

    //This is request scoped
    @Inject
    private MyRequestScopedObj obj;

    @GET
    @Path("/{id}")
    @Produces("application/json")
    public Thing getById(@PathParam("id") String thingId) {
        return thingDb.findById(thingId);
    }
}
@将其标记为Singleton的RedisThingDb注释

@Qualifier
@Singleton
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER     })
public @interface RedisThingDb {

}
创建RedisDb对象的生产者代码

@Produces
@RedisThingDb
public ThingDb getRedisDb() {
    return new RedisDb();// This should be called once, because @RedisThingDb is singleton.
}
RedisDb

public class RedisDb implements ThingDb {
    public RedisDb() {
    logger.debug("Constructing...");
    }

    public Thing findById(Long id){
     ...
    }
}
来自pom.xml实现的依赖关系是Wildfly容器

    <dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-api</artifactId>
        <version>7.0</version>
        <scope>provided</scope>
    </dependency>

我使用javax.annotation.ManagedBean@ManagedBean annotation将JAX-RS转换为CDI托管bean。@RedisThingDb注释被标记为@Singleton。JAX-RS资源是请求范围的,并向其中注入了其他请求范围的bean。

@ManagedBean来自JSF,与CDI无关

将其替换为@Named


我发现您的代码有两个问题。首先,您使用@RedisThingDB作为@Stereotype,但它没有注释@Stereotype。你也应该去掉它上面的@Qualifier

第二个建议是,应该使用范围注释端点。RESTEasy将为您添加一个作用域@RequestScoped


第三,构造函数可以被多次调用。真正需要注意的是@PostConstruct方法是否被反复调用。由于CDI使用代理,因此会调用构造函数。如果这仍然没有帮助-尝试使用@ApplicationScoped而不是@Singleton。

不要在非GUI对象上使用@Named。为什么@“命名”用于一般用途,例如,与Spring中的“@Component”相同。还有一个javax.annotation.ManagedBean。它与JSF ManagedBean一样工作。ManagedBean作用域被认为是CDI中定义任何内容的更多bean。大多数JAX-RS运行时在资源类上看到@RequestScoped或@ApplicationScoped时将支持注入。您可以指定您正在使用的JAX-RS/Java EE的版本吗?@JohnAment我的maven依赖项如下:-如果我运行的是javax javaee api 7.0WildFly@JohnAment对不起,我不能找出如何正确格式化我的评论。我使用的是javax.javaee-API7.0,提供了作用域,并对Wildfly应用程序containerGreat表示感谢。您是否也可以在问题中发布您的beans.xml?