Лучший способ для реализации стратегии проектирования шаблонов весной - PullRequest
0 голосов
/ 11 октября 2018

Я хочу реализовать strategy design pattern в приложении весенней загрузки.Я создаю BeanPostProcessor для конструкции strategy resolver:

@Component
public class HandlerInAnnotationBeanPostProcessor implements BeanPostProcessor {

    private final UnpHandlersResolver unpHandlersResolver;

    public HandlerInAnnotationBeanPostProcessor(UnpHandlersResolver unpHandlersResolver) {
        this.unpHandlersResolver = unpHandlersResolver;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        Annotation[] annotations = bean.getClass().getAnnotations();
        for (Annotation annotation : annotations) {
            if (annotation instanceof HandlerIn) {

                if (bean.getClass() != UnpHandler.class)
                    throw new RuntimeException("Not UnpHandler bean annotated by HandlerIn");

                SmevMessageType[] type = ((HandlerIn) annotation).type();
                for (SmevMessageType smevMessageType : type) {
                    unpHandlersResolver.setHandler(smevMessageType, (UnpHandler) bean);
                }
            }
        }
        return bean;
    }
}

И создаю резольвер:

@Slf4j
@Component
public class UnpHandlersResolverImpl implements UnpHandlersResolver {

    private Map<SmevMessageType, UnpHandler> map = new HashMap<>();

    @Override
    public void setHandler(SmevMessageType messageType, UnpHandler unpHandler) {
        map.put(messageType, unpHandler);
    }

    @Override
    public UnpHandler getUnpHandler(SmevMessageType type) {
        UnpHandler sendRequestHandler = map.get(type);
        if (sendRequestHandler == null)
            throw new IllegalArgumentException("Invalid SendRequestHandler type: " + type);
        return sendRequestHandler;
    }
}

Мой BeanPostProcessor сканирует все компоненты с аннотацией HandlerIn и добавляет их в резольверMUP.Я думаю, что это неправильно:

unpHandlersResolver.setHandler(smevMessageType, (UnpHandler) bean);

Но я не понимаю, как я могу добавить find bean в resolver.До этой реализации я использую bean-компоненты в @Postconstruct методе resolver, например:

context.getBeansWithAnnotation(HandlerIn.class);

Но в этом решении у меня есть context в resolver, и я думаю, что это плохо.

Подскажите, как правильно реализовать то, что я хочу?Короче говоря, я хочу иметь набор классов, которые реализуют различное поведение.И класс, который их контролирует.Дайте классу параметр, чтобы он выбрал правильную стратегию и дал ее мне.Как это:

Handler handler = handlersResolver.getHandler(messageType);
Result result = handler.somthing(param);

1 Ответ

0 голосов
/ 11 октября 2018

Я попытаюсь сделать простой пример.

Interface Greeting {

void sayHello();

String getSupportedLanguage();

}

Тогда у вас есть X реализаций, и вы можете перебирать их в конструкторе "resolver" для построения карты.(Хотя я видел это в коде как прокси или декоратор, т.е. GreetingProxy или GreetingDecorator)

@Service
public GreetingResolver {

  private Map<String, Greeting> languageToGreetingMap = new HashMap<>();

  @Autowired
  public GreetingResolver(List<Greeting> greetings) {
    for (Greeting greeting : greetings) {
      languageToGreetingMap.put(greeting.getSupportedLanguage(), greeting);
    }
  }

  public void sayGreetingForLanguage(String language) {
    languageToGreetingMap.get(language).sayHello();
  }

}

Это базовый пример того, как можно создать шаблон стратегии в Spring.Каждая реализация интерфейса «Приветствие» знает только о себе и о том, что она может поддерживать.Затем мы автоматически связываем все реализации в списке и перебираем, чтобы создать карту один раз , а затем во время выполнения извлекать и использовать только соответствующую запись из карты.

Примечание: это было напечатано "свободной рукой "непосредственно на веб-странице, поэтому, пожалуйста, прости любые опечатки в коде.

...