|
@@ -1,196 +0,0 @@
|
|
|
-package com.chelvc.framework.base.interceptor;
|
|
|
-
|
|
|
-import java.util.Collections;
|
|
|
-import java.util.List;
|
|
|
-import java.util.Map;
|
|
|
-import java.util.Objects;
|
|
|
-import java.util.Set;
|
|
|
-import java.util.stream.Collectors;
|
|
|
-import java.util.stream.Stream;
|
|
|
-
|
|
|
-import com.chelvc.framework.base.annotation.Group;
|
|
|
-import com.chelvc.framework.base.annotation.Groups;
|
|
|
-import com.chelvc.framework.base.context.ApplicationContextHolder;
|
|
|
-import com.chelvc.framework.base.context.GroupEvent;
|
|
|
-import com.chelvc.framework.base.context.SessionContextHolder;
|
|
|
-import com.chelvc.framework.base.context.ThreadContextHolder;
|
|
|
-import com.chelvc.framework.base.group.GroupHandler;
|
|
|
-import com.chelvc.framework.base.group.GroupStore;
|
|
|
-import com.chelvc.framework.common.model.Caps;
|
|
|
-import com.chelvc.framework.common.model.Invoking;
|
|
|
-import com.chelvc.framework.common.util.ObjectUtils;
|
|
|
-import com.chelvc.framework.common.util.StringUtils;
|
|
|
-import com.google.common.collect.Lists;
|
|
|
-import com.google.common.collect.Maps;
|
|
|
-import lombok.RequiredArgsConstructor;
|
|
|
-import lombok.extern.slf4j.Slf4j;
|
|
|
-import org.aspectj.lang.ProceedingJoinPoint;
|
|
|
-import org.aspectj.lang.annotation.Around;
|
|
|
-import org.aspectj.lang.annotation.Aspect;
|
|
|
-import org.springframework.beans.factory.annotation.Autowired;
|
|
|
-import org.springframework.context.ApplicationContext;
|
|
|
-import org.springframework.stereotype.Component;
|
|
|
-
|
|
|
-/**
|
|
|
- * 用户业务分组拦截器
|
|
|
- *
|
|
|
- * @author Woody
|
|
|
- * @date 2024/11/24
|
|
|
- */
|
|
|
-@Slf4j
|
|
|
-@Aspect
|
|
|
-@Component
|
|
|
-@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
|
|
-public class BusinessGroupInterceptor {
|
|
|
- private final GroupStore store;
|
|
|
- private final ApplicationContext applicationContext;
|
|
|
- private final Map<Class<?>, GroupHandler> handlers = Maps.newConcurrentMap();
|
|
|
-
|
|
|
- /**
|
|
|
- * 判断请求是否匹配分组
|
|
|
- *
|
|
|
- * @param group 分组注解实例
|
|
|
- * @return true/false
|
|
|
- */
|
|
|
- private boolean matches(Group group) {
|
|
|
- return StringUtils.notEmpty(group.scene())
|
|
|
- && (ObjectUtils.isEmpty(group.channels()) || SessionContextHolder.isChannel(group.channels()))
|
|
|
- && (ObjectUtils.isEmpty(group.versions()) || SessionContextHolder.isVersion(group.versions()))
|
|
|
- && (ObjectUtils.isEmpty(group.platforms()) || SessionContextHolder.isPlatform(group.platforms()))
|
|
|
- && (ObjectUtils.isEmpty(group.terminals()) || SessionContextHolder.isTerminal(group.terminals()));
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 初始化分组处理器
|
|
|
- *
|
|
|
- * @param type 处理器类型
|
|
|
- * @return 分组处理器实例
|
|
|
- */
|
|
|
- private GroupHandler initializeGroupHandler(Class<? extends GroupHandler> type) {
|
|
|
- GroupHandler handler = ApplicationContextHolder.getBean(this.applicationContext, type, false);
|
|
|
- if (handler == null && (handler = this.handlers.get(type)) == null) {
|
|
|
- handler = this.handlers.computeIfAbsent(type, k -> ObjectUtils.instance(type));
|
|
|
- }
|
|
|
- return handler;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 执行分组逻辑
|
|
|
- *
|
|
|
- * @param target 拦截目标
|
|
|
- * @param groups 分组注解列表
|
|
|
- * @param args 分组执行参数
|
|
|
- */
|
|
|
- private void execute(Object target, List<Group> groups, Object... args) {
|
|
|
- Map<String, Caps> stores = null;
|
|
|
- for (Group group : groups) {
|
|
|
- try {
|
|
|
- GroupHandler handler = this.initializeGroupHandler(group.handler());
|
|
|
- Caps value = handler.execute(group.scene(), args);
|
|
|
- if (value != null && group.storing()) {
|
|
|
- if (stores == null) {
|
|
|
- stores = Maps.newHashMapWithExpectedSize(groups.size());
|
|
|
- }
|
|
|
- stores.put(group.scene(), value);
|
|
|
- } else {
|
|
|
- value = ObjectUtils.ifNull(value, Caps.NONE);
|
|
|
- this.applicationContext.publishEvent(new GroupEvent(target, group.scene(), value));
|
|
|
- }
|
|
|
- } catch (Exception e) {
|
|
|
- log.error("Business group handle failed: {}", group.scene(), e);
|
|
|
- }
|
|
|
- }
|
|
|
- try {
|
|
|
- stores = ObjectUtils.ifEmpty(stores, this.store::set, Collections::emptyMap);
|
|
|
- stores.forEach((scene, group) -> {
|
|
|
- group = ObjectUtils.ifNull(group, Caps.NONE);
|
|
|
- this.applicationContext.publishEvent(new GroupEvent(target, scene, group));
|
|
|
- });
|
|
|
- } catch (Exception e) {
|
|
|
- log.error("Business group handle failed", e);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 执行分组逻辑
|
|
|
- *
|
|
|
- * @param target 拦截目标
|
|
|
- * @param invoking 分组时间点
|
|
|
- * @param groups 分组注解列表
|
|
|
- * @param args 分组执行参数
|
|
|
- */
|
|
|
- private void execute(Object target, Invoking invoking, List<Group> groups, Object... args) {
|
|
|
- List<Group> sync = null, async = null;
|
|
|
- for (Group group : groups) {
|
|
|
- if (group.invoking() == invoking) {
|
|
|
- if (group.async()) {
|
|
|
- if (async == null) {
|
|
|
- async = Lists.newLinkedList();
|
|
|
- }
|
|
|
- async.add(group);
|
|
|
- } else {
|
|
|
- if (sync == null) {
|
|
|
- sync = Lists.newLinkedList();
|
|
|
- }
|
|
|
- sync.add(group);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- if (ObjectUtils.notEmpty(async)) {
|
|
|
- List<Group> copy = async;
|
|
|
- ThreadContextHolder.run(() -> this.execute(target, copy, args));
|
|
|
- }
|
|
|
- if (ObjectUtils.notEmpty(sync)) {
|
|
|
- this.execute(target, sync, args);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 方法调用分组拦截
|
|
|
- *
|
|
|
- * @param point 方法拦截点
|
|
|
- * @param groups 分组注解实例
|
|
|
- * @return 方法调用结果
|
|
|
- * @throws Throwable 方法调用异常
|
|
|
- */
|
|
|
- @Around("@annotation(groups)")
|
|
|
- public Object intercept(ProceedingJoinPoint point, Groups groups) throws Throwable {
|
|
|
- if (Objects.isNull(SessionContextHolder.getId())) {
|
|
|
- return point.proceed(point.getArgs());
|
|
|
- }
|
|
|
-
|
|
|
- // 获取匹配的分组注解列表
|
|
|
- List<Group> matches = Stream.of(groups.value()).filter(this::matches)
|
|
|
- .collect(Collectors.toCollection(Lists::newLinkedList));
|
|
|
- if (ObjectUtils.isEmpty(matches)) {
|
|
|
- return point.proceed(point.getArgs());
|
|
|
- }
|
|
|
-
|
|
|
- // 获取已存储分组结果
|
|
|
- Object target = point.getTarget();
|
|
|
- try {
|
|
|
- Set<String> scenes = matches.stream().filter(Group::storing).map(Group::scene).collect(Collectors.toSet());
|
|
|
- Map<String, Caps> stores = ObjectUtils.ifEmpty(scenes, this.store::get, Collections::emptyMap);
|
|
|
- stores.forEach((scene, group) -> {
|
|
|
- if (group != null) {
|
|
|
- matches.removeIf(annotation -> Objects.equals(annotation.scene(), scene));
|
|
|
- this.applicationContext.publishEvent(new GroupEvent(target, scene, group));
|
|
|
- }
|
|
|
- });
|
|
|
- } catch (Exception e) {
|
|
|
- log.error("Business group handle failed", e);
|
|
|
- return point.proceed(point.getArgs());
|
|
|
- }
|
|
|
-
|
|
|
- // 执行分组逻辑(方法调用前后)
|
|
|
- Object[] args = point.getArgs();
|
|
|
- if (ObjectUtils.notEmpty(matches)) {
|
|
|
- this.execute(target, Invoking.REQUEST, matches, args);
|
|
|
- }
|
|
|
- Object value = point.proceed(args);
|
|
|
- if (ObjectUtils.notEmpty(matches)) {
|
|
|
- this.execute(target, Invoking.RESPONSE, matches, value);
|
|
|
- }
|
|
|
- return value;
|
|
|
- }
|
|
|
-}
|