Передача Closure в Spring bean-компонент с использованием определений bean-компонентов grails

Возможно ли определение bean-компонента, включающее замыкание? Время от времени мне хотелось иметь почти идентичные экземпляры класса, но отличаться в некотором небольшом поведении - больше, чем данные, поэтому просто передать разные поля в моих определениях bean-компонентов недостаточно.

Пример определения желаемого компонента:

beans {
    myCustomWidget1(Widget) {
        myClosure = { w -> return w.doThis() }
    }

    myCustomWidget2(Widget) {
        myClosure = { w -> return w.doThat() }
    }
}

Пример класса:

class Widget {
    Closure myClosure

    ...
}

Проблема в том, что Anonymous (Inner) Beans уже использует синтаксис закрытия, и эти анонимные bean-компоненты оцениваются при запуске приложения вместо установки поля Closure класса. Это, очевидно, приводит к исключению во время выполнения.

Я преодолел это ранее, создав небольшие вспомогательные классы, которые я вставляю в свой компонент, при этом изменения поведения записываются как методы с тем же именем. Я считаю, что это правильный подход, но я надеялся на более лаконичный, «заводной» способ.

Мы используем Grails 2.4.2, но я считаю, что BeanBuilder будет рассматривать мое желаемое закрытие как анонимный компонент, независимо от версии grails / groovy.


person tylerwal    schedule 26.10.2017    source источник


Ответы (1)


Один из способов сделать это вместо этого ...

beans {
    myCustomWidget1(Widget) {
        myClosure = { w -> return w.doThis() }
    }

    myCustomWidget2(Widget) {
        myClosure = { w -> return w.doThat() }
    }
}

Попробуй это...

beans {
    myCustomWidget1(Widget) { bean ->
        bean.setPropertyValue 'myClosure', { w -> return w.doThis() }
    }

    myCustomWidget2(Widget) { bean ->
        bean.setPropertyValue 'myClosure', { w -> return w.doThat() }
    }
}
person Jeff Scott Brown    schedule 26.10.2017