Documentation
¶
Overview ¶
Package aop 提供轻量级方法级切面(面向切面编程),对标 Spring AOP 的 @Before / @After / @Around,用于 Service 层:
- 方法调用前后拦截(日志、耗时统计)
- 前置校验(权限、参数),返回 error 终止调用
- 环绕包装(事务、重试、熔断、上下文注入)
Web 层请使用 webiris 中间件(等同环绕切面:AccessLog/Auth/Limit/ErrorHandler)。 本包面向非 Web 场景(Service/Repository 方法)。
用法:
// 原始方法(任意签名)
getUser := func(ctx context.Context, id int64) (*User, error) { ... }
// 环绕切面:耗时 + 日志
getUser = aop.Around(getUser, func(ctx context.Context, params []interface{},
next func() ([]interface{}, error)) ([]interface{}, error) {
start := time.Now()
results, err := next()
log.Printf("GetUser cost=%s err=%v", time.Since(start), err)
return results, err
}).(func(context.Context, int64) (*User, error))
// 前置校验:返回 error 终止调用
getUser = aop.Before(getUser, func(ctx context.Context, params []interface{}) error {
if id := params[1].(int64); id <= 0 {
return errors.New("invalid user id")
}
return nil
}).(func(context.Context, int64) (*User, error))
与 gbxioc 配合:将装饰后的 Service 结构注册进容器, 业务调用方无感知(接口签名不变)。
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ErrAborted = errors.New("aop: call aborted by before hook")
ErrAborted 由前置切面返回时,调用被终止的通用错误。
Functions ¶
func After ¶
func After(fn interface{}, hooks ...AfterHook) interface{}
After 为目标函数附加后置切面(记录日志/耗时/结果审计)。
func Around ¶
func Around(fn interface{}, hook AroundHook) interface{}
Around 为目标函数附加环绕切面(事务/重试/熔断/耗时统计)。
func Before ¶
func Before(fn interface{}, hooks ...BeforeHook) interface{}
Before 为目标函数附加前置切面,返回与原函数同签名的新函数(需类型断言使用)。 hook 返回 error 时终止调用,直接返回该错误(结果切片为空)。
Types ¶
type AroundHook ¶
type AroundHook func(ctx context.Context, params []interface{}, next func() ([]interface{}, error)) ([]interface{}, error)
AroundHook 环绕切面:包裹目标方法调用;调用 next() 执行目标方法。
type Aspect ¶ added in v1.19.0
type Aspect interface {
// Name 切面名(日志/去重用)。
Name() string
// Before 前置拦截:可读/改 JoinPoint.Params;返回 error 终止调用。
// 返回 ErrAborted 时调用被终止,不执行目标方法。
Before(ctx context.Context, joinPoint *JoinPoint) error
// After 后置回调:目标方法返回后执行(无论成功失败),
// 可读取 JoinPoint.Results / Err / Cost。
After(ctx context.Context, joinPoint *JoinPoint)
}
Aspect 面向切面接口(对标 Spring AOP @Aspect): 实现该接口即成为可接入的切面,业务 Service 通过 aop.Proxy 自动拦截。
type LogAspect struct{}
func (LogAspect) Name() string { return "log" }
func (LogAspect) Before(ctx context.Context, jp *aop.JoinPoint) error {
log.Printf("call %s params=%v", jp.Method, jp.Params)
return nil
}
func (LogAspect) After(ctx context.Context, jp *aop.JoinPoint) {
log.Printf("call %s cost=%s err=%v", jp.Method, jp.Cost, jp.Err)
}
type BeforeHook ¶
BeforeHook 前置切面:在目标方法调用前执行;返回 error 终止调用。
type Context ¶
type Context struct {
// Method 方法名(反射推断,无则空)。
Method string
// Params 调用参数(只读,修改不生效)。
Params []interface{}
}
Context 携带调用信息。
type JoinPoint ¶ added in v1.19.0
type JoinPoint struct {
// Method 被调用方法名(如 "GetUser")。
Method string
// Target 目标对象(Service 实现实例)。
Target interface{}
// Proxy 代理对象(调用方持有的引用)。
Proxy interface{}
// Params 调用参数;Before 中可修改(修改会传递给目标方法与后续切面)。
Params []interface{}
// Results 目标方法返回值(不含 error);After 中可读取。
Results []interface{}
// Err 目标方法返回的错误;Before 阶段为 nil。
Err error
// Start 调用开始时间。
Start time.Time
// Cost 调用耗时(After 中有效)。
Cost time.Duration
}
JoinPoint 连接点上下文:切面中可获取/操作的全部调用信息。 与 Spring AOP 的 JoinPoint/ProceedingJoinPoint 对齐。
type Proxy ¶ added in v1.19.0
type Proxy struct {
// contains filtered or unexported fields
}
Proxy 是面向切面的方法调用执行器: 业务 Service 接口的代理实现通过 Invoke 触发切面链,目标方法由 next 闭包执行。
type UserService interface { GetUser(ctx context.Context, id int64) (*User, error) }
type userServiceProxy struct {
inner *userServiceImpl
aop *aop.Proxy
}
func (p *userServiceProxy) GetUser(ctx context.Context, id int64) (*User, error) {
var result *User
_, err := p.aop.Invoke(ctx, "GetUser", []interface{}{ctx, id}, func() ([]interface{}, error) {
var callErr error
result, callErr = p.inner.GetUser(ctx, id)
return []interface{}{result}, callErr
})
return result, err
}
func NewProxy ¶ added in v1.19.0
NewProxy 创建代理执行器。 target 为目标对象(JoinPoint.Target);aspects 按注册顺序执行 (Before 顺序、After 逆序,洋葱模型,与 Spring 一致)。
func (*Proxy) AddAspects ¶ added in v1.19.0
AddAspects 运行时追加切面(热插拔切面)。