001/* 002 * Copyright (c) 2023-2026, Agents-Flex (fuhai999@gmail.com). 003 * <p> 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * <p> 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * <p> 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package com.agentsflex.core.model.chat; 018 019import java.util.ArrayList; 020import java.util.Collections; 021import java.util.List; 022 023/** 024 * 全局聊天拦截器管理器。 025 * <p> 026 * 该类提供静态方法,用于注册和管理应用于所有 {@link BaseChatModel} 实例的全局拦截器。 027 * 全局拦截器会在实例级拦截器之前执行,适用于统一的日志、安全、监控等横切关注点。 028 * <p> 029 * <strong>使用建议</strong>: 030 * <ul> 031 * <li>在应用启动阶段(如 Spring 的 {@code @PostConstruct} 或 main 方法)注册全局拦截器</li> 032 * <li>避免在运行时动态修改,以确保线程安全和行为一致性</li> 033 * </ul> 034 */ 035public final class GlobalChatInterceptors { 036 037 /** 038 * 全局拦截器列表,使用 synchronized 保证线程安全 039 */ 040 private static final List<ChatInterceptor> GLOBAL_INTERCEPTORS = new ArrayList<>(); 041 042 /** 043 * 私有构造函数,防止实例化 044 */ 045 private GlobalChatInterceptors() { 046 // 工具类,禁止实例化 047 } 048 049 /** 050 * 注册一个全局拦截器。 051 * <p> 052 * 该拦截器将应用于所有后续创建的 {@link BaseChatModel} 实例。 053 * 054 * @param interceptor 要注册的拦截器,不能为 null 055 * @throws IllegalArgumentException 如果 interceptor 为 null 056 */ 057 public static synchronized void addInterceptor(ChatInterceptor interceptor) { 058 if (interceptor == null) { 059 throw new IllegalArgumentException("ChatInterceptor must not be null"); 060 } 061 GLOBAL_INTERCEPTORS.add(interceptor); 062 } 063 064 /** 065 * 批量注册多个全局拦截器。 066 * <p> 067 * 拦截器将按列表顺序添加,并在执行时按相同顺序调用。 068 * 069 * @param interceptors 拦截器列表,不能为 null;列表中元素不能为 null 070 * @throws IllegalArgumentException 如果 interceptors 为 null 或包含 null 元素 071 */ 072 public static synchronized void addInterceptors(List<ChatInterceptor> interceptors) { 073 if (interceptors == null) { 074 throw new IllegalArgumentException("Interceptor list must not be null"); 075 } 076 for (ChatInterceptor interceptor : interceptors) { 077 if (interceptor == null) { 078 throw new IllegalArgumentException("Interceptor list must not contain null elements"); 079 } 080 } 081 GLOBAL_INTERCEPTORS.addAll(interceptors); 082 } 083 084 /** 085 * 获取当前注册的全局拦截器列表的不可变视图。 086 * <p> 087 * 该方法供 {@link BaseChatModel} 内部使用,返回值不应被外部修改。 088 * 089 * @return 不可变的全局拦截器列表 090 */ 091 public static List<ChatInterceptor> getInterceptors() { 092 return Collections.unmodifiableList(GLOBAL_INTERCEPTORS); 093 } 094 095 /** 096 * 清空所有全局拦截器。 097 * <p> 098 * <strong>仅用于测试环境</strong>,生产环境应避免调用。 099 */ 100 public static synchronized void clear() { 101 GLOBAL_INTERCEPTORS.clear(); 102 } 103 104 /** 105 * 获取当前全局拦截器的数量。 106 * <p> 107 * 用于诊断或监控。 108 * 109 * @return 拦截器数量 110 */ 111 public static synchronized int size() { 112 return GLOBAL_INTERCEPTORS.size(); 113 } 114}