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. FreeBSD pkg安装软件时出现创建用户失败解决

    问题示例:[1/1] Installing package...===> Creating groups.Creating group 'package' with gid '000'.===& ...

  2. Java基础API

    API API概述 API (Application Programming Interface) :应用程序编程接口 java中的API指的就是 JDK 中提供的各种功能的 Java类,这些类将底层 ...

  3. 菜刀jsp小马

    逛google收获小马一枚,收藏一下 <%@page import="java.io.*,java.util.*,java.net.*,java.sql.*,java.text.*&q ...

  4. java例题_23 递归求年龄

    1 /*23 [程序 23 求岁数] 2 题目:有 5 个人坐在一起,问第五个人多少岁,他说比第 4 个人大 2 岁.问第 4 个人岁数,他说比第 3 个 3 人大 2 岁.问第三个人,又说比第 2 ...

  5. Java类集框架详细汇总-底层分析

    前言: Java的类集框架比较多,也十分重要,在这里给出图解,可以理解为相应的继承关系,也可以当作重要知识点回顾: Collection集合接口 继承自:Iterable public interfa ...

  6. ES 分页方案

    ES 中,存在三种常见的分页方案: FROM, SIZE Search-After Scroll 下面将依次比较三种方案之间的 trede-off,并给出相应建议的应用场景. 常见分页,FROM, S ...

  7. AOE网与关键路径

    声明:图片及内容基于https://www.bilibili.com/video/BV1BZ4y1T7Yx?from=articleDetail 原理 AOE网 关键路径 数据结构 核心代码 Topo ...

  8. DevOps教程:DevOps 面试题

     [注]本文译自:https://www.javatpoint.com/devops-interview-questions

  9. Dapper, Ef core, Freesql 插入大量数据性能比较(二)

    在上一篇文章中,我们比较出单表插入9999行数据,Dapper > EfCore > Freesql.在本文中,我们来看看级联插入 构建9999行数据 List<Entity> ...

  10. 阿里妈妈Java后端 社招5面(Offer已拿)

    最近由于个人原因, 由于前面两面的时间过去的有点久了,只能根据记忆大概写些记得问题.   阿里妈妈1面 40mins(2021-02-22) 1. 能简单介绍下自己和自己做的项目吗? 2. 关于项目的 ...