【问题标题】:Inject guice managed dependency in a non guice class在非 guice 类中注入 guice 托管依赖项
【发布时间】:2016-04-15 15:33:30
【问题描述】:

我有一个类 (CustomConnectionProvider),它将由第三方库 (hibernate) 使用 class.forName().newInstance() 实例化。我需要注入一个 guice 托管依赖项,例如 MyDatabaseFactory,它将为多租户提供数据源。

我不能直接@Inject MyDatabaseFactory,因为CustomConnectionProvider 不是托管bean。而且我无法控制它是如何创建的。

我刚开始使用 Guice 作为 Play 应用程序的一部分。任何示例或想法将不胜感激,我正在寻找像 ServiceLocator 这样的解决方案。

针对特定情况修复 幸运的是,Play.application() 提供了一个静态方法来获取injector,我正在使用它来获取我的工厂实例。我仍然想知道我是否必须在不玩的情况下修复它。

Play 2.5 更新 Play.application() 在 2.5 中已弃用。我们需要按照罗伯特的建议使用静态注入。

【问题讨论】:

  • 嘿,这是hibernate特有的吗?如果是这样,则有:github.com/google/guice/wiki/GuicePersist,这是休眠的 guice 模型。如果您需要手动执行此操作,则应在创建其他所有内容的模块中创建实体管理器(休眠的东西)。这样,您将获得 guice 管理的持久性。我确实有一个关于后者的例子,但是我没有使用 Play
  • @pandaadb,它并不特定于 Hibernate。它专门用于将对象注入到另一个根本没有被 Guice 初始化的类中,并且该类的初始化在某个第三方库中。

标签: java hibernate guice


【解决方案1】:

您可以使用静态注入。见https://github.com/google/guice/wiki/Injections

它使对象可以部分参与依赖注入,方法是在不被注入自身的情况下获得对注入类型的访问权。使用

requestStaticInjection() 

在一个模块中指定要在注入器创建时注入的类:

@Override public void configure() { 
requestStaticInjection(ProcessorFactory.class); ... }

Guice 将注入具有 @Inject 注释的类的静态成员。

【讨论】:

  • 仅链接答案应包含您的答案中包含的页面的相关部分,您能否添加一些上下文?
  • 看来是这样实现的,我试试看能不能这样注入。
  • 正如文档中提到的,这实际上是一种不推荐的方式,它确实会产生很多问题。我不得不改变我的注射方式,我把它作为这个问题的另一个答案发布了。这可能会帮助其他有同样问题的人。
【解决方案2】:

实际上,requestStaticInjection 不是推荐的方式。正如this link 解释的(This API is not recommended for general use because it suffers many of the same problems as static factories: it's clumsy to test, it makes dependencies opaque, and it relies on global state.),它在少数情况下会产生很多问题。行为不一致,注入也不是一直成功。

我不得不采取稍微不同的方法:我的情况有点复杂,我的类的实例将由 Hibernate 使用 Class.forName() 创建,这可能是静态注入可能失败的另一种情况.

我必须创建一个 Singleton 工厂,它将在模块创建开始时初始化并绑定到 Guice Injector,这个工厂将保存我需要注入到我的实际类中的实际 bean。它提供了一个静态方法来获取所需的bean。

public Class RequiredBeanFactory {
        private static RequiredBean bean;
        //note this is a package private
        RequiredBeanFactory(RequiredBean bean) {
            this.bean = bean;
        }

        public static RequiredBean getBean() {
            return bean;
        }
    }

在我的模块中,我正在对其进行初始化和绑定。

public class MyModule extends AbstractModule {
    private final RequiredBean bean;

    @Inject
    public MyModule(RequiredBean bean) {
        this.bean = bean;
    }

    protected void configure() {
        RequiredBeanFactory factory = new RequiredBeanFactory(this.bean);
        bind(RequireBeanFactory.class).toInstance(factory);
    }
}

在我的 HibernateCustom 类中,我只使用 RequiredBeanFactory.getBean()

这是一种 hack,可能与 Guice 提到的具有相同的副作用,但它在我的控制范围内并且行为是一致的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-09
    • 1970-01-01
    • 2012-01-26
    • 1970-01-01
    • 2011-01-02
    相关资源
    最近更新 更多