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
すべての Bean をスキャンしHandlerIn
、リゾルバーの mup に追加します。それをするのは間違っていると思います:
unpHandlersResolver.setHandler(smevMessageType, (UnpHandler) bean);
しかし、find Bean をリゾルバーに追加する方法がわかりません。この実装の前に、次のような@Postconstruct
方法で豆を見つけました。resolver
context.getBeansWithAnnotation(HandlerIn.class);
しかし、このソリューションでは私が持っていてcontext
、resolver
悪いと思います。
私が望むものを適切に実装する方法を教えてください。要するに、さまざまな動作を実装する一連のクラスが必要です。そしてそれらを制御するクラス。クラスにパラメーターを与えて、彼が正しい戦略を選択し、それを私に与えるようにします。このような:
Handler handler = handlersResolver.getHandler(messageType);
Result result = handler.somthing(param);