【问题标题】:Best way for imlement Strategy design pattern in Spring在 Spring 中实现策略设计模式的最佳方法
【发布时间】:2018-10-11 09:36:24
【问题描述】:

我想在 Spring Boot 应用程序中实现 strategy design pattern。我为构造strategy resolver 创建BeanPostProcessor

@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 的bean 并添加到解析器的mup 中。我认为这样做是错误的:

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

但我不明白如何将查找 bean 添加到解析器。在此实现之前,我在resolver@Postconstruct 方法中找到了bean,例如:

context.getBeansWithAnnotation(HandlerIn.class);

但在这个解决方案中,我在resolver 中有context,我认为这很糟糕。

告诉我如何正确实现我想要的?简而言之,我想要一组实现不同行为的类。以及控制它们的类。给班级一个参数,以便他选择正确的策略并将其提供给我。像这样:

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

【问题讨论】:

标签: java spring design-patterns strategy-pattern post-processor


【解决方案1】:

我将尝试做一个简单的例子。

Interface Greeting {

void sayHello();

String getSupportedLanguage();

}

然后你有X个实现,你可以在你的“解析器”的构造函数中循环它们来构建地图。 (我在代码中看到过这称为代理或装饰器,即 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 中执行策略模式的基本示例。 “Greeting”的每个接口实现只知道它自己以及它可以支持什么。然后,我们将所有实现自动装配到一个列表中并循环创建地图一次,然后在运行时仅检索和使用地图中的相关条目。

注意:这是直接在网页中输入的“徒手”,因此请原谅代码中的任何拼写错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-02
    • 1970-01-01
    • 2020-01-19
    • 1970-01-01
    相关资源
    最近更新 更多