总线模式

2022-02-03  本文已影响0人  hemiao3000

::: 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);
                }
            }
        }
    }
}
上一篇下一篇

猜你喜欢

热点阅读