如何在我的自定义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的任何子类。