使用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与自定义注解转义字典值
一直以来,前端展示字典一般以中文展示为主,若在表中存字典值中文,当字典表更改字典值对应的中文,会造成数据不一致,为此设置冗余字段并非最优方案,若由前端自己写死转义,不够灵活,若在业务代码转义,臃肿也不 ...
随机推荐
- [CF1854C] Expected Destruction
题目描述 You have a set $ S $ of $ n $ distinct integers between $ 1 $ and $ m $ . Each second you do th ...
- Semantic Kernel 正式发布 v1.0.1 版本
微软在2023年12月19日在博客上(Say hello to Semantic Kernel V1.0.1)发布了Semantic kernel的.NET 正式1.0.1版本.新版本提供了新的文档, ...
- 华企盾DSC由于半透明软件设置了需要管理员权限打开导致半透明打不开加密文件
解决方法: 1.右键该应用程序->属性->兼容性,去掉[以管理员权限运行此程序] 2.也可以打开控制面板->系统和安全->用户账户控制设置调至最低
- MD5 or Bcrypt?
MD5 or Bcrypt? 摘要 首先是一个错误的认识观念问题,很多人觉得MD5是一个加密算法.不然,他实则是一种摘要算法,也可以叫哈希函数.他的作用是将目标文本转换成具有相同长度.不可逆的杂凑字符 ...
- DVWA Command Injection(命令注入)全等级
Command Injection(命令注入) 目录: Command Injection(命令注入) 1. Low 利用 1.nc反弹shell 2.msf上马 2.Medium 3. High 4 ...
- 防火墙配置SNMP
深信服AC配置SNMP 深信服AF配置SNMP 深信服AD配置SNMP 在接口上启用是snmp管理,平台有网神的mib,可以都读到数据
- CUDA驱动深度学习发展 - 技术全解与实战
全面介绍CUDA与pytorch cuda实战 关注TechLead,分享AI全维度知识.作者拥有10+年互联网服务架构.AI产品研发经验.团队管理经验,同济本复旦硕,复旦机器人智能实验室成员,阿里云 ...
- Kubernetes常见错误总结
1.屏幕持续打印Pod日志报error: unexpected EOF错误 Kubernetes: requesting flag for "kubectl logs" to av ...
- CSS 基础 3 - 定位 Postion 属性
CSS 基础 3 - 定位 Postion 属性 static position 属性的默认值,元素随 HTML 流移动 top/left/right/bottom 属性无效 relative 和 s ...
- 文心一言 VS 讯飞星火 VS chatgpt (62)-- 算法导论6.5 1题
文心一言 VS 讯飞星火 VS chatgpt (62)-- 算法导论6.5 1题 一.试说明 HEAP-EXTRACT-MAX在堆A=(15,13,9,5,12,8,7,4,0,6,2,1)上的操作 ...