换个角度理解之AOP与IOC
老生常谈的话题,所以我这里所说的内容当然不能是一些老掉牙,被人咀嚼了无数次的残渣。
我争取从一个特别的角度给你留下别样的印象。现在无法理解没关系,只需要记住这些话,在以后的工作和训练中反复回味即可。等你悟出自己的道,欢迎到时候来一起讨论。
1. IOC
控制反转,一般被和DI混淆。在我们试图明白这些概念前,来思考下这个问题:
”OOP中我们通过构造不同的对象来完成不同的功能,最终在这些实例的共同努力下完成既定的任务。那么我们以主体或者说调度者的视野来看,我真的关心我拿到的这些实例到底是个什么吗?”
答案显而易见,我并不关心,我一点都不关心, 我不关心你是个什么,我不关心你里面装了什么,我不关心你是怎么被构建出来的,我仅仅只关心你是否能正确完成我要求你完成的那几个功能(即我只关心你是否能正确完成你所声明的那几个方法(接口定义),更极端点说,就算这几个方法里,你只要把我们关心(即调用)的那个方法实现对,哪怕其他的方法你全给实现错了,我也认为你合格了,我不关心你的'品质','出生','思想觉悟'等等其他一切事情。)。在《七周七语言》这本书里里有这样一个词:“鸭子类型”—— 用蹼走路,会呱呱叫,它就是鸭子。用在这里应该非常合适吧。
这里举一个让我顿悟的例子,这个例子来自于《Mastering Ninject for Dependency Injection》(这书只有英文版, 当初咬牙把英文版的看完了, 紧接着放该电子文件的U盘坏了, 靠!三年了, 至今记得当时那个恨啦!)。文中以木匠和手术的主刀医生为例,木匠在干活时他所使用的工具都需要自己去取;而主刀医生在干活时工具都是由助手递过去的,主刀医生根本不需要关心工具的来源。他只需要关注于自己的本质工作即可,而木匠除了本质工作之外,还得负责找出合适的工具来完成这件事。
那好,既然我这么多不关心,那么对象的构造工作完全没必要放在我这里,我想要的是一个"容器", 在“真正需要”的时候从中取出那个实现了我想要的功能的那个对象,仅此而已。另外《Clean Code》里就专门有一章来讲解我们应该将对象的构建和对象的使用区分开。
所以:
- 想清楚自己真正需要的到底是什么?
- 相比较应该知道什么,知道自己不该知道什么也很重要。
2. AOP
在讨论AOP之前,请先看看下面这句“优秀框架的基本素质之一就是在关键的过程中设置拦截性接口,越通用的框架就越不应该对用户的行为进行任何假设性的约束,包括框架自身的行为都最好是以扩展的方式并入”。
如果你很好奇我为什么突然说这句?那么接下来就是重点:其实这段话里的关键字就是那个“拦截性接口”;现在让我们回想下AOP的使用场景,是否可以概括为这样一句话:我希望在xx方法执行的前后进行某些操作,甚至可以根据操作的结果来决定是否执行这个方法的实际逻辑。联系前后两个,是不是非常非常相似!具体的代码我就不重复,网上一堆。这里我就贴一下Java中的两种实现方式吧:
a. Java实现AOP之动态代理
动态代理有以下特点:
- 代理类所在包:
java.lang.reflect.Proxy
- 代理对象,不需要实现接口。
- 代理对象的生成,是利用JDK的API,动态的在内存中构建代理对象(需要我们指定创建代理对象/目标对象实现的接口的类型)
- 动态代理也叫做JDK代理,接口代理。
b. Java实现AOP之Cglib子类代理
Cglib子类代理实现方法:
1.需要引入cglib的jar文件,但是Spring的核心包中已经包括了Cglib功能,所以直接引入spring-core-3.x.x.jar
即可。
2.引入功能包后,就可以在内存中动态构建子类。
3.代理的类不能为final,否则报错。
4.目标对象的方法如果为final/static,那么就不会被拦截,即不会执行目标对象额外的业务方法。
关于AOP的好处我就不多说了。下面是开涛大神的链接地址,代码什么都有。
3. 联系
IOC和AOP相辅相成;因为你不关心拿到的是什么,所以我可以在你拿到这个实现所需功能的对象之前,我可以对它进行修改,附加上一些东西,甚至整个将它们替换掉,而这些附加的功能最终会在特定时刻发生效果,而这些特定时刻就是我们在设置AOP时的约束。
具体实例就是Spring容器了,其思想和sql类似——你告诉我对象有些啥,以及它们之间的关系,剩下的工作就交给我了。也是因为实际的构建过程由Spring负责,而你又不关心实际的对象(你关心的是功能是否如期实现),那么AOP就顺理成章了。
再做一点引申阅读吧。这是不是有点像JVM所处理的class文件,JVM只要求你传递的文件符合既定要求,至于这个文件是何处而来,传递给JVM之前是否有过二次转换,JVM其实一点都不关心,这就给了各种编译器以无限大的自由度去进行各种自定制,关于这一点大家可以阅读《深入理解Java虚拟机》,我这里就不越疱代俎了。
4. Links
- 《SICP》—— 会当凌绝顶一览众山小,不多解释了!
- 《Clean Code》—— 此书之后,再无代码规范。
- 《优秀框架的基本素质》—— 这是一篇博客;作者是阿里的梁飞。
- 我对AOP的理解 -- 开涛大神的,里面有示例代码等。我就不再自己重复一遍了。