文章目录
- 1. 自定义注解如何使用
- 2. 自定义注解使用场景
- 2.1 自定义注解使用AOP做权限校验
- 2.2 自定义注解使用AOP记录用户操作日志
- 2.3 自定义注解使用AOP记录接口请求时长
1. 自定义注解如何使用
需要使用@interface修饰,加上三个元注解
- @Documented:生成API文档使用
- @Target:决定此注解能加的范围,类、方法、属性上面
- @Retention:作用域(在什么时候有作用,java–》class–》运行时)
@Documented
@Target(ElementType.METHOD)//决定此注解能加的范围,类,方法,属性
@Retention(RetentionPolicy.RUNTIME)//作用域(在什么时候有作用,java--》class--》运行时)
public @interface SysLog {String name() default "";
}
2. 自定义注解使用场景
2.1 自定义注解使用AOP做权限校验
1. 编写自定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@Documented
public @interface Authority {String authority() default "";
}
2. 编写切面
定义切面并编写权限放行的逻辑
@Aspect
@Component
public class AuthoritionAspect {@Pointcut("execution(* com.aigaofeng.aopdemo.controller.UserController.*(..))")public void pointcut() {}@Around("pointcut()")public void advice(ProceedingJoinPoint joinPoint) throws Throwable {MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();Method method = methodSignature.getMethod();if (!method.isAnnotationPresent(Authority.class)) {//没有使用注解默认放行joinPoint.proceed(); } else {Authority authority = fetchPermission(methodSignature);//[1] 取出请求方的权限信息String userPermission = "root"; //假设用户权限为 TESTSystem.out.println("用户权限: " + userPermission);//[2] 和注解的值做比较 authority.authority()if (userPermission.equals(authority.authority())){//[3] 校验通过放行用户System.out.println("放行");joinPoint.proceed();}return;}}private Authority fetchPermission(MethodSignature methodSignature) {return methodSignature.getMethod().getAnnotation(Authority.class);}}
3. 编写测试类
在方法上使用自定义注解 @Authority(authority = “root”)
@RestController
public class UserController {@AutowiredUserInfoService userInfoService;@Authority(authority = "root")@RequestMapping("/getUser")public String getUser(){Integer userCount = userInfoService.getUserCount();System.out.println("获取数据库的users:"+userCount);return "success";}
}
4. 测试
在浏览器或postman上请接口,观察日志
2.2 自定义注解使用AOP记录用户操作日志
1. 编写自定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@Documented
public @interface SysLog {String operation() default "";//操作内容
}
2. 创建对应的实体类
@Data
@TableName(value = "user_info")
public class UserInfo implements Serializable {private static final long serialVersionUID = 1L;private String id;private String name;private String email;private String phone;private Date logTime;
}
3. 编写切面
@Aspect
@Component
public class SysLogAspect {/*** 定义@Before增强,拦截带有@SysLog注解的方法,并记录操作日志*/// 定义切点(拦截的规则)@Pointcut("execution(* com.aigaofeng.aopdemo.controller.UserController.*(..))")public void pointcut() {}@Around("pointcut()")public Object around(ProceedingJoinPoint point) throws Throwable {long start = System.currentTimeMillis();Object[] args = point.getArgs();Object proceed = point.proceed(point.getArgs());//调用目标方法long end = System.currentTimeMillis();long consuming = end - start;//方法执行时间//获取签名从而获取自定义注解上的value值MethodSignature methodSignature = (MethodSignature) point.getSignature();SysLog sysLog = methodSignature.getMethod().getAnnotation(SysLog.class);String declaringTypeName = methodSignature.getDeclaringTypeName();//类名String name = methodSignature.getName();//方法名String qualified = declaringTypeName+name;//全限定名UserInfo userInfo = new UserInfo();userInfo.setName("张三");userInfo.setId("1001");userInfo.setPhone("15523637367");userInfo.setEmail("526381269.qq.com");userInfo.setLogTime(new Date());System.out.println("请求对对象:"+ userInfo.getName());return proceed;}}
4. 编写测试方法
@SysLog(operation = "添加用户") // 调用加了@SysLog注解的方法需要额外的记录用户的操作日志@GetMapping("/test")public String test() {System.out.println("谁请求了该方法");return "ok";}
5. 测试
2.3 自定义注解使用AOP记录接口请求时长
步骤:
1.自定义注解
2.编写切面类
@Around("pointcut()")public Object around(ProceedingJoinPoint point) throws Throwable {long start = System.currentTimeMillis();Object[] args = point.getArgs();Object proceed = point.proceed(point.getArgs());//调用目标方法long end = System.currentTimeMillis();long consuming = end - start;//方法执行时间return proceed;}
3.在方法上使用自定义注解。