Как сбросить управляемый компонент Spring

ПРИМЕЧАНИЕ. Эта проблема может быть связана или не связана с Vaadin, в зависимости от того, существует ли «лучшее» решение для «сброса» bean-компонента или нет.

Фоновый сценарий

Я создаю мастер для ввода некоторых значений, которые по завершении отправляются в таблицу (используя Vaadin и надстройку «Мастера для Vaadin»).

Дополнение не предоставляет возможности сбросить мастер (т.е. вернуться к шагу 1) без принудительного вызова текущих шагов (переопределенных) методов onAdvance() и onBack(), которые вернут false на некоторых моих шагах. потому что я использую логику в этих методах на случай, если использование, например, не заполнило все необходимые данные.

Я не могу просто создать новый экземпляр мастера, потому что я использую Spring для управления этим @Component.

Итак, это оставляет мне фактический сброс bean-компонента, чтобы правильно сбросить мастер.

Мой вопрос

Как «сбросить» управляемый компонент Spring (@Component)? Я должен добавить, что этот Bean также имеет некоторые зависимости, внедренные в него.

или... (для народа ваадин):

Есть ли другой способ сбросить настройки этого мастера, кроме создания нового мастера?

Некоторый код

@Component
@Scope("session")
public class MyWizard extends Wizard {

    @Inject
    private MyWizardContainer myWizardContainer;
    @Inject
    private MyService myService;
    @Inject
    private MyWizardStep1 myWizardStep1;
    @Inject
    private MyWizardStep2 myWizardStep2;
    @Inject
    private MyWizardStep3 myWizardStep3;
    @Inject
    private MyMainTableContainer myMainTableContainer;

    final static Logger logger = LoggerFactory.getLogger(MyWizard.class);

    private static final long serialVersionUID = 1L;

    public MyWizard() {
        setupListener();
    }

    public void addSteps() {
        this.addStep(myWizardStep1);
        this.addStep(myWizardStep2);
        this.addStep(myWizardStep3);
        this.mainLayout.setComponentAlignment(this.footer, Alignment.BOTTOM_LEFT);
    }

    private void setupListener() {

        this.addListener(new WizardProgressListener() {

            @Override
            public void wizardCompleted(WizardCompletedEvent event) {
                endWizard("Wizard Finished Successfully!");
            }

            @Override
            public void wizardCancelled(WizardCancelledEvent event) {
                endWizard("Wizard Cancelled!");
            }

            @Override
            public void stepSetChanged(WizardStepSetChangedEvent event) {
                // TODO Auto-generated method stub
            }

            @Override
            public void activeStepChanged(WizardStepActivationEvent event) {
                // TODO Auto-generated method stub
            }
        });
    }

    private void resetWizard() {
        myWizardContainer.removeAll(); //here I'm simply resetting all data that the user generated thus far in the wizard
        this.activateStep(myWizardStep1); //this will not work, as some steps will not always return true on onBack() and/or onAdvance()
    }

    private void endWizard(String message) {
        resetWizard();
        this.setVisible(false);
        Notification.show(message);
    }
}

person Roger    schedule 07.01.2014    source источник


Ответы (1)


SpringVaadinIntegration, который вы, вероятно, используете, не требует, чтобы все элементы были @Components, только пользовательский интерфейс должен быть аннотирован.

Ваш мастер и его шаги не должны быть компонентами в этом случае, если вам действительно нужно внедрить в них зависимости, вы можете использовать аннотацию @Configurable, которая позволяет вводить зависимости в классы, не управляемые Spring (некоторые дополнительные настройки необходимы, чтобы заставить его работать) . Просто создайте мастер и шаги как новые объекты, когда они вам понадобятся.

person dzezzz    schedule 07.01.2014
comment
Ваше предложение звучит разумно, и вы правы в своем предположении, что я использую SVI. У меня было ощущение, что я делаю что-то не так, и я не знал об аннотации @Configuration. Я попробую это первым делом завтра и вернусь с результатами! Спасибо! - person Roger; 08.01.2014
comment
Я не понимаю, как настроить @Configuration, чтобы Wizard (POJO) принимал @Inject. Я создал простой пример после прочтения документации Spring для @Configuration, используя @Configuration аннотированный класс AppConfig, который создает new Wizard и простой @Component, который Wizard должен иметь возможность использовать (MyService). Однако в документации ничего не упоминается (что я мог найти) о фактическом внедрении bean-компонента (например, MyService) в POJO-ized Wizard. Когда я пытаюсь, я получаю BeanCreationException. Любые подсказки? - person Roger; 08.01.2014
comment
Большое спасибо за вашу помощь, @dzezzz. Однако хлопоты с использованием AspectJ LTW наконец достали меня. Я не мог заставить его играть с Tomcat. Я верю, что ваше решение может сработать, но мы все еще создаем здесь новый мастер, что делает ответ недействительным, и я не могу его принять. Я решил это аналогичным образом, используя @Scope (прототип) в компоненте Wizard и создав новый Wizard, получив объект Wizard из ApplicationContext. Работает как часы. - person Roger; 09.01.2014