弱语言代表:Hyperf,一个基于 PHP Swoole 扩展的常驻内存框架
注解概念的举例说明;
-
说白了就是,你当领导,破烂事让秘书帮你去安排,你只需要批注一下,例如下周要举办一场活动,秘书将方案交给你审批,你看完后,在上面批注,要找4个知名专家来做客,要拍摄10张优质的图片做宣发小手册,秘书接到后,就开始按照你的要求帮你邀请这4个知名专家,同时还会给你拍一堆照片,同时筛选出来10个优质的做成小手册。
-
因为注解就是一种批注,批注者是不用执行的,所以注解里面看不到什么代码细节,而只是定义了该注解传入的可选参数
-
这是以leader的方式来理解注解,如果站在流水线工人的角度来理解也可以,每个流水线的工人招聘进来之后,对公司并不了解,也不知道有多少部门,但一进来就要上手开始干活了。例如A工人现在干的是加别针,他的职位牌上就是加别针,而别针的目的是为了挂铭牌,但是目前这个流水线工人不知道铭牌让谁来加,所以他就在别针上加了一个备注——挂铭牌,管理者整理衣服时会让找来挂铭牌的工人进行挂铭牌
-
这样工人的行为就被拆解的足够细,而整个调度过程被另外一个体系控制,所以每个工人的工作就变轻松了,他只需要知道自己要干什么,需要什么即可,至于上一个或下一个流程是谁,他不关心,这样就实现了彻底的解耦。
-
-
变换到代码层面来理解,就是你加上备注的代码,不是直接就拿去运行了,会有一个组织者,SpringBoot中就是 starter,这个 starter 会把所有带有注解的类(招聘清单)自动创建成对象(符合清单的工人),就像提前招聘好流水线工人,每个工人都给他们配备好各自的工具,等到流水线启动后,starter 就开始分发请求进来,然后在每个环节上,调度对应的工人进行处理,处理完了之后,再交付下一个工人进行处理,所以你看到的带有注解的源码,只是整个流水线中的一个逻辑节点,这种逻辑节点也称之为嵌入式节点;
-
在执行过程中,因为强弱语言对于注解的处理方式是不同的,所以也产生了两种解决方案,SpringBoot 基于 Java,注解就是语言特性,所以有很多处理逻辑的细节都在语言底层帮你做了,没有暴露出来,对开发者来说,就更加友好,而 Hyperf 基于 PHP,PHP 没有注解这个概念,就要人为完全模拟处理注解的过程,因此 Java 在编译后生成了新的一套代码,而 php 没有编译过程,所以hyperf 就得自己实现编译的过程,hyperf 就将注解代码生成 Proxy 代码,实际执行的也是 Proxy 代码,Java 执行的是 class 代码,实际执行的也是 class 代码,此时,两者就统一了。
-
如果一个人只学了SpringBoot,这个过程是很难理解到的,因为 JAVA并未暴露这个过程给你们,你们只能从更高的非 JAVA 程序员哪里了解到这个过程,所以单一语言的编程人员是会长期处于一种朦胧的认知中;
-
同理还有协程的概念,单独从 GO 语言去了解协程(没有细节,直接上,但是还是同步语言,协程天生就是异步语言,你从同步入手肯定会懵逼),会让人琢磨不透,如果从 python 接触协程又会暴露太多细节(同时 python 也是同步语言就更懵逼了),只有从中间态的 Javascript 入手才最简单,因为浏览器本身已经帮你实现了协程,但是又有的事件以及事件监听都是协程编程,这样你可以在中间过程彻底地体验协程的玩法(yield 语法使用),玩熟了yield 之后,再跑到 python 那边自己模拟启动一个浏览器事件循环服务,然后再执行 yield 时,理解就豁然开朗,在搞懂这块之后,再学习Go,那基本就是得心应手,这样才能玩出花来。
我相信经过上面这个解释,小白用户对注解应该一下子就豁然开朗了。
https://www.bookstack.cn/read/hyperf-2.0/annotation.md
什么是注解什么是注释?
在解释注解之前我们需要先定义一下 注解
与 注释
的区别:
-
注释:给程序员看,帮助理解代码,对代码起到解释、说明的作用。
-
注解:给应用程序看,用于元数据的定义,单独使用时没有任何作用,需配合应用程序对其元数据进行利用才有作用。
应用程序,你可以理解为hyperf的启动程序bin/hyperf.php
识别了这个过程,并进行一定的处理,尤其是hyperf自定义一些注解标签,在启动bin/hyperf.php
时,会将带有注解标签的源代码翻译成执行代码,在具体执行时使用。生成proxy代理类的过程就跟npm预编译过程一样,对代码进行重新的生成。真正打包的代码是npm预编译完成后的代码,而不是源代码,而hyperf实际参与运行的代码也不是你写的源代码,认识生成代理类,所以你想调试时,在自己的源代码打断点是没用的,必须要在代理类中打断点。
SpringBoot的注解
-
实现逻辑Hyperf没太大区别,区别在于语言特性,PHP语言没有注解这个概念,只有一个PHPDoc,拿来自动生成文档用的,既然能自动生成文档,那肯定是程度能识别的,所以有些人就使用PHPDoc这个东西来实现注解,只要碰到了有@的字符,然后在获取@字符后的内容,就可以按照该内容执行处理逻辑,就OK了
-
Java的注解是语言本身的一种属性,是可以在编译时和运行时直接获得的,这直接省去了一个解析处理环节,只需要收集被注解标记的类和属性即可,这样应用程序就可以将自己已经收集到的数据进行赋值和收集,进行统一处理。
-
SpringBoot将整个Web过程都写好了,预留了大量的要填空的内容,这些要填空的地方都起了个名字,例如叫
@Controller
,@Service
,@Repository
,然后你把你写的代码上面标记这些内容,那么SpringBoot在运行时,就知道你填了这个空,在需要用到你这个逻辑时,它会从收集器中提取出来执行,同时呢,你也想获取一些东西,例如@Value
,@Configuration
这些注解就可以将一些内容直接填充进来,只不过这个过程是发生在运行时,你这里只管拿去用,实现逻辑即可,到时组装起来后,就可以正常运行了,这个也可以理解为嵌入式Web开发吧,接收外界的数据,完全独立处理,然后返回结果。 -
SpringBoot注解是先编译完成之后,SpringBoot启动时执行,所以仍然可以进行编译检查。