Guice 按需注入

Guice on-demand injection

我一直在学习 Guice。我看到有按需注入 here.

我想知道它的用途和一些例子。我有一个场景,我从 conf 文件中读取一组属性。那里没有注射。稍后我想将我从这些属性中获得的配置 class 的相同实例注入到其他一些 class.

class Props {
    //set of properties read from a config file to this class

}

Props props = readProperties(); // instance of this class having all the properties but not put into injection container

稍后连接class我想用它的注入

@Inject
public Connection(Props props) {
    this.props = props;
}

这种情况下可以使用Guice的按需注入吗?此外,我正在使用 Play 框架的 conf 文件来加载我的模块文件。 play.modules.enabled += com.example.mymodule

加载模块中的属性,并通过 bindConstant

加载它们

如果您想使用完全相同的配置实例(class 道具),您可以将其实例绑定为 singleton with a provider binding。这当然不是唯一的解决方案,但对我来说很有意义。

这是一个例子:

定义提供者:

public class PropsProvider implements Provider<Props>
{
    @Override
    public Props get()
    {
        ...read and return Props here...
    }
}

在单例范围内使用提供程序绑定:

bind(Props.class).toProvider(PropsProvider.class).in(Singleton.class);

注入你的配置:

@Inject
public Connection(Props props) {
    this.props = props;
}

您可以阅读文档:

Singletons are most useful for:

  • stateful objects, such as configuration or counters
  • objects that are expensive to construct or lookup
  • objects that tie up resources, such as a database connection pool.

也许您的配置对象符合第一个和第二个条件。我会避免从模块内部读取配置。看看为什么 here.

我在一些单元测试用例中使用了按需注入,在这些用例中我想在被测组件中注入模拟依赖项并且使用了字段注入(这就是我尽量避免字段注入的原因:-))和由于某些原因,我不想使用 InjectMocks

这是一个示例:

组件:

class SomeComponent
{
    @Inject
    Dependency dep;

    void doWork()
    {
        //use dep here
    }
}

测试本身:

@RunWith(MockitoJUnitRunner.class)
public class SomeComponentTest
{
    @Mock
    private Dependency mockDependency;

    private SomeComponent componentToTest;

    @Before
    public void setUp() throws Exception
    {
        componentToTest = new SomeComponent();

        Injector injector = Guice.createInjector(new AbstractNamingModule()
        {
            @Override
            protected void configure()
            {
                bind(Dependency.class).toInstance(mockDependency);
            }
        });

        injector.injectMembers(componentToTest);
    }

    @Test
    public void test()
    {
         //test the component and/or proper interaction with the dependency
    }

}