我正在尝试将Guice集成到JSF 1.2(Sun RI)应用程序中,我希望能够对我的托管bean执行以下操作:
@Inject
注释然后@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);
}
}
我尝试了以下内容:
Injector.injectMembers(Object)
(@PostConstruct
未在超类中处理)VariableResolver
(@PostConstruct
在 @Inject
<)之前处理 GuiceResolver
(似乎根本不起作用 - 可能与this issue有关)我很高兴考虑其他选择,如果这似乎是接近事情的错误方式......任何帮助表示赞赏。
我使用的是Guice 1.0。我现在升级到Guice 2.0但问题仍然存在。我找到了some discussion that seems to relate to my issue ...但我不明白如何使用这些信息:(
答案 0 :(得分:1)
不幸的是,我没有给你答案,但我会说这个......
- manually invoking Injector.injectMembers(Object)(@PostConstruct未在超类中处理)
让对象注入自己看起来可能有效 - 你不一定需要使用超类:
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。
- using a custom VariableResolver(@PostConstruct在@Inject之前处理)
这看起来不像是一种声音技术。如果我正确读取代码,每次解析对象时都会注入依赖项。
- using MyFaces' GuiceResolver(似乎根本不起作用 - 可能与this issue有关)
我怀疑这个补丁遇到了我提到的问题(不同的解析器,同一作者,无论如何)。除了错误之外,尝试同时使用两种不同的JSF(Sun和Apache)实现是行不通的。
我在野外看到了几个Guice / JSF项目(guicesf; jsf-sugar;也许还有更多?)但是还没有尝试过,所以我不知道他们是否会有所帮助你甚至是多么稳定。
无论你做什么,关注Web Beans(概述here)可能是一个想法,因为这可能会影响JSF中未来的bean处理功能(如果我理解Guice在正确堆叠,您可以使用它来实现 Web Bean - 而不是我建议您这样做。
答案 1 :(得分:1)
在做了一堆阅读之后,我得出的结论是,如果你使用JSF和Guice,最好避免使用@PostConstruct
。
在您提供的示例中,您可以注入Baz
:
public final class Foo {
@Inject private Baz baz;
}
如果Guiz无法创建Baz,但必须由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();
}
}
答案 2 :(得分:0)
This answer似乎有一个很好的解决方案来解决这个问题。具体来说,它建议在init()方法上使用@Inject注释,保证在调用构造函数后调用它。请注意,如果您正在使用属性注入,它可能无效。