在自定义Wicket类中,与以下内容不同,我使用的是一个应该由Spring注入的服务bean,如SpringBean注释所定义的那样(来自wicket-spring项目)。
public class ReportExportFileModel extends AbstractReadOnlyModel<File> {
@SpringBean(name = "reportService")
ReportService reportService;
ReportDto reportDto;
ReportExportFileModel(ReportDto reportDto) {
this.reportDto = reportDto;
}
@Override
public File getObject() {
try {
return reportService.generatePentahoReport(reportDto);
} catch (ReportGenerationException e) {
// ...
}
}
}
但是,这不起作用:reportService.generatePentahoReport()
因NullPointerException而失败,因为由于某种原因,Spring没有注入bean 。
奇怪的是,我在Wicket页面上使用了完全相同的模型代码作为匿名内部类,并且没有问题。
我该如何解决这个问题?
答案 0 :(得分:16)
wicket依赖注入与实现IComponentInstantiationListener的类一起使用。只要实例化Component,就会调用这些应用程序级侦听器。这是用于依赖注入组件的钩子。
模型类没有这样的机制。任何模型都可以直接实现IModel,因此没有抽象基类可以调用监听器,这与Component不同。
我为注入的模型使用以下基类(Wicket 1.5):
public abstract class InjectedDetachableModel<T> extends LoadableDetachableModel<T> {
public InjectedDetachableModel() {
Injector.get().inject(this);
}
public InjectedDetachableModel(T a_entity) {
super(a_entity);
Injector.get().inject(this);
}
}
修改强>: 1.4和1.5之间的相关差异摘要,摘自Wicket 1.5 migration guide:
@Override
protected void init()
{
// initialize Spring
addComponentInstantiationListener(new SpringComponentInjector(this, applicationContext));
}
和
InjectorHolder.getInjector().inject(Object object)
@Override
protected void init()
{
// initialize Spring
getComponentInstantiationListeners().add(new SpringComponentInjector(this, applicationContext))
}
和
Injector.get().inject(Object object)
答案 1 :(得分:7)
显然,Spring bean不会自动注入其他类而不是Pages 。我也使用我的自定义WebRequestCycle类来运行它。
一个简单的解决方案是使用InjectorHolder.getInjector().inject(this)
手动触发注射。
因此,编写这样的构造函数使模型按预期工作:
ReportExportFileModel(ReportDto reportDto) {
this.reportDto = reportDto;
InjectorHolder.getInjector().inject(this);
}
编辑:啊,在发布此消息之后,我发现了另一个问题with a more accurate explanation正在发生的事情:
@SpringBean仅适用于Component的任何子类。