使用aop去自定义注解,实现用户在请求的时候记录下来,如日志功能等
首先搞清楚aop的几个概念:
AOP即是面向切面,是Spring的核心功能之一,主要的目的即是针对业务处理过程中的横向拓展,以达到低耦合的效果。
「切面(Aspect)」:一个关注点的模块化。以注解@Aspect的形式放在类上方,声明一个切面。
「连接点(Joinpoint)」:在程序执行过程中某个特定的点,比如某方法调用的时候或者处理异常的时候都可以是连接点。
「通知(Advice)」:通知增强,需要完成的工作叫做通知,就是你写的业务逻辑中需要比如事务、日志等先定义好,然后需要的地方再去用。增强包括如下五个方面:
@Before:在切点之前执行@After:在切点方法之后执行@AfterReturning:切点方法返回后执行@AfterThrowing:切点方法抛异常执行@Around:属于环绕增强,能控制切点执行前,执行后,用这个注解后,程序抛异常,会影响@AfterThrowing这个注解。
「切点(Pointcut)」:其实就是筛选出的连接点,匹配连接点的断言,一个类中的所有方法都是连接点,但又不全需要,会筛选出某些作为连接点做为切点。
「引入(Introduction)」:在不改变一个现有类代码的情况下,为该类添加属性和方法,可以在无需修改现有类的前提下,让它们具有新的行为和状态。其实就是把切面(也就是新方法属性:通知定义的)用到目标类中去。
「目标对象(Target Object)」:被一个或者多个切面所通知的对象。也被称做被通知(adviced)对象。既然Spring AOP是通过运行时代理实现的,这个对象永远是一个被代理(proxied)对象。
「AOP代理(AOP Proxy)」:AOP框架创建的对象,用来实现切面契约(例如通知方法执行等等)。在Spring中,AOP代理可以是JDK动态代理或者CGLIB代理。
「织入(Weaving)」:把切面连接到其它的应用程序类型或者对象上,并创建一个被通知的对象。这些可以在编译时(例如使用AspectJ编译器),类加载时和运行时完成。Spring和其他纯Java AOP框架一样,在运行时完成织入。
Spring Boot 如何整合AOP自定义一个注解?
在实际开发中对于横向公共的逻辑需要抽取出来,这时候就需要使用AOP,比如日志的记录、权限的验证等等,这些功能都可以用注解轻松的完成。
添加依赖starter:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
自定义一个注解:
package com.example.demo.config; import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; @Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SysLog { OperationType operationType() default OperationType.SELECT; String value() default "";
}
package com.example.demo.config; /**
* @author Albert.Yang
*/ public enum OperationType {
SELECT,SAVE,UPDATE,DELETE
}
定义一个切面:
package com.example.demo.config; import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component; @Component
@Aspect
@Configuration
public class SysLogAspect { @Pointcut("@annotation(com.example.demo.config.SysLog)")
public void pointCut() {} @Around("pointCut()")
//@Around("@annotation(sysLog)") //2种写法,一种可以不单独写@Pointcut,而以SysLog sysLog作为入参。
public Object around(ProceedingJoinPoint point) throws Throwable {
long beginTime = System.currentTimeMillis(); //逻辑开始时间
System.out.println("@Around:执行目标方法之前...");
Object result = point.proceed(); //执行方法
System.out.println("@Around:执行目标方法之后...");
saveLog(point,beginTime);//todo,保存日志,自己完善
return result;
} private void saveLog(ProceedingJoinPoint point, long beginTime) {
System.out.println("Around-----" + beginTime + point.getSignature());
} @Before("@annotation(sysLog)")
public void doBefore(JoinPoint joinPoint, SysLog sysLog) {
System.out.println("doBefore-----" +joinPoint.getSignature() + sysLog.value());
} @AfterReturning(pointcut = "@annotation(sysLog)", returning = "returnValue")
public void releaseResource(JoinPoint joinPoint, SysLog sysLog, Object returnValue) {
System.out.println("AfterReturning-----" +joinPoint.getSignature() + sysLog.operationType().toString());
} }
测试:
以上配置完成后即可使用,只需要在需要的方法上标注@SysLog注解即可,如下:
package com.example.demo.controller; import com.example.demo.config.SysLog;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController; /**
* @Author Tim
* @Date 2020/11/20 11:40
*/
@RestController
public class Controller1 { @SysLog
@GetMapping("/add")
public String add(){
System.out.println("请求成功");
return "请求成功";
} }
package com.example.demo.controller; import com.example.demo.config.OperationType;
import com.example.demo.config.SysLog;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController; /**
* @Author Tim
* @Date 2020/11/20 11:40
*/
@RestController
public class ControlleDemo { @SysLog(operationType = OperationType.UPDATE, value = "請求2")
@GetMapping("/add2")
public String add(){
System.out.println("请求2");
return "请求2";
} }
注意有个执行顺序问题:
@Around是可以同时在所拦截方法的前后执行一段逻辑。
@Before是在所拦截方法执行之前执行一段逻辑。
@After 是在所拦截方法执行之后执行一段逻辑。

使用aop去自定义注解,实现用户在请求的时候记录下来,如日志功能等的更多相关文章
- spring AOP 和自定义注解进行身份验证
一个SSH的项目(springmvc+hibernate),需要提供接口给app使用.首先考虑的就是权限问题,app要遵循极简模式,部分内容无需验证,用过滤器不能解决某些无需验证的方法 所以最终选择用 ...
- AOP 实现自定义注解
1.自定义注解2.编写 AOP3.测试 1.自定义注解 package com.base.yun.spring.aop; import java.lang.annotation.Documented; ...
- 用AOP拦截自定义注解并获取注解属性与上下文参数(基于Springboot框架)
目录 自定义注解 定义切面 获取上下文信息JoinPoint ProceedingJoinPoint 定义测试方法 测试结果 小结 AOP可以用于日志的设计,这样话就少不了要获取上下文的信息,博主在设 ...
- 【spring boot】SpringBoot初学(6)– aop与自定义注解
前言 github: https://github.com/vergilyn/SpringBootDemo 一.AOP 官方demo:https://github.com/spring-project ...
- springboot通过AOP和自定义注解实现权限校验
自定义注解 PermissionCheck: package com.mgdd.sys.annotation; import java.lang.annotation.*; /** * @author ...
- SpringBoot中搭配AOP实现自定义注解
1 springBoot的依赖 确定项目中包含可以注解的依赖 <dependency> <groupId>org.springframework.boot</groupI ...
- Spring Boot系列——AOP配自定义注解的最佳实践
AOP(Aspect Oriented Programming),即面向切面编程,是Spring框架的大杀器之一. 首先,我声明下,我不是来系统介绍什么是AOP,更不是照本宣科讲解什么是连接点.切面. ...
- 使用AOP获取自定义注解的内容
目录结构: 一:自定义注解 package org.example.annotation; import java.lang.annotation.ElementType; import java.l ...
- SpringBoot框架:通过AOP和自定义注解完成druid连接池的动态数据源切换(三)
一.引入依赖 引入数据库连接池的依赖--druid和面向切面编程的依赖--aop,如下所示: <!-- druid --> <dependency> <groupId&g ...
- 基于SpringBoot 、AOP与自定义注解转义字典值
一直以来,前端展示字典一般以中文展示为主,若在表中存字典值中文,当字典表更改字典值对应的中文,会造成数据不一致,为此设置冗余字段并非最优方案,若由前端自己写死转义,不够灵活,若在业务代码转义,臃肿也不 ...
随机推荐
- 学会XPath,轻松抓取网页数据
一.定义 XPath(XML Path Language)是一种用于在 XML 文档中定位和选择节点的语言.XPath的选择功能非常强大,可以通过简单的路径选择语法,选取文档中的任意节点或节点集.学会 ...
- Vue2.0 学习 第二组 语法模板
本笔记主要参考菜鸟教程和官方文档编写. 1.文本绑定 一般在dom中用{{}}标时,并且在vue构造体内的data中定义文本内容 <div id="app"> & ...
- MySQL调优的一些总结
SQL优化可以从那几个方面去优化 1.基本写法优化: 1.少使用select * ,尽量使用具体字段: 2.对于条件来说等号之类两边的字段类型要一致,字符串不加单引号索引会失效: 3.尽量少使用Ord ...
- 2021AI量化投资训练营重磅升级,自带编程的优势显而易见
量化交易规模突破万亿大关 国内量化交易规模快速发展,今年量化基金已突破万亿大关,并且量化私募的整体业绩十分亮眼,过去5年一线量化私募的超额收益基本在20%~30%,量化交易的占比已达到20%-30%( ...
- python 获取apk 信息
python 获取apk 信息 1.安装androguard pip install androguard 2.获取apk的相关信息 引入基础信息 from androguard.misc impor ...
- Docker部署系列之Docker Compose安装Redis三主三从集群
总结/朱季谦 在日常开发或者编程当中,经常需要用到redis集群,若是按照传统的方式,一个机器一个机器搭建,难免过于繁琐,故而可以通过dock er-compose编排方式,快速搭建.我在搭建过程当中 ...
- 踩坑ffmpeg录制的mp4无法在浏览器上播放
前言 使用ffmpeg编译好的程序在电脑上进行音视频转换,可以参考这篇:<windows电脑FFmpeg安装教程手把手详解_windows安装ffmpeg>,而我们要做的是在游戏引擎中集成 ...
- .NET周刊【1月第1期 2023-01-07】
一月头条:C# 被评为2023年度编程语言! 在TIOBE指数的历史上,祝贺 C# 首次赢得了年度编程语言奖项!C# 已经是十大顶尖选手超过两个十年了,现在它正在迎头赶上四大语言,凭借一年内最大增幅( ...
- Spring源码学习笔记3——根据BeanDefinition实例化Bean的前置准备
一丶前言 笔记1和笔记2中我们分析了如何根据xml和注解加载生成BeanDefinition,并注册到BeanFactory,接下载便是Bean的加载,在加载之前会进行一些前置准备 二丶前置准备 和B ...
- 2023-11-29:用go语言,给你一个字符串 s ,请你去除字符串中重复的字母,使得每个字母只出现一次。 需保证 返回结果的字典序最小。 要求不能打乱其他字符的相对位置)。 输入:s = “cba
2023-11-29:用go语言,给你一个字符串 s ,请你去除字符串中重复的字母,使得每个字母只出现一次. 需保证 返回结果的字典序最小. 要求不能打乱其他字符的相对位置). 输入:s = &quo ...