之前我已经写过一篇关于AOP的文章了,那篇把比较重要的知识点都讲解过了一篇啦:,很荣幸被开源中国推荐过~~
如果没有AOP的基础,建议先看看上面那篇文章~
如果没有代理模式基础,建议先看看:这篇文章
如果都看过了,这篇就放心食用吧!
这篇文章主要是补充和强化一些比较重要的知识点,并会把上面的两本书关于AOP的知识点整理出来并画成一个思维导图来全面了解Spring AOP的知识点!
那么接下来就开始吧,如果有错的地方希望能多多包涵,并不吝在评论区指正!
一、Spring AOP全面认知结合《Spring 实战 (第4版)》和《精通Spring4.x 企业应用开发实战》两本书的AOP章节将其知识点整理起来~
1.1AOP概述AOP称为面向切面编程,那我们怎么理解面向切面编程??
我们可以先看看下面这段代码:
我们学Java面向对象的时候,如果代码重复了怎么办啊??可以分成下面几个步骤:
1:抽取成方法
2:抽取类
抽取成类的方式我们称之为:纵向抽取
通过继承的方式实现纵向抽取
但是,我们现在的办法不行:即使抽取成类还是会出现重复的代码,因为这些逻辑(开始、结束、提交事务)依附在我们业务类的方法逻辑中!
现在纵向抽取的方式不行了,AOP的理念:就是将分散在各个业务逻辑代码中相同的代码通过横向切割的方式抽取到一个独立的模块中!
上面的图也很清晰了,将重复性的逻辑代码横切出来其实很容易(我们简单可认为就是封装成一个类就好了),但我们要将这些被我们横切出来的逻辑代码融合到业务逻辑中,来完成和之前(没抽取前)一样的功能!这就是AOP首要解决的问题了!
1.2Spring AOP原理被我们横切出来的逻辑代码融合到业务逻辑中,来完成和之前(没抽取前)一样的功能
没有学Spring AOP之前,我们就可以使用代理来完成。
如果看过我写的这篇文章的话,一定就不难理解上面我说的那句话了
代理能干嘛?代理可以帮我们增强对象的行为!使用动态代理实质上就是调用时拦截对象方法,对方法进行改造、增强!
其实Spring AOP的底层原理就是动态代理!
来源《精通Spring4.x 企业应用开发实战》一段话:
Spring AOP使用纯Java实现,它不需要专门的编译过程,也不需要特殊的类装载器,它在运行期通过代理方式向目标类织入增强代码。在Spring中可以无缝地将Spring AOP、IoC和AspectJ整合在一起。
来源《Spring 实战 (第4版)》一句话:
Spring AOP构建在动态代理基础之上,因此,Spring对AOP的支持局限于方法拦截。
在Java中动态代理有两种方式:
JDK动态代理
CGLib动态代理
JDK动态代理是需要实现某个接口了,而我们类未必全部会有接口,于是CGLib代理就有了~~
CGLib代理其生成的动态代理对象是目标类的子类
Spring AOP默认是使用JDK动态代理,如果代理的类没有接口则会使用CGLib代理。
那么JDK代理和CGLib代理我们该用哪个呢??在《精通Spring4.x 企业应用开发实战》给出了建议:
如果是单例的我们最好使用CGLib代理,如果是多例的我们最好使用JDK代理
原因:
JDK在创建代理对象时的性能要高于CGLib代理,而生成代理对象的运行性能却比CGLib的低。
如果是单例的代理,推荐使用CGLib
看到这里我们就应该知道什么是Spring AOP(面向切面编程)了:将相同逻辑的重复代码横向抽取出来,使用动态代理技术将这些重复代码织入到目标对象方法中,实现和原来一样的功能。
这样一来,我们就在写业务时只关心业务代码,而不用关心与业务无关的代码
1.3AOP的实现者AOP除了有Spring AOP实现外,还有著名的AOP实现者:AspectJ,也有可能大家没听说过的实现者:JBoss AOP~~
我们下面来说说AspectJ扩展一下知识面:
AspectJ是语言级别的AOP实现,扩展了Java语言,定义了AOP语法,能够在编译期提供横切代码的织入,所以它有专门的编译器用来生成遵守Java字节码规范的Class文件。