feat: 设计模式-责任链模块
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
package cn.meowrain.aioj.backend.framework.banner;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class EnvironmentBanner implements ApplicationListener<ApplicationReadyEvent> {
|
||||
|
||||
@Value("${spring.application.name:unknown}")
|
||||
private String appName;
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationReadyEvent event) {
|
||||
|
||||
Environment env = event.getApplicationContext().getEnvironment();
|
||||
|
||||
// Active profiles
|
||||
String profiles = String.join(",", env.getActiveProfiles());
|
||||
if (profiles.isEmpty()) {
|
||||
profiles = "default";
|
||||
}
|
||||
|
||||
// Port
|
||||
String port = env.getProperty("server.port", "unknown");
|
||||
|
||||
// JVM info
|
||||
String jvm = System.getProperty("java.version") + " (" + System.getProperty("java.vendor") + ")";
|
||||
|
||||
// PID
|
||||
String pid = ManagementFactory.getRuntimeMXBean().getPid() + "";
|
||||
|
||||
// Time
|
||||
String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
||||
|
||||
// Git commit id (如果没有 git.properties,不会报错)
|
||||
String gitCommit = env.getProperty("git.commit.id.abbrev", "N/A");
|
||||
|
||||
printBanner(appName, profiles, port, jvm, pid, time, gitCommit);
|
||||
}
|
||||
|
||||
private void printBanner(String appName,
|
||||
String profiles,
|
||||
String port,
|
||||
String jvm,
|
||||
String pid,
|
||||
String time,
|
||||
String gitCommit) {
|
||||
|
||||
String banner = "\n" +
|
||||
"------------------------------------------------------------\n" +
|
||||
" ✨AI Online Judge✨ - " + appName + "\n" +
|
||||
" Environment : " + profiles + "\n" +
|
||||
" Port : " + port + "\n" +
|
||||
" Git Commit : " + gitCommit + "\n" +
|
||||
" JVM : " + jvm + "\n" +
|
||||
" PID : " + pid + "\n" +
|
||||
" Started At : " + time + "\n" +
|
||||
"------------------------------------------------------------\n";
|
||||
System.out.println(banner);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package cn.meowrain.aioj.backend.framework.designpattern.chains;
|
||||
|
||||
import org.springframework.core.Ordered;
|
||||
|
||||
public interface AbstractChianHandler<T> extends Ordered {
|
||||
/**
|
||||
* 执行责任链逻辑
|
||||
*
|
||||
* @param requestParam 责任链执行入参
|
||||
*/
|
||||
void handle(T requestParam);
|
||||
|
||||
/**
|
||||
* 责任链组件标识
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
String mark();
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package cn.meowrain.aioj.backend.framework.designpattern.chains;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 公共责任链容器
|
||||
*
|
||||
* @param <T>
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class CommonChainContext<T> implements ApplicationContextAware, CommandLineRunner {
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
private final Map<String, List<AbstractChianHandler<T>>> abstractChainHandlerMap = new HashMap<>();
|
||||
|
||||
public void handler(String mark, T requestParam) {
|
||||
List<AbstractChianHandler<T>> merchantAdminAbstractChainHandlers = abstractChainHandlerMap.get(mark);
|
||||
if (merchantAdminAbstractChainHandlers == null || merchantAdminAbstractChainHandlers.isEmpty()) {
|
||||
throw new RuntimeException(String.format("[%s] Chain of Responsibility ID is undefined.", mark));
|
||||
}
|
||||
merchantAdminAbstractChainHandlers.forEach(h -> {
|
||||
h.handle(requestParam);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(String... args) throws Exception {
|
||||
log.info("【责任链路初始化】开始加载并分组所有处理器...");
|
||||
applicationContext.getBeansOfType(AbstractChianHandler.class)
|
||||
.values()
|
||||
.forEach(handler -> {
|
||||
// 打印当前处理器的类名和它所属的 ChainMark
|
||||
String handlerName = handler.getClass().getSimpleName();
|
||||
String mark = handler.mark();
|
||||
log.info(" -> 发现处理器:{},归属链路:{}", handlerName, mark);
|
||||
abstractChainHandlerMap
|
||||
.computeIfAbsent(handler.mark(), k -> new ArrayList<>())
|
||||
.add(handler);
|
||||
});
|
||||
|
||||
// 步骤 2: 对每个链路中的处理器进行排序 (Sort 阶段)
|
||||
abstractChainHandlerMap.forEach((mark, handlers) -> {
|
||||
handlers.sort(Comparator.comparing(Ordered::getOrder));
|
||||
|
||||
// 打印排序后的 Bean 列表
|
||||
String sortedList = handlers.stream()
|
||||
.map(h -> String.format("%s (Order:%d)", h.getClass().getSimpleName(), h.getOrder()))
|
||||
.collect(Collectors.joining(" -> "));
|
||||
|
||||
log.info(" ✅ 链路 {} 排序完成:{}", mark, sortedList);
|
||||
});
|
||||
|
||||
log.info("【责任链路初始化】所有处理器链已完全就绪。");
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user