[英]Inject a singleton bean into a request scoped JAX-RS resource
我试图将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注入了该资源。
我的代码有两个问题。 例如,您将@RedisThingDB
用作@Stereotype
,但未标注@Stereotype
。 您也应该在其上@Qualifier
。
其次,更值得推荐的是,您应该使用范围对端点进行注释。 RESTEasy将为您添加一个范围@RequestScoped
。
第三,可以多次调用构造函数。 真正要注意的是您的@PostConstruct
方法是否被重复调用。 由于CDI使用代理,因此调用了构造函数。 如果仍然不能解决问题,请尝试使用@ApplicationScoped
而不是@Singleton
。
@ManagedBean来自JSF,与CDI不相关http://docs.oracle.com/javaee/6/api/javax/faces/bean/ManagedBean.html
将其替换为@Named
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.