首页 > 其他分享 >Spring的AOP概念详解

Spring的AOP概念详解

时间:2024-07-01 16:56:35浏览次数:3  
标签:事务 spring Spring AOP 详解 通知 执行 方法

AOP详解:

1.介绍:

面向切面编程,是一种将非业务代码与业务代码进行分离的一种思想,在实际开发中,往往有许多重复操作,例如事务提交,权限验证,保存口志等功能需要在业务代码重复调用,面向切面编程,就是将非业务代码进行抽取,然后在不修改原来代码的前提下,为我们的业务代码,添加额外的功能.

面向切面编程的好处就是: 减少重复,专注业务;
注意:面向切面编程只是面向对象编程的一种补充
2.核心原理:

使用动态代理的方式在执行方法前后或者出现异常的时候做加入相关的逻辑.

3.使用案例:

事务处理:开启事务,关闭事务,出现异常后回滚事务 权限判断:在执行方法前,判断是否具有权限 日志:在执行前进行日志处理

4.总结:

AOP就是把重复的非业务代码通过动态代理的方式实现,让开发者配置一次后就不用再考虑重复的非业务代码

AOP思想不是spring中特有的,是java中的动态代理模式,是spring框架使用了这一思想

5.基本概念:

(1) 连接点(Joinpoint):类中可以被增强(可以添加额外功能的方法)的方法

(2) 切入点(Pointcut):类中实际被增强的方法,把额外功能实际切入的方法

(3) 通知(Advice):是指一个切面在特定的连接点要做的事情(增强的功能),通知分为方法执行前通知,方法执行后通知,环绕通知等

(4) 目标(Target):代理的目标对象,连接点和切入点方法所在的类

(5) 代理(Proxy):向目标对象应用通知时创建的代理对象(目前使用的代理对象由spring框架生成,目前我们不需要关心)

6.springAOP实现:

下载 AOP 相关 jar

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>

AspectJ 中常用的通知有五种类型:

注解放在对应的方法上方:

    @Before("execution(* com.lzy.springpro.dao.*.*(..))")
    public void saveLog(){
        System.out.println("方法执行成功");
    }

AOP中的通知类型:
@Before 前置通知,在我们的方法实际执行前调用
@After 后置通知,子啊方法执行后执行,即使出现异常也会执行
@AfterReturning 返回通知,方法成功执行之后通知,出现异常不通知
@AfterThrowing 异常通知,当切入点出现异常执行,没有异常不执行
@Around 环绕通知,方法执行前后都有通知,可以实现其余四个通知

启动 AspectJ 支持:

<aop:aspectj-autoproxy/>

同时spring.xml还要配置AOP相关:

xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation=        
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        @Before("execution(* com.lzy.springpro.dao.AdminDao.saveAdmin(..))")
        @After("execution(* com.lzy.springpro.dao.*.*(..))")
        @AfterReturning("execution(* com.lzy.springpro.dao.*.*(..))")
        @AfterThrowing("execution(* com.lzy.springpro.dao.*.*(..))")
        @Around("execution(* com.lzy.springpro.dao.*.*(..))")

Around:

    @Around("execution(* com.lzy.springpro.dao.*.*(..))")
    public void around(ProceedingJoinPoint joinPoint){
        try{
            System.out.println("保存日志"); //前置通知

            Object[] args=joinPoint.getArgs();  //获取方法中的参数
            System.out.println(Arrays.toString(args));
            joinPoint.proceed();    //调用我们自己的方法

            System.out.println("提交事务"); //返回通知
        }catch (Throwable e){
            System.out.println("系统异常"); //异常通知
        }
        System.out.println("后置通知"); //后置通知
    }
7.Spring 事物管理
什么是数据库事务

​ 数据库事务是一次对数据库执行的若干操作的管理,这一次操作的若干条sql语句,应该是一个整体的单元

例如转账:

​ 一次转账操作,对于用户来讲已是一个操作,但是这一次操作中,会执行多条sql语句,例如语句1:从A账户减钱 语句2:从B账户加钱。两个语句必须是一个整体,要么都成功执行,要么都不执行。这是事务特征的最基本的原子性特征。只有当一次操作完成后,向数据库提交事务后,数据库才会将多条sql真正的执行。

为什么需要事务?

​ 保证数据的完整性,不能一半保存到数据库,一半没保存成功。

之前在jdbc中是每次执行完sql后,事务九自动提交的。(自动提交是有风险的)在mybatis中是手动sqlSession.commit();提交的,这很麻烦

spring事务管理:

​ spring事务管理就是AOP的基础上,当我们的方法完全执行后,再提交事务,如果方法中有异常,就不提交事务。

​ spring中的事务管理有两种方式:

1.编程式事务

​ 需要我们再业务代码中手动提交

2.声明式事务
配置事物管理器
<!-- 配置 spring 事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
注解方式
<!-- 开启注解事务管理 -->
<tx:annotation-driven transaction-manager="transactionManager"/>

在类或方法上使用@Transactional :

/*
    @Transactional 可以添加在类上,这样类中所有的方法都在事务管理中进行
                   也可以添加在方法上,只有所添加的方法再事务管理中进行
 */
 @Transactional(rollbackFor = Exception.class)
public class LoginService {
	......	
}

声明式事务几种失效场景:

1.@Transactional用在了非public方法上面(受封装的不能直接获取的)
2.异常被catch捕获了,认为方法没有出现异常
3.默认出现编译期异常,事务失效,可以在@Transactional(rollbackFor=Exception.class)设置回滚异常类型为Exception,这样即使出现编译期异常,也是有效的
4.数据库引擎不支持事务,目前mysql中只有innodb引擎支持事务

标签:事务,spring,Spring,AOP,详解,通知,执行,方法
From: https://blog.csdn.net/qq_45576281/article/details/140105280

相关文章

  • springboot使用itextpdf+jfreechart制作PDF文档
    1.springboot引入的依赖组件项目中需要引入itextpdf和jfreechart两个组件,版本根据项目所需进行引入,maven组件版本查询可根据如下地址进行查询:maven组件查询<dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><vers......
  • spring趣玩
    自定义banner先上图片,替换spring启动标志;或者也可以在启动类代码设置Banner也可以通过设置springApplication.setBannerMode(Banner.Mode.OFF);关闭打印横幅ApplicationRunner和@PostConstructApplicationRunner是一种灵活的机制,可以用来执行数据库迁移、预加载数据、启动定......
  • springboot-javax.validation检查是否属于指定的值
    引入依赖:<!--jsr303--><dependency><groupId>javax.validation</groupId><artifactId>validation-api</artifactId><version>1.1.0.Final</version></dependency><!--hibernatevalidator--><depen......
  • 鸿蒙技术之WebSocket连接详解
    WebSocket连接详解WebSocket是一种在单个TCP连接上提供全双工通信信道的协议,它允许服务器主动向客户端推送数据,非常适合实时通信和数据交换频繁的应用场景。以下是WebSocket连接的详细步骤和知识点:1.创建WebSocket对象首先,需要通过createWebSocket()方法创建一个WebSock......
  • java springboot过滤器
    在SpringBoot应用中添加自定义过滤器,可以通过实现Filter接口或继承OncePerRequestFilter类来创建过滤器,并使用FilterRegistrationBean将其注册到Spring容器中。以下是一个简单的示例:1.创建过滤器类        首先,创建一个实现Filter接口的类,或者为了简化单次请求处......
  • springboot-javax.validation编写自定义校验注解
    引入依赖:<!--jsr303--><dependency><groupId>javax.validation</groupId><artifactId>validation-api</artifactId><version>1.1.0.Final</version></dependency><!--hibernatevalidator--><depen......
  • 【Linux命令详解 - ssh命令】 ssh命令用于远程登录到其他计算机,实现安全的远程管理
    文章标题简介一,参数列表二,使用介绍*1\.连接远程服务器2.使用SSH密钥登录*2.1生成密钥对2.2将公钥复制到远程服务器3.端口转发*3.1本地端口转发3.2远程端口转发4.X11转发5.文件传输与远程命令执行*5.1文件传输*5.1.1从本地向远程......
  • spring 定时任务 使用线程池
    spring线程池定义packagecom.minex.icp.tool.conf;importlombok.extern.slf4j.Slf4j;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.scheduling.annotation.AsyncConfi......
  • springboot+vue前后端分离项目-vue项目搭建6-文件上传下载
    1.新增com/example/demo/controller/FileController.javapackagecom.example.demo.controller;importcn.hutool.core.io.FileUtil;importcn.hutool.core.util.IdUtil;importcn.hutool.core.util.StrUtil;importcom.example.demo.common.Result;importjakarta.ser......
  • 使用Swagger 3注解编写API文档详解
    在现代软件开发中,API文档的编写是至关重要的一环,它不仅能帮助开发者理解和正确使用API,还能提升团队协作效率。Swagger3是一个流行的API文档规范,通过注解的方式可以清晰地定义API的各个方面。本文将深入探讨Swagger3中常用的注解及其使用方法。@OpenAPIDefinition和@Inf......