拦截的含义
在软件设计中,"拦截"指的是在某个执行流程中插入一个或多个处理点,这些处理点可以检查、修改或者替换原有流程中的数据或行为。拦截器可以在不修改原有代码的情况下,对特定的操作进行增强或改变。
拦截器的核心思想
拦截器模式(Interceptor Pattern)是一种设计模式,它允许你在调用某个方法之前或之后,插入额外的处理逻辑。这些逻辑可以是日志记录、性能监控、安全控制等。
拦截器的工作方式
通常,拦截器会定义一个接口,该接口包含了一个方法(如intercept),该方法接收一个"调用对象"。该拦截器可以在调用原始操作之前和之后执行自己的逻辑,甚至可以决定是否调用原始操作。
拦截器与责任链的关系
拦截器通常组织成责任链,每个拦截器在链中依次被调用。每个拦截器都可以决定是否将请求传递给下一个责任链,或者直接返回相应,从而中断链。
在责任链中,拦截器可以对请求进行拦截,即在请求到达目标之前进行预处理,也可以在响应返回之后进行处理。这里的拦截并不是完成阻断,而是类似于"中间处理"的意思。
责任链模式在拦截器中的核心体现
链式传递机制
- 每个拦截器接收一个Chain对象
- 通过调用chain.proceed()将控制权传递给下一个拦截器
- 形成了明确的"传递链"
灵活的组织结构
- 拦截器可以动态添加、移除、排序
- 每个拦截器不需要知道链中的其他拦截器
- 符合"开闭原则"(对扩展开放,对修改封闭)
统一处理接口
- 所有拦截器实现相同的接口
- 链的节点有统一的处理方式
流程控制
- 拦截器可以选择是否继续传递(调用proceed())
- 可以修改拦截前和拦截后的逻辑
总结
责任链模式让多个拦截器能够有序地、灵活地组合在一起,形成一个处理流水线,每个拦截器都是这个流水线上的一个工作站,而chain对象就是传送带,负责在站与站之间传递工作项。
示例代码
定义责任链接口Chain
kotlin
//责任链接口
interface Chain {
fun request():Request
fun proceed(request: Request):Response
}
拦截器接口Interceptor
kotlin
//拦截器接口
interface Interceptor {
fun interceptor(chain:Chain):Response
}
请求对象
kotlin
//请求对象
data class Request(val userName:String,val passWord:String,val headers:Map<String,String> = HashMap())
响应对象
kotlin
//响应对象
data class Response(val code:Int,val message:String,val token:String? = null)
日志拦截器
kotlin
class LoggingInterceptor: Interceptor {
override fun interceptor(chain: Chain): Response {
val request = chain.request()
println("📝 [日志] 收到登录请求: ${request.userName}")
// 继续执行下一个拦截器或真实请求
val response = chain.proceed(request)
println("📝 [日志] 返回结果: ${response.message} (code=${response.code})")
return response
}
}
校验拦截器
kotlin
class ValidationInterceptor:Interceptor {
override fun interceptor(chain: Chain): Response {
val request = chain.request()
if(request.userName==""){
return Response(400,"用户名不为空")
}
if(request.passWord.length<6){
return Response(400,"密码长度不能少于6位")
}
println("校验通过")
//校验通过,继续
return chain.proceed(request)
}
}
认证拦截器
kotlin
class AuthInterceptor : Interceptor {
override fun interceptor(chain: Chain): Response {
val original = chain.request()
val newRequest = original.copy(
headers = original.headers + mapOf("Device-ID" to "DEVICE_8888")
)
println("🔑 [认证] 添加设备ID到请求头")
val reponse = chain.proceed(newRequest)
println("认证返回结果")
return reponse
}
}
核心代码
kotlin
class RealChain(
private val interceptors:List<Interceptor>,
private val index:Int,
private val originalRequest:Request
):Chain {
override fun request(): Request {
return originalRequest
}
override fun proceed(request: Request): Response {
//所有拦截器执行完毕,执行真实业务
if(index >= interceptors.size){
return executeRealLogin(request)
}
//获取当前拦截器,并创建下一个chain
val nextChain = RealChain(interceptors,index+1,request)
return interceptors[index].interceptor(nextChain)
}
private fun executeRealLogin(request: Request):Response{
println("✅ 执行真实登录: ${request.userName}")
return if (request.userName == "admin" && request.passWord == "123456") {
Response(200, "登录成功", "abc123xyz")
} else {
Response(401, "用户名或密码错误")
}
}
}
日志输出

使用拦截器+责任链之后:
职责分离:每个拦截器只做一件事(单一职责)
可插拔扩展:新增功能只需要加一个Interceptor,无需改主流程
短路机制:当某个拦截器判断"无需继续时",可直接返回Response,不再调用chain.proceed()
java
if (isCached) {
return cacheResponse; // 不再往下传
}
return chain.proceed(request); // 继续传递
比如以下场景:
- 缓存命中 → 直接返回,跳过网络请求
- Token 过期 → 返回错误,不执行后续业务
- 权限不足 → 拦截并返回 403
这是责任链模式的特性:处理者可自主决定是否将请求传递给下一个节点。
比如在项目中,比如有免密支付和创建预订单两个拦截器去构建请求request。
我需要先进行请求免费支付流程,如果是PayPal才会走免密支付,否则直接return success,交由下一个拦截器创建预订单流程。
如果是免密支付则会赋值freePwd=true并传递给创建预订单的接口,预订单接口请求成功后结束拦截器流程(因为就两个拦截器),比如请求google支付的话就需要将请求预订单成功拿到返回的订单id(obfuscatedProfile)传递给google
sdk拉起支付。
代码示例:
支付拦截器流程分析
拦截器1:有密支付拦截器
检查是否满足有密支付条件(如用户开通了该功能)
若满足:执行有密支付逻辑,成功后设置 bypassPayment = true
若不满足:直接调用 chain.proceed() 继续下一个拦截器
拦截器2:创建预订单拦截器
检查 bypassPayment 标志
若为 true:直接使用有密支付结果
若为 false:创建新预订单
对 Google Pay 等渠道处理支付参数(如获取 obfuscatedProfile)
终止条件
当预订单创建完成后,责任链结束
代码实现示例(Kotlin)
kotlin
// 支付请求类(贯穿整个责任链)
data class PaymentRequest(
val isFastPayEnabled: Boolean,
var isBypassPayment: Boolean = false,
var paymentToken: String? = null,
var orderId: String? = null
)
// 支付响应类
data class PaymentResponse(
val isSuccess: Boolean,
val orderId: String? = null,
val error: String? = null
)
// 拦截器接口
interface PaymentInterceptor {
fun intercept(chain: PaymentChain): PaymentResponse
}
// 责任链接口
interface PaymentChain {
val request: PaymentRequest
fun proceed(): PaymentResponse
}
// 有密支付拦截器
class FastPayInterceptor : PaymentInterceptor {
override fun intercept(chain: PaymentChain): PaymentResponse {
val req = chain.request
if (!req.isFastPayEnabled) {
return chain.proceed() // 继续下一个拦截器
}
return simulateFastPay().also {
if (it.isSuccess) {
req.isBypassPayment = true
req.paymentToken = "FAST_${System.currentTimeMillis()}"
}
} ?: chain.proceed()
}
private fun simulateFastPay(): PaymentResponse {
println("⚡ 执行有密支付...")
return PaymentResponse(true) // 模拟成功
}
}
// 预订单拦截器
class OrderInterceptor : PaymentInterceptor {
override fun intercept(chain: PaymentChain): PaymentResponse {
val req = chain.request
return when {
else -> {
val order = createOrder()
if (order.isSuccess) {
req.orderId = "ORDER_${System.currentTimeMillis()}"
println("🛒 创建预订单: ${req.orderId}")
processGooglePay(order)
}
order
}
}
}
private fun createOrder(): PaymentResponse {
println("⏳ 创建预订单...")
return PaymentResponse(true)
}
private fun processGooglePay(order: PaymentResponse) {
if (order.isSuccess) {
println(" 处理Google Pay,获取obfuscatedProfile...")
// 这里会返回给客户端用于调起Google Pay SDK
}
}
}
// 实现的责任链
class RealPaymentChain(
override val request: PaymentRequest,
private val interceptors: List<PaymentInterceptor>,
private val index: Int = 0
) : PaymentChain {
override fun proceed(): PaymentResponse {
return if (index < interceptors.size) {
interceptors[index].intercept(
RealPaymentChain(request, interceptors, index + 1)
)
} else {
// 所有拦截器执行完毕的默认响应
PaymentResponse(false, error = "支付流程未完成")
}
}
}
// 客户端调用
fun main() {
val request = PaymentRequest(isFastPayEnabled = true) // 测试有密支付
// val request = PaymentRequest(isFastPayEnabled = false) // 测试普通支付
val chain = RealPaymentChain(
request,
listOf(FastPayInterceptor(), OrderInterceptor())
)
val response = chain.proceed()
println("\n💳 最终结果: $response")
}
状态传递:通过共享的 PaymentRequest 对象在拦截器间传递状态,最终构建一个request。