metadata

package
v0.0.5 Latest Latest
Warning

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

Go to latest
Published: Aug 2, 2026 License: MIT Imports: 7 Imported by: 0

README

metadata 包 — 元数据编程

所属层级: Core Layer
设计理念: 反射驱动,注解解析
设计灵感: Spring MetadataReader

概述

metadata 包提供元数据编程和注解处理能力,参考 Spring MetadataReader 设计,支持通过 struct tag 或自定义解析器读取类型的元数据信息。

核心功能
功能 说明
元数据读取 通过反射读取类型的元数据信息
注解解析 支持 struct tag 注解解析
缓存机制 避免重复解析同一类型
可扩展 支持自定义注解解析器

核心接口

MetadataReader 元数据读取器
type MetadataReader interface {
    // GetAnnotations 获取目标的所有注解
    GetAnnotations(target any) []Annotation
    
    // GetAnnotation 获取指定名称的注解
    GetAnnotation(target any, name string) Annotation
    
    // HasAnnotation 检查是否存在指定注解
    HasAnnotation(target any, name string) bool
}
AnnotationResolver 注解解析器
type AnnotationResolver interface {
    ResolveAnnotations(t reflect.Type) []Annotation
}
Annotation 注解结构体
type Annotation struct {
    Name       string
    Attributes map[string]any
}

内置实现

ReflectMetadataReader 基于反射的元数据读取器

基于反射的元数据读取器,带缓存机制:

  • 避免重复解析同一类型
  • 支持自定义 AnnotationResolver
  • 线程安全的缓存访问
TagAnnotationResolver 基于 struct tag 的注解解析器

基于 struct tag 的注解解析器:

  • 解析格式为 metadata:"name:attr1=val1,attr2=val2" 的 tag
  • 支持多种属性类型
  • 自动类型转换

快速开始

基本使用
package main

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

type User struct {
    Name string `metadata:"field:name=fullName,required=true"`
    Age  int    `metadata:"field:name=age,type=number"`
}

func main() {
    reader := metadata.NewReflectMetadataReader(nil)
    anns := reader.GetAnnotations(User{})

    for _, ann := range anns {
        fmt.Printf("Annotation: %s\n", ann.Name)
        for key, val := range ann.Attributes {
            fmt.Printf("  %s: %v\n", key, val)
        }
    }
}

API 参考

获取指定注解
ann := reader.GetAnnotation(User{}, "field")
if ann.Name != "" {
    name, _ := ann.GetStringAttribute("name")
    required, _ := ann.GetAttribute("required")
    fmt.Printf("Field name: %s, Required: %v\n", name, required)
}
检查注解存在性
if reader.HasAnnotation(User{}, "field") {
    // User 结构体有 field 注解
}
自定义注解解析器
type CustomResolver struct{}

func (r *CustomResolver) ResolveAnnotations(t reflect.Type) []metadata.Annotation {
    // 自定义解析逻辑
    return []metadata.Annotation{
        {
            Name: "custom",
            Attributes: map[string]any{
                "key": "value",
            },
        },
    }
}

reader := metadata.NewReflectMetadataReader(&CustomResolver{})

使用示例

Struct Tag 格式
`metadata:"name:attr1=val1,attr2=val2"`
  • name:注解名称
  • attr1=val1:属性键值对
  • 多个属性用逗号分隔
示例
type User struct {
    Name string `metadata:"field:name=fullName,required=true,minLength=1"`
    Age  int    `metadata:"field:name=age,type=number,min=0,max=150"`
}
与验证框架集成
type Validator struct {
    reader metadata.MetadataReader
}

func (v *Validator) Validate(obj any) error {
    anns := v.reader.GetAnnotations(obj)
    
    for _, ann := range anns {
        if ann.Name == "field" {
            required, _ := ann.GetAttribute("required")
            if required == true {
                // 检查字段是否为空
                fieldValue := reflect.ValueOf(obj).FieldByName(ann.Attributes["name"].(string))
                if fieldValue.IsZero() {
                    return fmt.Errorf("field %s is required", ann.Attributes["name"])
                }
            }
        }
    }
    
    return nil
}
与依赖注入集成
type BeanFactory struct {
    reader metadata.MetadataReader
}

func (f *BeanFactory) CreateBean(t reflect.Type) any {
    anns := f.reader.GetAnnotations(t)
    
    for _, ann := range anns {
        if ann.Name == "bean" {
            name, _ := ann.GetStringAttribute("name")
            scope, _ := ann.GetStringAttribute("scope")
            
            // 根据注解创建 Bean
            return f.createBeanInstance(t, name, scope)
        }
    }
    
    return nil
}

最佳实践

1. 使用缓存提升性能
// ✅ 推荐:使用内置缓存机制
reader := metadata.NewReflectMetadataReader(nil)
// 第一次解析会缓存,后续直接使用缓存
anns := reader.GetAnnotations(User{})

// ⚠️ 不推荐:每次都创建新的读取器
func getAnnotations() []metadata.Annotation {
    reader := metadata.NewReflectMetadataReader(nil)
    return reader.GetAnnotations(User{})
}
2. 自定义注解解析器
// ✅ 推荐:根据需求自定义解析器
type DatabaseResolver struct{}

func (r *DatabaseResolver) ResolveAnnotations(t reflect.Type) []metadata.Annotation {
    var anns []metadata.Annotation
    
    // 解析数据库相关注解
    if t.Kind() == reflect.Struct {
        if tableTag, ok := t.FieldByName("ID").Tag.Lookup("db"); ok {
            anns = append(anns, metadata.Annotation{
                Name: "table",
                Attributes: map[string]any{
                    "name": tableTag,
                },
            })
        }
    }
    
    return anns
}

reader := metadata.NewReflectMetadataReader(&DatabaseResolver{})

// ⚠️ 不推荐:使用默认解析器处理所有场景
reader := metadata.NewReflectMetadataReader(nil)
3. 类型安全的属性访问
// ✅ 推荐:使用类型安全的访问方法
ann := reader.GetAnnotation(User{}, "field")
name, ok := ann.GetStringAttribute("name")
if !ok {
    // 处理类型错误
}

required, ok := ann.GetBoolAttribute("required")
if !ok {
    // 处理类型错误
}

// ⚠️ 不推荐:直接访问 Attributes map
name := ann.Attributes["name"].(string) // 可能 panic
4. 与依赖注入集成
// ✅ 推荐:将 MetadataReader 注册为 Bean
container.Register(
    reflect.TypeOf(&metadata.MetadataReader{}),
    core.Bean(createMetadataReader()),
    core.Singleton(),
)

// 注入使用
type BeanFactory struct {
    Reader metadata.MetadataReader `inject:"metadataReader"`
}

func (f *BeanFactory) CreateBean(t reflect.Type) any {
    anns := f.Reader.GetAnnotations(t)
    // 根据注解创建 Bean
}
5. 设计原则
  • 参考 Spring MetadataReader:借鉴 Spring 的元数据编程设计理念
  • 缓存优化:避免重复解析,提高性能
  • 类型安全:利用 Go 的反射机制实现类型安全的元数据读取
  • 可扩展:支持自定义注解解析器
  • 零外部依赖:核心框架仅使用 Go 标准库

Documentation

Overview

Package metadata 提供元数据管理功能,用于 enhance 框架。

该模块用于存储和管理应用、组件、请求等的元数据信息。 提供类型安全的元数据访问接口,支持注解解析和配置元数据生成。

架构设计

  • Annotation: 注解结构体,用于标记和描述
  • PropertyMetadata/GroupMetadata/HintMetadata: 配置元数据结构
  • ConfigurationMetadata: 完整的配置元数据
  • MetadataGenerator: 元数据生成器接口
  • PropertyIndex: 属性索引接口,用于快速查找
  • TagAnnotationResolver: 基于 struct tag 的注解解析器接口

核心功能

  • 注解解析: 支持基于 struct tag 的注解解析
  • 配置元数据: 自动生成配置元数据(属性、组、提示)
  • 属性索引: 支持快速查找和按前缀查询
  • 类型映射: 自动映射 Go 类型到配置类型字符串

使用方式

生成配置元数据:

type ServerConfig struct {
    Port int    `config:"server.port" description:"服务端口"`
    Host string `config:"server.host" description:"服务地址"`
}

metadata := metadata.GenerateFromStruct(&ServerConfig{})
jsonStr, _ := metadata.ToJSON()

使用注解解析器:

resolver := metadata.NewTagAnnotationResolver("metadata")
annotations := resolver.ResolveAnnotations(reflect.TypeOf(MyStruct{}))

配置提示

支持为配置属性添加提示值和提供者:

gen := metadata.NewMetadataGenerator()
gen.Register(&config)
gen.WithHint("server.port", []metadata.HintValue{
    {Value: "8080", Description: "默认端口"},
})

Package metadata 提供元数据管理功能,用于 enhance 框架。

Package metadata 提供元数据管理功能,用于 enhance 框架。

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func GenerateJSON

func GenerateJSON(configs ...any) (string, error)

GenerateJSON 从结构体生成 JSON 格式的元数据。

func GetBoolAttribute

func GetBoolAttribute(ann Annotation, key string) (bool, bool)

GetBoolAttribute 获取布尔类型的属性值

参数:

  • ann: 注解
  • key: 属性键

返回值:

  • bool: 属性值
  • bool: 是否存在

func GetIntAttribute

func GetIntAttribute(ann Annotation, key string) (int, bool)

GetIntAttribute 获取整数类型的属性值

参数:

  • ann: 注解
  • key: 属性键

返回值:

  • int: 属性值
  • bool: 是否存在且类型匹配

func GetStringAttribute

func GetStringAttribute(ann Annotation, key string) (string, bool)

GetStringAttribute 获取字符串类型的属性值

参数:

  • ann: 注解
  • key: 属性键

返回值:

  • string: 属性值
  • bool: 是否存在

func ValidateProperty

func ValidateProperty(name string, value string, metadata PropertyMetadata) error

ValidateProperty 验证属性值。

Types

type Annotation

type Annotation struct {
	// Name 注解名称。
	Name string
	// Attributes 注解属性。
	Attributes map[string]any
}

Annotation 注解结构体。

type ConfigurationMetadata

type ConfigurationMetadata struct {
	// Groups 配置组。
	Groups []GroupMetadata `json:"groups,omitempty"`
	// Properties 配置属性。
	Properties []PropertyMetadata `json:"properties"`
	// Hints 配置提示。
	Hints []HintMetadata `json:"hints,omitempty"`
}

ConfigurationMetadata 完整的配置元数据。

func GenerateFromStruct

func GenerateFromStruct(configs ...any) *ConfigurationMetadata

GenerateFromStruct 从结构体类型直接生成元数据。

func (*ConfigurationMetadata) ToJSON

func (m *ConfigurationMetadata) ToJSON() (string, error)

ToJSON 将元数据转换为 JSON 字符串。

type GroupMetadata

type GroupMetadata struct {
	// Name 组名称(如 server)。
	Name string `json:"name"`
	// Type 组类型(结构体名称)。
	Type string `json:"type"`
	// Description 组描述。
	Description string `json:"description,omitempty"`
	// SourceType 来源类型。
	SourceType string `json:"sourceType,omitempty"`
}

GroupMetadata 配置组元数据。

type HintMetadata

type HintMetadata struct {
	// Name 属性名称。
	Name string `json:"name"`
	// Values 可选值。
	Values []HintValue `json:"values,omitempty"`
	// Providers 提供者。
	Providers []HintProvider `json:"providers,omitempty"`
}

HintMetadata 配置提示元数据。

type HintProvider

type HintProvider struct {
	// Name 提供者名称。
	Name string `json:"name"`
	// Parameters 参数。
	Parameters map[string]string `json:"parameters,omitempty"`
}

HintProvider 提示提供者。

type HintValue

type HintValue struct {
	// Value 值。
	Value string `json:"value"`
	// Description 描述。
	Description string `json:"description,omitempty"`
}

HintValue 提示值。

type MetadataGenerator

type MetadataGenerator interface {
	// Register 注册配置结构体。
	Register(config any) MetadataGenerator

	// WithHint 添加配置提示。
	WithHint(propertyName string, values []HintValue) MetadataGenerator

	// WithHintProvider 添加提示提供者。
	WithHintProvider(propertyName string, providerName string, params map[string]string) MetadataGenerator

	// Generate 生成配置元数据。
	Generate() *ConfigurationMetadata
}

MetadataGenerator 元数据生成器接口。

用于从结构体生成配置元数据。

func NewMetadataGenerator

func NewMetadataGenerator() MetadataGenerator

NewMetadataGenerator 创建元数据生成器。

type PropertyIndex

type PropertyIndex interface {
	// Get 获取属性元数据。
	Get(name string) (PropertyMetadata, bool)

	// Has 检查属性是否存在。
	Has(name string) bool

	// GetAll 获取所有属性。
	GetAll() []PropertyMetadata

	// GetByPrefix 按前缀获取属性。
	GetByPrefix(prefix string) []PropertyMetadata
}

PropertyIndex 属性索引接口。

用于快速查找和按前缀查询属性元数据。

func NewPropertyIndex

func NewPropertyIndex(metadata *ConfigurationMetadata) PropertyIndex

NewPropertyIndex 创建属性索引。

type PropertyMetadata

type PropertyMetadata struct {
	// Name 属性名称(如 server.port)。
	Name string `json:"name"`
	// Type 属性类型。
	Type string `json:"type"`
	// Description 属性描述。
	Description string `json:"description,omitempty"`
	// DefaultValue 默认值。
	DefaultValue string `json:"defaultValue,omitempty"`
	// Deprecated 是否已弃用。
	Deprecated bool `json:"deprecated,omitempty"`
	// DeprecationReason 弃用原因。
	DeprecationReason string `json:"deprecationReason,omitempty"`
	// SourceType 来源类型(结构体名称)。
	SourceType string `json:"sourceType,omitempty"`
	// Required 是否必填。
	Required bool `json:"required,omitempty"`
	// Secret 是否是敏感信息(如密码)。
	Secret bool `json:"secret,omitempty"`
}

PropertyMetadata 配置属性元数据。

type TagAnnotationResolver

type TagAnnotationResolver interface {
	// ResolveAnnotations 解析指定类型的注解。
	ResolveAnnotations(typ reflect.Type) []Annotation
}

TagAnnotationResolver 基于 struct tag 的注解解析器接口。

解析格式为 `metadata:"name:attr1=val1,attr2=val2"` 的 tag。 支持多种属性类型和自动类型转换。

func NewTagAnnotationResolver

func NewTagAnnotationResolver(tagName string) TagAnnotationResolver

NewTagAnnotationResolver 创建 TagAnnotationResolver。

参数:

  • tagName: tag 名称,默认为 "metadata"

返回值:

  • TagAnnotationResolver: 解析器实例

Jump to

Keyboard shortcuts

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