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>效果

相關文章
相關標籤/搜索