【第13章】spring-aop全注解版

文章目录

  • 前言
  • 一、准备
    • 1.引入库
    • 2. 业务类
      • 2.1 service
      • 2.2 impl
  • 二、核心代码
    • 1. 切面类
    • 2. 配置类
    • 3. 启动类
    • 4. 执行结果
  • 总结


前言

Spring AOP(Aspect-Oriented Programming,面向切面编程)是Spring框架中的一个重要模块,它提供了一种将横切关注点(cross-cutting concerns)从业务逻辑中分离出来的方法。横切关注点通常包括日志记录、事务管理、安全性等,这些关注点经常散落在代码的各个角落,导致代码重复和难以维护。

通过使用Spring AOP,你可以将这些横切关注点定义为切面(Aspect),然后将它们织入(weave)到目标对象的方法执行流程中。这样,你可以在不影响业务逻辑的前提下,添加或修改横切关注点的行为。

Spring AOP主要使用代理模式来实现,它为目标对象创建一个代理对象,并在代理对象上拦截方法调用。当方法被调用时,代理对象会根据切面的配置来决定是否执行额外的操作(如日志记录、事务管理等)。

Spring AOP的主要特点包括:

  1. 声明式编程:你可以通过注解或XML配置文件来声明切面、切点和通知(advice),而无需修改业务代码。
  2. 集成性强:Spring AOP与Spring的其他模块(如Spring MVC、Spring Data等)无缝集成,可以轻松地在Spring应用中实现面向切面编程。
  3. 可扩展性:你可以自定义切面、切点和通知的实现,以满足特定的业务需求。

需要注意的是,Spring AOP是基于代理的,因此它只能拦截通过Spring容器管理的bean之间的方法调用。对于非Spring管理的对象或方法(如静态方法、私有方法等),Spring AOP可能无法提供支持。如果需要更强大的AOP功能,可以考虑使用AspectJ等更专业的AOP框架。


一、准备

1.引入库

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>${spring-version}</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>${spring-version}</version>
</dependency>

2. 业务类

2.1 service

package org.example.aop.annotation;

/**
 * Create by zjg on 2024/4/14
 */
public interface Calculator {
    int add(int i,int j);
    int sub(int i,int j);
    int mul(int i,int j);
    int div(int i,int j);
}

2.2 impl

package org.example.aop.annotation.impl;


import org.example.aop.annotation.Calculator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Create by zjg on 2024/4/14
 */
public class CalculatorImpl implements Calculator {
    private Logger logger = LoggerFactory.getLogger(CalculatorImpl.class);
    @Override
    public int add(int i, int j) {
        logger.debug("add({},{})",i,j);
//        int s=1/0;
        return i+j;
    }

    @Override
    public int sub(int i, int j) {
        logger.debug("sub({},{})",i,j);
        return i-j;
    }

    @Override
    public int mul(int i, int j) {
        logger.debug("mul({},{})",i,j);
        return i*j;
    }

    @Override
    public int div(int i, int j) {
        logger.debug("div({},{})",i,j);
        return i/j;
    }
}

二、核心代码

1. 切面类

package org.example.aop.annotation.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.util.Arrays;

/**
 * Create by zjg on 2024/4/14
 */
@Component
@Aspect
public class LogAspect {
    private Logger logger = LoggerFactory.getLogger(LogAspect.class);
    @Pointcut("execution(* org.example.aop.annotation.*.*(..))")
    public void pointcut(){}
    @Before("pointcut()")
    public void before(JoinPoint joinPoint){
        String name = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
        logger.debug("[{}前置通知]{}",name, Arrays.toString(args));
    }
    @AfterReturning(value="pointcut()",returning = "result")
    public void afterReturning(JoinPoint joinPoint,Object result){
        String name = joinPoint.getSignature().getName();
        logger.debug("[{}返回通知][{}]",name,result);
    }
    @AfterThrowing(value="pointcut()",throwing = "exception")
    public void afterThrowing(JoinPoint joinPoint,Exception exception){
        String name = joinPoint.getSignature().getName();
        logger.debug("[{}异常通知][{}]",name,exception.getMessage());
    }
    @After("pointcut()")
    public void after(JoinPoint joinPoint){
        String name = joinPoint.getSignature().getName();
        logger.debug("[{}后置通知]",name);
    }
    @Around("pointcut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        String name = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
        logger.debug("[{}环绕通知前置]{}",name,Arrays.toString(args));
        Object result = null;
        try {
            result= joinPoint.proceed();
            logger.debug("[{}环绕通知返回][{}]",name,result);
        }catch (Exception exception){
            logger.debug("[{}环绕通知异常]",name);
        }finally {
            logger.debug("[{}环绕通知后置]",name);
        }
        return result;
    }
}

2. 配置类

package org.example.aop.annotation.config;

import org.example.aop.annotation.Calculator;
import org.example.aop.annotation.impl.CalculatorImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

/**
 * Create by zjg on 2024/4/14
 */
@Configuration
@ComponentScan("org.example.aop.annotation")
@EnableAspectJAutoProxy
public class SpringConfig {
    @Bean
    public Calculator calculator(){
        return new CalculatorImpl();
    }
}

3. 启动类

package org.example.aop.annotation;

import org.example.aop.annotation.config.SpringConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * Create by zjg on 2024/4/14
 */
public class SpringApplication {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext acac = new AnnotationConfigApplicationContext(SpringConfig.class);
        Calculator calculator = acac.getBean("calculator", Calculator.class);
        calculator.add(1,1);
    }
}

4. 执行结果

[2024-04-14 13:50:14.032][main][DEBUG]- org.example.aop.annotation.aspect.LogAspect.around(LogAspect.java:52) - [add环绕通知前置][1, 1]
[2024-04-14 13:50:14.033][main][DEBUG]- org.example.aop.annotation.aspect.LogAspect.before(LogAspect.java:31) - [add前置通知][1, 1]
[2024-04-14 13:50:14.033][main][DEBUG]- org.example.aop.annotation.impl.CalculatorImpl.add(CalculatorImpl.java:16) - add(1,1)
[2024-04-14 13:50:14.033][main][DEBUG]- org.example.aop.annotation.aspect.LogAspect.afterReturning(LogAspect.java:36) - [add返回通知][2]
[2024-04-14 13:50:14.034][main][DEBUG]- org.example.aop.annotation.aspect.LogAspect.after(LogAspect.java:46) - [add后置通知]
[2024-04-14 13:50:14.034][main][DEBUG]- org.example.aop.annotation.aspect.LogAspect.around(LogAspect.java:56) - [add环绕通知返回][2]
[2024-04-14 13:50:14.034][main][DEBUG]- org.example.aop.annotation.aspect.LogAspect.around(LogAspect.java:60) - [add环绕通知后置]


总结

回到顶部

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

黑洞路由、 DDoS 攻击 、 环路

黑洞路由 DDoS 攻击 DDoS 攻击是一种针对服务器、服务或网络的恶意行为。DDoS 攻击通过向目标发送大量流量&#xff0c;使其不堪重负&#xff0c;导致资源和带宽被耗尽。因此&#xff0c;目标可能会变慢或崩溃&#xff0c;无法正常处理合法的流量。DDoS 攻击通常是由僵尸网络…

Jmeter 性能-内存溢出问题定位分析

1、堆内存溢出 ①稳定性压测一段时间后&#xff0c;Jmeter报错&#xff0c;日志报&#xff1a; java.lang.OutOfMemoryError.Java heap space ②用jmap -histo pid命令dump堆内存使用情况&#xff0c;查看堆内存排名前20个对象。 看是否有自己应用程序的方法&#xff0c;从…

CentOS7下安装mysql8或者mysql5.7

mysql8 1、下载 访问mysql官网下载mysql8软件包 https://dev.mysql.com/downloads/mysql/ 选择相应的版本如&#xff1a;RPM Bundle mysql-8.0.33-1.el7.x86_64.rpm-bundle.tar RPM Bundle 8.0.33 下载地址&#xff1a;https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.…

电脑桌面便签软件哪个好?好用的电脑桌面便签

电脑作为我们日常工作的重要工具&#xff0c;承载着大量的任务和项目。当工作任务繁重时&#xff0c;如何在电脑桌面上高效管理这些任务就显得尤为重要。这时&#xff0c;选择一款优秀的桌面便签软件&#xff0c;无疑会给我们带来极大的便利。 一款好的桌面便签软件&#xff0…

【React】Ant Design自定义主题风格及主题切换

Ant Design 的自定义主题&#xff0c;对于刚入手的时候感觉真是一脸蒙圈&#xff0c;那今天给它梳理倒腾下&#xff1b; 1、自定义主题要点 整体样式变化&#xff0c;主要两个部分&#xff1a; 1.1、Design Token https://ant.design/docs/react/customize-theme-cn#theme 官…

ffmpeg入门

ffmpeg入——安装 Fmpeg地址 FFmpeg源码地址&#xff1a;https://github.com/FFmpeg/FFmpeg FFmpeg可执行文件地址&#xff1a;https://ffmpeg.org/download.html Windows平台 Windows平台下载解压后如图所示&#xff08;文件名称以-share结尾的是开发库&#xff09; FFmpeg…

Eagle for Mac v1.9.13注册版:强大的图片管理工具

Eagle for Mac是一款专为Mac用户设计的图片管理工具&#xff0c;旨在帮助用户更高效、有序地管理和查找图片资源。 Eagle for Mac v1.9.13注册版下载 Eagle支持多种图片格式&#xff0c;包括JPG、PNG、GIF、SVG、PSD、AI等&#xff0c;无论是矢量图还是位图&#xff0c;都能以清…

AndroidStudio AGP 7+, 编译aar并输出到本地仓库

1 编写构建gradle脚本代码 1.1 配置publication和repository 在指定moudle目录下新建名为"maven-publish.gradle"文件&#xff0c;其声明的publication和repository如下所示&#xff1a; apply plugin: maven-publish// This creates a task called publishReleas…

《星光对话》系列直播:带你入门数据要素

2020年12月9日&#xff0c;财政部提出企业数据资源可作为资产列入财务报表&#xff0c;打响数据要素“1N”的第一枪&#xff1b; 2022年12月2日&#xff0c;《关于构建数据基础制度更好发挥数据要素作用的意见》“数据二十条”通过提出构建数据产权、流通交易、收益分配、安全治…

维护SQLite的私有分支(二十六)

返回&#xff1a;SQLite—系列文章目录 上一篇&#xff1a;SQLite、MySQL 和 PostgreSQL 数据库速度比较&#xff08;本文阐述时间很早比较&#xff0c;不具有最新参考性&#xff09;&#xff08;二十五&#xff09; 下一篇&#xff1a;SQLite数据库中JSON 函数和运算符 1…

# 从浅入深 学习 SpringCloud 微服务架构(三)注册中心 Eureka(1)

从浅入深 学习 SpringCloud 微服务架构&#xff08;三&#xff09;注册中心 Eureka&#xff08;1&#xff09; 段子手168 1、微服务的注册中心 注册中心可以说是微服务架构中的”通讯录”&#xff0c;它记录了服务和服务地址的映射关系。 在分布式架构中服务会注册到这里&am…

美易官方:美债美元黄金继续涨?

全球金融市场波动加剧&#xff0c;投资者对避险资产的需求不断升温。在这一背景下&#xff0c;“投行老将”们纷纷发表观点&#xff0c;认为避险情绪尚未结束&#xff0c;美债、美元和黄金等避险资产有望继续上涨。 巴克莱一位资深投资银行家表示&#xff0c;由于担心中东冲突升…

在Linux系统中搜索当前路径及其子目录下所有PDF文件中是否包含特定字符串

目录标题 方法一&#xff1a;pdfgrep方法二&#xff1a;使用find和xargs与pdftotext&#xff08;将PDF转换为文本&#xff09;组合&#xff0c;然后用grep搜索 方法一&#xff1a;pdfgrep pdfgrep -ri "rockchip" .方法二&#xff1a;使用find和xargs与pdftotext&am…

动手学深度学习11 权重衰退

动手学深度学习11 权重衰退 1. 权重衰退2. 代码实现3. QA 视频&#xff1a; https://www.bilibili.com/video/BV1UK4y1o7dy/?spm_id_fromautoNext&vd_sourceeb04c9a33e87ceba9c9a2e5f09752ef8 电子书&#xff1a; ttps://zh-v2.d2l.ai/chapter_multilayer-perceptrons/wei…

Mamba 学习

Vision Mamba U-Mamba 以后的趋势&#xff1a; 1.Mamba模型机机制上和transform一样&#xff0c;但是参数量上做了改进&#xff0c;可以直接替代 2.vision上可以实时处理

视频太大怎么压缩变小?8种方法随时压缩视频大小

视频太大怎么压缩变小&#xff1f;视频压缩方式分为两种&#xff0c;有损压缩和无损压缩&#xff0c;什么是有损什么是无损压缩&#xff0c;什么时候视频用无损压缩更好&#xff1f;什么时候用有损压缩更好&#xff1f;如何调整视频参数实现基本无损压缩&#xff1f; 今天就借助…

小红书笔记写作方法和技巧分享,纯干货!

很多小伙伴感叹小红书笔记流量就是一个玄学&#xff0c;有时精心撰写的笔记却没有人看&#xff0c;自己随便写的笔记却轻轻松松上热门。实际上你还是欠点火候&#xff0c;小红书笔记写作是有一套方法和技巧的&#xff0c;总归是有套路的&#xff0c;如果你不知道&#xff0c;请…

数仓建模—物理数据模型

文章目录 数仓建模—物理数据模型什么是物理数据模型物理数据模型示例如何构建物理数据模型物理数据模型与逻辑数据模型逻辑模型和物理模型之间有什么关系逻辑数据模型的好处物理数据模型的好处数仓建模—物理数据模型 前面我们讲了数据模型和逻辑数据模型,你可以参考前面的文…

【JAVA进阶篇教学】第四篇:JDK8中函数式接口

博主打算从0-1讲解下java进阶篇教学&#xff0c;今天教学第四篇&#xff1a;JDK8中函数式接口。 在 Java 8 中&#xff0c;函数式接口是指只包含一个抽象方法的接口。这种接口可以用作 Lambda 表达式的类型&#xff0c;从而使得函数式编程在 Java 中变得更加方便和灵活。下面…

【题解】NC398 腐烂的苹果(多源BFS)

https://www.nowcoder.com/practice/54ab9865ce7a45968b126d6968a77f34?tpId196&tqId40529&ru/exam/oj 从每个腐烂的苹果开始使用广度优先遍历&#xff08;bfs&#xff09; class Solution {int n, m;int dx[4] {0, 0, 1, -1};int dy[4] {1, -1, 0, 0};vector<v…