前言:
当if else的条件少的话,代码可阅读性及逻辑不影响阅读和扩展。一旦if else过多的话会导致逻辑比较混乱,不易扩展并且很容易出错。
实现方案:
1、定义一个@HandlerType注解,一个value属性,其值对应 if 条件的值
2、定义一个接口或者抽象类,抽AbstractHandler,抽象逻辑处理方法handler方法交给具体的业务实现
3、根据自己的业务,定义多个类实现AbstractHandler接口。每个实现类都注册到Spring容器中
4、对每个AbstractHandler的实现类都标注上@HandlerType注解,值为其要处理 if 条件的值
5、定义一个HandlerContext,用来扫描具有 @HandlerType注解的类,并将注解中的value作为key,对应的类作为value,初始化其属性handlerMap
6、通过条件从Spring容器中获取一个对应的AbstractHandler实例
7、执行实例对应的handler方法
举个例子:
有这样一个需求,需要监听一个Kafka topic下的不同类型的消息,类型从监听到的message中去区分,不同的类型的消息,处理逻辑也不同。代码:
1、定义自定义注解
/** * Kafka监听消息的topic动作编号 * * @author yangyongjie * @date 2019/11/7 * @desc */ @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface ListenerAction { /** * topic动作编号 * * @return */ int value(); }
2、定义抽象处理器
/** * 抽象的Kafka消息处理器 * * @author yangyongjie * @date 2019/11/7 * @desc */ public abstract class AbstractListenerHandler { /** * 消息处理 * * @param data */ public abstract void handler(String data); }
3、具体实现处理器,多个,这里只列一个
4、在具体的处理器上标注@HandlerType注解,表示其要处理的逻辑分支,这里表示只处理action为2001的消息
/** * PartnerId 变更消息监听处理器 * @author yangyongjie * @date 2019/11/7 * @desc */ @ListenerAction(2001) @Component public class PartnerIdListenerHandler extends AbstractListenerHandler { @Override public void handler(String data) { // dosomething } }
5、扫描具有 @HandlerType注解的类,并将注解中的value作为key,对应的类作为value,初始化其属性handlerMap
** * 消息处理器的处理器 * 1.扫描包中标有@ListenerAction注解的类 * 2.将注解中的动作编号值作为key,对应的类作为value,初始化handlerMap * * @author yangyongjie * @date 2019/11/7 * @desc */ @Component public class ListenerHandlerContext implements ApplicationContextAware { private ApplicationContext applicationContext; /** * 保存处理器的map,key为action,value为处理器Class */ private static final Map<Integer, Class> HANDLER_MAP = new HashMap<>(4); public AbstractListenerHandler getListenerHandlerInstance(Integer action) throws BssException { Class<?> clazz = HANDLER_MAP.get(action); if (clazz == null) { throw new BssException(ResponseEnum.ERROR_HANDLER_NOT_FOUND.getCode(), ResponseEnum.ERROR_HANDLER_NOT_FOUND.getMsg()); } return (AbstractListenerHandler) applicationContext.getBean(clazz); } /** * 扫描@ListenerAction,初始化ListenerHandlerContext,将其注册到Spring容器中 * * @param applicationContext * @throws BeansException */ @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; // 遍历所有带有@ListenerAction注解的类 Map<String, Object> listenerHandlerBeans = applicationContext.getBeansWithAnnotation(ListenerAction.class); if (MapUtils.isNotEmpty(listenerHandlerBeans)) { for (Object listenerHandlerBean : listenerHandlerBeans.values()) { Integer action = listenerHandlerBean.getClass().getAnnotation(ListenerAction.class).value(); HANDLER_MAP.put(action, listenerHandlerBean.getClass()); } } } }
6、获取处理器,执行逻辑分支
@Autowired private ListenerHandlerContext listenerHandlerContext; ... // 获取消息监听处理器 AbstractListenerHandler listenerHandler = listenerHandlerContext.getListenerHandlerInstance(action); // kafka消息逻辑处理 listenerHandler.handler(data);
END.