spring boot自定义注解

一、注解

  注解英文称 Annotaion,是Java从1.5开始支持加入源码的特殊语法元数据,做为程序的元数据嵌入到程序当中。注解实现有一个重要的接口Annotation接口,利用@interface关键字,将全部使用该关键字的注解类都实现Annotation接口。Annontation像一种修饰符同样,应用于包、类型、构造方法、方法、成员变量、参数及本地变量的声明语句中。前端

二、优势

使用注解的好处:java

  一、帮助代码编译检查web

  二、提升代码的识别度,好比 @override @Deprecated spring

  三、减小重复代码,简化代码apache

  四、根据注解生成帮助文档,如 @Decument 等app

三、元注解

基本语法:ide

 @Target({ElementType.METHOD, ElementType.TYPE})
 @Retention(RetentionPolicy.RUNTIME)
 @Documented
 public @interface AnnotationName{
  
 }

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

  • @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 标注的方法重载了父类的方法

 四、自定义注解

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 "";
}

注意:规定注解里面只能使用java基本数据类型和String、enum、Annotation、classspa

五、自定义注解示例

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 "";
}

2>实现接口,code

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());
    }
}

3>在须要的类或方法中增长注解

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) {
        ...
    }
}

4>效果

相关文章
相关标签/搜索