Java Springboot 自定义注解

元注解就是注解的注解,用来描述注解的

  • @Retention 定义该注解的生命周期
  1. RetentionPolicy.SOURCE :作用于源码阶段,比如常见的 @Override, @SuppressWarnings;
  2. RetentionPolicy.CLASS :作用于字节码阶段
  3. RetentionPolicy.RUNTIME :作用于运行阶段
  • @Target 定义该注解的作用范围 
  1. ElementType.TYPE :用于注解到类,接口、枚举类
  2. ElementType.FIELD:字段,包括枚举类常量
  3. ElementType.METHOD:方法声明
  4. ElementType.PARAMETER:参数声明
  5. ElementType.CONSTRUCTOR:构造器声明
  6. ElementType.LOCAL_VARIABLE :局部变量声明
  7. ElementType.ANNOTATION_TYPE :用于注解声明,即注解的注解,元注解
  8. ElementType.PACKAGE :包声明
  • 其他注解
  1. @Document 注解将生成到javadoc中
  2. @Deprecated  表示过时的类
  3. @Inherited 是否允许子类继承该注解
  4. @SuppressWarnings 编译器忽略掉无法识别的警告名
  5. @Override 标注的方法重载了父类的方法

实例代码

/**
 * @author FWG
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.FIELD,ElementType.METHOD,ElementType.PARAMETER})
@Documented
public @interface PayableAnnotation
{
    String businessName();
}

获取注解值

@MyAnnotation1(name = "abc")
public class Demo1 {

    @MyAnnotation1(name = "xyz")
    private Integer age;

    @MyAnnotation2(model = TranscationModel.Read)
    public void list() {
        System.out.println("list");
    }

    @MyAnnotation3(models = {TranscationModel.Read, TranscationModel.Write})
    public void edit() {
        System.out.println("edit");
    }

    public void hello1(@IsNotNull(true) String name) {
        System.out.println("hello:" + name);
    }
}
//获取类上的注解
MyAnnotation1 annotation1 = Demo1.class.getAnnotation(MyAnnotation1.class);
System.out.println(annotation1.name());//abc

// 获取方法上的注解
MyAnnotation2 myAnnotation2 = Demo1.class.getMethod("list").getAnnotation(MyAnnotation2.class);
System.out.println(myAnnotation2.model());//Read

// 获取属性上的注解
MyAnnotation1 myAnnotation1 = Demo1.class.getDeclaredField("age").getAnnotation(MyAnnotation1.class);
System.out.println(myAnnotation1.name());// xyz

// 获取参数上的注解
for (Parameter parameter : demo3.getClass().getMethod("hello1", String.class).getParameters()) {
    IsNotNull annotation = parameter.getAnnotation(IsNotNull.class);
    if(annotation != null){
        System.out.println(annotation.value());//true
    }
}

3.使用实例

3.1 定义注解接口

import java.lang.annotation.*;

/**
 * 打印出操作日志
 * @author 
 * @create 2019/11/4
 */
//定义该注解的作用范围
@Target({ElementType.TYPE, ElementType.METHOD})
//定义该注解的生命周期
@Retention(RetentionPolicy.RUNTIME)
//注解将生成到javadoc中
@Documented
public @interface SystemLog {
    /**
     * 日志内容
     * @return
     */
    String message() default "";
}

3.2 实现接口

import com.example.shiro.config.SystemLog;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * 日志拦截
 * @author 
 * @create 2019/11/4
 */
@Slf4j
//使用order属性,设置该类在spring容器中的加载顺序
@Order(10)
//作用是把当前类标识为一个切面供容器读取
@Aspect
//把普通类实例化到spring容器中
@Component
public class OuterServiceAop {

    @Pointcut("@annotation(com.example.shiro.config.SystemLog)")
    public void serviceAop(){}

    @Before("serviceAop()")
    public void doBefore(JoinPoint joinPoint) {
        log.info("前置通知");
    }

    @After("serviceAop()")
    public void doAfter(JoinPoint joinPoint) {
        log.info("后置通知");
    }

    @AfterReturning(pointcut = "serviceAop()", returning = "res")
    public void doAfterReturning(JoinPoint joinPoint, Object res) {
        log.info("日志返回通知");
        //请求方法
        String method = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();
        log.info("method:"+ method);

        //日志描述
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method1 = signature.getMethod();
        SystemLog annotation = method1.getAnnotation(SystemLog.class);
        String message = annotation.message();
        log.info(message);
    }

    @AfterThrowing(pointcut = "serviceAop()", throwing = "e")
    public void doAfterThrowing(JoinPoint joinPoint, Throwable e) {
        log.info("异常通知");
        log.info("异常信息:" + e.getMessage());
    }
}

在需要的类或方法中增加注解

import com.example.shiro.config.SystemLog;
import com.example.shiro.entity.User;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;
import com.example.shiro.common.BaseController;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author 
 * @since 2019-11-01
 */
@RestController
@RequestMapping("/user")
public class UserController extends BaseController {

    @PostMapping("/login")
    @SystemLog(message = "用户登录")
    public String login(User user) {
        ...
    }
}
上一篇
下一篇