4

我已经成功地使用 Guice 将提供程序注入到现有 java web 应用程序的 servlet 部分,但是,我无法通过应用程序的业务层(非 servlet java 类)访问注入器。

我已经阅读了 Injecting the Injector,但对我来说,这似乎更像是一种 hack,并且在包括 Guice 文档在内的几个地方,它说不要做太多。

我想我的问题是,我在哪里引导一个 java web 应用程序,以便非 servlet/filter 类可以访问在我用来扩展 GuiceServletContextListener 的类中创建的注入器?有没有办法在不注入注入器的情况下使这些类可注入?

谢谢,如果您需要任何澄清,请告诉我。

编辑:

我正在尝试使用一个简单的记录器来做到这一点,到目前为止,在我的 servlet 中,我调用:

@Inject
   private static org.slf4j.Logger log;

注入在 MyLoggerModule 中设置如下(在使用 ServletModule 的 createInjector 调用中):

@Override
   public void configure() {
       bindListener(Matchers.any(), new SLF4JTypeListener()); // I
       built my own SLF4JTypeListener...
   }

这一切都在 servlet 中完美运行,但是当由不是 servlet 或过滤器的类调用时,字段注入不起作用。

4

2 回答 2

1

Guice 不会拦截对新对象的调用,因此如果您的业务层尚未使用 Guice 创建需要注入的对象,则需要对其进行修改。

注入仅在 Guice在注入期间处理时才有效。因此,从您制作的基础注入器开始,@Inject您所请求的实例所需的任何标记都将由 Guice 尽其所能提供,反过来,在这些实例的实例化过程中,@Inject将填写进一步​​的注释由提供者和绑定直到没有新的需要被实例化。但是从那时起,您将不会将字段注入在 Guice 注入之外创建的 servlet 中,可能是通过调用new某处,这可能是您的对象工厂正在做的事情。

您需要更改您的对象工厂以使用提供者而不是新的。如果您可以编辑这些内容,则不会太难,因为 Guice 可以为您提供绑定的默认提供程序。

因此,您的业务层可以感知 Guice 的一种方法是让创建 servlet 的任何东西首先创建一个 Injector,然后请求由该注入器创建 servlet。如果这意味着您将拥有多个注射器,那么是的,这将是一个问题,但仅适用于您希望成为单例的对象。因此,您可以为单例注入器创建一个工厂模式类,或者您可以找到创建 servlet 本身的这些类(此处键入 bar)的位置(在 foo 中),然后从那里的注入器开始(在 foo 中)使用一个Guice 注入器创建这些(bar 类型)类并修改它们(bar 类型)以请求它们将使用的 servlet 的提供者,而不是调用新的 servlet。

现在我考虑到这一点,如果对于 10 到 20 种 servlet 类型只发生一次或两次,这可能很简单,或者如果有一些框架定义了完全灵活的行为,以便在何时以及为什么更新时,它可能会很复杂。

按照建议,另一种选择是始终避免在字段上使用 @Inject。因此,现在您的 servlet 将org.slf4j.Loggera 作为构造参数。构造函数标记为@Inject,并将参数的值分配给该字段。然后,您不使用注入的任何地方都应该在新调用时因参数数量不正确而中断。通过弄清楚如何获取此处提供的 servlet 或如何将 servlet 的提供者获取到类中来解决这些问题。

于 2011-09-24T23:13:43.513 回答
0

不确定你的意思......如果你将对象注入到你的 servlet/过滤器中,这些对象的依赖项也会被 Guice 注入,依此类推。

你如何创建你试图注入这个记录器的类?它们必须由 Guice 创建才能注入,这意味着没有new

于 2011-09-18T03:13:30.100 回答