如何将 Spring bean 注入到我的自定义 Wicket 模型类中?
在自定义 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 页面上使用了与匿名内部类完全相同的模型代码,并且那里没有问题。
我该如何解决这个问题?
In a custom Wicket class, not unlike the following, I'm using a service bean which should be injected by Spring, as defined with the SpringBean annotation (from the wicket-spring project).
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) {
// ...
}
}
}
However, this doesn't work: reportService.generatePentahoReport()
fails with NullPointerException, because the bean has not been injected by Spring for some reason.
Curiously, I've used the exact same Model code as anonymous inner class on a Wicket Page, and there was no problem there.
How can I fix this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
wicket 依赖注入与实现 IComponentInstantiationListener 的类一起使用。每当实例化组件时,就会调用这些应用程序级侦听器。这是用于组件依赖注入的钩子。
模型类没有这样的机制。任何模型都可以直接实现 IModel,因此没有可以调用侦听器的抽象基类,这与 Component 不同。
我将以下基类用于我的注入模型 (Wicket 1.5):
编辑:
1.4 和 1.5 之间的相关差异摘要,摘自 Wicket 1.5 迁移指南:
Wicket 1.4
和
检票口 1.5:
和
The wicket dependency-injection works with classes implementing IComponentInstantiationListener. These application-level listeners are called whenever a Component is instantiated. This is the hook used for dependency injection of components.
The model classes do not have such a mechanism in place. Any model can directly implement IModel so there is no abstract base class which can call the listeners, unlike Component.
I use the following base class for my injected models (Wicket 1.5):
Edit:
Summary of relevant differences between 1.4 and 1.5, taken from Wicket 1.5 migration guide:
Wicket 1.4
and
Wicket 1.5:
and
显然,Spring bean 不会自动注入到 Pages 之外的其他类。我也使用自定义的 WebRequestCycle 类来实现此目的。
一种简单的解决方案是使用 InjectorHolder.getInjector().inject(this) 手动触发注入。
因此,像这样编写构造函数可以使模型按预期工作:
编辑:啊,在发布此内容后,我发现了另一个SO问题对正在发生的事情有更准确的解释:
Apparently Spring beans don't get automatically injected to other classes than Pages. I've run to this also with my custom WebRequestCycle class.
One easy solution is to trigger the injection manually using
InjectorHolder.getInjector().inject(this)
.So, writing the constructor like this makes the model work as intended:
Edit: ah, right after posting this, I found another SO question with a more accurate explanation of what's going on: