Aspect

(与SpringBoot整合)

总结

  1. 作用位置

    try{
    try{
    @Around 前置环绕通知
    @Before 前置通知
    method.invoke(..);
    }catch(){
    @AfterThrowing 异常通知
    throw.....;
    }finally{
    @After 后置通知
    }
    @AfterReturning 返回通知
    }finally{
    @Around 后置环绕通知
    }
  2. 执行流程

    1. 正常情况: @Around ==> @Before ==> 目标方法 ==> @After ==> @AfterReturning ==> @Around;
    2. 异常情况: @Around ==> @Before ==> 目标方法(出现异常) ==> @AfterThrowing ==> @After ==> @Around;

代码演示

1. 引入aop依赖

pom.xml

        <!--    引入AOP依赖    -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>

2. 核心业务类

Service层

UserService.java

@Service
public class UserService { public void service1(){
System.out.println("Service-1-执行");
} public String service2(){
System.out.println("Service-2-执行");
//int i = 1/0; //异常测试
return "Success!!!";
} public ArrayList<String> service3(String userName){
System.out.println("Service-3-执行");
ArrayList<String> list = new ArrayList<>();
list.add("Service-3-执行成功!!!");
list.add(userName);
return list;
} }

3. 切面

MyAspect.java

注:一定要将切面作为Spring组件注入容器

@Component
@Aspect
public class MyAspect { //定义切入点
@Pointcut("within(com.juyss.service.*)")
public void pointcut(){} //环绕通知 ===> 正常情况执行在@Before和@After之前,如果执行过程中抛异常,只执行前置环绕通知,后置环绕不执行
@Around(value = "pointcut()")
public Object around(ProceedingJoinPoint point){
System.out.println("前置环绕通知!!!");
Object proceed = null;
try {
System.out.println("point.proceed()执行前----------------------------");
Signature signature = point.getSignature();
System.out.println("获取类名:"+signature.getName());
System.out.println("point.proceed()执行前----------------------------");
proceed = point.proceed();
System.out.println("point.proceed()执行后----------------------------");
System.out.println("获取返回值:"+proceed);
System.out.println("point.proceed()执行后----------------------------");
} catch (Throwable throwable) {
throwable.printStackTrace();
}
System.out.println("后置环绕通知!!!");
return proceed;
} //前置通知 ===> 方法执行前
@Before("pointcut()")
public void before(){
System.out.println("前置通知生效!!!");
} //返回通知 ===> 方法正常执行完后执行,可以获取返回值.如果方法执行过程中抛异常,则不会执行
@AfterReturning(value = "pointcut()",returning = "returnValue")
public void afterReturning(Object returnValue){
System.out.println("返回通知生效!!! ------返回值:"+returnValue);
} //后置通知 ===> 在finally代码块中执行,无论如何都会执行的通知
@After("pointcut()")
public void after(JoinPoint joinPoint){
Signature signature = joinPoint.getSignature();
System.out.println("后置通知生效!!! ------ 方法名:"+signature.getName());
} //异常通知 ===> 在执行过程中抛出异常时执行
@AfterThrowing(value = "pointcut()",throwing = "e")
public void afterThrowing(Exception e){
System.out.println("异常通知生效!!! 异常信息:"+e.getMessage());
}
}

4. 测试类

AspectApplicationTests.java

@SpringBootTest
class AspectApplicationTests { @Autowired
private UserService service; @Test
public void Test(){
service.service1();
System.out.println("************************************************************************");
service.service2();
System.out.println("************************************************************************");
service.service3("方法参数");
System.out.println("************************************************************************");
} }

5. 测试结果

正常运行时:

前置环绕通知!!!
point.proceed()执行前----------------------------
获取类名:service1
point.proceed()执行前----------------------------
前置通知生效!!!
Service-1-执行
返回通知生效!!! ------返回值:null
后置通知生效!!! ------ 方法名:service1
point.proceed()执行后----------------------------
获取返回值:null
point.proceed()执行后----------------------------
后置环绕通知!!!
************************************************************************************************
前置环绕通知!!!
point.proceed()执行前----------------------------
获取类名:service2
point.proceed()执行前----------------------------
前置通知生效!!!
Service-2-执行
返回通知生效!!! ------返回值:Success!!!
后置通知生效!!! ------ 方法名:service2
point.proceed()执行后----------------------------
获取返回值:Success!!!
point.proceed()执行后----------------------------
后置环绕通知!!!
************************************************************************************************
前置环绕通知!!!
point.proceed()执行前----------------------------
获取类名:service3
point.proceed()执行前----------------------------
前置通知生效!!!
Service-3-执行
返回通知生效!!! ------返回值:[Service-3-执行成功!!!, 方法参数]
后置通知生效!!! ------ 方法名:service3
point.proceed()执行后----------------------------
获取返回值:[Service-3-执行成功!!!, 方法参数]
point.proceed()执行后----------------------------
后置环绕通知!!!
************************************************************************************************

方法运行抛出异常时

前置环绕通知!!!
point.proceed()执行前----------------------------
获取类名:service1
point.proceed()执行前----------------------------
前置通知生效!!!
Service-1-执行
返回通知生效!!! ------返回值:null
后置通知生效!!! ------ 方法名:service1
point.proceed()执行后----------------------------
获取返回值:null
point.proceed()执行后----------------------------
后置环绕通知!!!
************************************************************************************************
前置环绕通知!!!
point.proceed()执行前----------------------------
获取类名:service2
point.proceed()执行前----------------------------
前置通知生效!!!
Service-2-执行
异常通知生效!!! 异常信息:/ by zero
后置通知生效!!! ------ 方法名:service2
java.lang.ArithmeticException: / by zero
at com.juyss.service.UserService.service2(UserService.java:25)
##############其他异常信息省略################
后置环绕通知!!!
************************************************************************************************
前置环绕通知!!!
point.proceed()执行前----------------------------
获取类名:service3
point.proceed()执行前----------------------------
前置通知生效!!!
Service-3-执行
返回通知生效!!! ------返回值:[Service-3-执行成功!!!, 方法参数]
后置通知生效!!! ------ 方法名:service3
point.proceed()执行后----------------------------
获取返回值:[Service-3-执行成功!!!, 方法参数]
point.proceed()执行后----------------------------
后置环绕通知!!!
************************************************************************************************

SpringBoot面向切面编程(AOP)的更多相关文章

  1. 设计模式之面向切面编程AOP

    动态的将代码切入到指定的方法.指定位置上的编程思想就是面向切面的编程. 代码只有两种,一种是逻辑代码.另一种是非逻辑代码.逻辑代码就是实现功能的核心代码,非逻辑代码就是处理琐碎事务的代码,比如说获取连 ...

  2. Spring学习手札(二)面向切面编程AOP

    AOP理解 Aspect Oriented Program面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术. 但是,这种说法有些片面,因为在软件工程中,AOP的价值体现的并 ...

  3. Spring学习笔记:面向切面编程AOP(Aspect Oriented Programming)

    一.面向切面编程AOP 目标:让我们可以“专心做事”,避免繁杂重复的功能编码 原理:将复杂的需求分解出不同方面,将公共功能集中解决 *****所谓面向切面编程,是一种通过预编译方式和运行期动态代理实现 ...

  4. Spring框架学习笔记(2)——面向切面编程AOP

    介绍 概念 面向切面编程AOP与面向对象编程OOP有所不同,AOP不是对OOP的替换,而是对OOP的一种补充,AOP增强了OOP. 假设我们有几个业务代码,都调用了某个方法,按照OOP的思想,我们就会 ...

  5. Spring之控制反转——IoC、面向切面编程——AOP

      控制反转——IoC 提出IoC的目的 为了解决对象之间的耦合度过高的问题,提出了IoC理论,用来实现对象之间的解耦. 什么是IoC IoC是Inversion of Control的缩写,译为控制 ...

  6. 【串线篇】面向切面编程AOP

    面向切面编程AOP 描述:将某段代码“动态”的切入到“指定方法”的“指定位置”进行运行的一种编程方式 (其底层就是Java的动态代理)spring对其做了简化书写 场景: 1).AOP加日志保存到数据 ...

  7. 04 Spring:01.Spring框架简介&&02.程序间耦合&&03.Spring的 IOC 和 DI&&08.面向切面编程 AOP&&10.Spring中事务控制

    spring共四天 第一天:spring框架的概述以及spring中基于XML的IOC配置 第二天:spring中基于注解的IOC和ioc的案例 第三天:spring中的aop和基于XML以及注解的A ...

  8. [译]如何在ASP.NET Core中实现面向切面编程(AOP)

    原文地址:ASPECT ORIENTED PROGRAMMING USING PROXIES IN ASP.NET CORE 原文作者:ZANID HAYTAM 译文地址:如何在ASP.NET Cor ...

  9. Spring框架系列(4) - 深入浅出Spring核心之面向切面编程(AOP)

    在Spring基础 - Spring简单例子引入Spring的核心中向你展示了AOP的基础含义,同时以此发散了一些AOP相关知识点; 本节将在此基础上进一步解读AOP的含义以及AOP的使用方式.@pd ...

随机推荐

  1. C# 应用 - 多线程 5) 死锁

    两个线程中的每一个线程都尝试锁定另外一个线程已锁定的资源时,就会发生死锁. 两个线程都不能继续执行. 托管线程处理类的许多方法都提供了超时设定,有助于检测死锁. 例如,下面的代码尝试在 lockObj ...

  2. P2188 小Z的 k 紧凑数 题解(数位DP)

    题目链接 小Z的 k 紧凑数 解题思路 数位DP,把每一个数位的每一个数对应的可能性表示出来,然后求\(num(1,r)-num(1,l-1)\),其中\(num(i,j)\)表示\([i,j]\)区 ...

  3. RSA典型非对称加密算法

    私钥加密-->公钥解密,反之亦然,但不安全.也可以当做数字签名. public class RSACoder {         //非对称加密算法         public static  ...

  4. HDU_6590 Code 【凸包】

    一.题目 Code 二.分析 题目描述了一大堆东西,就是想问二维空间里,能不能确定$d  w_1   w_2$使得函数满足$f(x_1,x_2) = y$,并且$sign(x)$函数是一个信号函数,只 ...

  5. go语言几个最快最好运用最广的web框架比较

    比较一下常用的golang web框架 令人敬畏的Web框架 如果你为自己设计一个小应用程序,你可能不需要一个Web框架,但如果你正在进行生产,那么你肯定需要一个,一个好的应用程序. 虽然您认为自己拥 ...

  6. apktool 回编译报错:No resource identifier found for attribute 'xxxxxx' in package 'android' W:

    C:\xxxx\app-release\res\layout-v26\xxxx.xml:5: error: No resource identifier found for attribute 'xx ...

  7. Springboot2.x集成lettuce连接redis集群报超时异常Command timed out after 6 second(s)

    文/朱季谦 背景:最近在对一新开发Springboot系统做压测,发现刚开始压测时,可以正常对redis集群进行数据存取,但是暂停几分钟后,接着继续用jmeter进行压测时,发现redis就开始突然疯 ...

  8. nodeJS详解2

    Nodejs应用场景 创建应用服务 web开发 接口开发 客户端应用工具  gulp webpack vue脚手架 react脚手架 小程序 NodeJs基于 Commonjs模块化开发的规范,它定义 ...

  9. Centos7安装nexus(maven私服)以及maven的相关配置

    一.nexus安装: 1.获取nexus下载地址: 查询nexus最新版本地址:https://help.sonatype.com/repomanager3/download 当前最新版本为nexus ...

  10. 论Redis分布式锁的正确使用姿势

    前言 日常开发中,秒杀下单.抢红包等等业务场景,都需要用到分布式锁.而Redis非常适合作为分布式锁使用.本文将分七个方案展开,跟大家探讨Redis分布式锁的正确使用方式.如果有不正确的地方,欢迎大家 ...