Reputation: 3691
I have to make a very small REST app and even if i'm used to Spring, Jersey seems lighter than Spring (maybe I'm wrong?).
I use Jersey 2.25 on a Tomcat 8.0.39.
I have a DAO class that currently access a text file (will be upgrade to a jdbc connection). Those read/write operations must be synchronized, hence I want my DAO instance to be a singleton.
@Singleton
public class ModelDao extends IModelDao
public ModelDao() {
System.out.println("init ModelDao");
}
@Override
public MyModel read(int id){...}
}
This singleton is injected in a service:
@Path("/Model/")
public class ModelService {
@Inject
private IModelDao modelDao;
@Path("{id}")
@GET
@Produces("application/json")
public MyModel getModel(@PathParam("id") Integer id) {
return modelDao.read(id);
}
}
Through a binder
public class DaoBinder extends AbstractBinder {
@Override
protected void configure() {
bind(ModelDao.class).to(IModelDao.class);
}
}
In a ResourceConfig
, I register the binder and my packages.
When I use my service, I get the correct data but the ModelDao
constructor is called on each request. So the read/write operations are not synchronized.
I understood a class annotated @Singleton
was supposed to be instantiated only once in my app.
Does I get it wrong?
Upvotes: 1
Views: 616
Reputation: 209082
Binding a service through the AbstractBinder
with Jersey, the @Singleton
annotation is not supported. You need to use the bind().to().in(Scope)
syntax, where Scope
would be e.g. Singleton.class
, RequestScoped.class
. The default scope is PerLookup
, which is causing the behavior you are currently experiencing.
Also instead of bind(Class).to(Class)
, you could use bind(Instance).to(Class)
, which would auto atically make it a singleton, without needing g to specify the scope.
Upvotes: 2
Reputation: 3960
After you set your class as Singleton do you register it in your application?
Something like this:
public class App extends ResourceConfig {
public App () {
register(ModelDao.class);
}
}
Upvotes: -1