Spring AOP(一)五种增强(Advice)

2023-10-27

AOP术语都非常抽象,结合某些小例子就会形象、具体一些。

连接点(Joinpoint)

Spring仅支持方法的连接点,即仅能在方法调用前、方法调用后、方法抛出异常时及方法调用前后,这些程序执行点织入增强。
黑客攻击系统需要找到突破口,从某种程度上来说,AOP也可以看成一个黑客(因为它要向目标类中嵌入额外的代码逻辑),而连接点就是AOP向目标类打入楔子的候选锚点。

接口名:org.aspectj.lang.JoinPoint

在这里插入图片描述
其中,最常用的是以下几个:

  • getArgs()
  • getTarget()
  • getSignature()

相关接口:org.aspectj.lang.ProceedingJoinPoint extends JoinPoint
在这里插入图片描述
其中,最常用的是以下几个:

  • proceed()
  • proceed(Object[])
小例子(环绕增强)
public class UserInfo {
    private String name;

    public UserInfo(String name) {
        this.name = name;
    }
...
}
public interface IBaseMapper {
    void insert(UserInfo userInfo);
}
public interface IOrderMapper extends IBaseMapper {
    void save(String name, Integer age);
}
@Service
public class OrderMapperService implements IOrderMapper {
    @Override
    public void save(String name, Integer age) {
        System.out.println("### 进入save(..),name=" + name);
    }

    @Override
    public void insert(UserInfo userInfo) {
        System.out.println("### 进入insert(..)");
    }
}
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

@Aspect
@Component
public class OrderAspect {

    // 也可以先自定义注解,再:@Pointcut("@annotation(com.xxx.MyAnnotation)")
    @Pointcut(value = "execution(* com.javatpoint.service.IOrderMapper.*(..))")
    private void logDisplayingBalance() {
    }

    @Around(value = "logDisplayingBalance()")
    public void aroundAdvice(ProceedingJoinPoint jp) throws Throwable {
        System.out.println("### The method aroundAdvice() before invokation of the method " + jp.getSignature().getName() + " method");
        try {
            jp.proceed();
        } finally {
        }

        // ProceedingJoinPoint的常用方法
        Object[] args = jp.getArgs();
        MethodSignature methodSignature = (MethodSignature)jp.getSignature();
        Method method = methodSignature.getMethod();
        Class<?>[] parameterTypes = method.getParameterTypes();
        Object target = jp.getTarget();

        // 模拟:修改为大写后,再次重复执行
        repeatExecuteMethod(target, method, args);

        System.out.println("### The method aroundAdvice() after invokation of the method " + jp.getSignature().getName() + " method");
    }

    /**
     * 重复执行
     * 可以加入一些特殊处理,例如:小写转大写、加密、脱敏处理等
     * @param target
     * @param method
     * @param args
     * @return
     */
    public Object repeatExecuteMethod(Object target, Method method, Object[] args) {
        try {
            Object invoke = method.invoke(target, toUpperCase(args));
            return invoke;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private Object[] toUpperCase(Object[] args) {
        if (args == null || args.length == 0) {
            return args;
        }

        List<Object> list = new ArrayList<>();

        for (Object obj : args) {
            if (obj instanceof String) {
                String obj2Str = (String)obj;
                list.add(obj2Str.toUpperCase());
            } else {
                list.add(obj);
            }
        }

        return list.toArray();
    }
}

import com.javatpoint.service.IOrderMapper;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import com.javatpoint.service.BankService;

@SpringBootApplication
// @EnableAspectJAutoProxy annotation enables support for handling the components marked with @Aspect annotation.
// It is similar to tag in the xml configuration.
@EnableAspectJAutoProxy
public class AopAroundAdviceExampleApplication {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(AopAroundAdviceExampleApplication.class, args);

        IOrderMapper order = context.getBean(IOrderMapper.class);
        order.save("yaoyao", 12);
        order.insert(new UserInfo("jjk"));

        context.close();
    }
}

前置增强
@Aspect
@Component
public class EmployeeServiceAspect {

	@Before(value = "execution(* com.javatpoint.service.EmployeeService.*(..)) and args(empId2, fname, sname)")
	public void beforeAdvice(JoinPoint joinPoint, String empId2, String fname, String sname) {
		System.out.println("Before method:" + joinPoint.getSignature());
		System.out.println("Creating Employee with first name - " + fname + ", second name - " + sname + " and id - " + empId2);
	}
}

注意上面“ and args ”的用法,不是EmployeeService类的所有方法都增强,仅仅是三个参数,且三个String类型的方法才增强。

后置增强
@Aspect
@Component
public class EmployeeServiceAspect {
	@After(value = "execution(* com.javatpoint.service.EmployeeService.*(..)) and args(empId, fname, sname)")
	public void afterAdvice(JoinPoint joinPoint, String empId, String fname, String sname) {
		System.out.println("After method:" + joinPoint.getSignature());
		System.out.println("Successfully created Employee with first name - " + fname + ", second name - " + sname + " and id - " + empId);
	}
}
方法返回值前增强
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import com.javatpoint.model.Account;

@Aspect
@Component
public class AccountAspect {
    //implementing after returning advice
    @AfterReturning(value = "execution(* com.javatpoint.service.impl.AccountServiceImpl.*(..))", returning = "account")
    public void afterReturningAdvice(JoinPoint joinPoint, Account account) {
        System.out.println("After Returing method:" + joinPoint.getSignature());
        System.out.println(account);
    }
抛出异常增强
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class AccountAspect {
    //implementing after throwing advice	
    @AfterThrowing(value = "execution(* com.javatpoint.service.impl.AccountServiceImpl.*(..))", throwing = "ex")
    public void afterThrowingAdvice(JoinPoint joinPoint, Exception ex) {
        System.out.println("After Throwing exception in method:" + joinPoint.getSignature());
        System.out.println("Exception is:" + ex.getMessage());
    }
}
资料
  • https://www.javatpoint.com/spring-boot-aop
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring AOP(一)五种增强(Advice) 的相关文章

随机推荐

  • chatgpt赋能python:使用Python制作动画的步骤和工具

    使用Python制作动画的步骤和工具 Python不仅是一种流行的编程语言 还可以用于制作动画 本文将介绍一些基本步骤和工具 帮助你制作出精美的动画作品 步骤一 选择一个好的动画框架 Python有很多强大的动画框架可以使用 其中一些最受欢
  • bak文件、vim、.DS_Store文件

    bak文件泄露 有些时候网站管理员可能为了方便 会在修改某个文件的时候先复制一份 将其命名为xxx bak 而大部分Web Server对bak文件并不做任何处理 导致可以直接下载 从而获取到网站某个文件的源代码 常见的网站源码的文件名有
  • 克隆get项目报错 OpenSSL SSL_read: Connection was reset, errno 10054解决办法

    克隆get项目报错 OpenSSL SSL read Connection was reset errno 10054解决办法 通过报错我们看到这个问题是链接被重置 问题 解决方法 在命令号修改设置解除ssl验证 git config gl
  • 强化学习中的马尔可夫决策过程,常见公式回顾

    0 基础知识 0 1 贝尔曼方程 这个公式是强化学习的核心 其中 s 可以看成未来的某个状态 p s s 是指从当前状态转移到未来状态的概率 V s 代表的是未来某一个状态的价值 我们从当前状态开始 有一定的概率去到未来的所有状态 所以我们
  • Vite2 + Vue3 + TypeScript + Pinia 搭建一套企业级的开发脚手架

    Vue2 与 Vue3 的区别 Vue3由于完全由TS进行重写 在应用中对类型判断的定义和使用有很强的表现 同一对象的多个键返回值必须通过定义对应的接口 interface 来进行类型定义 要不然在 ESLint 时都会报错 Vue2 与
  • Java从入门到实战总结-3.7、XML和JSON

    Java从入门到实战总结 3 7 XML和JSON 文章目录 Java从入门到实战总结 3 7 XML和JSON 1 前言 2 XML介绍 1 XML概述 2 用途 3 处理器与应用 4 标记 Markup 与内容 content 5 标签
  • java 利用方法实现数组之间的传递

    import java util public class HelloWorld public static void main String args int arr 1 2 3 int output transform arr 运用tr
  • springboot打印启动信息

    打印启动信息 param application 应用 SneakyThrows private static void printMsg ApplicationContext application String ip InetAddre
  • vuex(4.x)

    1 简介 vuex状态管理插件 在vue最重要就是数据驱动和组件化 每个组件都有自己的data template和methods data是数据 我们也叫做状态 通过methods中方法改变状态来更新视图 在单个组件中修改状态更新视图是很方
  • vue - mvvm模式的理解?

    1 MVVM 是Model View ViewModel 的缩写 它是一种基于前端开发的架构模式 其核心是提供对View 和 ViewModel 的双向数据绑定 2 MVVM 中的核心 VM vm负责连接 View 和 Model 保证视图
  • Python如何永久修改sys.path

    Python如何永久修改sys path 起因 这两天运行需要用命令行来运行python文件 但是总是报错ModuleNotFoundError No module named xxx tf liushanlin liushanlindeM
  • 解决Fastjson的下划线与大小写映射问题

    一 问题场景 目前我有一个类如下所示 Data ToString class BTEST Long infoId Long info id 需要执行的方法如下 Test public void jsonToBean Map
  • python3使用pykeyboard和Pyhook的问题及解决

    python3 7无法import pykeyboard的原因 问题1 ModuleNotFoundError No module named windows 问题2 cant import name PyKeyboard from pkk
  • python(列表、元组、字典)详解

    文章目录 什么是列表 列表的定义 in max min sum在列表中的使用 操作列表 初识元组 元组定义 列表与元组的区别 初识字典 字典的结构与创建方法 字典的遍历 字典支持的数据类型 循环 什么是列表 列表就是队列 是各种数据类型的集
  • 关于数论中的互质数的最大不能组合数

    题意 给定A和B A和B互质 求最大不能组合数 和不能组合数的个数 基础知识 Gcd A B 1 Lcm A B AB剩余类 把所有整数划分成m个等价类 每个等价类由相互同余的整数组成任何数分成m个剩余类 分别为 mk mk 1 mk 2
  • 新论文石锤Transformer:别只看注意力,没有残差和MLP,它啥都不是

    作者 青暮 基于注意力的架构在机器学习社区中已经变得无处不在 Transformer最初在机器翻译打出名堂 随着BERT的问世几乎统治了整个NLP领域 RNN LSTM等老前辈瑟瑟发抖 GPT 3的零样本学习能力又令人不禁怀疑其智能本质 还
  • 简单几步,让Mac外接显示器更好用

    光懂得给MacBook连接外置显示器还不行 了解这几点 才能让Mac外接显示器更好用 可以在两个显示器桌面之间任意拖拽移动软件窗口 这也是双 多 显示器一个高效的地方 将外接显示器设置为最佳分辨率 MacBook连接上外接显示器后 打开 系
  • Qt之工程文件

    文章目录 1 注释 2 QT 3 模板变量 TEMPLATE 4 TARGET 5 CONFIG 6 控制输出目录 6 1 UIC DIR 6 2 RCC DIR 6 3 MOC DIR 6 4 OBJECTS DIR 6 5 DESTDI
  • linux下制作动态库

    1 动态库的介绍 动态库 也叫共享库 动态库与用户编写的程序相互独立 不被包含在用户生成的可执行文件当中 2 动态库的创建 第一步 将写好的程序编译 我们事先写好两个程序 bye c hello c 一个输出hello一个输出bye 在终端
  • Spring AOP(一)五种增强(Advice)

    AOP术语都非常抽象 结合某些小例子就会形象 具体一些 连接点 Joinpoint Spring仅支持方法的连接点 即仅能在方法调用前 方法调用后 方法抛出异常时及方法调用前后 这些程序执行点织入增强 黑客攻击系统需要找到突破口 从某种程度