MST
星途 面试题库

面试题:Java中Spring框架里常用的自定义注解及使用场景

在Spring框架中,要求你列举至少两个自定义注解,并阐述其在项目中的常见使用场景,比如用于权限控制、日志记录等场景下,如何自定义注解并使用。
21.6万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

自定义注解一:权限控制注解

  1. 自定义注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Permission {
    String value() default "";
}
  1. 使用场景
    • 在项目中,当需要对某些接口方法进行权限控制时,可以在方法上使用该注解。例如,一个后台管理系统,不同角色有不同的操作权限。
    • 实现方式:通过切面(Aspect)来处理这个注解。切面类可以获取当前登录用户的角色信息,然后根据注解中设定的权限值,判断当前用户是否有权限访问该方法。如果没有权限,可以抛出异常或者返回特定的错误信息。
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class PermissionAspect {
    @Around("@annotation(permission)")
    public Object checkPermission(ProceedingJoinPoint joinPoint, Permission permission) throws Throwable {
        // 获取当前登录用户角色信息
        String userRole = getCurrentUserRole(); 
        if ("admin".equals(userRole) || permission.value().equals(userRole)) {
            return joinPoint.proceed();
        } else {
            throw new RuntimeException("无权限访问");
        }
    }

    private String getCurrentUserRole() {
        // 这里应该是从当前登录状态等获取用户角色的逻辑
        return "user";
    }
}

自定义注解二:日志记录注解

  1. 自定义注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface LogRecord {
    String value() default "";
}
  1. 使用场景
    • 在项目中,为了记录系统中重要方法的调用情况,比如记录接口的入参、出参以及调用时间等信息。
    • 实现方式:同样通过切面来处理该注解。切面类在方法执行前后记录相关信息,然后可以将这些信息保存到日志文件或者数据库中。
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.Date;

@Aspect
@Component
public class LogRecordAspect {
    @Around("@annotation(logRecord)")
    public Object recordLog(ProceedingJoinPoint joinPoint, LogRecord logRecord) throws Throwable {
        Date startTime = new Date();
        Object[] args = joinPoint.getArgs();
        System.out.println("方法 " + joinPoint.getSignature().getName() + " 开始执行,入参:" + Arrays.toString(args));
        Object result = joinPoint.proceed();
        Date endTime = new Date();
        System.out.println("方法 " + joinPoint.getSignature().getName() + " 执行结束,出参:" + result + ",执行时间:" + (endTime.getTime() - startTime.getTime()) + " 毫秒");
        return result;
    }
}