有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何在自定义Wicket模型类中注入Springbean?

在一个定制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) 个答案

  1. # 1 楼答案

    wicket依赖项注入与实现IComponentInstanceListener的类一起工作。每当实例化组件时,就会调用这些应用程序级侦听器。这是用于组件依赖项注入的钩子

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

    我为我的注入模型(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)
    
  2. # 2 楼答案

    显然,Spring Bean不会自动注入到Pages之外的类中。我的自定义WebRequestCycle类也实现了这一点

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

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

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

    编辑:啊,在发布这篇文章之后,我发现了另一个关于发生了什么的问题with a more accurate explanation

    @SpringBean works only in any subclass of Component.