jhamon
jhamon

Reputation: 3691

Jersey Singleton instantiated multiple time

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

Answers (2)

Paul Samsotha
Paul Samsotha

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

ddarellis
ddarellis

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

Related Questions