Как правильно использовать ExtensionManager и ExtensionHandler, реализующие классы

#java #spring #broadleaf-commerce

#java #spring #broadleaf-коммерция

Вопрос:

  • Broadleaf использует класс ExtensionManager, реализующий InvocationHandler, для расширения функциональных возможностей (через extensionHandlers) и предоставления каких-либо перехватов (например, сначала попробуйте вызов метода ExtensionManager, и если он не обрабатывается, продолжайте нормально), чтобы изменить поведение классов фреймворка без необходимости их расширения и переопределения методов.

  • Мой первый вопрос: какова мотивация этого подхода, если полиморфизм — это целая парадигма, решающая эту проблему? Каковы преимущества?

  • Во-вторых, если я собираюсь использовать его, как правильно это сделать?

  • Например, я попытался расширить методы AbstractInventoryServiceExtensionHandler и переопределить методы (потому что broadleaf 5.0.1 содержит ошибку в InventoryServiceImpl относительно CHECK_QUANTITY InventoryType в методе retrieveQuantitiesAvailable)

  • Затем я расширил InventoryServiceExtensionManager и попытался зарегистрировать этот extensionHandler с переопределенными методами

  • В момент вызова рассматриваемого метода я получил сообщение об ошибке при вызове метода getProxy(), вызванного в ExtensionManager, в котором говорится, что ClassCastException из Proxy.toString() и список обработчиков пуст, хотя я зарегистрировал обработчик?

  • В конце я просто расширил InventoryServiceImpl и исправил ошибку, которая решила мою проблему, но оставила меня с вышеупомянутыми вопросами.

Ответ №1:

Мой первый вопрос: какова мотивация этого подхода, если полиморфизм — это целая парадигма, решающая эту проблему? Каковы преимущества?

Это позволяет нескольким «модулям» (плагинам) в экосистеме Broadleaf изменять поведение во время выполнения (путем регистрации), а не во время компиляции. Это более слабая связь. Кроме того, такие вещи, как полиморфизм, ломаются, если вам нужно изменить одно и то же место в коде несколько раз (в этот момент вам понадобится множественное наследование)

Во-вторых, если я собираюсь использовать его, как правильно это сделать?

Исходя из того, что вы сказали, вам никогда не нужно расширять диспетчер расширений, а вместо этого только обработчик расширений. Затем обработчик должен зарегистрироваться в диспетчере. Вот пример:

 @Component
public class MyInventoryExtensionHandler extends AbstractInventoryServiceExtensionHandler {

    @Resource
    protected InventoryServiceExtensionManager extensionManager;

    @PostConstruct
    public void init() {
         extensionManager.registerHandler(this);
    }

    @Override
    public ExtensionResultStatusType retrieveQuantitiesAvailable(Collection<Sku> skus, Map<String, Object> context, ExtensionResultHolder<Map<Sku, Integer>> result) {
        ...
        ...
        return ExtensionResultStatusType.HANDLED;
    }
}
  

Например, я попытался расширить методы AbstractInventoryServiceExtensionHandler и переопределить методы (потому что broadleaf 5.0.1 содержит ошибку в InventoryServiceImpl относительно CHECK_QUANTITY InventoryType в методе retrieveQuantitiesAvailable)

В чем была ошибка?

Комментарии:

1. Спасибо за ваш ответ. Я начинаю с демонстрационного сайта версии 5.0.1 и обнаруживаю несколько ошибок. Сначала это — если это тип инвентаризации контрольного количества, карта инвентаризации sku в этом методе не заполняется доступными количествами, если оно не равно null. В результате получается 0 доступного количества, и вы не можете добавить товар в корзину, потому что 0 < 1.

2. Во-вторых, сегодня у меня возникли проблемы с добавлением новой страницы в admin. После часа отладки я понимаю, что у PageImpl больше нет проверяемого поля (в версии 4.0 у него есть), и он терпит неудачу в AuditableListener, где он пытается получить это поле с помощью отражения и без проверки вызывает для него методы, что приводит к исключению NullPointerException.

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

4. Похоже, это не ошибка; если тип инвентаря — «проверить количество», и у вас не установлено количество… похоже, это должно быть равно нулю.

5. Если вы не хотите фактически проверять количество, измените тип инвентаря на null или ALWAYS_AVAILABLE .