简介
  • 本文是一个老师在学校给学生上课的简单案例,介绍了AOP的五个通知的使用,以及通知的执行顺序。通过自定义注解来充当切入点,获取注解的类型分别对不同的老师做对应的业务处理。
  • 代码中的消息响应体(Result)大家可以自定义类型。

一、AOP的五大通知

前置通知:Before
环绕通知:Around
后置通知:After
后置返回通知:AfterReturning
后置异常通知:AfterThrowing

执行顺序如下图所示:

二、AOP的使用方式

1.创建一个课题实体对象

package com.cloud.industryapi.test;import lombok.Data;/*** 课题实体* @date 2022/3/25 16:26*/
@Data
public class ArticleEntity {/*** PK*/private Integer id;/*** 课题*/private String title;/*** 内容*/private String content;}

2.定义一个切入点,这里以自定义注解的方式实现

package com.cloud.industryapi.test;import java.lang.annotation.*;/*** 切点标识* @author * @date 2022/3/25 13:09*/
@Target({ElementType.METHOD,ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PointcutId {String type() default "";
}

3.声明要织入的切面

package com.cloud.industryapi.test;import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;/*** 切面*/
@Slf4j
@Aspect
@Component
public class ArticleAspect {/*** 定义切入点*/@Pointcut("@annotation(com.cloud.industryapi.test.PointcutId)")public void pointcut(){}/*** 环绕通知* @param joinPoint* @param id* @return* @throws Throwable*/@Around("pointcut() && @annotation(id)")public Object around(ProceedingJoinPoint joinPoint, PointcutId id) throws Throwable {log.info("-------------around start-------------");Object[] objects = joinPoint.getArgs();switch (id.type()){case "language":ArticleEntity language = (ArticleEntity) objects[0];log.info("-------------语文老师课前备课,课题:{}-------------",language.getTitle());break;case "mathematics":log.info("-------------数学老师课前备课-------------");break;default:throw new RuntimeException("类型非法");}//joinPoint.proceed()Object s = joinPoint.proceed();log.info("-------------叮铃铃铃铃...放学了-------------");log.info("-------------around end-------------");return s;}/*** 前置通知* @param joinPoint* @param id*/@Before("pointcut()  && @annotation(id)")public void before(JoinPoint joinPoint,PointcutId id){log.info("-------------before start-------------");log.info("-------------学生进入教室,准备上课-------------");log.info("-------------before end-------------");}/*** 后置通知* @param joinPoint* @param id*/@After("pointcut() && @annotation(id)")public void after(JoinPoint joinPoint,PointcutId id){log.info("-------------after start-------------");log.info("-------------学校广播:老师们,同学们,中午好,今天学校食堂免费为你们准备了烧鸡,人手一鸡-------------");log.info("-------------after end-------------");}/*** 后置返回通知* @param joinPoint* @param id*/@AfterReturning("pointcut() && @annotation(id)")public void afterReturn(JoinPoint joinPoint, PointcutId id){log.info("-------------AfterReturning-------------");log.info("-------------老师们同学们拿着烧鸡回家了-------------");log.info("-------------学校关闭了大门-------------");log.info("-------------AfterReturning-------------");}/*** 后置异常通知* @param joinPoint* @param id*/@AfterThrowing("pointcut() && @annotation(id)")public void afterThrow(JoinPoint joinPoint,PointcutId id){log.info("-------------AfterThrowing-------------");log.info("-------------完蛋,小明同学迷路了。。。-------------");log.info("-------------AfterThrowing-------------");}}
  • 注意:ProceedingJoinPoint的proceed()方法相当于前置通知和后置通知的分水岭。\color{#FF0000}{注意:ProceedingJoinPoint的proceed()方法相当于前置通知和后置通知的分水岭。}注意:ProceedingJoinPoint的proceed()方法相当于前置通知和后置通知的分水岭。
  • 说明:ProceedingJoinPoint的proceed()方法在执行前用来做一些,例如:读取日志,然后执行目标方法。ProceedingJoinPoint的proceed()方法执行后,用来做一些,例如:写入日志\color{#0000FF}{说明:ProceedingJoinPoint的proceed()方法在执行前用来做一些,例如:读取日志,然后执行目标方法。ProceedingJoinPoint的proceed()方法执行后,用来做一些,例如:写入日志}说明:ProceedingJoinPoint的proceed()方法在执行前用来做一些,例如:读取日志,然后执行目标方法。ProceedingJoinPoint的proceed()方法执行后,用来做一些,例如:写入日志

4.编写控制器

package com.cloud.industryapi.test;import com.cloud.common.kit.Result;
import com.cloud.common.page.FrontPagination;
import com.cloud.industry.dto.ExclusiveJumpConfigDto;
import com.cloud.industry.facede.ExclusiveJumpConfigFacede;
import com.cloud.industry.qo.ExclusiveJumpConfigQo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.List;/*** 文章 - 控制器*/
@Slf4j
@RestController
@RequestMapping("/aop/test")
public class ArticleController {/*** 后置异常通知*/@PointcutId@RequestMapping("/afterThrow")public void afterThrow(){log.info("-------------------进入了目标方法-------------------");System.out.println(2/0);}/*** 语文课** @param ae* @return*/@PointcutId(type = "language")@PostMapping("/language")public Result language(@RequestBody ArticleEntity ae) {log.info("-------------目标方法开始执行-------------");log.info("-------------语文老师进入教室,开始讲课《"+ae.getTitle()+"》-------------");System.out.printf("%s","深蓝的天空中挂着一轮金黄的圆月,下面是海边的沙地,都种着一望无际的碧绿的西瓜。\n" +"其间有一个十一二岁的少年,项带银圈,手捏一柄钢叉,向一匹猹尽力的刺去。\n" +"那猹却将身一扭,反从他的胯下逃走了。\n");log.info("-------------目标方法结束执行-------------");return Result.success("执行结束");}/*** 数学课** @param ae* @return*/@PointcutId(type = "mathematics")@PostMapping("/mathematics")public Result mathematics(@RequestBody ArticleEntity ae) {log.info("-------------目标方法开始执行-------------");log.info("-------------数学老师进入教室-------------");log.info("-------------“同学们,今天这节数学课,由我代上”-------------");log.info("-------------“起立”-------------");log.info("-------------”体~育~老~师~好~~“-------------");log.info("-------------目标方法结束执行-------------");return Result.success("执行结束");}
}

5.请求控制器

最后是请求的响应

完成

SpringAOP简单案例相关推荐

  1. java 向nodejs 发送请求简单案例

    java  向nodejs 发送请求简单案例 最近在做nodejs的东西,一直不明白java如何与nodejs建立连接,下面写了一个简单demo: nodejs端: var http = requir ...

  2. ViewPager 实现页面左右滑动的简单案例1

    ViewPager 实现页面左右滑动的简单案例 主要Activity: <RelativeLayoutxmlns:android="http://schemas.android.com ...

  3. BaseAdapter的一个简单案例

    BaseAdapter的一个简单案例 主Activity import android.os.Bundle; import android.app.Activity; import android.v ...

  4. Redis简单案例(二) 网站最近的访问用户

    原文:Redis简单案例(二) 网站最近的访问用户 我们有时会在网站中看到最后的访问用户.最近的活跃用户等等诸如此类的一些信息.本文就以最后的访问用户为例, 用Redis来实现这个小功能.在这之前,我 ...

  5. jQuery ajax简单案例-验证用户名是否可用

    jQuery ajax简单案例-验证用户名是否可用 HTML <!DOCTYPE html> <html> <head> <meta charset=&quo ...

  6. Android复习12【广播接收者-BroadcastReceiver(简单案例-发送广播、静态注册、动态注册、本地广播、代码示例(别处登陆踢用户下线)、常用系统广播总结、音乐播放器)】

    2020-04-28[11周-周二] 音乐播放器Android代码下载:https://wws.lanzous.com/ifqzihaxvij 目   录 简单案例-发送广播 2)动态注册实例(监听网 ...

  7. webrtc简单案例——音视频采集和播放

    webrtc简单案例--音视频采集和播放 目录 打开摄像头并将画面显示到页面 打开麦克风并在页面播放捕获的声音 同时打开摄像头和麦克风,并在页面显示画面和播放捕获的声音 1. 打开摄像头并将画面显示到 ...

  8. Redis简单案例(四) Session的管理

    Redis简单案例(四) Session的管理 原文:Redis简单案例(四) Session的管理 负载均衡,这应该是一个永恒的话题,也是一个十分重要的话题.毕竟当网站成长到一定程度,访问量自然也是 ...

  9. Redis简单案例(三) 连续登陆活动的简单实现

    原文:Redis简单案例(三) 连续登陆活动的简单实现 连续登陆活动,或许大家都不会陌生,简单理解就是用户连续登陆了多少天之后,系统就会送一些礼品给相应的用户.最常见的 莫过于游戏和商城这些.游戏就送 ...

  10. 适合初学者的struts简单案例

    2019独角兽企业重金招聘Python工程师标准>>> 前言:虽然现在ssh开发满天飞,但是对于初学者来说,未必是好事,从基础学起,一步一个脚印,也许对他们来说更好. 接下来的时间里 ...

最新文章

  1. 【人尽其才】颠覆思维☞合理分配工作
  2. RESTful API 中的 Status code 是否要遵守规范
  3. 【PP模块】报废(损耗)类别简介(Scrap Categories and Their Effects)
  4. HTML-语义类标签
  5. 轻松学PHP编程 源代码
  6. java界面 文件选择器_掌握java技术 必备java工具应用知识
  7. 团队作业4——第一次项目冲刺(Alpha版本)第三天
  8. HDOJ_1016 素数环
  9. Xcode 工程文件打开不出来, cannot be opened because the project file cannot be parsed.
  10. Oracle中UNION和ORDER BY共用方法
  11. mysql职业要求_运维职业要求
  12. 使用npm-check-updates模块升级插件
  13. Spring揭秘——什么是IOC和DI
  14. 图片批量上传至服务器/华为云obs 前台采用webuploader.js div+css布局 图片.zip华为云obs浏览器下载
  15. 02组团队项目-Alpha冲刺-4/6
  16. vue开发之图片加载不出来问题解决
  17. 烤仔TVのCCW丨密码学通识(一)密码学基础及常见误区
  18. Chrome浏览器获取Google搜索结果批量URL
  19. 怎么弄gif图片html,怎么弄gif动态图
  20. sql server误删数据恢复delete(低效版)

热门文章

  1. android 应用开启以后,动态检测并或者相机权限。
  2. 写在控制层的VO是什么?
  3. 【HAVENT原创】Spring Boot + Kafka 消息日志开发
  4. 平差的理解及一种最简单的高斯马尔科夫模型(Gauss Markov Model)
  5. 【学习笔记】生物数据库の初步了解
  6. 2018年中国人均GDP接近1万美元,这在全球处于什么样的水平?
  7. Pytorch 基于ResNet-18的服饰识别(使用Fashion-MNIST数据集)
  8. 女性手游市场,金矿还是深坑?
  9. 几种常见的7号电池的容量
  10. 如何给澳洲路局写信refound罚金,遇到交通罚款怎么办