美文网首页
总线模式

总线模式

作者: hemiao3000 | 来源:发表于2022-02-03 15:00 被阅读0次

    ::: tip
    『总线模式』并非 23 种设计模式之一。它更像是一种编程技巧。
    :::

    @Slf4j
    @Component
    @SuppressWarnings("UnstableApiUsage")
    public class Bus implements ApplicationListener<ApplicationStartedEvent> {
    
        private final ApplicationContext context;
    
        /**
         * 两张注册表, 
         * - handlerMap 的 value 是业务类对象, 
         * - methodMap 的 value 是业务类的方法对象,
         * - 二者的 key 都是业务方法的参数类对象
         */
        private final Map<Class<?>, Object> handlerMap = new HashMap<>();
        private final Map<Class<?>, Method> methodMap = new HashMap<>();
    
        public Bus(ApplicationContext context) {
            this.context = context;
        }
    
        /**
         * 注册
         */
        public void register(Class<?> argumentType, Object target, Method method) {
            handlerMap.put(argumentType, target);
            methodMap.put(argumentType, method);
        }
    
        /**
         * 执行方法
         */
        public void post(Object argument) {
            Class<?> argumentType = argument.getClass();
            Object target = handlerMap.get(argumentType);   // 获取已注册的业务层 handler 对象
            Method method = methodMap.get(argumentType);    // 获取已注册的业务方法 handle 对象
            ReflectionUtils.invokeMethod(method, target, argument);     // 调用对应的业务方法
        }
    
        @Override
        public void onApplicationEvent(ApplicationStartedEvent event) {
            log.info("Spring IoC 已初始化完成");
            String[] names = context.getBeanNamesForAnnotation(Service.class);
            for (String name : names) {
                log.info(name);
                Object serviceBean = context.getBean(name);
    
                // 找到当前 @Service 类下的所有方法
                Method[] methods = ReflectionUtils.getAllDeclaredMethods(serviceBean.getClass());
                for (Method method : methods) {
                    // 筛选出当前 @Service 类下带有 @Subscribe 注解的方法
                    if (!ObjectUtils.isEmpty(method.getAnnotation(Subscribe.class))){
                        Class<?> parameterType = method.getParameterTypes()[0];
                        // 注册
                        register(parameterType, serviceBean, method);
                    }
                }
            }
        }
    }
    

    相关文章

      网友评论

          本文标题:总线模式

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