Spring AOP基础

结绳记事,总结,思考,方有成长~

AOP是什么

AOP是Aspect Oriented Programing的简称,即面向切面编程。它为程序开发提供了一个崭新的思考角度,可以将重复性的横切逻辑抽取到统一的模块中。通过OOP的纵向抽象和AOP的横向抽取,程序才可以真正解决重复性代码问题。

AOP术语

  • 连接点(Joinpoint):类中具有边界性质的特定点,比如类中某个方法调用前、调用后、方法抛出异常后,这都是被称为“连接点”。
  • 切点(Pointcut):在为数众多的“连接点”中,AOP通过“切点”定位到具体的“连接点”。借助数据库查询概念来理解再好不过:连接点相当于数据库中的记录,而切点相当于查询条件。切点和连接点不是一对一的关系,一个切点可以匹配多个连接点。
  • 增强(Advice):织入目标类连接点上的程序代码,同时也包含方位信息,比如方法执行前、执行后、抛出异常后。
  • 织入(Weaving):将增强添加到目标类的具体连接点上的过程,AOP有3种织入方式:
    • 编译期织入,要求使用特殊的Java编译器。
    • 类装载期织入,要求使用特殊的类装载器。
    • 动态代理织入,在运行期为目标类添加增强生成子类的方式。
      Spring采用动态代理织入,使用纯Java实现,不需要专门的编译过程,也不需要特殊的类装载器,它在运行期通过代理方式向目标类织入增强代码。
      AspectJ采用编译期织入和类装载期织入,是语言级的AOP实现,有一个专门的编译器来生成遵守Java字节码规范的Class文件。
  • 代理(Proxy):一个类被AOP织入增强后,就产生一个结果类,它是融合了原类和增强逻辑的代理类。
    Spring AOP使用动态代理技术在运行期织入增强的代码,分为JDK动态代理 和 CGLib动态代理。使用JDK动态代理,目标类必须实现接口,而CGLib不对目标类做任何限制,它通过动态生成目标类子类的方式提供代理。JDK在创建代理对象时性能高于CGLib,而生成的代理对象的运行性能却比CGLib低。如果是singleton的代理,则推荐使用CGLib动态代理。
  • 切面(Aspect):切面由切点和增强组成。即包括了横切代码的逻辑,又包括了连接点的定义。

AOP无法增强

例如在一个service类中有2个方法bus1()和bus2()都使用了@Cacheable缓存注解也就是希望2个方法都启用缓存。如果业务处理过程中,bus1()调用了bus2(),则bus2()方法永远无法启用缓存。
原因为:方法内部之间调用的时候,不会使用被增强的代理类,而是直接调用未被增强原类的方法,这也就是bus2()无法被织入增强的原因。

@AspectJ

Spring AOP中定义一个切面是比较繁琐的,需要实现专门的接口,并进行一些较为复杂的配置,推荐使用@AspectJ注解,可以非常容易的定义一个切面,而不需要实现任何接口。
注意:Spring在处理@AspecJ注解表达式时,需要将Spring的asm模块添加到类路径中。asm是轻量级的字节码处理框架,因为Java的反射机制无法获取入参名,Spring就利用asm处理@AspectJ中所描述的方法入参名。
此外,Spring采用AspectJ提供的@AspectJ注解类库及相应的解析类库,需要再pom.xml文件中添加aspect.weaver和aspectj.tools类包的依赖。
在使用@AspectJ切面时,需要基于Schema的aop命名空间进行配置,如下:

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="……"
			xmlns:aop="http://www.……">
			<!-- 基于@AspectJ切面的驱动器>
			<aop:aspectj-autoproxy />
</beans>

@AspectJ定义切面的切点表达式,最合适的方式推荐注解,自定义注解,然后在需要增强的方法上使用该注解即可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章