手擼golang 仿spring ioc/aop 之5 如何掃描
緣起
最近閱讀 [Spring Boot技術內(nèi)幕: 架構(gòu)設計與實現(xiàn)原理] (朱智勝 , 2020.6)
本系列筆記擬采用golang練習之
Talk is cheap, show me the code.
Spring
Spring的主要特性:
1. 控制反轉(zhuǎn)(Inversion of Control, IoC)
2. 面向容器
3. 面向切面(AspectOriented Programming, AOP)
源碼gitee地址:
https://gitee.com/ioly/learning.gooop
原文鏈接:
https://my.oschina.net/ioly
目標
- 參考spring常用注解氓皱,使用golang編寫“基于注解的靜態(tài)代碼增強器/生成器”
配置: ComponentScan,Configuration, Bean
Bean聲明:Component, Service, Controller
Bean注入:Autowried
AOP注解:Before, After, Around, PointCut
子目標(Day 5)
- Q:搞點啥?
- A:掃描go代碼文件
- Q:具體點?
- A:遞歸掃描指定的目錄下所有go代碼,并提取結(jié)構(gòu)體,字段,方法和注解信息
- Q:什么思路莉兰?
- A:
- 讀取go文件>解析package>解析import>解析struct列表>解析field列表>解析method列表
- 逐struct,解析注解
- 逐field礁竞,解析注解
- 逐method糖荒,解析注解
- Q:如何解析?
- A:讀取文本>清除注釋>逐行正則掃描
- Q:清除注釋模捂?
- A:因為注釋里面可以寫任何東西捶朵,所以清除注釋后可以減少解析錯誤的可能
- Q:如何清除?
- A:
- LINE_COMMENT = '//' [^\r\n]*
- 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之前的連續(xù)注釋行
- 提取 '// @'開頭的注釋 認為是注解行
- 提取具體注解
- ANNOTATION = '@' \w+ (SPACE+ ANNOTATION_ATTRIBUTE+)?
- ANNOTATION_ATTRIBUTE = AA_KEY '=' AA_VALUE
- AA_KEY = \w+
- AA_VALUE = [^\w,]+
(未完待續(xù))