一、我所知道的AOPjava
初看起来,上来就是一大堆的术语,并且还有个拉风的名字,面向切面编程,都说是OOP的一种有益补充等等。一下让你不知所措,心想着:管不得不少人都和我说AOP多难多难。当我看进去之后,我才行发现:他就是一些Java基础上的朴实无华的应用,包括IOC(见《Spring IOC(依赖注入、控制反转)概念理解》),包括许许多多这样的名词,都是万变不离其宗而已。spring
二、为何要用AOP编程
1)就是为了方便,看一个国外颇有名的大师说,编程的人都是“懒人”,由于他把本身作的事情都让程序去作了。用了AOP能让你少写不少代码,这点就够充分了吧。安全
2)就是为了更清晰的逻辑,可让你的业务逻辑去关注本身自己的业务,而不去想一些其余的事情。这些其余的事情包括:安全,事物,日志等等。框架
三、那些AOP术语代理
初看这么多术语,一会儿都很差接受,慢慢来,很快就会搞懂。日志
下面的图简化和形象的说明了AOP对象
形象上看,AOP编程,就像作汉堡同样。blog
原始面包 - 目标对象的方法。业务组件就好了。继承
肉块 - Advice
汉堡 - AOP代理的方法。
将肉加到面包 - 引入
关键就是:切面定义了哪些链接点会获得通知。
四、我所理解的AOP原理
spring用代理类包裹切面,吧他们织入到Spring管理的bean中,也就是说代理类假装成目标类,它会截取对目标类中方法的调用,然调用者对目标类的调用都先变成假装类,假装类这就先执行了切面,再把调用转发给真正的目标bean。
如今能够本身想想,怎么搞出来这个假装类,才不会被调用者发现(过JVM的检查,JAVA是强类型检查,哪里都要检查类型)。
1)实现和目标类相同的接口。
我也实现和你同样的接口,反正上层都是接口级别的调用,这样我就假装成了和目标类同样的类(实现了赞成接口,咱是兄弟了),也就逃过了类型检查,到java运行期的时候,利用多态的后期绑定(因此spring采用运行时),假装类(代理类)就变成了接口的真正实现,二他里面包裹了真实的那个目标类,最后实现具体功能的仍是目标类,只是不过假装在以前干了点事情(写日志,安全检查,事物等)。
这就比如一我的让你办事,每次这个时候,你弟弟就会出来,固然他分不出来了,觉得是你,你这个弟弟虽然办不了这个事,可是她知道你能办,因此就答应下来了,而且收了点礼物(写日志),收完礼物了,给把事给人家办了啊,因此你弟弟又找你这个哥哥来了,最后把这事办了仍是你本身。可是你本身并不知道你弟弟已经收了礼物了,你只是专心把这件事作好。
顺着这个思想,要是自己这个类就没实现一个接口呢,你怎么假装我,我就压给没有机会让你搞出这个双胞胎弟弟,那么就用第2种代理方式,建立一个目标类的子类,生个儿子,让儿子假装我。
2)生成子类调用。
此次用子类来作假装,固然这样也能逃过JVM的强类型检查,我继承的吗,固然查不出来了,子类重写了目标类的全部方法,固然在这些重写的方法中,不只实现了目标类的功能,还在这些功能以前,实现了一些其余的(写日志,安全检查,事物等)。
此次的对比就是,儿子先从爸爸那儿把本事都学会了,全部人都找儿子办事,可是儿子每次办和爸爸一样的事以前,都要收点小礼物(写日志),而后才去办真正的事。固然爸爸是不知道儿子这么干的了。这里就有事情要说,某些本事是爸爸独有(final的),儿子学不会,学不了就办不了这个事,办不了这个事情,天然就不能收人家的礼物了。
前一种兄弟模式,spring会使用JDK的java.lang.reflect.Proxy类,它容许Spring动态生成一个新类来实现必要的接口,织入通知,而且把这些接口的任何调用都转发到目标类。
后一种父子模式,spring使用CGLIB库生成目标类的一个子类,在建立这个子类的时候,spring织入通知,而且把对这个子类的调用委托到目标类。
相比之下,仍是兄弟模式好一些,她能更好的实现松耦合,尤为在今天都高喊着面向接口编程的状况下,父子模式只是在没有实现接口的时候,也能织入通知,应该当作一种例外。