我正在尝试将Singleton 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);
}
}@RedisThingDb注释,将其标记为Singleton
@Qualifier
@Singleton
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER })
public @interface RedisThingDb {
}@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注入其中。
发布于 2014-08-05 07:57:33
我发现你的代码有两个问题。首先,您使用@RedisThingDB作为@Stereotype,但它不是带注释的@Stereotype。你也应该去掉上面的@Qualifier。
其次,这更像是一种建议,即您应该使用作用域注释端点。@RequestScoped,RESTEasy会为你添加一个作用域。
第三,构造函数被多次调用是完全可以的。真正需要注意的是@PostConstruct方法是否被重复调用。因为CDI使用代理,所以构造函数被调用。如果这仍然不能解决问题--尝试使用@ApplicationScoped而不是@Singleton。
发布于 2014-08-04 14:03:25
@ManagedBean来自JSF,与CDI http://docs.oracle.com/javaee/6/api/javax/faces/bean/ManagedBean.html无关
将其替换为@Named
http://docs.oracle.com/javaee/6/api/javax/inject/Named.html
https://stackoverflow.com/questions/25110794
复制相似问题