::: 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);
}
}
}
}
}
网友评论