问题
I've created JAX-RS service in which I want to inject an application scoped bean. The problem is that the bean is not injected. How is this caused and how can I solve it?
JAX-RS service:
@Path("room")
public class RoomService {
@Inject
GameController gc;
public RoomService() {}
@Path("create")
@GET
@Produces("application/json")
public String create() {
Room r = new Room();
gc.addRoom(r); // gc is null
return r.toJson();
}
}
Application scoped bean
import java.util.ArrayList;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Named;
import pepuch.multuplayergameserver.entity.Game;
import pepuch.multuplayergameserver.entity.Room;
@Named
@ApplicationScoped
public class GameController {
private Game game;
public GameController() {
this.game = new Game(new ArrayList<Room>());
}
public boolean addRoom(Room room) {
if (!game.getRooms().contains(room)) {
return game.getRooms().add(room);
}
return false;
}
}
回答1:
You need to make the bean a managed resource to make it eligible for injection. At the bare minimum, add @RequestScoped
to the JAX-RS SIB to make it injection-worthy.
Another alternative annotation is @ManagedBean
. The point is , Jersey won't address the desired injection target, if the parent bean is not in a managed context
import javax.enterprise.context.RequestScoped
@RequestScoped
@Path("room")
public class RoomService {
@Inject
GameController gc;
public RoomService() {}
@Path("create")
@GET
@Produces("application/json")
public String create() {
Room r = new Room();
gc.addRoom(r); // gc is null
return r.toJson();
}
}
EDIT: be sure to have a beans.xml file in your WEB-INF folder. Your beans.xml file will look something like:
<beans xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
</beans>
EDIT: Based on this JIRA, you may replace @RequestScoped
with @ManagedBean
回答2:
The built-in context object is active during servlet, web service and EJB invocations, or in the case of the conversation context object, for JSF requests.
You may have difficulty accessing request,scope and application beans from JAX-RS service as it doesn't clearly states the support for this , however in your case it seems like you just need a singleton rather than a context based bean.
Keep it like this if you are using CDI (beans.xml),
@Singleton
public class GameController {
private Game game;
public GameController() {
this.game = new Game(new ArrayList<Room>());
}
....
}
If you are using CDI with Spring (no beans.xml) then keep the @Named
@Named
@Singleton
public class GameController {
private Game game;
public GameController() {
this.game = new Game(new ArrayList<Room>());
}
....
}
If the above doesn't work then I will suggest marking your JAX-RS service as @ManagedBean
along with the above change as it is unclear if CDI manages JAX-RS service.
回答3:
Add cdi-api.jar to your project.
来源:https://stackoverflow.com/questions/15453350/unable-to-inject-applicationscoped-bean-in-jax-rs-service