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

时间:2014-08-04 01:49:20

标签: java java-ee singleton jax-rs cdi

我正在尝试将Singleton bean注入到我的Request范围的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);
    }
}

@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)注释将JAX-RS转换为CDI托管bean。 @RedisThingDb注释标记为@Singleton。 JAX-RS资源是请求范围的,并且有其他请求范围的bean注入其中。

2 个答案:

答案 0 :(得分:0)

我在您的代码中看到了两个问题。例如,您使用@RedisThingDB作为@Stereotype,但未注释@Stereotype。你也应该放弃@Qualifier

其次,更多的建议是,您应该使用范围注释您的端点。 RESTEasy将为您添加范围@RequestScoped

第三,完全可以多次调用构造函数。值得注意的是,如果重复调用@PostConstruct方法。由于CDI使用代理,因此会调用构造函数。如果仍然无效 - 尝试使用@ApplicationScoped而不是@Singleton

答案 1 :(得分:-1)