牛批!京东大佬终于把Spring AOP知识点总结出来了,再也不怕踩坑

Hello,今天给各位童鞋们分享的是Spring AOP,赶紧拿出小本子记下来吧

image.png

AOP介绍

面向切面编程(AOP)和面向对象编程(OOP)类似,也是一种编程模式。Spring AOP 是基于 AOP 编程模式的一个框架,它的使用有效减少了系统间的重复代码,达到了模块间的松耦合目的。它将业务逻辑的各个部分进行隔离,使开发人员在编写业务逻辑时可以专心于核心业务,从而提高了开发效率。AOP 采取横向抽取机制,取代了传统纵向继承体系的重复性代码,其应用主要体现在事务处理、日志管理、权限控制、异常处理等方面。

目前最流行的 AOP 框架有两个,分别为 Spring AOP 和 AspectJ。这里介绍Spring AOP的,从 Spring 2.0 开始,Spring AOP 引入了对 AspectJ 的支持。

专业术语说明

  • 通知(Advice): AOP 框架中的增强处理。通知描述了切面何时执行以及如何执行增强处理。
  • 连接点(join point): 连接点表示应用执行过程中能够插入切面的一个点,这个点可以是方法的调用、异常的抛出。在 Spring AOP 中,连接点总是方法的调用。
  • 切点(PointCut): 可以插入增强处理的连接点。
  • 切面(Aspect): 切面是通知和切点的结合。
  • 引入(Introduction):引入允许我们向现有的类添加新的方法或者属性。
  • 织入(Weaving): 将增强处理添加到目标对象中,并创建一个被增强的对象,这个过程就是织入。

Spring AOP 的特点

Spring 中的 AOP 是通过动态代理实现的。不同的 AOP 框架支持的连接点也有所区别,例如,AspectJ 和 JBoss,除了支持方法切点,它们还支持字段和构造器的连接点。而 Spring AOP 不能拦截对对象字段的修改,也不支持构造器连接点,我们无法在 Bean 创建时应用通知。

AOP分类

  • 静态 AOP 实现, AOP 框架在编译阶段对程序源代码进行修改,生成了静态的 AOP 代理类(生成的 *.class 文件已经被改掉了,需要使用特定的编译器),比如 AspectJ。
  • 动态 AOP 实现, AOP 框架在运行阶段对动态生成代理对象(在内存中以 JDK 动态代理,或 CGlib 动态地生成 AOP 代理类),如 SpringAOP。

各种AOP实现方式比较

image.png

动态代理的介绍在设计模式那里会介绍,这个就不描述了。

Spring AOP使用

有两种使用方式:一种是使用Spring中的 org.springframework.aop.framework.ProxyFactoryBean 类,这个类对应的切入点和通知提供了完整的控制能力,并可以生成指定的内容,但在开发中很少使用这种方式。开发中一般使用第二种方式,Spring使用AspectJ开发AOP,这种方式主要用基于 xml 和 Annotation 来实现的,下面也主要讲的是这种实现方式。

Spring使用AspectJ开发AOP

一般使用注解方式来开发,AspectJ 允许使用注解定义切面、切入点和增强处理,而 Spring 框架则可以识别并根据这些注解生成 AOP 代理。

具体实现流程:引入spring的jar包——》创建切面类 ——》创建 Spring 配置文件(使用注解的话就不需要了)【切面类的内容就是指定在什么方法上加上什么通知】——》执行(测试)加上通知的方法

通知类型:

image.png
切入点表达式

切入点表达式主要就是来配置拦截哪些类的哪些方法,就是下面 @Pointcut 经常用到的。

语法:

execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?)

参数讲解:

  • modifiers-pattern?【修饰的类型,可以不写】
  • ret-type-pattern【方法返回值类型,必写】
  • declaring-type-pattern?【方法声明的类型,可以不写】
  • name-pattern(param-pattern)【要匹配的名称,括号里面是方法的参数】
  • throws-pattern?【方法抛出的异常类型,可以不写】

符号讲解:

  • ?号代表0或1,可以不写
  • “*”号代表任意类型,0或多
  • 方法参数为…表示为可变参数

官方案例讲解:

image.png

注解方式

首先需要在Spring配置文件中开启AOP注解方式。xml方式开启

image.png
注解介绍:

  1. @Aspect:指定一个类为切面类
  2. @Pointcut:指定切入点表达式,通知最后增强哪些方法,注解所在的方法必须是private
  3. @Before:前置通知: 目标方法之前执行
  4. @After:后置通知:目标方法之后执行(始终执行)
  5. @AfterReturning:返回后通知: 执行方法结束前执行(异常不执行)
  6. @AfterThrowing:异常通知: 出现异常时候执行
  7. @Around:环绕通知: 环绕目标方法执行(常用)

使用案例:主要提供切面类的代码案例,拦截哪个类、测试代码就不提供了。

image.png
xml方式的实现

基于 XML 的声明式是指通过 Spring 配置文件的方式定义切面、切入点及声明通知,而所有的切面和通知都必须定义在 aop:config 元素中,下面提供一个案例:

<beans xmlns=”www.springframework.org/schema/bean…

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"

xsi:schemaLocation="  

        http://www.springframework.org/schema/beans

        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  

        http://www.springframework.org/schema/aop

        http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">

<!--目标类 -->

<bean id="customerDao" class="com.mengma.dao.CustomerDaoImpl" />

<!--切面类 -->

<bean id="myAspect" class="com.mengma.aspectj.xml.MyAspect"></bean>

<!--AOP 编程 -->

<aop:config>

    <aop:aspect ref="myAspect">

        <!-- 配置切入点,通知最后增强哪些方法 -->

        <aop:pointcut expression="execution ( * com.mengma.dao.*.* (..))"

            id="myPointCut" />

        <!--前置通知,关联通知 Advice和切入点PointCut -->

        <aop:before method="myBefore" pointeut-ref="myPointCut" />

        <!--后置通知,在方法返回之后执行,就可以获得返回值returning 属性 -->

        <aop:after-returning method="myAfterReturning"

            pointcut-ref="myPointCut" returning="returnVal" />

        <!--环绕通知 -->

        <aop:around method="myAround" pointcut-ref="myPointCut" />

        <!--抛出通知:用于处理程序发生异常,可以接收当前方法产生的异常 -->

        <!-- *注意:如果程序没有异常,则不会执行增强 -->

        <!-- * throwing属性:用于设置通知第二个参数的名称,类型Throwable -->

        <aop:after-throwing method="myAfterThrowing"

            pointcut-ref="myPointCut" throwing="e" />

        <!--最终通知:无论程序发生任何事情,都将执行 -->

        <aop:after method="myAfter" pointcut-ref="myPointCut" />

    </aop:aspect>

</aop:config>
复制代码

好啦,今天的文章就到这里了,希望能够帮助到屏幕前迷茫的你们

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享