【问题标题】:Guice on-demand injectionGuice 按需注入
【发布时间】:2017-04-12 12:55:05
【问题描述】:

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

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

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

稍后在连接类中我想使用它的注入

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

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

【问题讨论】:

    标签: java-8 guice playframework-2.5


    【解决方案1】:

    如果您想使用完全相同的配置实例(属于 Props 类),您可以将其实例绑定为 singletonprovider 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;
    }
    

    您可以阅读文档:

    单身人士最有用的是:

    • 有状态的对象,例如配置或计数器
    • 构建或查找成本高昂的对象
    • 占用资源的对象,例如数据库连接池。

    也许您的配置对象符合第一个和第二个条件。我会避免从模块中读取配置。看看为什么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
        }
    
    }
    

    【讨论】:

    • 嗨,我有一个问题。我本来想使用 Provider,但我从以前得到了对 Props 的引用,现在我无法阅读它。所以我只是想知道我是否可以在我得到它时注入它的引用,并在我使用它的任何地方进一步使用 Injector。
    • 有多种解决方案,具体取决于您的具体情况。不幸的是,我不熟悉 Play FW。但是...上面的单例是惰性的(在需要之前不会被实例化)-这意味着您仍然可以使用具有内部状态的提供程序-例如您可以在模块定义中使用相同的提供程序实例,并且在您读取道具的地方只需在同一个共享实例上调用诸如 provider.setProps(props) 之类的东西。不过这听起来很脏:-)
    【解决方案2】:

    通过bindConstant加载模块中的属性

    【讨论】:

      猜你喜欢
      • 2012-08-10
      • 1970-01-01
      • 2017-05-28
      • 2016-09-04
      • 1970-01-01
      • 2021-03-04
      • 2012-10-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多