如何在我的自定义Wicket模型类中注入Spring bean?

在一个自定义的Wicket类中,与以下内容不同,我使用的是一个应该由Spring注入的服务bean,如SpringBean注释(来自wicket-spring项目)所定义的。

public class ReportExportFileModel extends AbstractReadOnlyModel { @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页面上使用完全相同的模型代码作为匿名内部类,并且没有问题。

我怎样才能解决这个问题?

wicketdependency injection与实现IComponentInstantiationListener的类一起使用。 只要实例化Component,就会调用这些应用程序级侦听器。 这是用于dependency injection组件的钩子。

模型类没有这样的机制。 任何模型都可以直接实现IModel,因此与Component不同,没有可以调用侦听器的抽象基类。

我为我的注入模型使用以下基类(Wicket 1.5):

 public abstract class InjectedDetachableModel extends LoadableDetachableModel { 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迁移指南 :

Wicket 1.4

 @Override protected void init() { // initialize Spring addComponentInstantiationListener(new SpringComponentInjector(this, applicationContext)); } 

 InjectorHolder.getInjector().inject(Object object) 

Wicket 1.5:

 @Override protected void init() { // initialize Spring getComponentInstantiationListeners().add(new SpringComponentInjector(this, applicationContext)) } 

 Injector.get().inject(Object object) 

显然,Spring bean不会自动注入除Pages之外的其他类 。 我也使用自定义的WebRequestCycle类来运行它。

一个简单的解决方案是使用InjectorHolder.getInjector().inject(this)手动触发InjectorHolder.getInjector().inject(this)

因此,像这样编写构造函数使模型按预期工作:

 ReportExportFileModel(ReportDto reportDto) { this.reportDto = reportDto; InjectorHolder.getInjector().inject(this); } 

编辑 :嗯,在发布这个之后,我发现了另一个SO问题,更准确地解释了发生了什么:

@SpringBean仅适用于Component的任何子类。