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

时间:2011-11-16 16:43:01

标签: java spring dependency-injection 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页面上使用了完全相同的模型代码作为匿名内部类,并且没有问题。

我该如何解决这个问题?

2 个答案:

答案 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

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)

答案 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的任何子类。