I am experimenting with RequestFactory (RF) for the first time and am struggling to implement my first ServiceLocator
.
From the RequestContext
:
// Sign a user in or out of the app.
@ServiceName(
value="com.myapp.server.DefaultSignInOutService",
locator="com.myapp.server.DefaultSignInOutServiceLocator"
)
public interface SignInOutService extends RequestContext {
public Request<String> signIn(SignIn signIn);
public Request<Void> signOut(SignOut signOut);
}
And then the DefaultSignInOutServiceLocator
:
public class DefaultSignInOutServiceLocator implements ServiceLocator {
// I am using Guice-3.0 for server-side DI, and ServiceLocatorModule is an AbstractModule.
ServiceLocatorModule serviceLocatorModule = new ServiceLocatorModule();
// Will be initialized by Guice.
private DefaultSignInOutService signInOutService;
public DefaultSignInOutServiceLocator() {
super();
// Bootstrap DI.
Injector injector = GWT.createInjector(serviceLocatorModule);
// injector.getInstance() returns a fully-configured/wired
// DefaultSignInOutService instance.
setSignInOutService(injector.getInstance(SignInOutService.class));
}
@Override
public Object getInstance(Class<?> clazz) {
// I'm trying to use proper DI best practices here, and avoid code like:
//
// return new DefaultSignInOutService(true, "Yes", 35);
//
// Rather, I'd like to be able to return an already pre-configured service impl:
return signInOutService;
}
// Getters/setters, etc.
}
My understanding is that the ServiceLocator
s are basically factories for service implementations. If that's true, then if I'm using Guice for server-side DI, I need to initialize my Guice module from inside the locator's constructor. However, if there is any code that I need to write myself (elsewhere in the app) that creates an instance of DefaultSignInOutServiceLocator
and calls its getInstance()
method explicitly, then I don't need to put the ServiceLocatorModule
inside DefaultSignInOutServiceLocator
. In that case, I could have code like this:
public class DefaultSignInOutServiceLocator implements ServiceLocator {
@Injected
private DefaultSignInOutService signInOutService;
@Override
public Object getInstance(Class<?> clazz) {
return signInOutService;
}
// Getters/setters, etc.
}
So here are my questions:
- Are
ServiceLocator
impls an appropriate place to put Guice modules (and thus bootstrap DI from inside them)? Otherwise, how can I inject the locator with a properly-wired/confgured service impl?
- Or, am I just not understanding the purpose of
ServiceLocator#getInstance()
?
- And if I am on the right track here, then what "scope" (Spring DI terminology) should the injected
signInOutService
be? Should it be a singleton or a multiton/prototype? Do I need to worry about thread-safety here (multiple threads obtaining the same signInOutService
instance)? Or does GWT somehow ensure that the RequestFactoryServlet accesses locators in a thread-safe way?