SpringBoot AOP

news2025/1/18 4:51:07

SpringBoot AOP

目录

  • SpringBoot AOP
    • 写法一: @Before("execution(* com.bjpowernode.springboot07.javabean.Man.eat(..))")
      • 一、AOP开发
      • 1.1 概述
      • 1.2使用方法
      • 1.3创建项目并添加maven依赖
      • 1.4 创建Javabean测试类
      • 1.5 创建切面
      • 1.6 测试类
      • 1.7 测试结果
      • 1.8 结论
      • 1.9 代理方式的切换
        • 1.9.1 设计一个接口ManInterface
        • 1.9.2 javaBean目标类Man实现ManInterface接口
        • 1.9.3 修改application.yml文件的切换方式代理方式
        • 1.9.4 测试类
        • 1.9.5 测试结果
    • 写法二:
    • public static final String POINT_CUT = "execution(* com.bjpowernode.springboot03aop.domain.Man.*(..))";
    • @Before(value=POINT_CUT)
      • 二、AOP开发
      • 2.1 pom.xml
      • 2.2 javabean
      • 2.3 切面类(不一样的地方)
      • 2.4 测试类
      • 2.5 测试结果
    • 写法三:
    • 三、AOP开发
      • 3.1 pom.xml
      • 3.2 javabean
      • 3.3 切面类(不一样的地方)
      • 3.4 测试类
      • 3.5 测试结果

写法一: @Before(“execution(* com.bjpowernode.springboot07.javabean.Man.eat(…))”)

一、AOP开发

1.1 概述

aop是spring的两大功能模块之一,功能非常强大,为解耦提供了非常优秀的解决方案。SpringBoot集成aop是非常方便的,下面使用aop来拦截业务组件的方法

Aop的作用:在不修改源代码的情况下,对类里面的方法进行增强(前置,后置,环绕,异常)

Aop的关键点:
切入点: 被增强的方法
通知/增强: 就是具体增强的代码

1.2使用方法

使用springboot操作aop 与 直接使用spring的注解方式操作aop方式是一致的

1.3创建项目并添加maven依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

1.4 创建Javabean测试类

javabean

Man.java

package com.bjpowernode.springboot07.javabean;

import lombok.Data;
import org.springframework.stereotype.Component;

@Data
@Component
public class Man {
    public void eat(String foodName){
        System.out.println(foodName+"真好吃");
    }

}

1.5 创建切面

package com.bjpowernode.springboot07.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class ManAspect {

    @Before("execution(* com.bjpowernode.springboot07.javabean.Man.eat(..))")
    public void beforeAdvice(){
        System.out.println("ManAspect.beforeAdvice");
    }

    @After("execution(* com.bjpowernode.springboot07.javabean.Man.eat(..))")
    public void afterAdvice(){
        System.out.println("ManAspect.afterAdvice");
    }

    @Around("execution(* com.bjpowernode.springboot07.javabean.Man.eat(..))")
    public void aroundAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("ManAspect.aroundAdvice--start");
        proceedingJoinPoint.proceed();
        System.out.println("ManAspect.aroundAdvice--end");
    }
}

1.6 测试类

package com.bjpowernode.springboot07;

import com.bjpowernode.springboot07.javabean.Man;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class Springboot07ApplicationTests {
    @Autowired
    private Man man;

    @Test
    public void testAop(){
        System.out.println(man.getClass().getName());
        man.eat("油条");
    }

}

1.7 测试结果

在这里插入图片描述

1.8 结论

springboot aop 默认的动态代理方式为cglib
SpringBoot 2.x开始,AOP为了解决使用JDK动态代理可能导致的类型转换异常,而使用CGLIB。

1.9 代理方式的切换

使用JDK动态代理的方式

1.9.1 设计一个接口ManInterface

package com.bjpowernode.springboot07.javabean;

public interface ManInterface {
    void eat(String foodName);
}

1.9.2 javaBean目标类Man实现ManInterface接口

在这里插入图片描述

package com.bjpowernode.springboot07.javabean;

import lombok.Data;
import org.springframework.stereotype.Component;

@Data
@Component
public class Man implements ManInterface{
    public void eat(String foodName){
        System.out.println(foodName+"真好吃");
    }

}

从springBoot2.x以后,切换代理方式需要在配置文件中配置,使用注解切换的方式失效了
在这里插入图片描述

1.9.3 修改application.yml文件的切换方式代理方式

spring:
    aop:
        proxy-target-class: false # false表示使用JDK代理  true表示使用CGLIB代理,SpringBoot2.x以后默认使用CGLIB代理

1.9.4 测试类

需要改为注入接口

 package com.bjpowernode.springboot07;

import com.bjpowernode.springboot07.javabean.Man;
import com.bjpowernode.springboot07.javabean.ManInterface;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class Springboot07ApplicationTests {


    @Autowired
    private ManInterface man;


    @Test
    public void testAop(){
        System.out.println(man.getClass().getName());
        man.eat("油条");
    }
}

1.9.5 测试结果

在这里插入图片描述

写法二:

public static final String POINT_CUT = “execution(* com.bjpowernode.springboot03aop.domain.Man.*(…))”;

@Before(value=POINT_CUT)

二、AOP开发

2.1 pom.xml

   <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

2.2 javabean

Man.java

package com.bjpowernode.springboot03aop.domain;

import org.springframework.stereotype.Component;

/*
*将此类加入IOC管理
* AOP作用的类一定要加入IOC容器中
*/
@Component
public class Man {

    /**
     * 吃饭的方法
     * @param foodName
     * @return
     */
    public String eat(String foodName){
        System.out.println("吃"+foodName);
        int i=1/0;
        return foodName+"很好吃";
    }

}

2.3 切面类(不一样的地方)

package com.bjpowernode.springboot03aop.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

/*
*切面类加入IOC容器管理
* 添加切面的标识
*/
@Aspect
@Component
public class ManAspect {

    /*
    *切入点
    */
    public static final String POINT_CUT = "execution(* com.bjpowernode.springboot03aop.domain.Man.*(..))";

    /*
    * 前置通知
    */
    @Before(value=POINT_CUT)
    public void before(){
        System.out.println("吃饭前洗手");
    }

    /*
    * 后置通知
    */
    @After(POINT_CUT)
    public void after(){
        System.out.println("饭后甜点");
    }

    /**
     * 环绕通知
     * @param proceedingJoinPoint
     * @return
     */
    @Around(value = POINT_CUT)
    public Object around(ProceedingJoinPoint proceedingJoinPoint){
        Object result = null;
        try {
            System.out.println("执行目标方法之前");
            //执行目标方法
            result = proceedingJoinPoint.proceed();
            System.out.println("执行目标方法之后");
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return result;
    }

    /**
     * 异常通知
     * @param ex
     */
    @AfterThrowing(value = POINT_CUT,throwing = "ex")
    public void afterThrowing(Throwable ex){
        System.out.println("异常了"+ex.getMessage());
    }

}

2.4 测试类

package com.bjpowernode.springboot03aop;

import com.bjpowernode.springboot03aop.domain.Man;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class Springboot03AopApplicationTests {

    @Autowired
    private Man man;

    @Test
    void contextLoads() {
        System.out.println(man.getClass().getName());
        man.eat("面条");
    }

}

2.5 测试结果

在这里插入图片描述

写法三:

三、AOP开发

3.1 pom.xml

   <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

3.2 javabean

Man.java

package com.bjpowernode.springboot03aop.domain;

import org.springframework.stereotype.Component;

/*
*将此类加入IOC管理
* AOP作用的类一定要加入IOC容器中
*/
@Component
public class Man {

    /**
     * 吃饭的方法
     * @param foodName
     * @return
     */
    public String eat(String foodName){
        System.out.println("吃"+foodName);
        int i=1/0;
        return foodName+"很好吃";
    }

}

3.3 切面类(不一样的地方)

package com.bjpowernode.springboot03aop2.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

/*
*切面类加入IOC容器管理
* 添加切面的标识
*/
@Aspect
@Component
public class ManAspect {

    @Pointcut("execution(* com.bjpowernode.springboot03aop2.domain.Man.*(..))")
    public void pointCutMethod(){

    }

    /*
    * 前置通知
    */
    @Before("pointCutMethod()")
    public void before(){
        System.out.println("吃饭前洗手");
    }

    /*
    * 后置通知
    */
    @After("pointCutMethod()")
    public void after(){
        System.out.println("饭后甜点");
    }

    /**
     * 环绕通知
     * @param proceedingJoinPoint
     * @return
     */
    @Around("pointCutMethod()")
    public Object around(ProceedingJoinPoint proceedingJoinPoint){
        Object result = null;
        try {
            System.out.println("执行目标方法之前");
            //执行目标方法
            result = proceedingJoinPoint.proceed();
            System.out.println("执行目标方法之后");
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return result;
    }

    /**
     * 异常通知
     * @param ex
     */
    @AfterThrowing(value = "pointCutMethod()",throwing = "ex")
    public void afterThrowing(Throwable ex){
        System.out.println("异常了"+ex.getMessage());
    }

}

3.4 测试类

package com.bjpowernode.springboot03aop;

import com.bjpowernode.springboot03aop.domain.Man;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class Springboot03AopApplicationTests {

    @Autowired
    private Man man;

    @Test
    void contextLoads() {
        System.out.println(man.getClass().getName());
        man.eat("面条");
    }

}

3.5 测试结果

在这里插入图片描述

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

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

相关文章

pytest学习和使用16-HTML报告如何生成?(pytest-html)

16-HTML报告如何生成&#xff1f;&#xff08;pytest-html&#xff09;1 插件介绍2 pytest-html安装3 生成报告3.1 插件执行方式3.2 执行效果3.3 指定报告生成的路径4 合并css5 报告中的行显示设置6 报告增强6.1 自定义css6.2 报告标题6.3 环境6.4 其他摘要信息6.5 Extra内容6.…

198. 打家劫舍

198. 打家劫舍 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff0c;影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统&#xff0c;如果两间相邻的房屋在同一晚上被小偷闯入&#xff0c;系统会自动报警。 给定一个代表每个…

MySQL调优-Innodb引擎SQL执行的BufferPool缓存机制

目录 Innodb引擎SQL执行的BufferPool缓存机制 为什么Mysql不能直接更新磁盘上的数据而且设置这么一套复杂的机制来执行SQL了&#xff1f; 为什么直接更新磁盘是随机读写&#xff1f;为什么读写磁盘的日志文件是顺序读写&#xff1f; 为什么不直接读写磁盘而是选择读写Buffer…

【吐槽贴】项目经理的进阶日常:项目要收尾了,我却慌了

最近忙着写年终总结&#xff0c;还以为这次的年终奖稳了&#xff0c;结果犯了一个致命的错误&#xff0c;年终奖差点都没了。我负责的一个项目由于客户方比较着急&#xff0c;计划在过年放假前要完成交付&#xff0c;项目进度都完成的差不多了。现在还剩近10天的工期&#xff0…

2022尚硅谷SSM框架跟学(二)MyBatis基础二

2022尚硅谷SSM框架跟学二MyBatis基础二6.MyBatis的各种查询功能6.1查询一个实体类对象6.2查询一个list集合6.3查询单个数据MyBatis别名对应文档6.4查询一条数据为map集合6.5查询多条数据为map集合(1)方式一(2)方式二7.特殊SQL的执行7.1模糊查询7.2批量删除7.3动态设置表名7.4添…

SpringBoot+VUE前后端分离项目学习笔记 - 【16 SpringBoot集成JWT】

JWT简介 JWT是json web token缩写。用点号分为三段&#xff0c;分别表示头、信息和签名。可以使用在RESTFUL接口定义&#xff0c; 也可以使用在普通的web。它将用户信息加密到token里&#xff0c;服务器不保存任何用户信息。服务器通过密钥验证token的正确性&#xff0c;判断是…

模板的基本概念

模板函数模板泛型编程基本概念函数模板格式函数模板的实现函数模板的实例化类模板类模板格式类模板的实例化模板参数的匹配原则复数的相加函数模板 泛型编程 泛型编程是编写与类型无关的通用代码&#xff0c;是代码复用的一种手段。模板是泛型编程的基础。 基本概念 函数模…

【自学C++】C++命名空间引入

C命名空间引入 C命名空间引入教程 C 中的命名空间的引入&#xff0c;我们通常使用 using 语句后面加上命名空间名即可。 C命名空间引入详解 语法 using namespace namespaceName参数 参数描述using引入命名空间使用的关键字。namespace引入命名空间使用的关键字。namespa…

数影周报:2亿Twitter用户资料仅售2美元,微盟集团将筹约15.9亿港元

本周看点&#xff1a;黑客以2美元出售2亿Twitter用户个人资料&#xff1b;Twitter 第三轮裁员&#xff1b;京东科技成立京东云事业部&#xff1b;TikTok Shop越南收入赶超Lazada&#xff1b;微盟集团将筹资约15.9亿港元......数据安全那些事黑客以2美元出售2亿Twitter用户资料近…

2023年山东最新建筑施工架子工(建筑特种作业)模拟题库及答案

百分百题库提供特种工&#xff08;架子工&#xff09;考试试题、特种工&#xff08;架子工&#xff09;考试预测题、特种工&#xff08;架子工&#xff09;考试真题、特种工&#xff08;架子工&#xff09;证考试题库等,提供在线做题刷题&#xff0c;在线模拟考试&#xff0c;助…

mosquitto使用与openssl证书配置

开发环境&#xff1a;ubuntu18.04 64bitmqtt客户端测试工具&#xff1a;mqtt.fx 1.7.11.安装# 引入库 sudo apt-add-repository ppa:mosquitto-dev/mosquitto-ppa sudo apt-get update # 安装 sudo apt-get install mosquitto #安装客户端 sudo apt-get install mosquitto-clie…

《NDT-LOAM: A Real-Time Lidar Odometry andMapping With Weighted NDT and LFA》深大学生

Abstract激光雷达同时定位和建图&#xff08;Lidar-SLAM&#xff09;从激光雷达上处理点云&#xff0c;并完成定位和建图。激光激光通常分为前端里程计和后端优化&#xff0c;可以并行运行以提高计算效率。前端里程计通过处理点云来估计激光雷达的运动&#xff0c;在点云配准中…

python自学之《21天学通Python》(6)

第9章 迭代器、生成器与装饰器 迭代器、生成器与装饰器是Python语言中常用的语法形式。 迭代器的使用简化了循环程序的代码并可以节约内存&#xff0c;生成器的使用也可以节约大量的内存&#xff0c;特别是需要生成大量序列的对象时。迭代器是一种可以从其中连续迭代的一个容器…

Shell 数组

数组中可以存放多个值。Bash Shell 只支持一维数组&#xff08;不支持多维数组&#xff09;&#xff0c;初始化时不需要定义数组大小&#xff08;与 PHP 类似&#xff09;。与大部分编程语言类似&#xff0c;数组元素的下标由 0 开始。Shell 数组用括号来表示&#xff0c;元素用…

教你如何巧妙化解SSRF漏洞攻击

SSRF是一种由攻击者构造请求&#xff0c;由服务端发起请求的安全漏洞。一般情况下&#xff0c;ssrf攻击的目标是外网无法访问的内部系统。简单来说就是利用服务器漏洞以服务器的身份发送一条构造好的请求给服务器所在内网进行攻击。 SSRF漏洞&#xff08; 服务器端请求伪造 &a…

【pandas】教程:9-如何轻松处理时间序列数据

Pandas 如何轻松处理时间序列数据 数据 本节使用的数据为 data/air_quality_no2_long.csv&#xff0c;链接为 pandas案例和教程所使用的数据-机器学习文档类资源-CSDN文库 import pandas as pd import matplotlib.pyplot as pltair_quality pd.read_csv("data/air_qua…

实战字节码-01-基础知识

开篇字节码是什么、做什么这类问题不在这里赘述&#xff0c;《实战字节码》系列旨在帮助没接触过字节码的人能够快速上手做应用开发&#xff0c;并构建字节码技术的知识骨架&#xff0c;所以不会系统地介绍字节码技术的方方面面&#xff0c;也尽量避免叙述理论和概念相关的东西…

【笔记:模拟CMOS集成电路】噪声——基本电路噪声性能(2)

【笔记&#xff1a;模拟CMOS集成电路】噪声——基本电路噪声性能&#xff08;2&#xff09;前言1 噪声——分析基础2 噪声——基本电路噪声性能2.1 MOS管噪声模型(1)电阻RG热噪声和沟道热噪声(2)衬底电阻热噪声(3)源极寄生电阻RS热噪声2.2常见组态的单级放大器噪声分析2.2.1 CS…

Python电影观众数量回归分析 随机森林 可视化 实验报告

实验报告&#xff1a;Python电影观众数量回归分析随机森林可视化-数据挖掘文档类资源-CSDN文库 前言 随着经济的发展和人民日益增长的美好生活需要的显著提升&#xff0c;看电影成为了人民群众在闲暇时光娱乐的重要途径。面对百花齐放的电影产业&#xff0c;哪些电影更能带动市…

OpenGL期末大作业——模拟太阳系(免费开源)

目录 一、项目介绍 二、配置与运行 三、项目地址 一、项目介绍 这是一个综合的openGL场景&#xff0c;模拟太阳系。场景中有光照&#xff0c;纹理等&#xff0c;并有丰富的视角控制&#xff0c;UI交互&#xff0c;比如WASD/IJKL键控制视角的移动等等。一个太阳系的场景&#…