自定义注解的定义及使用场景

文章目录

    • 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上请接口,观察日志
在这里插入图片描述
自定义注解的定义及使用场景_第1张图片

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张图片

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.在方法上使用自定义注解。

你可能感兴趣的:(Java,spring)