我的编程空间,编程开发者的网络收藏夹
学习永远不晚

【Spring】面向切面编程详解(AOP)

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

【Spring】面向切面编程详解(AOP)

🌕博客x主页:己不由心王道长🌕!
🌎文章说明:spring🌎
✅系列专栏:spring
🌴本篇内容:对面向切面编程即AOP进行一个详细讲解(对所需知识点进行选择阅读呀~)🌴
☕️每日一语:在人生的道路上,即使一切都失去了,只要一息尚存,你就没有丝毫理由绝望。因为失去的一切,又可能在新的层次上复得。☕️
🕤作者详情:作者是一名双非大三在校生,喜欢Java,欢迎大家探讨学习,喜欢的话请给博主一个三连鼓励。🕤

一、AOP概述

什么是AOP

AOP(Aspect Oriented Program)即面向切面编程。我们先回顾以下三层架构,三层架构式垂直架构,即一层对另一层提供服务,不能越级访问,分级进行运作。
在这里插入图片描述
上述架构是垂直分布的,而面向切面则是一个切面:
到底是什么切面呢?
就是把各种类中冗余的代码提取出来,在需要用的时候就横向切入,就像一个切面一样。
到底是什么冗余代码呢?事务处理、异常处理等等!突然来一大堆听不懂。
举个栗子:
在这里插入图片描述

比如说事务控制,在我们的业务中,虽然查询是最多的,但是添加、修改、删除也不少。查询不用提交事务,而后面的都得提交事务,在JDBC中,我们一般都手动提交事务。
在这里插入图片描述
都得提交事务,难道要在调用每一个方法执行完之后都编写一段提交事务的代码吗?这当然可以,不过太傻了!

④解决办法
上面看到了事务提交每次都编写代码会造成代码冗余,复用性不好,也不利于维护(事务提交与代码耦合死了)。
这是我们可以把上面重复的代码提取出来,制成一个切面,需要用的地方就声明它

⑤ 实现先行剧透:通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。

AOP应用场景

日志记录、性能统计、安全控制、事务处理、异常处理

二、AOP的基本术语

术语介绍

Joint point(连接点): 连接点就是可以被拦截的点,在程序中,通常指的是方法,在Spring中只支持方法类型的连接点。在其他的地方可能支持类,这里记住方法就行了。
Pointcut(切点): 切入点就是对连接点中哪些点进行拦截的定义,对连接点(一般所有方法都可做连接点)进行条件筛选。
Advice(通知/增强): 通知就是我们拦截到切点之后,对它做的事情叫做通知或者增强,比如上面的事务,我们拦截到addUser之后,要对它增强,使其在完成方法之后增强提交事务,异常的时候发生回滚。
Aspect(切面): 即切入点和通知的结合(多个切入点共有一个通知,连在一起像不像一个面?)
Weaving(织入): 指的是在把增强的方法加入到目标对象(切点方法的拥有者)来创建新的对象的过程,spring采用的是动态代理织入(jdk动态代理和子类动态代理都有),AspectJ采用编译期织入和类装载织入。

术语举例详解

先说一个故事吧:
有一天,小吉和他的小伙伴(连接点)去后山的山洞冒险,发现山洞里有一个shiti,小吉和其他一部分小伙伴(切点)就把这个shiti抬了出去,回家后其他抬了的小伙伴都die了,这时候小吉的身上开始发绿,爷爷看到就说:“不好,是绿shi寒警告”。

Joint point(连接点): 在上面的故事里,小吉和他的伙伴都能够被绿,就是都能被增强,可以看到绿shi寒警告是可以作用在上面所以人的身上。在Spring中,这些人就等于可以被增强的方法。
Pointcut(切点): 在上面的故事里,只有小吉和其他几名抬了这个东西的小伙伴收到了绿shi寒,其他没有抬的小伙伴则没有事。可以看出来Pointcut(切点)是有条件的Joint point(连接点),抬了的人被增强了。
Advice(通知/增强): 上面的小伙伴在抬了以后,那个东西就对他们进行了增强。
Aspect(切面): 切点和通知的结合,上面的切点就是抬了的小伙伴和小吉,通知是抬之后的作用,切点有很多,连载一起就像一个面一样。

三、AOP实例说明

一、创建maven工程
二、导入相关配置文件

<dependencies>        <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->        <dependency>            <groupId>org.springframework</groupId>            <artifactId>spring-context</artifactId>            <version>5.2.5.RELEASE</version>        </dependency>        <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->        <dependency>            <groupId>org.springframework</groupId>            <artifactId>spring-core</artifactId>            <version>5.2.5.RELEASE</version>        </dependency>        <!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->        <dependency>            <groupId>org.springframework</groupId>            <artifactId>spring-aop</artifactId>            <version>5.2.5.RELEASE</version>        </dependency>        <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->        <dependency>            <groupId>org.aspectj</groupId>            <artifactId>aspectjweaver</artifactId>            <version>1.9.6</version>            <scope>runtime</scope>        </dependency>

三、添加applicationContext.xml核心配置文件

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"       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.xsd       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

注意、上面给了Aop的命名空间。

四、定义接口和实现类
这里的实现类里面定义的方法就是连接点,至于要增强哪个方法,由程序员根据自己的业务要求,自己指定,要增强的方法就是切点
在这里插入图片描述

package com.bipt.ServiceAop;public interface UserService {    public void save();    public void addUser();}package com.bipt.ServiceAop.impl;import com.bipt.ServiceAop.UserService;public class ImplUserService implements UserService {    @Override    public void save() {        System.out.println("save......");    }    @Override    public void addUser() {        System.out.println("AddUser.......");    }}

在Spring配置文件中添加bean,把ImplUserService作为连接点
在这里插入图片描述

四、写通知类和在配置文件中引入

package com.bipt.ServiceAop;public class MyAdvice {    public void advice1(){        System.out.println("吉尼抬没?");    }}

在这里插入图片描述

五、定义切入点和制作切面

<aop:config>        <!--配置切点,即在哪些方法用到增强,后面是表达式-->        <aop:pointcut id="mypointCut" expression="execution( void com.bipt.ServiceAop.impl.ImplUserService.save())"/>        <!--配置切面,切面就是通知加上增强-->        <aop:aspect id="myadvice" ref="Advice">            <!--before表示前置通知,在切点执行之前执行,method则是通知里的一种方法-->            <aop:before method="advice1" pointcut-ref="mypointCut"></aop:before>        </aop:aspect>    </aop:config>

六、测试
测试要先导入测试的依赖,这里不用Spring的依赖,用junit。

 <!-- https://mvnrepository.com/artifact/junit/junit -->        <dependency>            <groupId>junit</groupId>            <artifactId>junit</artifactId>            <version>4.12</version>            <scope>test</scope>

然后编写测试类

package com.bipt;import com.bipt.ServiceAop.UserService;import com.bipt.ServiceAop.impl.ImplUserService;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import javax.annotation.processing.SupportedAnnotationTypes;public class MyTest {    @Test    public void AopTest(){        ApplicationContext App = new ClassPathXmlApplicationContext("applicationContext.xml");        UserService userService = (UserService) App.getBean("JointPoint");        userService.save();    }}

测试结果如下:
在这里插入图片描述
可以看到结果正确,我们完成了一个入门测试,至于为什么通知在切入点之前执行是因为我们在上面配置切面的时候使用的是before,即前置增强。

四、通知类型详解

概述

通知类型大致分为六类: 分别是前置通知、后置通知、环绕通知、最终通知、异常抛出通知和引介通知。
上述通知中的引介通知我们是用不到的,这里不做介绍。

前置通知

即before,在上面的例子中我们可以清楚的看到,前置通知在切入点方法执行之前执行了。这就是前置通知的作用范围。前置通知的方式一把也可以用作权限验证。

后置通知

即after—running 在目标方法执行之后执行

<aop:pointcut id="after" expression="execution(* com.bipt.ServiceAop.impl.ImplUserService.save())"/>        <!--配置切面,切面就是通知加上增强-->        <aop:aspect  ref="Advice">            <!--before表示后置通知,在切点执行之前执行,method则是通知里的一种方法--><!--            <aop:around method="advice2" pointcut-ref="mypointCut2" ></aop:around>-->            <!--后置通知-->            <aop:after-returning method="after_running" pointcut-ref="after" />

在这里插入图片描述

环绕通知

环绕通知是重点,是最重要的一个通知。环绕通知功能比较强大,它可以追加功能到方法执行的前后,这也是比较常用的方式,它可以实现其他四种通知类型的功能。
环绕通知的怎么做到在方法执行前后追加功能呢? 不难,做一个演示
在这里插入图片描述

最终通知

即after。不管前面发生什么,最终通知都会执行。这里进行演示

<aop:aspect id="myadvice" ref="Advice">            <!--before表示后置通知,在切点执行之前执行,method则是通知里的一种方法-->            <aop:after method="advice1" pointcut-ref="mypointCut"></aop:after>        </aop:aspect>

结果:
在这里插入图片描述
可以看到两个方法执行循序与前置通知相反了。

六、AOP实现声明式事务

二、添加事务管理

事务分为声明式事务和编程式事务,编程式事务就是JDBC的事务提交、回滚等等,这样不太方便,我们有很多的方法都要用到事务,不能需要一个就编写一个,这样太重复了。我们可以把事务抽取出来,利用Spring提高的声明式事务管理来处理。
Spring声明式事务是基于AOP(面向切面)实现的
① 配置事务管理器
事务管理器有很多种,不同的数据访问层框架有不同的实现,而Mybatis的事务管理器为:DataSourceTransactionManager
在这里插入图片描述
②配置事务增强/通知(Advice)
在这里插入图片描述
③ 配置切面
在这里插入图片描述

配置代码:

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xmlns:context="http://www.springframework.org/schema/context"       xmlns:tx="http://www.springframework.org/schema/tx"       xmlns:aop="http://www.springframework.org/schema/aop"       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd       http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context.xsd       http://www.springframework.org/schema/tx  http://www.springframework.org/schema/tx/spring-tx.xsd        http://www.springframework.org/schema/aop expression="com.bipt.controller"/>    </context:component-scan>    <!--导入配置文件-->    <context:property-placeholder location=" classpath:config.properties"></context:property-placeholder>    <!--配置数据源-->    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">        <property name="driverClassName" value="${jdbc.driver}">    </bean>    <!--配置事务管理器-->    <bean id="transactionManager" class="    org.springframework.jdbc.datasource.DataSourceTransactionManager">        <property name="dataSource" ref="dataSource"></property>    </bean>    <!--配置事务增强-->    <tx:advice id="transactionAdvice" transaction-manager="transactionManager">        <tx:attributes>            <tx:method name="login*"  read-only="true"/>            <tx:method name="register*" propagation="REQUIRED" rollback-for="Exception,RuntimeException" read-only="false"/>        </tx:attributes>    </tx:advice>    <!--配置切面-->    <aop:config>        <aop:advisor advice-ref="transactionAdvice" pointcut-ref="transactionPointcut"></aop:advisor>        <aop:aspect ref="dataSource">            <aop:pointcut id="transactionPointcut" expression="execution(* com.bipt.service.*.*(..)) "/>        </aop:aspect>    </aop:config></beans>

结语

码字不易、觉得有帮助的小伙伴动动小手给个三连,无比感谢。

来源地址:https://blog.csdn.net/qq_63992577/article/details/127353729

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

【Spring】面向切面编程详解(AOP)

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

【Spring】面向切面编程详解(AOP)

文章目录 一、AOP概述什么是AOPAOP应用场景 二、AOP的基本术语术语介绍术语举例详解 三、AOP实例说明四、通知类型详解概述前置通知后置通知环绕通知最终通知 六、AOP实现声明式事务
2023-08-30

Spring超详细讲解AOP面向切面

面向对象编程是一种编程方式,此编程方式的落地需要使用“类”和“对象”来实现,所以,面向对象编程其实就是对“类”和“对象”的使用,面向切面编程,简单的说,就是动态地将代码切入到类的指定方法、指定位置上的编程思想就是面向切面的编程
2022-11-13

Java面向切面编程AOP怎么实现

这篇文章主要介绍“Java面向切面编程AOP怎么实现”,在日常操作中,相信很多人在Java面向切面编程AOP怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java面向切面编程AOP怎么实现”的疑惑有所
2023-06-04

Java aop面向切面编程有什么特点

面向切面编程(AOP)是一种软件开发范式,用于将横切关注点(cross-cutting concerns)与主要业务逻辑分离。AOP 可以在不改变原始代码的情况下,通过引入切面(aspect)对应用程序进行功能增强、横切关注点的处理等操作
Java aop面向切面编程有什么特点
2024-03-01

【Spring】一文带你吃透AOP面向切面编程技术(上篇)

个人主页: 几分醉意的CSDN博客_传送门 文章目录 💖AOP概念✨AOP作用✨AOP术语✨什么时候需要用AOP 💖Aspectj框架介绍✨Aspectj的5个通知注解✨Aspectj切入
2023-08-30

Spring超详细讲解面向对象到面向切面

面向对象编程是一种编程方式,此编程方式的落地需要使用“类”和“对象”来实现,所以,面向对象编程其实就是对“类”和“对象”的使用,面向切面编程,简单的说,就是动态地将代码切入到类的指定方法、指定位置上的编程思想就是面向切面的编程
2022-11-13

编程热搜

目录