1.Unlua源码解析(附二) 源码中的源多少重要类及核心函数逐行解释
2.76 张图,剖析 Spring AOP 源码,源码小白居然也能看懂,反码大神,补码请收下我的源多少膝盖!
Unlua源码解析(附二) 源码中的重要类及核心函数逐行解释
源码解析:重要类及核心函数逐行解释 1. FClassDesc 该类用于描述一个类,包含类名、反码类大小和继承关系等信息。补码 2. FFunctionDesc 对应UE中的源多少UFunction,存储更详细信息,源码如参数、反码元数据,补码允许FFunctionDesc调用方法。源多少 3. FProporityDesc 描述参数,源码并提供参数在Lua和C++间转换的反码辅助方法。 4. FFieldDesc 用于描述字段的类。 5. FReflectionRegistry 用于注册反射信息,借助UE反射接口加载类。 6. FLuaContext 全局类,负责绑定Lua对象和实现Lua与C++间的交互。 7. LuaCore 包含很多关键方法,如注册类、注册方法,是刷广告app源码Unlua的核心类。 8. UUnLuaManager 集成绑定Lua与C++的多种方法。FReflectionRegistry内重要方法
2.1 RegisterClass
-: 通过UE反射接口尝试加载指定类。 : 调用RegisterClass方法。2.2 RegisterClass
-: 若无参数,返回。 -: 获取并检查类的类型信息,仅当类型为Struct时继续。 -: 若已注册,使用注册信息;否则注册新信息,返回。2.3 RegisterClassInternal
存名称和Struct到FClassDesc字典,便于后续使用。 -: 创建FClassDesc并记录相关信息。 -: 遍历父类,记录父类名称和Struct。2.4 GetClassChain
获取类的继承链,OutChain表示类及其父类。LuaCore内重要方法
3.1 Global_RegisterClass
读取类型信息,注册类。3.2 RegisterClass
记录反射信息,创建元表,便于Lua与C++交互。3.3 RegisterClassInternal
创建元表,云微信源码设置元方法,记录全局表中。3.4 RegisterClassCore
创建元表,设置元方法,记录元表信息。3.5 SetTableForClass
将类元表放入全局表。3.6 Class_Index
处理类索引方法。3.7 GetField
获取字段或方法。3.8 GetFunctionList
获取模块内所有方法。3.9 PushObjectCore
创建并绑定Lua对象。3. NewLuaObject
创建Lua表表示UObject。FLuaContext内重要方法
4.1 FindExportedReflectedClass
通过名称查找导出的反射类。4.2 NotifyUObjectCreated
: 存储新创建的Object。 : 尝试绑定Lua到Object。4.3 TryToBindLua
绑定Lua模块到UObject。UUnLuaManager内重要方法
5.1 Bind
新UObject实例创建时,创建Lua对象并绑定。5.2 BindInternal
实现Lua绑定UObject的关键函数。 方法涵盖模块名与C++对象关联、覆盖C++函数、处理动画覆盖等。张图,剖析 Spring AOP 源码,delphi源码库小白居然也能看懂,大神,请收下我的膝盖!
本文将简要介绍AOP(面向切面编程)的基础知识与使用方法,并深入剖析Spring AOP源码。首先,我们需要理解AOP的基本概念。
1. **基础知识
**1.1 **什么是AOP?
**AOP全称为Aspect Oriented Programming,即面向切面编程。AOP的思想中,周边功能(如性能统计、日志记录、事务管理等)被定义为切面,核心功能与切面功能独立开发,然后将两者“编织”在一起,这就是AOP的核心。
AOP能够将与业务无关、却为业务模块共同调用的逻辑封装,减少系统重复代码,降低模块间的耦合度,有利于系统的可扩展性和可维护性。
1.2 **AOP基础概念
**解释较为官方,以下用“方言”解释:AOP包括五种通知分类。卖书小程序源码
1.3 **AOP简单示例
**创建`Louzai`类,添加`LouzaiAspect`切面,并在`applicationContext.xml`中配置。程序入口处添加`"睡觉"`方法并添加前置和后置通知。接下来,我们将探讨Spring内部如何实现这一过程。
1.4 **Spring AOP工作流程
**为了便于理解后面的源码,我们将整体介绍源码执行流程。整个Spring AOP源码分为三块,结合示例进行讲解。
第一块是前置处理,创建`Louzai`Bean前,遍历所有切面信息并存储在缓存中。第二块是后置处理,创建`Louzai`Bean时,主要处理两件事。第三块是执行切面,通过“责任链+递归”执行切面。
2. **源码解读
**注意:Spring版本为5.2..RELEASE,否则代码可能不同!这里,我们将从原理部分开始,逐步深入源码。
2.1 **代码入口
**从`getBean()`函数开始,进入创建Bean的逻辑。
2.2 **前置处理
**主要任务是遍历切面信息并存储。
这是重点!请务必注意!获取切面信息流程结束,后续操作都从缓存`advisorsCache`获取。
2.2.1 **判断是否为切面
**执行逻辑为:判断是否包含切面信息。
2.2.2 **获取切面列表
**进入`getAdvice()`,生成切面信息。
2.3 **后置处理
**主要从缓存拿切面,与`Louzai`方法匹配,创建AOP代理对象。
进入`doCreateBean()`,执行后续逻辑。
2.3.1 **获取切面
**首先,查看如何获取`Louzai`的切面列表。
进入`buildAspectJAdvisors()`,方法用于存储切面信息至缓存`advisorsCache`。随后回到`findEligibleAdvisors()`,从缓存获取所有切面信息。
2.3.2 **创建代理对象
**有了`Louzai`的切面列表,开始创建AOP代理对象。
这是重点!请仔细阅读!这里有两种创建AOP代理对象方式,我们选择使用Cglib。
2.4 **切面执行
**通过“责任链+递归”执行切面与方法。
这部分逻辑非常复杂!接下来是“执行切面”最核心的逻辑,简述设计思路。
2.4.1 **第一次递归
**数组第一个对象执行`invoke()`,参数为`CglibMethodInvocation`。
执行完毕后,继续执行`CglibMethodInvocation`的`process()`。
2.4.2 **第二次递归
**数组第二个对象执行`invoke()`。
2.4.3 **第三次递归
**数组第三个对象执行`invoke()`。
执行完毕,退出递归,查看`invokeJoinpoint()`执行逻辑,即执行主方法。回到第三次递归入口,继续执行后续切面。
切面执行逻辑已演示,直接查看执行方法。
流程结束时,依次退出递归。
2.4.4 **设计思路
**这部分代码研究了大半天,因为这里不是纯粹的责任链模式。
纯粹的责任链模式中,对象内部有一个自身的`next`对象,执行当前对象方法后,启动`next`对象执行,直至最后一个`next`对象执行完毕,或中途因条件中断执行,责任链退出。
这里`CglibMethodInvocation`对象内部无`next`对象,通过`interceptorsAndDynamicMethodMatchers`数组控制执行顺序,依次执行数组中的对象,直至最后一个对象执行完毕,责任链退出。
这属于责任链,实现方式不同,后续会详细剖析。下面讨论类之间的关系。
主对象为`CglibMethodInvocation`,继承于`ReflectiveMethodInvocation`,`process()`的核心逻辑在`ReflectiveMethodInvocation`中。
`ReflectiveMethodInvocation`的`process()`控制整个责任链的执行。
`ReflectiveMethodInvocation`的`process()`方法中,包含一个长度为3的数组`interceptorsAndDynamicMethodMatchers`,存储了3个对象,分别为`ExposeInvocationInterceptor`、`MethodBeforeAdviceInterceptor`、`AfterReturningAdviceInterceptor`。
注意!这3个对象都继承了`MethodInterceptor`接口。
每次`invoke()`调用时,都会执行`CglibMethodInvocation`的`process()`。
是否有些困惑?别着急,我将再次帮你梳理。
对象与方法的关系:
可能有同学疑惑,`invoke()`的参数为`MethodInvocation`,没错!但`CglibMethodInvocation`也继承了`MethodInvocation`,可自行查看。
执行逻辑:
设计巧妙之处在于,纯粹的责任链模式中,`next`对象需要保证类型一致。但这里3个对象内部没有`next`成员,不能直接使用责任链模式。怎么办呢?就单独设计了`CglibMethodInvocation.process()`,通过无限递归`process()`实现责任链逻辑。
这就是我们为什么要研究源码,学习优秀的设计思路!
3. **总结
**本文首先介绍了AOP的基本概念与原理,通过示例展示了AOP的应用。之后深入剖析了Spring AOP源码,分为三部分。
本文是Spring源码解析的第三篇,感觉是难度较大的一篇。图解代码花费了6个小时,整个过程都沉浸在代码的解析中。
难度不在于抠图,而是“切面执行”的设计思路,即使流程能走通,将设计思想总结并清晰表达给读者,需要极大的耐心与理解能力。
今天的源码解析到此结束,有关Spring源码的学习,大家还想了解哪些内容,欢迎留言给楼仔。