美文网首页
自定义注解开发

自定义注解开发

作者: ppamos | 来源:发表于2019-07-18 19:12 被阅读0次

    需求

    设想现有这样的需求,程序需要接收不同的命令CMD,
    然后根据命令调用不同的处理类Handler。
    很容易就会想到用Map来存储命令和处理类的映射关系。

    由于项目可能是多个成员共同开发,不同成员实现各自负责的命令的处理逻辑。
    因此希望开发成员只关注Handler的实现,不需要主动去Map中注册CMD和Handler的映射。

    • 定义注解类
    @Documented
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Component
    public @interface CmdMapping {
        int value() ;
    }
    
    • 处理器接口类
    public interface ICmdHandler {
        Object handle();
    }
    
    • 处理器实现类
    @CmdMapping(Cmd.REGISTER)
    public class RegisterHandler implements ICmdHandler
    {
        @Override public Object handle()
        {
            return "handle register request";
        }
    }
    
    @CmdMapping(Cmd.LOGOUT)
    public class LogoutHandler implements ICmdHandler {
        @Override
        public Object handle() {
            return "handle logout request";
        }
    }
    
    @CmdMapping(Cmd.LOGIN)
    public class LoginHandler implements ICmdHandler {
        @Override
        public Object handle() {
           return  "handle login request";
        }
    }
    
    • 注册处理类
    @Component
    public class HandlerDispatcherServlet implements
            InitializingBean, ApplicationContextAware
    {
    
        private ApplicationContext context;
    
        private Map<Integer, ICmdHandler> handlers = new HashMap<>();
    
        public Object handle(int cmd) {
            Object handle=null;
            try
            {
                handle = handlers.get(cmd).handle();
    
            }catch (RuntimeException e){
    
                return "没有这个命令";
            }
          return handle;
        }
    
        public void afterPropertiesSet() {
    
            String[] beanNames = this.context.getBeanNamesForType(ICmdHandler.class);
    
            System.out.println(Arrays.toString(beanNames));
            for (String beanName : beanNames) {
                Class<?> beanType = this.context.getType(beanName);
    
                if (beanType != null) {
    
                    CmdMapping annotation = AnnotatedElementUtils.findMergedAnnotation(
                            beanType, CmdMapping.class);
    
                    if(annotation != null) {
                        handlers.put(annotation.value().getCode(), (ICmdHandler) context.getBean(beanType));
                    }
                }
            }
    
        }
    
        public void setApplicationContext(ApplicationContext applicationContext)
                throws BeansException
        {
            this.context = applicationContext;
        }
    
    }
    
    • controller类
    @RestController
    public class TestController {
    
        @Autowired
        private HandlerDispatcherServlet handlerDispatcherServlet;
    
        @RequestMapping("/test")
        public Object test(@RequestParam int cmd){
          return  handlerDispatcherServlet.handle(cmd);
        }
    }
    
    • 最终结果
    localhost:8081/test?cmd=1
    handle register request
    
    

    相关文章

      网友评论

          本文标题:自定义注解开发

          本文链接:https://www.haomeiwen.com/subject/nrhrlctx.html