2

我是 Play 的忠实粉丝,现在我几乎在我的任何项目中都使用它。但是,随着我的一个项目变得更大,我决定包含一个 DI 解决方案。在对 Spring 和 Guice 进行了简短的考虑之后,我在 Guice 上停了下来,并为 Play 添加了 Guice 模块(http://www.playframework.com/modules/guice-1.0/home)。

它的问题似乎是注入仅适用于静态字段。这意味着我将不得不做类似的事情:

@InjectSupport
public class MyService {

    @Inject
    static MyBean myBean;

}

来自(http://java.dzone.com/articles/dependency-injection-play

这让我有点害怕,尤其是在测试方面。我的意思是,确实大多数 DI 解决方案总是尝试注入单例,例如 Spring 创建每个 bean 的单个实例并注入它,这在最后是一样的,但仍然如此。我应该有这些顾虑吗?

4

2 回答 2

2

在 Play 1 中,您可以轻松地将普通的 Guice 单例与静态注入的控制器字段结合起来,诀窍是让注解导入正确。

在您的播放控制器中,需要静态注入的作业和测试类使用 JSR330 注释版本:

import javax.inject.Inject;
public class Application extends Controller {
    @Inject private static MyService myService;
    ....
}

对于需要 @InjectSupport 的其他类,请使用 JSR330/module 导入:

import play.modules.guice.InjectSupport;
import javax.inject.Inject;
@InjectSupport
public class AnotherClass  {
    @Inject private static MyService myService;
}

对于 Guice 库实例化的实际(非静态)服务,您需要使用 Guice 注释版本(注意 com.google.inject 包):

import com.google.inject.Inject;
import com.google.inject.Singleton;
@Singleton
public class MyService {
    @Inject private AnotherService anotherService;  // note non-static injection
}

您还需要一个空模块来启动:

import com.google.inject.AbstractModule;
public class MainModule extends AbstractModule {
    @Override
    protected void configure() {}
}

这也应该适用于以除@Singleton 之外的其他方式创建的 Guice 类,例如 @Provides,尽管我还没有尝试过。

于 2013-09-24T09:05:34.947 回答
2

您绝对可以使用 Play 执行 Guice 注入。

  • 您不应该使用旧的 Guice 模块(1.0 版)。您提到的教程也是使用旧的 Guice 和旧的 Play(1.2 版!)

    请查看新的 Guice 模块(3.0 版)和 Play(2.1.1 版)

    http://www.playframework.com/documentation/2.1.1/JavaInjection

  • 注入实例变量时,需要动态创建控制器

    在您的路线文件中:

    GET     /                  @controllers.Application.index()
    

    在您的 Global.java 中,您需要覆盖 getControllerInstance:

    @Override
    public <A> A getControllerInstance(Class<A> controllerClass) throws Exception {
        return INJECTOR.getInstance(controllerClass);
    }
    
于 2013-05-30T04:57:50.780 回答