关于golang:手撸golang-仿spring-iocaop-之5-如何扫描

6次阅读

共计 2045 个字符,预计需要花费 6 分钟才能阅读完成。

手撸 golang 仿 spring ioc/aop 之 5 如何扫描

缘起

最近浏览 [Spring Boot 技术底细: 架构设计与实现原理] (朱智胜 , 2020.6)
本系列笔记拟采纳 golang 练习之
Talk is cheap, show me the code.

Spring

Spring 的次要个性:1. 管制反转(Inversion of Control, IoC)2. 面向容器
3. 面向切面(AspectOriented Programming, AOP)源码 gitee 地址:https://gitee.com/ioly/learning.gooop

原文链接:https://my.oschina.net/ioly

指标

  • 参考 spring 罕用注解,应用 golang 编写“基于注解的动态代码增强器 / 生成器”

    • 配置:ComponentScan,Configuration, Bean
    • Bean 申明:Component, Service, Controller
    • Bean 注入:Autowried
    • AOP 注解:Before, After, Around, PointCut

子目标(Day 5)

  • Q:搞点啥?
  • A:扫描 go 代码文件
  • Q:具体点?
  • A:递归扫描指定的目录下所有 go 代码,并提取构造体,字段,办法和注解信息
  • Q:什么思路?
  • A:

      1. 读取 go 文件 > 解析 package> 解析 import> 解析 struct 列表 > 解析 field 列表 > 解析 method 列表
      1. 逐 struct,解析注解
      1. 逐 field,解析注解
      1. 逐 method,解析注解
  • Q:如何解析?
  • A:读取文本 > 革除正文 > 逐行正则扫描
  • Q:革除正文?
  • A:因为正文外面能够写任何货色,所以革除正文后能够缩小解析谬误的可能
  • Q:如何革除?
  • A:

    • LINE_COMMENT = ‘//’ 1*
    • PARA_COMMENT = ‘/‘ . ‘*/’
  • Q:扫描 package?
  • A:PACKAGE =‘package’ SPACE+ \w+
  • Q:扫描 import?
  • A:

    • SINGLE_IMPORT = ‘import’ SPACE+ PACKAGE_LITERAL
    • PACKAGE_LITERAL = (PACKAGE_ALIAS SPACE+)? “\w+(/\w+)*”
    • MULTI_IMPORT = ‘import’ SPACE+ ‘(\r\n’ (SPACE* PACKAGE_LITERAL)+ ‘\r\n)’
  • Q:扫描 struct?
  • A:

    • STRUCT_START = ‘type’ SPACE+ \w+ SPACE+ ‘struct’ SPACE+ ‘{‘
    • STRUCT_END = ‘}’
  • Q:扫描 field?
  • A:

    • STRUCT_FIELD = SPACE+ \w+ FIELD_TYPE
    • FIELD_TYPE = BASIC_TYPE | CUSTOM_TYPE | POINTER_TYPE | ARRAY_TYPE | MAP_TYPE
    • BASIC_TYPE = ‘int’ | ‘string’ | ‘bool’ |’uint‘| ‘rune’ | ‘byte’ | ‘int8’ | ‘uint8’ | ‘int16’ | ‘uint16’ | ‘int32’ | ‘uint32’ | ‘int64’ | ‘uint64’ | ‘float32’ | ‘float64’
    • CUSTOM_TYPE = (PACKAGE_ALIAS.)?\w+
    • POINTER_TYPE = ‘*’ FIELD_TYPE
    • ARRAY_TYPE = ‘[]’ FIELD_TYPE
    • MAP_TYPE = ‘map[‘ FIELD_TYPE ‘]’ FIELD_TYPE
  • Q:扫描 method?
  • A:

    • METHOD_START = ‘func’ SPACE+ RECEIVER METHOD_ARGS METHOD_RETURNS? ‘{‘
    • RECEIVER = ‘(‘ RECEIVER_VAR *? RECEIVER_TYPE ‘)’
    • RECEIVER_VAR = \w+
    • RECEIVER_TYPE = \w+
    • METHOD_ARGS = ‘(‘ SPACE METHOD_ARG? (SPACE ‘,’ SPACE METHOD_ARG) ‘)’
    • METHOD_ARG = \w+ SPACE* FIELD_TYPE
    • RETURNS = SINGLE_RETURN | MULTI_RETURN
    • SINGLE_RETURN = FIELD_TYPE
    • METHOD_RETURNS = ‘(‘ SPACE RETURN_ARG? (SPACE ‘,’ SPACE RETURN_ARG) ‘)’
    • RETURN_ARG = NAMED_RETURN_ARG | UNNAMED_RETURN_ARG
    • NAMED_RETURN_ARG = \w+ SPACE* FIELD_TYPE
    • UNNAMED_RETURN_ARG = FIELD_TYPE
  • Q:提取注解?
  • A:

    • 提取指定 struct/field/method 之前的间断正文行
    • 提取 ‘// @’ 结尾的正文 认为是注解行
    • 提取具体注解

      • ANNOTATION = ‘@’ \w+ (SPACE+ ANNOTATION_ATTRIBUTE+)?
      • ANNOTATION_ATTRIBUTE = AA_KEY ‘=’ AA_VALUE
      • AA_KEY = \w+
      • AA_VALUE = 2+

(未完待续)


  1. \r\n ↩
  2. \w, ↩
正文完
 0