正确使用GWT RequestFactory ServiceLocator和DI

时间:2013-12-05 16:28:04

标签: java gwt guice requestfactory service-locator

我第一次尝试使用RequestFactory(RF),并且正在努力实现我的第一个ServiceLocator

来自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);
}

然后是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.
}

我的理解ServiceLocator s基本上是服务实现的工厂。如果这是真的,那么如果我将Guice用于服务器端DI,我需要从定位器的构造函数内部初始化我的Guice模块。但是,如果我需要自己编写代码(在应用程序的其他位置)创建DefaultSignInOutServiceLocator的实例并显式调用其getInstance()方法,那么我不需要放置{在ServiceLocatorModule内{1}}。在这种情况下,我可以使用这样的代码:

DefaultSignInOutServiceLocator

所以这是我的问题:

  1. public class DefaultSignInOutServiceLocator implements ServiceLocator { @Injected private DefaultSignInOutService signInOutService; @Override public Object getInstance(Class<?> clazz) { return signInOutService; } // Getters/setters, etc. } 是否有适当的位置放置Guice模块(从而从内部引导DI)?否则,如何向定位器注入正确连接/配置的服务impl?
  2. 或者,我只是不理解ServiceLocator的目的?
  3. 如果我在这里正确的轨道,那么注入ServiceLocator#getInstance()应该是什么“范围”(Spring DI术语)?它应该是单身还是多声道/原型?我是否需要担心线程安全(多个线程获取相同的signInOutService实例)?或者GWT以某种方式确保RequestFactoryServlet以线程安全的方式访问定位器?
  4. 提前致谢!

1 个答案:

答案 0 :(得分:3)

ServiceLocatorServiceLayerDecorator实例化,您可以插入自己的。

ServiceLocator和他们创建几乎单身的服务实例(如果可用内存很少,可以进行垃圾收集,之后重新创建新实例),所以你应该或者将它们配置为单身或者至少确保将它们视为这样(即为请求范围的值(例如当前用户)注入Provider。)

您可以在https://github.com/tbroyer/gwt-maven-archetypes

找到Maven原型形式的完整示例