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. ElasticSearch 进阶

    目录 ElasticSearch 进阶 SearchAPI 检索信息 Query DSL 基本语法格式 查询-match 查询-match_phrase 查询-multi_match 查询-bool复 ...

  2. js 获取树结构的节点深度

    需求:获取树结构的节点深度. 实现util.js: // 获取节点深度 参数为树结构array function getMaxFloor(treeData){ let deep = 0; functi ...

  3. web之面试常问问题:如何实现水平垂直居中?

    前提准备,在HTML页面中定义一个div,div中内容自定义. <div class="box sc">致我们呼啸而过的青春</div> 样式: div.b ...

  4. 【odoo14】第五章、服务器侧开发-基础

    本章包含如下内容: 定义模型方法和使用api装饰器 向用户反馈错误信息 针对不同的对象获取空数据集 创建新纪录 更新数据集数据 搜索数据 组合数据集 过滤数据集 遍历记录集 排序数据集 重写已有业务逻 ...

  5. java基础详解-集合

    一.集合组成 java集合主要由Map和Collection组成,Collection主要类图如下(图片来源于网络,懒得画图): 从上图中能很明显的看出来Collection下主要是Set.List和 ...

  6. Codeforces Round #541 F. Asya And Kittens

    题面: 传送门 题目描述: Asya把N只(从1-N编号)放到笼子里面,笼子是由一行N个隔间组成.两个相邻的隔间有一个隔板. Asya每天观察到有一对想一起玩,然后就会把相邻的隔间中的隔板取出来,使两 ...

  7. GreenDao3.2使用详解(增,删,改,查,升级)

    首先看一下效果图: 项目结构如下图所示: 第一步:在build中添加配置如下: projet 目录下的build.gradle dependencies { classpath 'org.greenr ...

  8. 输出质数(Java)

    输出质数 一.什么是质数 质数又称素数.一个大于1的自然数,除了1和它自身外,不能被其他自然数整除的数叫做质数,否则称为合数(规定1既不是质数也不是合数). 二.代码实现 1.输出100以内的质数 i ...

  9. 详解 ZooKeeper 数据持久化

    本文作者:HelloGitHub-老荀 Hi,这里是 HelloGitHub 推出的 HelloZooKeeper 系列,免费开源.有趣.入门级的 ZooKeeper 教程,面向有编程基础的新手. 项 ...

  10. kubernetes 降本增效标准指南| 容器化计算资源利用率现象剖析

    作者:詹雪娇,腾讯云容器产品经理,目前主要负责腾讯云集群运维中心的产品工作. 张鹏,腾讯云容器产品工程师,拥有多年云原生项目开发落地经验.目前主要负责腾讯云TKE集群和运维中心开发工作. 引言 降本增 ...