spel

package
v0.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 20, 2026 License: MIT Imports: 3 Imported by: 0

README

spel 包 — 表达式语言

所属层级: Core Layer
设计理念: SpEL 风格表达式,动态求值
设计灵感: Spring Expression Language (SpEL)

概述

spel 包提供 SpEL(Spring Expression Language)风格的表达式解析和求值能力,支持属性访问、方法调用和复杂表达式计算。

核心功能
功能 说明
表达式解析 解析 SpEL 风格的表达式
属性访问 支持对象属性访问
方法调用 支持对象方法调用
上下文求值 基于 EvaluationContext 的表达式求值
拦截器支持 支持表达式求值拦截

核心接口

SpelParser 表达式解析器
type SpelParser struct{}
Expression 表达式接口
type Expression interface {
    GetValue(ctx EvaluationContext) (any, error)
}
EvaluationContext 求值上下文
type EvaluationContext interface {
    GetVariable(name string) (any, bool)
    SetVariable(name string, value any)
}

快速开始

基本表达式
package main

import (
    "fmt"
    "github.com/xudefa/enhance/spel"
)

func main() {
    parser := spel.NewSpelParser()

    // 简单属性表达式
    expr, err := parser.ParseExpression("name")
    if err != nil {
        // 处理错误
    }

    ctx := spel.NewEvaluationContext()
    ctx.SetVariable("name", "Alice")

    value, err := expr.GetValue(ctx)
    fmt.Println(value) // Output: Alice
}

API 参考

复杂表达式
parser := spel.NewSpelParser()

// 嵌套属性访问
expr, _ := parser.ParseExpression("user.name")

ctx := spel.NewEvaluationContext()
ctx.SetVariable("user", User{Name: "Alice"})

value, _ := expr.GetValue(ctx)
// value == "Alice"
字面量
parser := spel.NewSpelParser()

// 布尔字面量
expr, _ := parser.ParseExpression("true")
value, _ := expr.GetValue(nil)
// value == true

// 数字字面量
expr, _ := parser.ParseExpression("42")
value, _ := expr.GetValue(nil)
// value == 42
表达式类型
PropertyExpression

简单属性表达式,访问上下文中的变量:

expr := &spel.PropertyExpression{Property: "name"}
ComplexExpression

复杂表达式,支持更复杂的表达式计算:

expr := &spel.ComplexExpression{Raw: "user.name"}

使用示例

条件表达式
parser := spel.NewSpelParser()

// 条件判断
expr, _ := parser.ParseExpression("age > 18")

ctx := spel.NewEvaluationContext()
ctx.SetVariable("age", 20)

result, _ := expr.GetValue(ctx)
// result == true
方法调用
parser := spel.NewSpelParser()

// 方法调用表达式
expr, _ := parser.ParseExpression("user.GetName()")

ctx := spel.NewEvaluationContext()
ctx.SetVariable("user", &User{Name: "Alice"})

value, _ := expr.GetValue(ctx)
// value == "Alice"
与 AOP 集成
// 使用表达式解析方法参数
func parseArgs(expr string, args []any) any {
    parser := spel.NewSpelParser()
    parsed, _ := parser.ParseExpression(expr)
    
    ctx := spel.NewEvaluationContext()
    for i, arg := range args {
        ctx.SetVariable(fmt.Sprintf("arg%d", i), arg)
    }
    
    value, _ := parsed.GetValue(ctx)
    return value
}

// 在拦截器中使用
func (i *MyInterceptor) Before(method string, args []any) {
    key := parseArgs("#arg0", args)
    cache.Get(key)
}

最佳实践

1. 缓存表达式解析结果
// ✅ 推荐:缓存解析后的表达式
var parsedExpr spel.Expression

func init() {
    parser := spel.NewSpelParser()
    parsedExpr, _ = parser.ParseExpression("user.name")
}

func evaluate(ctx spel.EvaluationContext) any {
    value, _ := parsedExpr.GetValue(ctx)
    return value
}

// ⚠️ 不推荐:每次求值都重新解析
func evaluate(ctx spel.EvaluationContext) any {
    parser := spel.NewSpelParser()
    expr, _ := parser.ParseExpression("user.name")
    return expr.GetValue(ctx)
}
2. 使用类型安全的求值
// ✅ 推荐:类型断言确保类型安全
func GetUserName(ctx spel.EvaluationContext) string {
    parser := spel.NewSpelParser()
    expr, _ := parser.ParseExpression("user.name")
    
    value, err := expr.GetValue(ctx)
    if err != nil {
        return ""
    }
    
    if name, ok := value.(string); ok {
        return name
    }
    return ""
}

// ⚠️ 不推荐:直接使用 any 类型
func GetUserName(ctx spel.EvaluationContext) any {
    parser := spel.NewSpelParser()
    expr, _ := parser.ParseExpression("user.name")
    value, _ := expr.GetValue(ctx)
    return value
}
3. 处理求值错误
// ✅ 推荐:检查求值错误
func safeEvaluate(ctx spel.EvaluationContext) (string, error) {
    parser := spel.NewSpelParser()
    expr, err := parser.ParseExpression("user.name")
    if err != nil {
        return "", fmt.Errorf("parse expression failed: %w", err)
    }
    
    value, err := expr.GetValue(ctx)
    if err != nil {
        return "", fmt.Errorf("evaluate expression failed: %w", err)
    }
    
    if name, ok := value.(string); ok {
        return name, nil
    }
    return "", fmt.Errorf("unexpected type: %T", value)
}

// ⚠️ 不推荐:忽略错误
func unsafeEvaluate(ctx spel.EvaluationContext) string {
    parser := spel.NewSpelParser()
    expr, _ := parser.ParseExpression("user.name")
    value, _ := expr.GetValue(ctx)
    return value.(string)
}
4. 与依赖注入集成
// ✅ 推荐:将 SpelParser 注册为 Bean
container.Register(
    reflect.TypeOf(&spel.SpelParser{}),
    core.Bean(spel.NewSpelParser()),
    core.Singleton(),
)

// 注入使用
type CacheService struct {
    Parser *spel.SpelParser `inject:"spelParser"`
}

func (s *CacheService) GetCacheKey(expr string, args []any) string {
    parsed, _ := s.Parser.ParseExpression(expr)
    ctx := spel.NewEvaluationContext()
    // 设置变量...
    value, _ := parsed.GetValue(ctx)
    return value.(string)
}

Documentation

Overview

Package spel 提供 Spring Expression Language (SpEL) 表达式支持,用于 enhance 框架。

Package spel 提供 Spring Expression Language (SpEL) 表达式支持,用于 enhance 框架。

该模块提供表达式解析、求值上下文、属性访问器和方法拦截器等功能。 参考 Spring Framework 的 SpEL 设计。

架构设计

  • Expression: 表达式接口,定义表达式求值和设置操作
  • ExpressionParser: 表达式解析器接口,解析表达式字符串
  • EvaluationContext: 表达式求值上下文接口,管理根对象和变量
  • PropertyAccessor: 属性访问器接口,提供属性读写操作
  • MethodInterceptor: 方法拦截器接口,用于方法调用拦截
  • MethodInvocation: 方法调用上下文接口,提供方法调用信息

核心功能

  • 表达式解析: 支持属性访问、方法调用、运算符等表达式语法
  • 动态求值: 在运行时根据上下文计算表达式值
  • 属性访问: 基于反射的属性读写支持
  • 变量管理: 支持在上下文中设置和获取命名变量
  • 方法拦截: 支持方法调用前后的拦截逻辑

使用方式

解析和求值表达式:

parser := spel.NewSpelParser()
expr, err := parser.ParseExpression("user.name")
if err != nil {
    // 处理解析错误
}

context := spel.NewStandardEvaluationContext(user)
value, err := expr.GetValue(context)

设置变量:

context.SetVariable("role", "admin")
expr, _ := parser.ParseExpression("#role")
value, _ := expr.GetValue(context)

方法拦截:

interceptor := spel.NewLoggingInterceptor()
chain := spel.NewInterceptorChain([]spel.MethodInterceptor{interceptor})
result, err := chain.Proceed()

Package spel 提供 Spring Expression Language (SpEL) 表达式支持,用于 enhance 框架。

Package spel 提供 Spring Expression Language (SpEL) 表达式支持,用于 enhance 框架。

Index

Constants

This section is empty.

Variables

View Source
var GlobalSpelParser = NewSpelParser()

GlobalSpelParser 全局 SpEL 解析器实例。

Functions

func Evaluate

func Evaluate(expression string, root any) (any, error)

Evaluate 计算表达式(便捷函数)。

Types

type EvaluationContext

type EvaluationContext interface {
	// GetRootObject 获取根对象。
	GetRootObject() any

	// SetRootObject 设置根对象。
	SetRootObject(root any)

	// GetVariable 获取命名变量。
	GetVariable(name string) (any, bool)

	// SetVariable 设置命名变量。
	SetVariable(name string, value any)

	// GetPropertyAccessor 获取属性访问器。
	GetPropertyAccessor() PropertyAccessor
}

EvaluationContext 表达式求值上下文接口。

管理表达式的根对象、命名变量和属性访问器。

func NewStandardEvaluationContext

func NewStandardEvaluationContext(root any) EvaluationContext

NewStandardEvaluationContext 创建标准求值上下文。

type Expression

type Expression interface {
	// GetValue 在给定上下文中计算表达式值。
	GetValue(context EvaluationContext) (any, error)

	// SetValue 在给定上下文中设置表达式值。
	SetValue(context EvaluationContext, value any) error

	// String 返回表达式字符串。
	String() string
}

Expression 表达式接口。

定义表达式求值和设置操作的标准接口。

func ParseExpression

func ParseExpression(expression string) (Expression, error)

ParseExpression 解析表达式(便捷函数)。

type ExpressionParser

type ExpressionParser interface {
	// ParseExpression 解析表达式字符串为 Expression。
	ParseExpression(expression string) (Expression, error)
}

ExpressionParser 表达式解析器接口。

解析表达式字符串为可执行的 Expression 对象。

func NewSpelParser

func NewSpelParser() ExpressionParser

NewSpelParser 创建 SpEL 表达式解析器。

type MethodInterceptor

type MethodInterceptor interface {
	// Invoke 执行拦截逻辑,可以选择调用原方法或返回自定义结果。
	Invoke(invocation MethodInvocation) (any, error)
}

MethodInterceptor 方法拦截器接口。

用于在方法调用前后执行额外逻辑,如日志、权限检查、缓存等。

func NewInterceptorChain

func NewInterceptorChain(interceptors []MethodInterceptor) MethodInterceptor

NewInterceptorChain 创建拦截器链。

func NewLoggingInterceptor

func NewLoggingInterceptor() MethodInterceptor

NewLoggingInterceptor 创建日志拦截器。

type MethodInvocation

type MethodInvocation interface {
	// GetMethod 获取方法名。
	GetMethod() string

	// GetArguments 获取方法参数。
	GetArguments() []any

	// GetTarget 获取目标对象。
	GetTarget() any

	// Proceed 继续执行原方法。
	Proceed() (any, error)
}

MethodInvocation 方法调用上下文接口。

提供对被调用方法、目标对象和参数的访问, 拦截器可以通过 Proceed() 继续执行原方法。

func NewSimpleMethodInvocation

func NewSimpleMethodInvocation(method string, arguments []any, target any, proceedFn func() (any, error)) MethodInvocation

NewSimpleMethodInvocation 创建简单方法调用。

type PropertyAccessor

type PropertyAccessor interface {
	// GetProperty 从目标对象获取指定属性。
	GetProperty(target any, name string) (any, error)

	// SetProperty 设置目标对象的指定属性。
	SetProperty(target any, name string, value any) error
}

PropertyAccessor 属性访问器接口。

提供从目标对象读写属性的标准方法。

func NewReflectPropertyAccessor

func NewReflectPropertyAccessor() PropertyAccessor

NewReflectPropertyAccessor 创建反射属性访问器。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL