Spring中责任链模式的工业级应用简单剖析
责任链模式在Spring框架中扮演着至关重要的角色,它被广泛应用于处理请求、安全控制、事务管理等多个核心领域。本文将深入分析Spring框架中责任链模式的工业级实现,揭示其设计精妙之处。
1. Spring MVC中的责任链模式
1.1 HandlerExecutionChain:Spring MVC的责任链核心
Spring MVC的核心处理链是HandlerExecutionChain,它将一个请求的处理过程分解为多个阶段,每个阶段由不同的处理器负责。
java
/**
* Spring MVC的处理器执行链
* 这是责任链模式在Web层的经典实现
*/
public class HandlerExecutionChain {
// 处理器对象(Controller方法)
private final Object handler;
// 拦截器链
private HandlerInterceptor[] interceptors;
// 拦截器索引,用于追踪执行位置
private int interceptorIndex = -1;
/**
* 执行预处理拦截器
*/
boolean applyPreHandle(HttpServletRequest request,
HttpServletResponse response) throws Exception {
HandlerInterceptor[] interceptors = getInterceptors();
if (!ObjectUtils.isEmpty(interceptors)) {
for (int i = 0; i < interceptors.length; i++) {
HandlerInterceptor interceptor = interceptors[i];
if (!interceptor.preHandle(request, response, this.handler)) {
// 如果某个拦截器返回false,触发已完成拦截器的后处理
triggerAfterCompletion(request, response, null);
return false;
}
this.interceptorIndex = i;
}
}
return true;
}
/**
* 执行后处理拦截器
*/
void applyPostHandle(HttpServletRequest request,
HttpServletResponse response,
ModelAndView mv) throws Exception {
HandlerInterceptor[] interceptors = getInterceptors();
if (!ObjectUtils.isEmpty(interceptors)) {
for (int i = interceptors.length - 1; i >= 0; i--) {
HandlerInterceptor interceptor = interceptors[i];
interceptor.postHandle(request, response, this.handler, mv);
}
}
}
/**
* 执行完成回调(无论成功还是异常)
*/
void triggerAfterCompletion(HttpServletRequest request,
HttpServletResponse response,
Exception ex) throws Exception {
HandlerInterceptor[] interceptors = getInterceptors();
if (!ObjectUtils.isEmpty(interceptors)) {
for (int i = this.interceptorIndex; i >= 0; i--) {
HandlerInterceptor interceptor = interceptors[i];
try {
interceptor.afterCompletion(request, response,
this.handler, ex);
} catch (Throwable ex2) {
logger.error("HandlerInterceptor.afterCompletion threw exception", ex2);
}
}
}
}
}
1.2 拦截器链的执行流程
Handler(Controller) Interceptor3 Interceptor2 Interceptor1 HandlerExecutionChain DispatcherServlet Handler(Controller) Interceptor3 Interceptor2 Interceptor1 HandlerExecutionChain DispatcherServlet 异常情况下的处理 getHandler() preHandle() true preHandle() true preHandle() true handle()处理业务 ModelAndView postHandle() postHandle() postHandle() 返回结果 抛出异常 afterCompletion(ex) afterCompletion(ex) afterCompletion(ex)
1.3 自定义拦截器示例
java
/**
* 日志拦截器
*/
@Component
@Slf4j
public class LoggingInterceptor implements HandlerInterceptor {
private static final String START_TIME = "startTime";
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
long startTime = System.currentTimeMillis();
request.setAttribute(START_TIME, startTime);
log.info("请求开始: {} {}, Handler: {}",
request.getMethod(),
request.getRequestURI(),
handler.toString());
// 记录请求参数(生产环境需注意敏感信息过滤)
if (log.isDebugEnabled()) {
Map<String, String[]> params = request.getParameterMap();
if (!params.isEmpty()) {
log.debug("请求参数: {}", params);
}
}
return true; // 继续执行链
}
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler,
ModelAndView modelAndView) throws Exception {
// 可以修改ModelAndView
if (modelAndView != null) {
modelAndView.addObject("processedBy", "LoggingInterceptor");
}
}
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex) throws Exception {
long startTime = (Long) request.getAttribute(START_TIME);
long duration = System.currentTimeMillis() - startTime;
log.info("请求完成: {} {}, 耗时: {}ms, 状态: {}, 异常: {}",
request.getMethod(),
request.getRequestURI(),
duration,
response.getStatus(),
ex != null ? ex.getMessage() : "无");
// 监控指标上报
Metrics.recordRequestDuration(request.getRequestURI(), duration);
}
}
/**
* 认证拦截器
*/
@Component
@Slf4j
public class AuthenticationInterceptor implements HandlerInterceptor {
@Autowired
private TokenService tokenService;
@Autowired
private UserService userService;
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
// 检查是否需要认证(通过注解标记)
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
if (handlerMethod.hasMethodAnnotation(AllowAnonymous.class)) {
return true; // 匿名访问,跳过认证
}
}
// 获取并验证Token
String token = extractToken(request);
if (StringUtils.isEmpty(token)) {
sendUnauthorized(response, "缺少认证Token");
return false; // 中断执行链
}
try {
// 验证Token有效性
String userId = tokenService.validateToken(token);
User user = userService.getUserById(userId);
// 将用户信息存入请求上下文
RequestContextHolder.setCurrentUser(user);
// 续期Token
tokenService.refreshToken(token);
log.debug("用户认证成功: userId={}", userId);
return true; // 继续执行链
} catch (TokenExpiredException e) {
sendUnauthorized(response, "Token已过期");
return false;
} catch (InvalidTokenException e) {
sendUnauthorized(response, "无效的Token");
return false;
}
}
private String extractToken(HttpServletRequest request) {
// 从Header、Cookie或参数中提取Token
String token = request.getHeader("Authorization");
if (StringUtils.startsWithIgnoreCase(token, "Bearer ")) {
return token.substring(7);
}
return request.getParameter("token");
}
private void sendUnauthorized(HttpServletResponse response, String message) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.setContentType("application/json");
try {
response.getWriter().write("{\"code\":401,\"message\":\"" + message + "\"}");
} catch (IOException e) {
log.error("写入响应失败", e);
}
}
}
2. Spring Security中的责任链模式
2.1 安全过滤器链:多层防护的责任链
Spring Security的安全体系完全构建在责任链模式之上,通过多个过滤器组成的安全链来保护应用。
java
/**
* Spring Security过滤器链配置
*/
@Configuration
@EnableWebSecurity
@Slf4j
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private JwtAuthenticationFilter jwtAuthenticationFilter;
@Autowired
private RateLimitFilter rateLimitFilter;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
// 责任链配置
.addFilterBefore(rateLimitFilter, UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
// 授权配置
.authorizeRequests()
.antMatchers("/api/public/**").permitAll()
.antMatchers("/api/admin/**").hasRole("ADMIN")
.antMatchers("/api/user/**").hasAnyRole("USER", "ADMIN")
.anyRequest().authenticated()
// 异常处理
.exceptionHandling()
.authenticationEntryPoint(new JwtAuthenticationEntryPoint())
.accessDeniedHandler(new JwtAccessDeniedHandler())
// 禁用CSRF(API场景)
.csrf().disable()
// Session管理
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
}
2.2 FilterChainProxy:安全链的管理者
java
/**
* Spring Security核心:FilterChainProxy
* 管理多个安全过滤器链
*/
public class FilterChainProxy extends GenericFilterBean {
// 多个安全链(按请求路径匹配)
private List<SecurityFilterChain> filterChains;
// 过滤器链执行器
private FilterChainProxy.FilterChainValidator filterChainValidator = new FilterChainProxy.FilterChainValidator();
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// 清理SecurityContext
SecurityContextHolder.clearContext();
// 获取当前请求对应的过滤器链
List<Filter> filters = getFilters((HttpServletRequest) request);
if (filters == null || filters.size() == 0) {
// 没有匹配的安全链,直接继续
chain.doFilter(request, response);
return;
}
// 执行安全过滤器链
VirtualFilterChain virtualFilterChain =
new VirtualFilterChain((HttpServletRequest) request, chain, filters);
virtualFilterChain.doFilter(request, response);
}
/**
* 虚拟过滤器链 - 责任链的核心实现
*/
private static class VirtualFilterChain implements FilterChain {
private final HttpServletRequest request;
private final FilterChain originalChain;
private final List<Filter> additionalFilters;
private final int size;
private int currentPosition = 0;
private VirtualFilterChain(HttpServletRequest request,
FilterChain chain,
List<Filter> additionalFilters) {
this.request = request;
this.originalChain = chain;
this.additionalFilters = additionalFilters;
this.size = additionalFilters.size();
}
@Override
public void doFilter(ServletRequest request, ServletResponse response)
throws IOException, ServletException {
if (currentPosition == size) {
// 所有安全过滤器执行完毕,执行原始链
originalChain.doFilter(request, response);
} else {
// 执行当前过滤器,并将自己作为下一个链传递
currentPosition++;
Filter nextFilter = additionalFilters.get(currentPosition - 1);
nextFilter.doFilter(request, response, this);
}
}
}
/**
* 根据请求路径获取对应的过滤器链
*/
private List<Filter> getFilters(HttpServletRequest request) {
for (SecurityFilterChain chain : filterChains) {
if (chain.matches(request)) {
return chain.getFilters();
}
}
return null;
}
}
2.3 典型的安全过滤器链顺序
Spring Security的标准过滤器链包含大约15个过滤器,按特定顺序执行:
java
// 标准安全过滤器链顺序(简化版)
public class DefaultSecurityFilterChain implements SecurityFilterChain {
@Override
public List<Filter> getFilters() {
return Arrays.asList(
// 1. 安全上下文持久化过滤器
new SecurityContextPersistenceFilter(),
// 2. 并发会话控制过滤器
new ConcurrentSessionFilter(),
// 3. 用户名密码认证过滤器
new UsernamePasswordAuthenticationFilter(),
// 4. Basic认证过滤器
new BasicAuthenticationFilter(),
// 5. Remember-Me认证过滤器
new RememberMeAuthenticationFilter(),
// 6. 匿名认证过滤器(确保SecurityContext不为null)
new AnonymousAuthenticationFilter("default"),
// 7. Session管理过滤器
new SessionManagementFilter(),
// 8. 异常转换过滤器
new ExceptionTranslationFilter(),
// 9. 权限验证过滤器(核心)
new FilterSecurityInterceptor(),
// 10. CSRF保护过滤器
new CsrfFilter(),
// 11. 注销过滤器
new LogoutFilter()
);
}
@Override
public boolean matches(HttpServletRequest request) {
// 匹配所有请求
return true;
}
}
3. Spring AOP中的责任链模式
3.1 拦截器链:AOP的责任链实现
Spring AOP通过拦截器链来实现切面编程,这也是责任链模式的典型应用。
java
/**
* AOP拦截器链(MethodInterceptor责任链)
*/
public class ReflectiveMethodInvocation implements ProxyMethodInvocation {
// 目标对象
protected final Object target;
// 目标方法
protected final Method method;
// 方法参数
protected Object[] arguments;
// 拦截器链
protected List<?> interceptorsAndDynamicMethodMatchers;
// 当前拦截器索引
private int currentInterceptorIndex = -1;
public ReflectiveMethodInvocation(Object target, Method method,
Object[] arguments,
List<Object> interceptorsAndDynamicMethodMatchers) {
this.target = target;
this.method = method;
this.arguments = arguments;
this.interceptorsAndDynamicMethodMatchers = interceptorsAndDynamicMethodMatchers;
}
/**
* 执行拦截器链
*/
@Override
public Object proceed() throws Throwable {
// 如果已经执行完所有拦截器,调用原始方法
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
// 获取下一个拦截器
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// 动态方法匹配器
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
if (dm.methodMatcher.matches(this.method, this.target.getClass(), this.arguments)) {
return dm.interceptor.invoke(this);
} else {
// 动态匹配失败,跳过此拦截器
return proceed();
}
} else {
// 普通拦截器
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
/**
* 调用原始方法
*/
protected Object invokeJoinpoint() throws Throwable {
return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments);
}
}
3.2 事务拦截器链示例
java
/**
* 事务拦截器链配置
*/
@Configuration
@EnableTransactionManagement
@Slf4j
public class TransactionConfig {
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean
public TransactionInterceptor transactionInterceptor(
PlatformTransactionManager transactionManager) {
TransactionInterceptor interceptor = new TransactionInterceptor();
interceptor.setTransactionManager(transactionManager);
// 配置事务属性(责任链的规则)
Properties transactionAttributes = new Properties();
transactionAttributes.setProperty("get*", "PROPAGATION_REQUIRED,readOnly");
transactionAttributes.setProperty("find*", "PROPAGATION_REQUIRED,readOnly");
transactionAttributes.setProperty("save*", "PROPAGATION_REQUIRED,-Exception");
transactionAttributes.setProperty("update*", "PROPAGATION_REQUIRED,-Exception");
transactionAttributes.setProperty("delete*", "PROPAGATION_REQUIRED,-Exception");
interceptor.setTransactionAttributes(transactionAttributes);
return interceptor;
}
@Bean
public Advisor transactionAdvisor(TransactionInterceptor transactionInterceptor) {
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
pointcut.setExpression("execution(* com.example.service.*.*(..))");
return new DefaultPointcutAdvisor(pointcut, transactionInterceptor);
}
}
/**
* 自定义事务拦截器(扩展点)
*/
@Component
@Slf4j
public class CustomTransactionInterceptor implements MethodInterceptor {
@Autowired
private TransactionInterceptor defaultTransactionInterceptor;
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
long startTime = System.currentTimeMillis();
String methodName = invocation.getMethod().getName();
try {
// 前置处理:记录事务开始
log.debug("事务开始: {}", methodName);
// 调用默认事务拦截器(责任链传递)
Object result = defaultTransactionInterceptor.invoke(invocation);
// 后置处理:记录事务提交
long duration = System.currentTimeMillis() - startTime;
log.debug("事务提交: {}, 耗时: {}ms", methodName, duration);
return result;
} catch (Exception e) {
// 异常处理:记录事务回滚
log.error("事务回滚: {}, 原因: {}", methodName, e.getMessage());
throw e;
}
}
}
4. Spring Cloud Gateway中的责任链模式
4.1 网关过滤器链
Spring Cloud Gateway完全基于责任链模式构建,通过过滤器链处理请求路由。
java
/**
* 网关过滤器链实现
*/
public class DefaultGatewayFilterChain implements GatewayFilterChain {
// 过滤器列表
private final List<GatewayFilter> filters;
// 当前过滤器索引
private int index;
public DefaultGatewayFilterChain(List<GatewayFilter> filters) {
this.filters = filters;
this.index = 0;
}
@Override
public Mono<Void> filter(ServerWebExchange exchange) {
if (this.index < filters.size()) {
GatewayFilter filter = filters.get(this.index);
this.index++;
// 执行当前过滤器,并将自己作为下一个链传递
return filter.filter(exchange, this);
} else {
// 所有过滤器执行完毕
return Mono.empty();
}
}
}
/**
* 网关过滤器工厂(责任链配置)
*/
@Component
@Slf4j
public class GatewayFilterFactory {
/**
* 创建全局过滤器链
*/
public List<GlobalFilter> createGlobalFilterChain() {
return Arrays.asList(
// 1. 路由过滤器(必须第一个)
new RouteToRequestUrlFilter(),
// 2. 负载均衡过滤器
new LoadBalancerClientFilter(),
// 3. 请求日志过滤器
new RequestLoggingFilter(),
// 4. 认证过滤器
new AuthenticationFilter(),
// 5. 限流过滤器
new RateLimiterFilter(),
// 6. 熔断过滤器
new CircuitBreakerFilter(),
// 7. 重试过滤器
new RetryFilter(),
// 8. 响应修改过滤器
new ModifyResponseFilter()
);
}
/**
* 创建路由特定过滤器链
*/
public List<GatewayFilter> createRouteFilterChain(Route route) {
List<GatewayFilter> filters = new ArrayList<>();
// 添加全局过滤器
filters.addAll(createGlobalFilterChain());
// 添加路由特定过滤器
filters.add(new StripPrefixFilter(route.getStripPrefix()));
filters.add(new SetPathFilter(route.getPath()));
// 根据配置添加过滤器
if (route.isSecure()) {
filters.add(new SecureHeadersFilter());
}
if (route.getRateLimit() > 0) {
filters.add(new RequestRateLimiterFilter(route.getRateLimit()));
}
return filters;
}
}
4.2 自定义网关过滤器
java
/**
* 自定义限流过滤器
*/
@Component
@Order(-1) // 执行顺序
@Slf4j
public class RateLimiterFilter implements GlobalFilter {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
String clientIp = getClientIp(request);
String path = request.getPath().value();
// 构建限流key
String rateLimitKey = "rate_limit:" + clientIp + ":" + path;
// 使用Redis令牌桶算法
Long current = redisTemplate.opsForValue().increment(rateLimitKey, 1);
if (current == 1) {
// 第一次访问,设置过期时间
redisTemplate.expire(rateLimitKey, 1, TimeUnit.SECONDS);
}
if (current > 100) { // 每秒100次限制
log.warn("触发限流: ip={}, path={}, count={}", clientIp, path, current);
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(HttpStatus.TOO_MANY_REQUESTS);
response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
String body = "{\"code\":429,\"message\":\"请求过于频繁,请稍后再试\"}";
DataBuffer buffer = response.bufferFactory().wrap(body.getBytes());
return response.writeWith(Mono.just(buffer));
}
// 继续执行过滤器链
return chain.filter(exchange);
}
private String getClientIp(ServerHttpRequest request) {
String xForwardedFor = request.getHeaders().getFirst("X-Forwarded-For");
if (StringUtils.hasText(xForwardedFor)) {
return xForwardedFor.split(",")[0].trim();
}
return request.getRemoteAddress() != null ?
request.getRemoteAddress().getAddress().getHostAddress() : "unknown";
}
}
5. Spring中的责任链模式最佳实践
5.1 链的配置与管理
java
/**
* 责任链配置工厂
*/
@Component
@Slf4j
public class ChainConfigFactory {
/**
* 根据配置创建责任链
*/
public <T extends ChainNode> List<T> createChain(
List<String> nodeNames,
Function<String, T> nodeFactory) {
List<T> chain = new ArrayList<>();
for (String nodeName : nodeNames) {
try {
T node = nodeFactory.apply(nodeName);
chain.add(node);
log.info("添加链节点: {}", nodeName);
} catch (Exception e) {
log.error("创建链节点失败: {}", nodeName, e);
// 根据配置决定是否中断
if (isStrictMode()) {
throw new ChainConfigurationException("链配置失败", e);
}
}
}
// 连接链节点
connectChainNodes(chain);
return chain;
}
/**
* 连接链节点
*/
private <T extends ChainNode> void connectChainNodes(List<T> chain) {
for (int i = 0; i < chain.size() - 1; i++) {
chain.get(i).setNext(chain.get(i + 1));
}
}
/**
* 动态重新配置责任链
*/
public <T extends ChainNode> void reconfigureChain(
List<T> existingChain,
List<String> newConfig) {
synchronized (existingChain) {
// 暂停链处理
pauseChain(existingChain);
// 创建新链
List<T> newChain = createChain(newConfig, nodeName -> {
// 尝试重用现有节点
return findExistingNode(existingChain, nodeName)
.orElseGet(() -> createNewNode(nodeName));
});
// 原子替换
existingChain.clear();
existingChain.addAll(newChain);
// 恢复链处理
resumeChain(existingChain);
}
}
}
5.2 监控与调试支持
java
/**
* 可监控的责任链
*/
public abstract class MonitorableChainNode implements ChainNode {
private ChainNode next;
private final String nodeName;
private final ChainMetrics metrics;
public MonitorableChainNode(String nodeName) {
this.nodeName = nodeName;
this.metrics = new ChainMetrics(nodeName);
}
@Override
public ChainResult process(ChainContext context) {
long startTime = System.nanoTime();
boolean success = false;
try {
metrics.recordRequest();
// 执行实际处理
ChainResult result = doProcess(context);
success = true;
return result;
} catch (Exception e) {
metrics.recordError();
throw e;
} finally {
long duration = System.nanoTime() - startTime;
metrics.recordDuration(duration);
metrics.recordSuccess(success);
// 记录详细日志
if (log.isDebugEnabled()) {
log.debug("链节点执行: node={}, success={}, duration={}ns",
nodeName, success, duration);
}
}
}
protected abstract ChainResult doProcess(ChainContext context);
@Override
public void setNext(ChainNode next) {
this.next = next;
}
@Override
public ChainNode getNext() {
return next;
}
public ChainMetrics getMetrics() {
return metrics;
}
}
/**
* 链监控指标
*/
public class ChainMetrics {
private final String nodeName;
private final AtomicLong requestCount = new AtomicLong();
private final AtomicLong errorCount = new AtomicLong();
private final AtomicLong totalDuration = new AtomicLong();
private final LongAdder successCount = new LongAdder();
// 滑动窗口统计
private final SlidingWindowStats slidingWindow;
public ChainMetrics(String nodeName) {
this.nodeName = nodeName;
this.slidingWindow = new SlidingWindowStats(60); // 60秒窗口
}
public void recordRequest() {
requestCount.incrementAndGet();
slidingWindow.recordRequest();
}
public void recordError() {
errorCount.incrementAndGet();
slidingWindow.recordError();
}
public void recordDuration(long duration) {
totalDuration.addAndGet(duration);
slidingWindow.recordDuration(duration);
}
public void recordSuccess(boolean success) {
if (success) {
successCount.increment();
}
}
public Map<String, Object> getStats() {
Map<String, Object> stats = new HashMap<>();
stats.put("nodeName", nodeName);
stats.put("totalRequests", requestCount.get());
stats.put("totalErrors", errorCount.get());
stats.put("successRate",
requestCount.get() > 0 ?
(double) successCount.sum() / requestCount.get() : 0.0);
stats.put("avgDuration",
requestCount.get() > 0 ?
totalDuration.get() / requestCount.get() : 0);
stats.putAll(slidingWindow.getWindowStats());
return stats;
}
}
6. Spring责任链模式的工业级特性
6.1 性能优化策略
java
/**
* 高性能责任链实现
*/
public class HighPerformanceChain {
// 使用数组而不是List,减少方法调用开销
private final ChainNode[] nodes;
private final int length;
// 热点节点缓存(基于历史数据优化)
private volatile int hotNodeIndex = -1;
public HighPerformanceChain(List<ChainNode> nodeList) {
this.nodes = nodeList.toArray(new ChainNode[0]);
this.length = nodes.length;
// 预热分析
analyzeAndOptimize();
}
public ChainResult process(ChainContext context) {
// 尝试热点节点
if (hotNodeIndex >= 0 && nodes[hotNodeIndex].canHandle(context)) {
return nodes[hotNodeIndex].process(context);
}
// 顺序执行
for (int i = 0; i < length; i++) {
if (nodes[i].canHandle(context)) {
// 更新热点节点
if (i != hotNodeIndex) {
hotNodeIndex = i;
}
return nodes[i].process(context);
}
}
throw new NoHandlerFoundException("无处理器能够处理该请求");
}
private void analyzeAndOptimize() {
// 基于历史数据重新排序节点
if (hasHistoricalData()) {
HistoricalData data = loadHistoricalData();
ChainNode[] optimized = optimizeNodeOrder(data);
System.arraycopy(optimized, 0, nodes, 0, length);
}
}
/**
* 自适应节点排序
*/
private ChainNode[] optimizeNodeOrder(HistoricalData data) {
return Arrays.stream(nodes)
.sorted((a, b) -> {
// 根据命中率和处理时间排序
double scoreA = calculateScore(a, data);
double scoreB = calculateScore(b, data);
return Double.compare(scoreB, scoreA); // 降序
})
.toArray(ChainNode[]::new);
}
}
6.2 故障隔离与恢复
java
/**
* 具有故障隔离的责任链
*/
public class FaultTolerantChain {
private final List<ChainNode> nodes;
private final CircuitBreakerConfig breakerConfig;
private final Map<String, CircuitBreaker> breakers = new ConcurrentHashMap<>();
public ChainResult process(ChainContext context) {
for (ChainNode node : nodes) {
String nodeName = node.getClass().getSimpleName();
CircuitBreaker breaker = breakers.computeIfAbsent(
nodeName, k -> new CircuitBreaker(breakerConfig));
try {
if (!breaker.allowRequest()) {
// 断路器打开,跳过此节点
log.warn("断路器打开,跳过节点: {}", nodeName);
continue;
}
ChainResult result = breaker.executeCallable(() ->
node.process(context));
// 处理成功
return result;
} catch (Exception e) {
// 记录失败
breaker.recordFailure();
log.error("节点处理失败: {}", nodeName, e);
// 根据策略决定:继续下一个节点或终止
if (node.isCritical()) {
throw new ChainProcessingException("关键节点失败", e);
}
// 非关键节点失败,继续下一个
}
}
throw new NoHandlerFoundException("所有节点都失败或无匹配节点");
}
}
/**
* 简单断路器实现
*/
public class CircuitBreaker {
private final CircuitBreakerConfig config;
private final AtomicInteger failureCount = new AtomicInteger();
private final AtomicLong lastFailureTime = new AtomicLong();
private volatile State state = State.CLOSED;
enum State { CLOSED, OPEN, HALF_OPEN }
public boolean allowRequest() {
if (state == State.OPEN) {
// 检查是否应该进入半开状态
long now = System.currentTimeMillis();
if (now - lastFailureTime.get() > config.getResetTimeout()) {
state = State.HALF_OPEN;
return true; // 允许一个测试请求
}
return false;
}
return true;
}
public void recordFailure() {
failureCount.incrementAndGet();
lastFailureTime.set(System.currentTimeMillis());
if (failureCount.get() >= config.getFailureThreshold()) {
state = State.OPEN;
}
}
public void recordSuccess() {
if (state == State.HALF_OPEN) {
// 半开状态成功,关闭断路器
state = State.CLOSED;
failureCount.set(0);
}
}
}
7. 总结与最佳实践
7.1 Spring中责任链模式的精髓
- 开箱即用的链管理:Spring提供了完整的链管理框架,无需从零实现
- 灵活的扩展点:通过接口和抽象类提供了丰富的扩展点
- 声明式配置:支持通过注解、XML、Java Config等多种方式配置链
- 性能优化:内置了链的缓存、排序、短路等优化策略
- 监控支持:与Spring Actuator集成,提供链的运行监控
7.2 工业级应用的最佳实践
| 实践点 | 说明 | 示例 |
|---|---|---|
| 链的配置外部化 | 将链配置放在配置文件或数据库中 | @ConfigurationProperties |
| 节点的可观测性 | 为每个节点添加监控指标 | Micrometer + Prometheus |
| 链的动态调整 | 支持运行时调整链顺序和节点 | Spring Cloud Config |
| 故障隔离 | 防止单个节点故障影响整个链 | Circuit Breaker模式 |
| 性能优化 | 根据历史数据优化节点顺序 | 热点节点缓存 |
7.3 选择责任链模式的场景
在Spring生态中,责任链模式特别适合以下场景:
- 请求处理管道:如Spring MVC拦截器、Gateway过滤器
- 安全检查链:如Spring Security过滤器链
- 事务管理链:如多个事务操作的组合
- 数据处理流水线:如ETL过程的多个处理步骤
- 事件处理链:如ApplicationEvent的多监听器处理
7.4 注意事项
- 避免过长的链:链过长会影响性能和调试难度
- 注意节点顺序:某些节点可能有严格的执行顺序要求
- 考虑短路逻辑:某些情况下可能需要提前结束链的执行
- 监控链的健康:需要监控每个节点的成功率和响应时间
- 提供调试支持:在开发环境提供链的调试信息