四:AOP

一:AOP概念?

  通过预编译方式或运行期动态代理等技术实现程序功能的统一维护的一种技术;AOP 可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率

二:AOP和OOP的区别?

  oop是针对业务处理过程的实体及其属性和行为进行抽象封装,以获得更加清晰高效的逻辑单元的划分;

  aop则是针对业务处理过程中的切面进行提取;它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果;

三:Hyperf里的AOP

  只需要理解一个概念即可,即Aspect(切面)

  (1):Aspect可以切入任意类或者任意注解类;

  (2):被切入的类必须由DI管理;

    因为Hyperf的AOP是基于DI实现的,必须使用的是Hyperf的DI组件即hyperf/di,必须通过DI创建的对象才能使AOP生效,直接new不行;且代理类缓存文件不存在时,才会重新生成代理类;

  (3):相对于其它框架实现的AOP功能的使用方式,Hyperf进一步简化了AOP的使用;不做过细的划分(如Before,After,AfterReturning,AfterThrowing),仅存在 环绕(Around)一种通用方式;

总结:

  用通俗的话来讲,就是在 Hyperf 里可以通过 切面(Aspect) 介入到任意类的任意方法的执行流程中去,从而改变或加强原方法的功能,这就是 AOP

  注意这里所指的任意类并不是完全意义上的所有类,在 Hyperf 启动初期用于实现 AOP 功能的类自身不能被切入

四:AOP的应用场景

  (1):参数校验

  (2):无侵入日志处理

  (3):安全控制,性能统计

  (4):事务处理,异常处理;

  (5):缓存

  (6):资源池,连接池管理

定义切面:

  每个 切面(Aspect) 必须实现 Hyperf\Di\Aop\AroundInterface 接口,并提供 public$classes$annotations 属性,为了方便使用,我们可以通过继承 Hyperf\Di\Aop\AbstractAspect 来简化定义过程,我们通过代码来描述一下。

 我们只要在Hyperf里面定义对应的Aspect类就可以做到对任意类的切入了;

 

例子:Aspect

  (1):假设我们有一个TestController类;

  (2):我们希望通过AOP对该类切入;

  (3):创建一个Aspect类,并在$classes属性定义该类的Tests方法;

  

 

 

 

 

  

 

 

   

 

 

  

 五:代理类缓存

  比如我们TestController的test方法改写为返回1111;

  请求返回结果为:

  

  

 

 

     我们把TestController的test方法改写为返回2222;返回仍然为:

  

   因为DI在创建这个TestController的时候,检测到了TestController的代理类缓存是存在的;就是直接返回对应的代理类缓存文件;而不是重新生成;

 

  所有被 AOP 影响的类,都会在 ./runtime/container/proxy/ 文件夹内生成对应的 代理类缓存,是否在启动时自动生成取决于 config/config.php 配置文件中 scan_cacheable 配置项的值,默认值为 false,如果该配置项为 true 则 Hyperf 不会扫描和生成代理类缓存,而是直接以现有的缓存文件作为最终的代理类。如果该配置项为 false,则 Hyperf 会在每次启动应用时扫描注解扫描域并自动的生成对应的代理类缓存,当代码发生变化时,代理类缓存也会自动的重新生成。

通常在开发环境下,该值为 false,这样更便于开发调试,而在部署生产环境时,我们可能会希望 Hyperf 提前将所有代理类提前生成,而不是使用时动态的生成,可以通过 php bin/hyperf.php 命令来生成所有代理类,然后再通过环境变量 SCAN_CACHEABLEtrue 修改该配置项的值,以达到启动时间更短、应用内存占用更低的目的。

基于以上,如果您使用 Docker 或 Kubernetes 等虚拟化技术来部署您的应用的话,您可以在镜像构建阶段就生成对应的代理类缓存并写入到镜像中去,在运行镜像实例时,可大大减少启动时间和应用内存。

 六:注解类的切入

 

 

 

 

 

 

 

 

  

 

 

posted @ 2022-02-18 17:25  痞子胥  阅读(244)  评论(0)    收藏  举报