简体   繁体   English

在非guice类中注入guice管理的依赖项

[英]Inject guice managed dependency in a non guice class

I have a class ( CustomConnectionProvider ) which will be instantiated by a third party library (hibernate) using class.forName().newInstance() . 我有一个类( CustomConnectionProvider ),它将使用class.forName().newInstance()由第三方库(hibernate)实例化。 I need to inject a guice managed dependency say MyDatabaseFactory which will provide data sources for multi-tenancy. 我需要注入一个guice托管依赖项,例如MyDatabaseFactory ,它将为多租户提供数据源。

I can not directly @Inject the MyDatabaseFactory, because CustomConnectionProvider is not a managed bean. 我无法直接@Inject MyDatabaseFactory,因为CustomConnectionProvider不是托管bean。 And I have no control over how it is being created. 我无法控制它是如何被创造出来的。

I just started with Guice as part of a Play application. 我刚开始使用Guice作为Play应用程序的一部分。 Any examples or ideas would be appreciated, I am looking for a solution like ServiceLocator . 任何示例或想法将不胜感激,我正在寻找像ServiceLocator这样的解决方案。

Fixed for specific case Luckily, Play.application() provides a static method to get the injector and I'm using it to get the instance of my Factory. 针对特定情况修复幸运的是, Play.application()提供了一个静态方法来获取injector ,我正在使用它来获取我的工厂实例。 I still want to know if I have to fix it without play. 我仍然想知道我是否必须在没有游戏的情况下修复它。

Update for Play 2.5 Play.application() is deprecated in 2.5. Play 2.5的更新 Play.application()在2.5中已弃用。 We need to use static injection as robert suggested. 我们需要像罗伯特建议的那样使用静态注射。

You can use static injection. 您可以使用静态注入。 See https://github.com/google/guice/wiki/Injections 请参阅https://github.com/google/guice/wiki/Injections

It makes it possible for objects to partially participate in dependency injection, by gaining access to injected types without being injected themselves. 通过获取对注入类型的访问而不自己注入,它使对象可以部分地参与依赖注入。 Use 使用

requestStaticInjection() 

in a module to specify classes to be injected at injector-creation time: 在模块中指定要在注入器创建时注入的类:

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

Guice will inject class's static members that have the @Inject annotation. Guice将注入具有@Inject注释的类的静态成员。

Actually, the requestStaticInjection is not a recommended way. 实际上, requestStaticInjection不是推荐的方式。 As the this link explains ( 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. ), it creates many problems under few circumstances. 正如这个链接所解释的那样( 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. ),它会产生很多问题。几点情况。 The behaviour is not consistent and the injection is not successful all the times. 行为不一致,注射一直不成功。

I had to take slightly different approach: My case is little complicated, the instance of my class will be created by Hibernate using Class.forName() , this may be yet another case where static injection may fail. 我不得不采取稍微不同的方法:我的情况有点复杂,我的类的实例将由Hibernate使用Class.forName()创建,这可能是静态注入可能失败的另一种情况。

I had to create a Singleton factory which will be initialized and bind to Guice Injector at the start of the module creation, this factory will hold the actual bean which I need to inject into my actual class. 我必须创建一个Singleton工厂,它将在模块创建开始时初始化并绑定到Guice Injector,这个工厂将保存我需要注入到我的实际类中的实际bean。 It provides a static method to get the required 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;
        }
    }

In my Module, I am initializing it and binding. 在我的模块中,我正在初始化它并绑定。

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

In my HibernateCustom class, I just use RequiredBeanFactory.getBean() . 在我的HibernateCustom类中,我只使用RequiredBeanFactory.getBean()

This is kind of a hack, may have the same side effects as Guice mentioned, but it is in my control and the behaviour is consistent. 这是一种黑客,可能与Guice提到的副作用相同,但它在我的控制下并且行为是一致的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM