|
@@ -1,17 +1,15 @@
|
|
|
package com.chelvc.framework.group;
|
|
|
|
|
|
import java.util.Collections;
|
|
|
+import java.util.Iterator;
|
|
|
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.context.ApplicationContextHolder;
|
|
|
import com.chelvc.framework.base.context.SessionContextHolder;
|
|
|
import com.chelvc.framework.base.context.ThreadContextHolder;
|
|
|
-import com.chelvc.framework.common.model.BiPair;
|
|
|
import com.chelvc.framework.common.model.Caps;
|
|
|
import com.chelvc.framework.common.model.Invoking;
|
|
|
import com.chelvc.framework.common.util.ObjectUtils;
|
|
@@ -27,11 +25,10 @@ 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
|
|
@@ -40,10 +37,9 @@ import org.springframework.stereotype.Component;
|
|
|
@Aspect
|
|
|
@Component
|
|
|
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
|
|
-public class GroupingInterceptor {
|
|
|
+public class GroupProcessInterceptor {
|
|
|
private final GroupStore store;
|
|
|
- private final ApplicationContext applicationContext;
|
|
|
- private final Map<Class<?>, GroupHandler> handlers = Maps.newConcurrentMap();
|
|
|
+ private final GroupHandlerFactory factory;
|
|
|
|
|
|
/**
|
|
|
* 判断请求是否匹配分组
|
|
@@ -60,17 +56,23 @@ public class GroupingInterceptor {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 初始化分组处理器
|
|
|
+ * 获取匹配的场景分组注解
|
|
|
*
|
|
|
- * @param type 处理器类型
|
|
|
- * @return 分组处理器实例
|
|
|
+ * @param groups 多场景分组注解实例
|
|
|
+ * @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));
|
|
|
+ private List<Group> matches(Groups groups) {
|
|
|
+ if (Objects.isNull(SessionContextHolder.getId())) {
|
|
|
+ return Collections.emptyList();
|
|
|
+ }
|
|
|
+
|
|
|
+ List<Group> matches = Lists.newLinkedList();
|
|
|
+ for (Group group : groups.value()) {
|
|
|
+ if (this.matches(group)) {
|
|
|
+ matches.add(group);
|
|
|
+ }
|
|
|
}
|
|
|
- return handler;
|
|
|
+ return matches.isEmpty() ? Collections.emptyList() : matches;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -81,79 +83,45 @@ public class GroupingInterceptor {
|
|
|
*/
|
|
|
private void execute(List<Group> groups, Object... args) {
|
|
|
// 执行场景分组
|
|
|
- List<BiPair<Group, GroupHandler, Caps>> values = Lists.newLinkedList();
|
|
|
+ Map<String, Caps> values = Maps.newHashMapWithExpectedSize(groups.size());
|
|
|
for (Group group : groups) {
|
|
|
try {
|
|
|
- GroupHandler handler = this.initializeGroupHandler(group.handler());
|
|
|
+ GroupHandler handler = this.factory.getHandler(group.handler());
|
|
|
Caps value = handler.execute(group.scene(), args);
|
|
|
- if (!group.storing()) {
|
|
|
- GroupContextHolder.setGroup(group.scene(), ObjectUtils.ifNull(value, Caps.NONE));
|
|
|
- }
|
|
|
if (value != null) {
|
|
|
- values.add(BiPair.of(group, handler, value));
|
|
|
+ values.put(group.scene(), value);
|
|
|
}
|
|
|
} catch (Exception e) {
|
|
|
log.error("Group execute failed: {}", group.scene(), e);
|
|
|
}
|
|
|
}
|
|
|
+ if (ObjectUtils.isEmpty(values)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
// 保存场景分组,以最终结果为准
|
|
|
- Map<String, Caps> stores = values.stream().filter(pair -> pair.getLeft().storing())
|
|
|
- .collect(Collectors.toMap(pair -> pair.getLeft().scene(), BiPair::getRight));
|
|
|
+ Map<String, Caps> stores;
|
|
|
try {
|
|
|
- stores = ObjectUtils.ifEmpty(stores, this.store::set, Collections::emptyMap);
|
|
|
- stores.forEach((scene, group) -> GroupContextHolder.setGroup(scene, ObjectUtils.ifNull(group, Caps.NONE)));
|
|
|
+ stores = this.store.set(values);
|
|
|
+ stores.forEach(GroupContextHolder::setGroup);
|
|
|
} catch (Exception e) {
|
|
|
log.error("Group storing failed", e);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// 执行分组完成回调方法
|
|
|
- for (BiPair<Group, GroupHandler, Caps> pair : values) {
|
|
|
- Group group = pair.getLeft();
|
|
|
- Caps value = pair.getRight();
|
|
|
- GroupHandler handler = pair.getMiddle();
|
|
|
- if (!group.storing() || value == stores.get(group.scene())) {
|
|
|
+ for (Group group : groups) {
|
|
|
+ String scene = group.scene();
|
|
|
+ Caps value = values.get(scene);
|
|
|
+ if (value != null && value == stores.get(scene)) {
|
|
|
try {
|
|
|
- handler.complete(group.scene(), value, args);
|
|
|
+ GroupHandler handler = this.factory.getHandler(group.handler());
|
|
|
+ handler.complete(scene, value, args);
|
|
|
} catch (Exception e) {
|
|
|
- log.error("Group complete failed: {}", group.scene(), e);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 执行分组逻辑
|
|
|
- *
|
|
|
- * @param invoking 分组时间点
|
|
|
- * @param groups 分组注解列表
|
|
|
- * @param args 分组执行参数
|
|
|
- */
|
|
|
- private void execute(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);
|
|
|
+ log.error("Group complete failed: {}", scene, e);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- if (ObjectUtils.notEmpty(async)) {
|
|
|
- List<Group> copy = async;
|
|
|
- ThreadContextHolder.run(() -> this.execute(copy, args));
|
|
|
- }
|
|
|
- if (ObjectUtils.notEmpty(sync)) {
|
|
|
- this.execute(sync, args);
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -166,39 +134,78 @@ public class GroupingInterceptor {
|
|
|
*/
|
|
|
@Around("@annotation(groups)")
|
|
|
public Object intercept(ProceedingJoinPoint point, Groups groups) throws Throwable {
|
|
|
- if (Objects.isNull(SessionContextHolder.getId())) {
|
|
|
- return point.proceed();
|
|
|
- }
|
|
|
-
|
|
|
// 获取匹配的分组注解列表
|
|
|
- List<Group> matches = Stream.of(groups.value()).filter(this::matches)
|
|
|
- .collect(Collectors.toCollection(Lists::newLinkedList));
|
|
|
+ List<Group> matches = this.matches(groups);
|
|
|
if (ObjectUtils.isEmpty(matches)) {
|
|
|
return point.proceed();
|
|
|
}
|
|
|
|
|
|
// 获取已存储分组结果
|
|
|
+ Set<String> scenes = matches.stream().map(Group::scene).collect(Collectors.toSet());
|
|
|
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) {
|
|
|
- GroupContextHolder.setGroup(scene, group);
|
|
|
- matches.removeIf(annotation -> Objects.equals(annotation.scene(), scene));
|
|
|
- }
|
|
|
- });
|
|
|
+ Map<String, Caps> values = this.store.get(scenes);
|
|
|
+ if (ObjectUtils.notEmpty(values)) {
|
|
|
+ values.forEach((scene, value) -> {
|
|
|
+ if (value != null) {
|
|
|
+ GroupContextHolder.setGroup(scene, value);
|
|
|
+ matches.removeIf(group -> Objects.equals(group.scene(), scene));
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
} catch (Exception e) {
|
|
|
log.error("Group loading failed", e);
|
|
|
return point.proceed();
|
|
|
}
|
|
|
|
|
|
- // 执行分组逻辑(方法调用前后)
|
|
|
- if (ObjectUtils.notEmpty(matches)) {
|
|
|
- this.execute(Invoking.REQUEST, matches, point.getArgs());
|
|
|
+ if (ObjectUtils.isEmpty(matches)) {
|
|
|
+ return point.proceed();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 执行方法前置分组
|
|
|
+ List<Group> sync = Lists.newLinkedList();
|
|
|
+ List<Group> async = Lists.newLinkedList();
|
|
|
+ Iterator<Group> iterator = matches.iterator();
|
|
|
+ while (iterator.hasNext()) {
|
|
|
+ Group group = iterator.next();
|
|
|
+ if (group.invoking() == Invoking.REQUEST) {
|
|
|
+ if (group.async()) {
|
|
|
+ async.add(group);
|
|
|
+ } else {
|
|
|
+ sync.add(group);
|
|
|
+ }
|
|
|
+ iterator.remove();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Object[] args = point.getArgs();
|
|
|
+ if (ObjectUtils.notEmpty(async)) {
|
|
|
+ ThreadContextHolder.run(() -> this.execute(async, args));
|
|
|
}
|
|
|
+ if (ObjectUtils.notEmpty(sync)) {
|
|
|
+ this.execute(sync, args);
|
|
|
+ }
|
|
|
+
|
|
|
Object value = point.proceed();
|
|
|
+
|
|
|
+ // 执行方法后置分组
|
|
|
if (ObjectUtils.notEmpty(matches)) {
|
|
|
- this.execute(Invoking.RESPONSE, matches, value);
|
|
|
+ async.clear();
|
|
|
+ iterator = matches.iterator();
|
|
|
+ while (iterator.hasNext()) {
|
|
|
+ Group group = iterator.next();
|
|
|
+ if (group.async()) {
|
|
|
+ async.add(group);
|
|
|
+ iterator.remove();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Object[] vars = new Object[args.length + 1];
|
|
|
+ System.arraycopy(args, 0, vars, 0, args.length);
|
|
|
+ vars[args.length] = value;
|
|
|
+ if (ObjectUtils.notEmpty(async)) {
|
|
|
+ ThreadContextHolder.run(() -> this.execute(async, vars));
|
|
|
+ }
|
|
|
+ if (ObjectUtils.notEmpty(matches)) {
|
|
|
+ this.execute(matches, vars);
|
|
|
+ }
|
|
|
}
|
|
|
return value;
|
|
|
}
|