我正在尝试将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注入其中。
答案 0 :(得分:0)
我在您的代码中看到了两个问题。例如,您使用@RedisThingDB
作为@Stereotype
,但未注释@Stereotype
。你也应该放弃@Qualifier
。
其次,更多的建议是,您应该使用范围注释您的端点。 RESTEasy将为您添加范围@RequestScoped
。
第三,完全可以多次调用构造函数。值得注意的是,如果重复调用@PostConstruct
方法。由于CDI使用代理,因此会调用构造函数。如果仍然无效 - 尝试使用@ApplicationScoped
而不是@Singleton
。
答案 1 :(得分:-1)
@ManagedBean来自JSF,与CDI无关 http://docs.oracle.com/javaee/6/api/javax/faces/bean/ManagedBean.html
将其替换为@Named