Spring AOP 不再怕了!

什么是AOP?

AOP(Aspect-Oriented Programming:面向切面编程)能够将那些与业务的逻辑无关 ,但是需要被业务模块所使用到的代码逻辑或责任 (如日志管理、权限控制、事务管理)封装起来,从而减少代码的冗余量,降低模块间的耦合度,有利于未来的可扩展性和可维护性

简单来说,AOP就是可以让你少写点经常写的代码~ 让你可以专注于业务逻辑,AOP会根据你的指示去帮你做那些你懒得做的重复工作

或许你可以给面试官举个例子:歌星都有好多助理,歌星最重要的一件事就是唱歌,其他事他不用关注,比如唱歌前可能需要和其他人谈合作,还要布置场地,唱歌后还要收钱等等,这些统统交给他对应的助理去做。

也许哪一天,这个歌星做慈善,免费唱歌了,不收钱了,那么就可以把收钱这个助力给辞退了。这就是
AOP,每个人各司其职,灵活组合,达到一种可配置的、可插拔的程序结构。AOP 的实现原理就是代理模式。

在程序中也是如此,通过代理,可以详细控制访问某个或者某类对象的方法,在调用这个方法前做前置处理,调用这个方法后做后置处理。

简单了解下AOP的一些概念

引用- 已失效

1.通知(Advice)

就是你想要的功能,也就是上面说的 安全,事物,日志等。你给先定义好把,然后在想用的地方用一下。

2.连接点(JoinPoint)

这个更好解释了,就是spring允许你使用通知的地方,那可真就多了,基本每个方法的前,后(两者都有也行),或抛出异常时都可以是连接点,spring只支持方法连接点.其他如aspectJ还可以让你在构造器或属性注入时都行,不过那不是咱关注的,只要记住,和方法有关的前前后后(抛出异常),都是连接点。

3.切入点(Pointcut)

上面说的连接点的基础上,来定义切入点,你的一个类里,有15个方法,那就有几十个连接点了对把,但是你并不想在所有方法附近都使用通知(使用叫织入,以后再说),你只想让其中的几个,在调用这几个方法之前,之后或者抛出异常时干点什么,那么就用切点来定义这几个方法,让切点来筛选连接点,选中那几个你想要的方法。

4.切面(Aspect)

切面是通知和切入点的结合。现在发现了吧,没连接点什么事情,连接点就是为了让你好理解切点,搞出来的,明白这个概念就行了。通知说明了干什么和什么时候干(什么时候通过方法名中的before,after,around等就能知道),而切入点说明了在哪干(指定到底是哪个方法),这就是一个完整的切面定义。

5.引入(introduction)

允许我们向现有的类添加新方法属性。这不就是把切面(也就是新方法属性:通知定义的)用到目标类中吗

6.目标(target)

引入中所提到的目标类,也就是要被通知的对象,也就是真正的业务逻辑,他可以在毫不知情的情况下,被咱们织入切面。而自己专注于业务本身的逻辑。

7.代理(proxy)

AOP框架创建的对象,代理就是目标对象的加强。Spring中的AOP代理可以使JDK动态代理,也可以是CGLIB代理,前者基于接口,后者基于子类

8.织入(weaving)

把切面应用到目标对象来创建新的代理对象的过程。有3种方式,spring采用的是运行时织入,生成字节码,再加载到虚拟机中,JDKProxy是利用反射原理,Cglib使用了ASM原理

AOP有哪些实现方式?

  1. 静态代理,使用 AOP 框架提供的命令进行编译,从而在编译阶段就可生成 AOP 代理类,因此也称为编译时增强
  2. 动态代理 ,在运行时在内存中“临时”生成 AOP 动态代理类,因此也被称为运行时增强

Spring中有哪些不同的通知类型

摘自

通知(advice)是你在你的程序中想要应用在其他模块中的横切关注点的实现。Advice主要有以下5种类型:

  • 前置通知(Before Advice): 在连接点之前执行的Advice,不过除非它抛出异常,否则没有能力中断执行流。使用 @Before 注解使用这个Advice。
  • 返回之后通知(After Retuning Advice): 在连接点正常结束之后执行的Advice。例如,如果一个方法没有抛出异常正常返回。通过 @AfterReturning 关注使用它。
  • 抛出(异常)后执行通知(After Throwing Advice): 如果一个方法通过抛出异常来退出的话,这个Advice就会被执行。通用 @AfterThrowing 注解来使用。
  • 后置通知(After Advice): 无论连接点是通过什么方式退出的(正常返回或者抛出异常)都会执行在结束后执行这些Advice。通过 @After 注解使用。
  • 围绕通知(Around Advice): 围绕连接点执行的Advice,就你一个方法调用。这是最强大的Advice。通过 @Around 注解使用。

Spring的AOP基于什么实现?

动态代理,本质上就是反射。当要代理的目标对象实现了某个接口时,Spring AOP会使用JDKProxy去创建代理对象,而对于没有实现接口的对象,Spring AOP 会使用Cglib去生成一个目标代理对象的子类来进行代理

CGLIB 创建的动态代理对象比 JDK 创建的动态代理对象的性能更高,但是 CGLIB 创建代理对象时所花费的时间却比 JDK 多得多。所以对于单例的对象,因为无需频繁创建对象,用 CGLIB 合适,反之使用JDK方式要更为合适一些。同时由于 CGLIB 由于是采用动态创建子类的方法,对于final修饰的方法无法进行代理。

什么是代理模式?

代理模式的核心作用就是通过代理,控制对对象的访问。它的设计思路是:定义一个抽象角色,让代理角色和真实角色分别去实现它。

真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用。它只关注真正的业务逻辑,比如歌星唱歌。

代理角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并在前后可以附加自己的操作,比如谈合同,布置场地,收钱等等。

这就是代理模式的设计思路。代理模式分为静态代理和动态代理。静态代理是我们自己创建一个代理类,而动态代理是程序自动帮我们生成一个代理

Spring AOP 和 AspectJ AOP 区别

Spring AOP 是运行时增强,而AspectJ AOP是编译时增强,Spring AOP是基于代理的,而AspectJ AOP是基于字节码操作。AspectJ AOP相对来说更强大,Spring AOP更简单,在切面少的情况下,使用AOP更清晰,但是切面多的情况下,应该使用AspectJ AOP,它在性能上更好

原创文章 14 获赞 52 访问量 1489

猜你喜欢

转载自blog.csdn.net/weixin_44233929/article/details/105807643