Search code examples
serviceosgiinstanceblueprint

How do you get a new service bean implementation instance each time you call an OSGi Blueprint service?


I have a java class, call it "Job", that implements an interface that I export as a service using blueprint. Although the class is defined as a bean with scope="prototype" in the blueprint xml file, and the service referen ces that bean, I can see from a System.out.println(this) statement in an instance method of the Job, that each time I access the service from a caller bundle, it reuses the same instance of the class Job that it created when I start the bundle; my caller bundle looks up the service references, calls context.getService(serviceReferences[0]) to get the reference to the Job service and then calls the method on that service (eg. Job.run()).

I thought making the scope of the service bean def prototype would give me a new instance of Job each time I called getService from the caller bundle, but my experiments are showing me that it's still using the same object instance.

So how do I call the service and have it create a new instance of Job each time, rather than reusing the same object?

I also need another service reference injected as a property into the bean Job since the bean interface doesn't have a set method to do this. So each new instance has to be created as the bean Job so that it can inject the property with a setX() method.


Solution

  • If you use prototype scope for a bean, it means that a new instance will be created every time the bean is injected to another bean / service within the same blueprint container.

    In your case a new instance of a bean is created as it is injected into the service component. However, the service component can provide only the same instance every time it is requested by another bundle.

    For me it seems to me that you try to use blueprint and prototype scope for a task that should be done programmatically. You want to use a service that creates a new instance every time. That means that you should define a JobFactory interface and its implementation and register it as an OSGi service. On the other side, you should use JobFactory to instantiate as many Job instances as you want.

    You could also use PrototypeServiceFactory but you have to register it programmatically as well. In my opinion, when someone wants to use PrototypeServiceFactory, it is time to extend the API with a Factory.