SpringAOP超详解!!!!

article/2025/9/14 8:17:43

文章目录

  • 一、什么是SpringAOP
  • 二、SpringAOP的应用场景
  • 三、Aop在 Spring 中的作用
  • 四、AOP的实现方式
    • 1、方式一:使用原生Spring API接口
    • 2、方式二:自定义类
    • 方式三:注解

一、什么是SpringAOP

SpringAOP的全称是(Aspect Oriented Programming)中文翻译过来是面向切面编程,AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高
了开发的效率。

个人理解:主要意思是我们的传统架构至上而下,后期想要从中间切入写代码添加功能,比如日志、权限、事务等,这时候我们就需要写使用代理模式写,SpringAOP就是专门把这一块写代码的地方给抽象了出来称为切面,从而解决的代码混乱的问题,它的底层实现也是基于==代理模式(动态代理)==完成的。
在这里插入图片描述

在这里插入图片描述

二、SpringAOP的应用场景

  • 日志记录
  • 权限验证(SpringSecurity有使用)
  • 事务控制(调用方法前开启事务, 调用方法后提交关闭事务 )
  • 效率检查(检测方法运行时间)
  • 数据源代理(seata里面,获取到数据源连接执行的sql)
  • 缓存优化 (第一次调用查询数据库,将查询结果放入内存对象, 第二次调用, 直接从内存对象返回,不需要查询数据库 )

三、Aop在 Spring 中的作用

提供声明式事允许用户自定义切面

  • 横切关注点:跨越应用程序多个横块的方法或功能,即是,与我们业务逻辑无关的,但是我们需要关注的部分,就是横切关注点。如日志,安全,缓存,事务等等.
  • 切面( ASPECT ):横切关注点被模块化的特殊对象,即,它是一个类。
  • 通知( Advice ):切面必须要完成的工作,即,它是类中的一个方法。
  • 目标( Target ):被通知象·代理( Proxy ):向目标对象应用通知之后创建的对象
  • 切入点( PointCut ):切面通知执行的"地点的定义
  • 连接点( JointPoint ):与切入点匹配的执行点

在这里插入图片描述

四、AOP的实现方式

使用AOP织入,需要导入一个依赖包

<dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.4</version></dependency>

1、方式一:使用原生Spring API接口

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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><!--注册bean--><bean id="userService" class="service.UserServiceImpl"/><bean id="log" class="log.Log"/><bean id="afterLog" class="log.AfterLog"/><!--配置aop:需要导入aop的约束--><aop:config><!--切入点:expression:表达式,execution(要执行的位置! * * * *)--><aop:pointcut id="pointcut" expression="execution(* service.UserServiceImpl.*(..))"></aop:pointcut><!--执行环绕增加--><aop:advisor advice-ref="log" pointcut-ref="pointcut"/><aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/></aop:config>
</beans>

UserService接口

package service;public interface UserService {public void add();public void delete();public void update();public void select();
}

UserServiceImpl实现类(切入点)

package service;public class UserServiceImpl implements UserService{@Overridepublic void add() {System.out.println("增加了一个用户");}@Overridepublic void delete() {System.out.println("删除了一个用户");}@Overridepublic void update() {System.out.println("更新了一个用户");}@Overridepublic void select() {System.out.println("查询了一个用户");}
}

前置通知

package log;import org.springframework.aop.MethodBeforeAdvice;import java.lang.reflect.Method;public class Log implements MethodBeforeAdvice {//method:要执行的目标对象的方法//args:参数//target:目标参数@Overridepublic void before(Method method, Object[] args, Object target) throws Throwable {System.out.println(target.getClass().getName()+"的"+method.getName()+"被执行了");}
}

后置通知

package log;import org.springframework.aop.AfterReturningAdvice;import java.lang.reflect.Method;public class AfterLog implements AfterReturningAdvice {//returnValue:返回值@Overridepublic void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {System.out.println("执行了"+method.getName()+"方法返回结果为:"+ returnValue);}
}

测试类

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import service.UserService;
import service.UserServiceImpl;import java.lang.annotation.Annotation;public class MyTest {public static void main(String[]  args) {ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");//动态代理的是接口UserService userService = (UserService) context.getBean("userService");userService.select();}
}

测试结果
在这里插入图片描述


2、方式二:自定义类

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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><!--注册bean--><bean id="userService" class="service.UserServiceImpl"/><bean id="log" class="log.Log"/><bean id="afterLog" class="log.AfterLog"/><bean id="diy" class="diy.DiyPointCut"/><aop:config><!--自定义切面,ref 要引用的类--><aop:aspect ref="diy"><!--切入点--><aop:pointcut id="point" expression="execution(* service.UserServiceImpl.*(..))"/><!--通知--><aop:before method="before" pointcut-ref="point"/><aop:after  method="after" pointcut-ref="point"/></aop:aspect></aop:config></beans>

UserService接口

package service;public interface UserService {public void add();public void delete();public void update();public void select();
}

UserServiceImpl实现类(切入点)

package service;public class UserServiceImpl implements UserService{@Overridepublic void add() {System.out.println("增加了一个用户");}@Overridepublic void delete() {System.out.println("删除了一个用户");}@Overridepublic void update() {System.out.println("更新了一个用户");}@Overridepublic void select() {System.out.println("查询了一个用户");}
}

自定义类

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

测试类

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import service.UserService;
import service.UserServiceImpl;import java.lang.annotation.Annotation;public class MyTest {public static void main(String[]  args) {ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");//动态代理的是接口UserService userService = (UserService) context.getBean("userService");userService.select();}
}

测试结果
在这里插入图片描述

方式三:注解

applicatonContext.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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><!--注册bean--><bean id="userService" class="service.UserServiceImpl"/><bean id="log" class="log.Log"/><bean id="afterLog" class="log.AfterLog"/><bean id="annotationPointCut" class="diy.AnnotationPointCut"/><!--开启注解支持!JDK(默认 proxy-target-class = "false") cglib(proxy-target-class = "true")--><aop:aspectj-autoproxy proxy-target-class="true"/></beans>

UserService接口

package service;public interface UserService {public void add();public void delete();public void update();public void select();
}

UserServiceImpl实现类(切入点)

package service;public class UserServiceImpl implements UserService{@Overridepublic void add() {System.out.println("增加了一个用户");}@Overridepublic void delete() {System.out.println("删除了一个用户");}@Overridepublic void update() {System.out.println("更新了一个用户");}@Overridepublic void select() {System.out.println("查询了一个用户");}
}

切面类

package diy;import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;@Aspect //标注这个类是一个切面
public class AnnotationPointCut {@Before("execution(* service.UserServiceImpl.*(..))")public void before(){System.out.println("===========方法执行前===========");}@After("execution(* service.UserServiceImpl.*(..))")public void after(){System.out.println("===========方法执行后===========");}//在环绕增强中,我们可以给定一个参数,代表我们要处理切入的点@Around("execution(* service.UserServiceImpl.*(..))")public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {System.out.println("环绕前");Signature signature = proceedingJoinPoint.getSignature();System.out.println("signature:" + signature);
//        //执行方法Object proceed = proceedingJoinPoint.proceed();System.out.println("环绕后");System.out.println(proceed);}
}

测试结果
在这里插入图片描述


http://chatgpt.dhexx.cn/article/geZ8bVj2.shtml

相关文章

springAOP的原理解析

一、缘起 因为springAOP原理其实是使用jdk动态代理和cglib动态代理&#xff0c; 在深入了解springAOP的原理之前&#xff0c;我们需要先补充一点有关动态代理的相关的知识&#xff0c;然后我们对于springAOP的理解才会更透彻。所谓动态代理技术是程序在动态运行期间动态的增强某…

SpringAOP简单案例

简介 本文是一个老师在学校给学生上课的简单案例&#xff0c;介绍了AOP的五个通知的使用&#xff0c;以及通知的执行顺序。通过自定义注解来充当切入点&#xff0c;获取注解的类型分别对不同的老师做对应的业务处理。代码中的消息响应体&#xff08;Result&#xff09;大家可以…

springAOP面试题

1.什么是SpringAop? 一般称为面向切面编程&#xff0c;用于将那些与业务无关&#xff0c;但却对多个对象产生影响的公共行为和逻辑&#xff0c;抽取并封装为一个可重用的模块&#xff0c;这个模块被命名为“切面”&#xff08;Aspect&#xff09;&#xff0c;减少系统中的重复…

SpringAOP复习

作业1 目录 作业1一.单选题二.填空题三.判断题 一.单选题 1、以下不属于ProxyFactoryBean类中的常用可配置属性的是&#xff08;&#xff09;。 A、target B、proxyInterfaces C、targetClass D、interceptorNames 答案&#xff1a;C ProxyFactoryBean 是FactoryBean 接口的…

04、SpringAOP详解

1、Spring AOP简介 1、什么是AOP 1、定义阐述 AOP的全称是 Aspect Oriented Programming&#xff0c;是面向切面编程的技术&#xff0c;把一个个的横切关注点放到某个模块中去&#xff0c;称之为切面。那么每一个的切面都能影响业务的某一种功能&#xff0c;切面的目的就是功…

SpringAop之joinPoint讲解

一、学习背景 摸鱼的时候继续复刻demo&#xff0c;没错&#xff0c;同之前一篇文章&#xff0c;在写aop时又发现自己对aop只停留在面试阶段&#xff0c;甚至还不如&#xff0c;完全不会实践&#xff0c;所以在此记录复刻aop用到的的一些且自己已经遗忘的知识。 那么复刻的一个…

SpringAOP详细配置与使用

目录 SpringAOP简介 AOP概念 Spring AOP简单流程图 Spring AOP之Annotation 前置通知(Before advice) 返回后通知(After reurning advice) 抛出异常后通知(After throwing advice) 后置通知(After (finally) advice) 环绕通知(Around advice) 引入(Introduction) Sp…

SpringAOP的注解形式

铁子们&#xff0c;快扫码关注啦&#xff01;或 wx搜索&#xff1a;“聊5毛钱的java”&#xff0c;关注可领取博主的Java学习视频资料&#xff0c;保证都是干货 上一篇讲了配置文件形式的SpringAOP&#xff1a;Spring中的AOP以及切入点表达式和各种通知 本篇继续看一下注解形…

Spring AOP超详细解析

AOP - 面向切面编程&#xff08;Aspect Oriented Programming&#xff09; Spring早期版本的核心功能&#xff1a;管理对象生命周期与对象分配。 即Bean本身的管理创建&#xff0c;以及它整个生命周期里跟其他对象相互之间引用装配 为了更好的实现管理和装配&#xff0c;一个…

Spring学习:AOP概述

一、AOP概念 AOP是指面向切面编程&#xff0c;利用 AOP 可以对业务逻辑的各个部分进行隔离&#xff0c;从而使得业务逻辑各部分之间的耦合度降低&#xff0c;提高程序的可重用性&#xff0c;同时提高了开发的效率。 通俗描述&#xff1a;不通过修改源代码方式&#xff0c;在主干…

SpringAOP学习--SpringAOP简介及原理

前文对AOP做了介绍&#xff0c;实际项目中&#xff0c;一般不会直接上手手动实现aop&#xff0c;而是使用一些高级封装的aop实现&#xff0c;如SpringAOP。 Spring是一个广泛应用的框架&#xff0c;SpringAOP则是Spring提供的一个标准易用的aop框架&#xff0c;依托Spring的IOC…

图文详解Spring AOP,你学会了吗?

如果说 IOC 是 Spring 的核心&#xff0c;那么面向切面编程AOP就是 Spring 另外一个最为重要的核心&#xff0c;需要重点掌握mikechen 本篇主要会详解以下六点&#xff1a; 1.AOP的定义 2.AOP的作用 3.AOP的应用场景 4.Spring AOP的术语 AOP核心概念Spring AOP 通知分类S…

Spring AOP全面详解(超级详细)

如果说IOC 是 Spring 的核心&#xff0c;那么面向切面编程AOP就是 Spring 另外一个最为重要的核心mikechen AOP的定义 AOP &#xff08;Aspect Orient Programming&#xff09;,直译过来就是 面向切面编程,AOP 是一种编程思想&#xff0c;是面向对象编程&#xff08;OOP&…

mysql执行SQL脚本

方法一 【Mysql的bin目录】\mysql –u用户名 –p密码 –D数据库<【sql脚本文件路径全名】 示例&#xff1a; 如果mysql配了全局变量&#xff0c;就不需要到Mysql的bin目录下执行&#xff0c;可以在任何地方使用用户名、密码、指定数据库等参数值与参数名不需要隔空格 不…

SpringBoot 实现SQL脚本自动执行

SpringBoot 实现配置SQL脚本自动执行 一. 背景 我们可能遇到过这种情况: 在公网开发时, 新增数据表非常容易, 直接登录到对应服务器的mysql / 使用Navicat访问mysql服务器. 然后去执行sql语句或脚本即可在内网开发时, 由于都在一个网段, 所以操作也比较方便但是在公网开发, 部…

flink-sql-client提交sql脚本文件

标题: flink-sql-client提交sql脚本文件 日期: 2021-10-22 22:11:34 标签: [flink,sql-client] 分类: flink 我们知道&#xff0c;sql-client.sh可以提供给我们一个sql交互界面&#xff0c;让我们没执行一个sql&#xff0c;就可以看到执行结果&#xff0c;也可以交互式查询表的…

如何在mysql中执行sql脚本文件

一、sql脚本文件 简介 xxxx.sql这种文件被称为sql脚本文件。sql脚本文件中编写了大量的sql语句。我们执行sql脚本文件的时候&#xff0c;该文件中所有的sql语句会全部执行&#xff01;批量的执行SQL语句&#xff0c;可以使用sql脚本文件。 上面这个vip.sql就是sql脚本文件&am…

使用sql脚本创建数据库表

准备脚本语句&#xff1a; CREATE TABLE test (title varchar(100) DEFAULT NULL,author varchar(10) DEFAULT NULL,digest varchar(255) DEFAULT NULL,content text,content_source_url varchar(500) DEFAULT NULL,thumb_media_id varchar(255) DEFAULT NULL,need_open_comme…

PowerDesigner生成Sql脚本

点击工具栏上的“Database”&#xff0c;选择“Change Current DBMS”进行修改导出脚本类型&#xff0c;可以选择mysql、sql server/ oracle 、db2等主流的数据库。 在DBMS中点击下拉菜单&#xff0c;选择要导出的数据库脚本&#xff0c;对名字进行自定义&#xff0c;点击确定即…

PowerDesigner导入sql脚本

一个好的数据库建模,不但可以让人直观的理解模型,充分的利用数据库技术,优化数据库的设计,而且还可以让新员工快速的熟悉数据库表结构与业务之间的关系.无奈的是随着开发过程中,数据库表结构字段的增删以及关联关系的变动给数据库模型带来维护上的巨大工作量.现为了维护上的简单…