> 本文约 1500 字,读完本文大概需要 5 分钟。
>
> - [《AOP 挖掘记》概念介绍及原理初探(一)](https://github.com/stone0090/aop-dig-down/blob/master/README.MD)
> - [《AOP 挖掘记》代理模式、jdk代理、cglib(二)](https://github.com/stone0090/aop-dig-down/blob/master/README-AOP-2.md)
> - [《AOP 挖掘记》jdk代理 - 源码解析(三)](https://github.com/stone0090/aop-dig-down/blob/master/README-AOP-3.md)
> - [《AOP 挖掘记》cglib - 源码解析(四)](https://github.com/stone0090/aop-dig-down/blob/master/README-AOP-4.md)
> - 《AOP 挖掘记》jdk代理、cglib 性能对比(五)【未完成】
> - 《AOP 挖掘记》徒手实现 AOP 框架(六)【未完成】
> - 《AOP 挖掘记》Spring AOP 源码解析(七)【未完成】
> - 《AOP 挖掘记》AspectJ AOP 原理解析(八)【未完成】
### AOP 的基本概念
AOP 是 Aspect-Oriented programming 的缩写,中文翻译为面向切面编程,它和 OOP 一样是一种编程思想。
AOP 把软件系统分为两个部分:`核心关注点` 和 `横切关注点`。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处都基本相似。比如权限认证、日志、事务处理。AOP 的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。通俗的讲就是将应用程序中的业务逻辑同对其提供支持的通用服务进行分离,AOP 可以说是 OOP 的补充和完善。
![](http://qn.shisb.com/blog/aop/1/1pool.jpg)
使用 OOP 的好处是可以设计出低耦合的系统,使系统更加灵活、更加易于维护,但同时也增加了代码的重复性。比如,我们要打印类中每个方法的出入参。按面向对象的编程思想,就必须在类的每方法中都加入日志打印功能。如下左图所示:
此时引入 AOP 的编程思想,将日志打印功能(切面),动态的切入到类中每个方法的前后(切点),无需改动原有代码,便可改变其原有的行为。如下右图所示:
![](http://qn.shisb.com/blog/aop/1/2pool.jpg)
除此之外,使用 AOP 的编程思想,还能降低模块的耦合度、增强代码的复用性、使系统更容易扩展。
### AOP 的相关术语
![](http://qn.shisb.com/blog/aop/1/3pool.jpg)
以上 AOP 术语在整个环节中的具体位置,如下图所示:
![](http://qn.shisb.com/blog/aop/1/4pool.jpg)
### AOP 的使用场景
![](http://qn.shisb.com/blog/aop/1/5pool.jpg)
### AOP 的实现原理
在了解了 AOP 的基本特征、相关术语、使用场景之后,对设计模式有一定了解的朋友,一定已经猜到 AOP 实际上是基于 `代理模式` 和 `装饰者模式` 实现的。
代理模式和装饰者模式都是常用的 Java 设计模式,它的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。如以下类图所示:
![](http://qn.shisb.com/blog/aop/1/6pool.jpg)
两种模式最主要的区别是:代理模式中,代理类对被代理的对象有控制权,决定其执行或者不执行。而装饰模式中,装饰类对代理对象没有控制权,只能为其增加一层装饰,以加强被装饰对象的功能。
所以,在使用 AOP 对方法进行权限校验时,会影响真实对象是否执行,可以理解为是通过代理模式实现的;在使用 AOP 对方法进行日志追踪时,不会影响真实对象的执行,可以理解为是通过装饰者模式实现的。由于两种模式区别不大,后面统一按代理模式进行表述。
按照代理的创建时期,代理类可以分为两种。
+ 静态代理:由程序员或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的 .class字节码 文件就已经存在。
+ 动态代理:在程序运行时,工具类会动态的生成代理类的 .class字节码 缓存在内存中,再运用反射机制,实例化出代理对象。
### AOP 的具体实现
上面有讲过,切面织入的方式有3种,分别是:
- 运行时织入(Runtime wearing):是指采用 jdk代理 或 cglib 工具进行切面的织入。
- 编译期织入(Compile time wearing):是指在 Java 编译期,采用特殊的编译器,将切面织入到 Java 类中。
- 类加载期织入(Classload time wearing):是指通过特殊的类加载器,在类字节码加载到 JVM 时织入切面。
我们最常用的 Spring AOP 是采用运行时织入(Runtime wearing),它是基于动态代理的实现的。如果需要代理的对象,实现了某个接口,那么 Spring AOP 会使用 jdk代理 去创建代理对象,而对于没有实现接口的对象,Spring AOP 会使用 cglib 生成一个被代理对象的子类,如下图所示:
![](http://qn.shisb.com/blog/aop/1/7pool.jpg)
Spring AOP 的目的并不是为了提供最完整的 AOP 实现,而是为了要帮助解决企业应用中的常见问题,提供一个 AOP 实现与 Spring IOC 之间的紧密集成。如果你计划在 Spring Beans 之上将横切关注点模块化,那么 Spring AOP 是你的首选。但如果你用的是普通的 Java 对象而不是 Spring beans,又或者是想支持全部的 Pointcut 类型,那么你就需要引入更完备的 AOP 框架 AspectJ 了。
AspectJ 是一个面向切面的框架,它无缝扩展了 Java 语言,它有一个专门的编译器用来生成遵守 Java 字节编码规范的 Class 文件。它采用编译期织入(Compile time wearing)和类加载期织入(Classload time wearing),它是基于静态代理的实现的,是语言级的 AOP 实现,提供了完备的 AOP 支持。编译期织入过程,如下图所示:
![](http://qn.shisb.com/blog/aop/1/8pool.jpg)
### 总结
除了 Spring AOP 和 AspectJ 之外,还有很多开源框架也包含了 AOP 的实现,例如:Hibernate、dynaop等,大家只要明白了其实现原理,就可以举一反三。后续我会带着大家徒手实现简单的 AOP 框架,敬请期待。
没有合适的资源?快使用搜索试试~ 我知道了~
基于Java的cglib库的动态代理测试项目.zip
共289个文件
java:250个
xml:16个
md:9个
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 52 浏览量
2024-09-04
09:32:15
上传
评论
收藏 479KB ZIP 举报
温馨提示
基于Java的cglib库的动态代理测试项目 项目概述 该项目主要用于测试和验证cglib库的动态代理功能。cglib是一个强大的Java库,用于生成和操作字节码,特别是在需要动态代理和AOP(面向切面编程)的场景中非常有用。通过该项目,开发者可以深入理解cglib库的核心功能,包括类生成、方法拦截、回调机制等。 主要功能 1. 动态代理生成 Enhancer: 用于生成动态代理类,支持继承指定的基类或实现接口,并在方法调用前后插入自定义逻辑。 MethodInterceptor: 用于拦截方法调用,提供“环绕通知”功能,允许在方法调用前后执行自定义逻辑。 CallbackFilter: 用于将方法映射到特定的回调,支持不同方法使用不同的回调逻辑。 2. 回调机制 Dispatcher: 在每次方法调用时返回一个对象,用于处理原始方法调用。 LazyLoader: 在第一次调用方法时加载实际对象,并将其用于后续的方法调用。 NoOp: 不执行任何操作,直接调用原始方法。 3. 类生成和转换 ClassGenerator: 用于生成类的字节码,
资源推荐
资源详情
资源评论
收起资源包目录
基于Java的cglib库的动态代理测试项目.zip (289个子文件)
.gitignore 3KB
.gitignore 3KB
.gitignore 3KB
.gitignore 184B
.gitignore 184B
proxy-pattern-sample.iml 2KB
cglib.iml 1KB
aop-dig-down.iml 585B
LeetCodeSolution.iml 488B
DataStructure.iml 433B
TestEnhancer.java 65KB
Enhancer.java 56KB
EmitUtils.java 41KB
TestFastClass.java 40KB
CodeEmitter.java 30KB
ReflectUtils.java 24KB
LinkListPractice.java 21KB
SequenceList.java 21KB
Dispatcher.java 19KB
StaticLinkList.java 17KB
PerformanceTest.java 17KB
TypeUtils.java 15KB
AbstractClassGenerator.java 15KB
KeyFactory.java 15KB
AbstractTransformTask.java 15KB
TestBulkBean.java 15KB
TestProxy.java 14KB
SequenceListPractice.java 13KB
TestXmlParsing.java 13KB
MethodDelegate.java 12KB
MethodProxy.java 12KB
ParallelSorter.java 12KB
BeanMap.java 12KB
TransformDemo.java 12KB
ClassEmitter.java 12KB
SortUtils.java 11KB
TestBeanMap.java 11KB
MethodInterceptorGenerator.java 11KB
BeanMapEmitter.java 11KB
Mixin.java 10KB
FastClassEmitter.java 10KB
InterceptFieldTransformer.java 10KB
DuplicatesPredicate.java 9KB
FieldProviderTransformer.java 9KB
FastClass.java 9KB
MethodVisitorTee.java 9KB
CglibProxyClient.java 9KB
MulticastDelegate.java 9KB
SingleLinkNode.java 9KB
TestInterceptFields.java 8KB
BeanGenerator.java 8KB
BulkBeanEmitter.java 8KB
TestMixin.java 8KB
BeanCopier.java 8KB
_15_Solution_00.java 8KB
ClassVisitorTee.java 8KB
StringSwitcher.java 8KB
TestTransformingLoader.java 7KB
LocalVariablesSorter.java 7KB
TestDelegates.java 7KB
DoubleLinkNode.java 7KB
TestKeyFactory.java 7KB
Constants.java 7KB
SortUtils.java 7KB
MA.java 7KB
ParallelSorterEmitter.java 6KB
DumpFieldsTask.java 6KB
InterfaceMaker.java 6KB
CallbackInfo.java 6KB
BulkBean.java 6KB
LoadingCache.java 6KB
LinkStack.java 6KB
ImmutableBean.java 6KB
SorterTemplate.java 6KB
ProxySample.java 6KB
AddDelegateTransformer.java 6KB
TestReflectPerf.java 6KB
ConstructorDelegate.java 6KB
TestAll.java 6KB
ILinerList.java 6KB
BridgeMethodResolver.java 6KB
TestDispatcher.java 6KB
MixinEmitter.java 6KB
_189_Solution_50.java 6KB
DebuggingClassWriter.java 5KB
TestTinyBitSet.java 5KB
Proxy.java 5KB
MA.java 5KB
CallbackHelper.java 5KB
Source.java 5KB
CircularQueue.java 5KB
_206_Solution_00.java 5KB
AbstractClassLoader.java 5KB
TestInterfaceMaker.java 5KB
AbstractClassFilterTransformer.java 5KB
TestBeanCopier.java 5KB
LinkQueue.java 5KB
TestParallelSorter.java 5KB
TestProxyRefDispatcher.java 5KB
ClassNameReader.java 5KB
共 289 条
- 1
- 2
- 3
资源评论
t0_54coder
- 粉丝: 2465
- 资源: 4951
下载权益
C知道特权
VIP文章
课程特权
开通VIP
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功