文章目录
- 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"; //假设用户权限为 TEST
System.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 {
@Autowired
UserInfoService 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.在方法上使用自定义注解。