SpringAOP理解实现方式

news2024/11/15 12:13:06

Aop

什么是Aop?

AOP就是面向切面编程,通过预编译方式以及运行期间的动态代理技术来实现程序的统一维护功能。

什么是切面,我理解的切面就是两个方法之间,两个对象之间,两个模块之间就是一个切面。假设在两个模块之间需要共同执行一系列操作,并且最后将这一系列操作注入到两个模块之间的指定位置。此时这一系列操作就是切面,注入这些操作的位置称之为切点

举例:公司员工上班

A员工上班需要在前台进行打卡,同样的B员工…其他员工都需要在前台打卡,那么如果为每一位员工提供单独的打卡通道就有些过于浪费资源。像这样

在这里插入图片描述

于是,在前台这个位置设置接口,声明公共的打卡方法,所有员工共同通过该接口进行打卡,那么在打卡时的一系列校验或者记录的整个操作就可以被称之为切面,前台这个空间位置就被称之为切点,如下图所示

在这里插入图片描述

aop主要作用就是进行日志记录、事务/异常处理等功能以便更好地维护开发,主要目的就是将这些行为从项目的业务逻辑代码中分离出来并且降低各个业务逻辑模块之间的耦合度。保证在执行aop操作的同时不会影响到项目的业务逻辑代码

几个概念

Aspect:切面 Aspect中会包含一些pointCut切入点以及一些Advice
Advice:通知 切面需要完成的工作,通过before、after、around来区别是在连接点之前或者之后 或者环绕
Target:目标 目标对象,该对象会被织入advice
PointCut:切点 即切面通知执行的地点 advice将会在这里发生
JointPoint:连接点 所有方法的执行点

PointCut用来修饰JointPoint,PointCut是advice执行的点,而JointPoint表示所有方法的执行点,通过PointCut可以确定哪些JointPoint是可以被织入的点

我们通常不希望advice会在所有的JointPoint点执行,PointCut的作用就是可以进行校验来更精准的匹配执行点。简单概括就是Jointpoint可以执行但未必执行,只有PointCut匹配到了JointPoint才可以在该点执行

Aspect切面可以理解为PointCut+Advice

使用AOP织入导入包

<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
  <groupId>org.aspectj</groupId>
  <artifactId>aspectjweaver</artifactId>
  <version>1.9.7</version>
  <scope>runtime</scope>
</dependency>

实现aop方式一

使用spring内置的API接口

准备:UserService、UserServiceImpl简单实现CRUD
在spring核心配置文件applicationContext.xml中配置aop:

<?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      https://www.springframework.org/schema/beans/spring-beans.xsd                     http://www.springframework.org/schema/aop                  https://www.springframework.org/schema/aop/spring-aop.xsd">
  <bean id="userServiceImpl" class="com.mount.service.UserServiceImpl"/>
  <bean id="log" class="com.mount.log.log"/>
  <bean id="afterLog" class="com.mount.log.AfterLog"/>

  <!--  配置AOP  -->
  <aop:config>
    <!-- 切入点 expression表达式  表示从哪里开始执行   -->
    <aop:pointcut id="pointcut" expression="execution(* com.mount.service.UserServiceImpl.*(..))"/>
    <!--      执行环绕增强  -->
    <aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
    <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
  </aop:config>
</beans>

编写执行前后日志

// 执行前  实现spring内置接口MethodBeforeAdvice
public class log implements MethodBeforeAdvice {
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println(target.getClass().getName()+"执行了"+method.getName()+"方法");
    }
}
// 执行后 实现AfterReturningAdvice 
public class AfterLog implements AfterReturningAdvice {
  public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
    System.out.println(target.getClass().getName()+"调用了"+method.getName()+"方法"+"返回的结果为"+returnValue);
  }
}

测试:

@Test
public void test01(){
  ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
  UserService bean = context.getBean("userServiceImpl", UserService.class);
  bean.insert();
}

实现aop方式二

使用自定义类,只需要在applicationContext.xml中重新配置aop,并且自己diy一个类即可,在配置时可以选择任一方法为前置日志或后置日志即可

<!--  配置AOP 方式二  -->
<bean id="diy" class="com.mount.diyLog.diyLogImpl"/>

<aop:config>
  <!--     自定义切面 ref引入的类   -->
  <aop:aspect ref="diy">
    <aop:pointcut id="pointcut" expression="execution(* com.mount.service.UserServiceImpl.*(..))"/>
    <aop:before method="before" pointcut-ref="pointcut"/>
    <aop:after method="after" pointcut-ref="pointcut"/>
  </aop:aspect>
</aop:config>

diylog类

public class diyLog {
  public void before(){
    System.out.println("===before方法执行===");
  }
  public void after(){
    System.out.println("===after方法执行===");
  }
}

注解实现aop

首先需要在applicationContext.xml文件中打开SpringAOP对注解的支持

<!-- SpringAop开启注解支持 -->
<aop:aspectj-autoproxy/>
<!-- 映射自定义注解实现log类 -->
<bean id="annoLog" class="com.mount.annoLog.annoLogImpl"/>

annoLog

// Aspect标注该类是一个切面
@Aspect
public class annoLogImpl {
  // 前置增强
  @Before("execution(* com.mount.service.UserServiceImpl.*(..))")
  public void before(){
    System.out.println("---方法执行前---");
  }
  // 后置增强
  @After("execution(* com.mount.service.UserServiceImpl.*(..))")
  public void after(){
    System.out.println("---方法执行后---");
  }

  // 环绕增强
  @Around("execution(* com.mount.service.UserServiceImpl.*(..))")
  public void around(ProceedingJoinPoint joinPoint) throws Throwable {
    System.out.println("环绕前");
    Object proceed = joinPoint.proceed();// 方法执行
    System.out.println("方法签名"+joinPoint.getSignature());
    System.out.println("方法执行返回="+proceed);
    System.out.println("环绕后");
  }
}

最终打印:

环绕前
---方法执行前---
删除成功!
---方法执行后---
方法签名Integer com.mount.service.UserService.delete()
方法执行返回=1
环绕后

可以发现,around环绕增强首先执行,在执行到joinPoint.proceed()时,会执行对应方法,执行对应方法的时候才会执行前置或后置的其他增强操作

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/343950.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

9.手动部署Java应用

Jenkins部署Java应用什么java应用手动部署java环境、手动进行代码发布过程1.环境准备配制负载均衡配制webserver&#xff08;tomcat&#xff09;集群本地做域名劫持查看效果2.模拟开发提交Java代码-->推送至gitlab上传代码至gitlab3.运维克隆代码&#xff0c;然后通过maven手…

Yolo-fastestv2训练自己的数据集记录

Yolo-fastestv2训练自己的数据集记录 第一节&#xff1a;代码来源 本机环境&#xff1a;ubuntu20&#xff0c;cuda,cudnn,pytorch1.11.0 代码来源&#xff1a;https://github.com/dog-qiuqiu/Yolo-FastestV2 配置环境后先测试一下环境 终端输入&#xff1a; python3 test.py…

Vue入门介绍

一、背景 目前前端主流框架有Vue、react、Angular等&#xff0c;其中Vue简单易学&#xff0c;只要稍微会点HTML、CSS、JavaScript基础就能很快上手Vue&#xff0c;其门槛低&#xff0c;上手速度快的特点&#xff0c;深受测试开发同学喜爱&#xff0c;已逐渐成为测开必备的前端…

spring回显方式在代码层面的复现(内存马系列篇十四)

前言 在前面的一章中&#xff0c;主要在理论上进行了各种内存马的实现&#xff0c;这里就做为上一篇的补充&#xff0c;自己搭建反序列化的漏洞环境来进行上文中理论上内存马的注入实践。 这是内存马系列文章的第十四篇。 环境搭建 可以使用我用的漏洞环境 https://github…

一款基于java的超级棒的开源支付系统(用来毕设也不错),国内首款开源的互联网支付系统

最近就快要到年末了&#xff0c;小编想着应该会有很多公司开始冲年度的业绩了&#xff0c;既然是冲业绩&#xff0c;就离不开我们的支付系统&#xff0c;所以小编就去网上给大家找到了一款超级棒的开源支付系统&#xff01;帮助大家从头到尾了解清楚这其中的逻辑&#xff01;所…

蓝牙 - 芯片制造商的代号编制以及在Windows上查看

在蓝牙技术的规范中&#xff0c;对很多信息都进行了整理和代号分配&#xff0c;比如生产蓝牙芯片的厂商&#xff0c;也进行了数字编号。 有一个专门的“Assigned Numbers”的PDF文档&#xff0c;记录了蓝牙规范中的各种类型数字所表示的含义。 本文介绍的数字类型&#xff0c…

JavaScript Window - 浏览器对象模型

JavaScript Window - 浏览器对象模型 浏览器对象模型 (BOM) BOM&#xff1a;Browser Object Model 是浏览器对象模型&#xff0c;BOM由多个对象构成&#xff0c;其中代表浏览器窗口的window对象是BOM的顶层对象也是核心对象&#xff0c;其他对象都是该对象的子对象。 BOM对象…

IB-PYP幼儿十大素质培养目标

作为IB候选学校&#xff0c;一直秉承IB教育的核心目标&#xff0c;贯彻在幼儿的学习生活中。IB教育之所以成为当今国际教育的领跑者&#xff0c;最主要的原因是IB教育是切切实实的“全人”教育&#xff0c;“素质”教育&#xff0c;拥有一套完整的教学服务体系。当我们走进IB“…

【机器学习实战】七、梯度下降

梯度下降 一、线性回归 线性回归算法推导过程可以基于最小二乘法直接求解&#xff0c;但这并不是机器学习的思想&#xff0c;由此引入了梯度下降方法。本文讲解其中每一步流程与实验对比分析。 1.初始化 import numpy as np import os %matplotlib inline import matplotli…

C语言(结构和指针)

目录 1.声明结构指针 2.用指针访问成员 3.传递结构成员 4.传递结构的地址 5.传递结构 6.机构的其他特性 7.结构中的字符数组和字符指针 关于为什么要使用指向结构的指针。 第一&#xff0c;就像指向数组的指针比数组本身更容易操作一样&#xff0c;指向结构的指针通常比…

5年自动化测试,终于进字节了,年薪30w其实也并非触不可及

我的职业生涯开始和大多数测试人一样&#xff0c;开始接触都是纯功能界面测试&#xff0c;第一份测试工作就是在电商公司做功能测试&#xff0c;工作忙忙碌碌&#xff0c;每天在各种业务需求学习和点点中度过&#xff0c;过了好几年发现自己还只是一个功能测试工程师&#xff0…

第十二章 Ambari二次开发之集成Alluxio

1、Alluxio高可用部署 生产环境&#xff1a;使用具有高可用性的模式来运行Alluxio masters。 1.1、Alluxio架构 ​ Alluxio可以被分为三个部分&#xff1a;**masters、workers以及clients。**一个典型的设置由一个主服务器、多个备用服务器和多个worker组成。客户端用于通过S…

机器学习实战--梯度下降法进行波士顿房价预测

前言&#xff1a; Hello大家好&#xff0c;我是Dream。 今天来学习一下如何使用机器学习梯度下降法进行波士顿房价预测&#xff0c;这是简单的一个demo&#xff0c;主要展示的是一些小小的思路~ 本文目录&#xff1a;一、波士顿房价预测1.全部的数据可视化2.地理数据可视化3.房…

基于”PLUS模型+“生态系统服务多情景模拟预测实践

工业革命以来&#xff0c;社会生产力迅速提高&#xff0c;人类活动频繁&#xff0c;此外人口与日俱增对土地的需求与改造更加强烈&#xff0c;人-地关系日益紧张。此外&#xff0c;土地资源的不合理开发利用更是造成了水土流失、植被退化、水资源短缺、区域气候变化、生物多样性…

根据手机号显示其运营商信息phone.find

【小白从小学Python、C、Java】【计算机等级考试500强双证书】【Python-数据分析】根据手机号显示其运营商信息phone.find选择题以下关于python代码表述错误的一项是?from phone import PhonephonePhone()print(【执行】phone.find())resultphone.find("13366667777"…

21.操作符优先级和结合性列表,复杂表达式求值顺序

目录一、复杂表达式求值顺序1.操作符的优先级2.操作符的结合性3.操作符是否控制执行的顺序二、求值顺序三、操作符优先级和结合性列表一、复杂表达式求值顺序 复杂表达式的求值顺序由三个因素决定&#xff1a; 1.操作符的优先级 2.操作符的结合性 3.操作符是否控制执行的顺序 1…

【代码随想录训练营】【Day12休息】【Day13】第五章|栈与队列|239. 滑动窗口最大值|347.前 K 个高频元素|总结

239.滑动窗口最大值 题目详细&#xff1a;LeetCode.239 看到滑动窗口&#xff0c;我立马想起了双指针&#xff0c;利用双指针可以非常清晰地理解解题思路&#xff1a; 定义一个变量 max_i 用于记录窗口中的最大值的索引每次窗口滑动后 如果出去的值是最大值&#xff0c;那么…

ChatGPT实火,这小东西牛在哪?

ChatGPT&#xff0c;真的火了啊&#xff01; 相信许多朋友都听说过 ChatGPT铺天盖地的赞美&#xff0c;但并不清楚它是个啥。 体制内让ChatGPT写材料&#xff0c;广告行业让ChatGPT写策划案&#xff0c;媒体让ChatGPT写新闻稿&#xff0c;程序员让ChatGPT写代码甚至还带修BUG服…

三、常用样式讲解一

文章目录一、企业站点样式实战1.1 版心1.2 reset.css1.3 index.css&#xff08;首页的样式&#xff09;1.4 溢出1.5 元素类型1.6 元素类型的转换1.7 行内块元素的特殊情况&#xff1a;img标签的特殊性一、企业站点样式实战 1.1 版心 1.2 reset.css /* reset.css用作清除一些常…

行人检测(人体检测)2:YOLOv5实现人体检测(含人体检测数据集和训练代码)

行人检测(人体检测)2&#xff1a;YOLOv5实现人体检测(含人体检测数据集和训练代码) 目录 行人检测(人体检测)2&#xff1a;YOLOv5实现人体检测(含人体检测数据集和训练代码) 1. 前言 2. 人体检测数据集说明 &#xff08;1&#xff09;人体检测数据集 &#xff08;2&#…