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. spring事务:事务控制方式,使用AOP控制事务,七种事务传播行为,声明事务,模板对象,模板对象原理分析

    知识点梳理 课堂讲义 1)事务回顾 1.1)什么是事务-视频01 事务可以看做是一次大的活动,它由不同的小活动组成,这些活动要么全部成功,要么全部失败. 1.2)事务的作用 事务特征(ACID) 原子 ...

  2. java实现回溯算法

    最近有在leetcode上面做算法题,已经遇到了两道回溯算法的题目,感觉一点思路都没有,现决定将java如何实现回溯算法做一次总结. 什么叫做回溯算法 (摘抄于百度百科) 回溯算法实际上一个类似枚举的 ...

  3. Go语言中利用append巧妙的删除slice切片中的元素

    package main import ( "fmt" ) //删除函数 func remove(s []string, i int) []string { return appe ...

  4. Linux 用户登陆提示This account is currently not available

    使用 su 切换到用户 hdfs 时提示:This account is currently not available,使用 hdfs 用户登陆会直接退出 ssh 窗口. 此时可以尝试检查文件 /e ...

  5. mysql连接不上本地服务器或者localhost:3306报错

    今天初学MySQL数据库就遇到问题: 主要是本地服务器登录问题 workbench里双击那个connection出现的 解决方法: 1:看一看防火墙,这是最常见的,这种主要是防火墙限制了访问,可能是安 ...

  6. PTA 冒泡排序

    6-4 冒泡排序 (10 分)   编程实现冒泡排序函数.void bubbleSort(int arr[], int n);.其中arr存放待排序的数据,n为数组长度(1≤n≤1000). 函数接口 ...

  7. vue实现日历

    vue实现日历 之前在上家公司做过一个公司人员考勤的东西,里面需要用到日历,当时自己用vue随便写了一个,比较简单 下面代码是删掉了其他功能的代码,只留下日历部分 <template> & ...

  8. Typora标题自动编号+设定快捷键技巧

    Typora标题自动编号 提示:要了解将这些CSS片段放在哪里,请参阅添加自定义CSS. 打开Typora偏好设置,打开主题文件夹,在主题文件夹中创建base.user.css文件,放置以下内容,则T ...

  9. 第20 章 : GPU 管理和 Device Plugin 工作机制

    GPU 管理和 Device Plugin 工作机制 本文将主要分享以下几个方面的内容: 需求来源 GPU 的容器化 Kubernetes 的 GPU 管理 工作原理 课后思考与实践 需求来源 201 ...

  10. python工业互联网应用实战11—客户端UI

    这个章节我们将演示用户端界面的开发,当前演示界面还是采用先实现基本功能再逐步完善的"敏捷"模式.首先聚焦在功能逻辑方面实现普通用户与系统的交互,普通用户通过url能查看到当前任务的 ...