Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
461 views
in Technique[技术] by (71.8m points)

java - How can I get a Spring bean injected in my custom Wicket model class?

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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):

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);
    }
}

Edit: Summary of relevant differences between 1.4 and 1.5, taken from Wicket 1.5 migration guide:

Wicket 1.4

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

and

InjectorHolder.getInjector().inject(Object object)

Wicket 1.5:

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

and

Injector.get().inject(Object object)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...