2

我正在尝试将 Guice 集成到 JSF 1.2 (Sun RI) 应用程序中,并且我希望能够对我的托管 bean 执行以下操作:

  1. @Inject使用 Guice注解注入依赖项,然后
  2. @PostConstruct使用注解执行初始化

我的问题是在处理注释@PostConstruct之前总是调用该方法。@Inject有谁知道这个问题的解决方案?

托管bean:

public final class Foo {

    @Inject private BazService bazService;
    private Baz baz;

    @PostConstruct
    public void init() {
        bar = bazService.loadBaz();
    }

    public void setBazService(BazService bazService) {
        this.bazService = bazService;
    }
}

托管 bean 声明:

<managed-bean>
  <managed-bean-name>foo</managed-bean-name>
  <managed-bean-class>bean.Foo</managed-bean-class>
  <managed-bean-scope>request</managed-bean-scope>
  <managed-property>
    <property-name>id</property-name>
    <value>#{param.id}</value>
  </managed-property>
</managed-bean>

Guice 绑定:

public final class MyGuiceModule extends AbstractModule {

    @Override
    protected void configure() {
        bind(BazService.class).to(DummyBazService.class).in(Scopes.SINGLETON);
    }
}

我尝试了以下方法:

如果这似乎是处理事情的错误方式,我很乐意考虑其他选择......感谢任何帮助。


编辑

我使用的是 Guice 1.0。我现在已经升级到 Guice 2.0,但问题仍然存在。我发现了一些似乎与我的问题有关的讨论......但我不明白如何使用这些信息:(

4

3 回答 3

1

经过大量阅读后,我得出结论,@PostConstruct如果您使用 JSF 和 Guice,可能最好避免使用。

在您给出的示例中,您可以注入Baz

public final class Foo {

    @Inject private Baz baz;
}

如果 Baz 不能由 Guice 创建,但必须由创建BazService,则可以使用提供程序方法:

public final class MyGuiceModule extends AbstractModule {

    @Override
    protected void configure() {
        bind(BazService.class).to(DummyBazService.class).in(Scopes.SINGLETON);
    }

    @Provides
    Baz provideBaz(BazService bazService) {
        return bazService.loadBaz();
    }
}
于 2009-05-21T20:47:32.307 回答
1

不幸的是,我没有给你答案,但我会说这个......

让对象注入自己看起来可能会起作用 - 您不一定需要使用超类:

public final class Foo {

  @Inject
  private BazService bazService;
  private Baz baz;

  @PostConstruct
  public void init() {
    InjectorFinder.getInjector().injectMembers(this);
    baz = bazService.loadBaz();
  }

  public void setBazService(BazService bazService) {
    this.bazService = bazService;
  }

}

我也认为没有理由保留对注入器的引用,因此请考虑一个实用程序类:

public class InjectorFinder {
  public static Injector getInjector() {
    FacesContext facesContext = FacesContext
        .getCurrentInstance();
    ExternalContext extContext = facesContext
        .getExternalContext();
    Map<String, Object> applicationMap = extContext
        .getApplicationMap();
    return (Injector) applicationMap.get(Injector.class
        .getName());
  }
}

@PostConstruct 和序列化会发生什么吗?这是我没有考虑太多的事情,但它可能会影响会话 bean。


这看起来不像是一种合理的技术。如果我正确阅读了代码,则每次解析对象时都会注入依赖项。


我怀疑这个补丁存在我提到的问题(不同的解析器,相同的作者,无论如何)。除了错误之外,尝试同时使用两种不同的 JSF 实现(Sun 和 Apache)是行不通的。


我已经在野外看到了几个 Guice/JSF 项目(guicefjsf-sugar;也许还有更多?)但还没有尝试过,所以我不知道它们是否会帮助你,甚至不知道它们有多稳定。

无论你做什么,关注Web Beans (这里是概述)可能是一个想法,因为这可能会影响 JSF 中未来的 bean 处理功能(如果我正确理解 Guice 在堆栈中的位置,你可以使用它来实现Web豆子——我不建议你这样做)。

于 2009-05-21T12:47:26.207 回答
0

这个答案似乎对如何解决这个问题有一个很好的解决方案。具体来说,它建议在 init() 方法上使用 @Inject 注释,保证在调用构造函数后调用。请注意,如果您使用属性注入,它可能不起作用。

于 2011-11-01T16:13:22.147 回答