最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot自定義注解開發(fā)指南

 更新時(shí)間:2022年06月02日 16:20:15   作者:愛嚶斯塔  
在開發(fā)SpringBoot程序的過程中,有可能與其他業(yè)務(wù)系統(tǒng)進(jìn)行對(duì)接開發(fā),獲取封裝公共的API接口等等,下面這篇文章主要給大家介紹了關(guān)于SpringBoot自定義注解的相關(guān)資料,需要的朋友可以參考下

一、Java注解(Annotation)

含義:Java注解是附加在代碼中的一些元信息,用于一些工具在編譯、 運(yùn)行時(shí)進(jìn)行解析和使用,起到說明、配置的功能。

1、JDK基本注解

@Override ——》重寫

@Deprecated ——》已過時(shí)

@SuppressWarnings(value = "unchecked")  ——》壓制編輯器警告

2、JDK元注解

含義:元注解用于修飾其他的注解(紀(jì)委:管干部的干部)

①、@Retention ——》定義注解的保留策略

@Retention(RetentionPolicy.SOURCE) //注解僅存在于源碼中,在class字節(jié)碼文件中不包含
@Retention(RetentionPolicy.CLASS)//默認(rèn)的保留策略,注解會(huì)在class字節(jié)碼文件中存在,但運(yùn)行時(shí)無法獲得,
@Retention(RetentionPolicy.RUNTIME)//注解會(huì)在class字節(jié)碼文件中存在,在運(yùn)行時(shí)可以通過反射獲取到

②、@Target ——》指定被修飾的Annotation可以放置的位置(被修飾的目標(biāo))

      @Target(ElementType.TYPE)  ——》接口、類
      @Target(ElementType.FIELD)   ——》屬性
      @Target(ElementType.METHOD)   ——》方法

      @Target(ElementType.PARAMETER)   ——》方法參數(shù)
      @Target(ElementType.CONSTRUCTOR)  ——》構(gòu)造函數(shù)
      @Target(ElementType.LOCAL_VARIABLE)  ——》局部變量
      @Target(ElementType.ANNOTATION_TYPE)  ——》注解
      @Target(ElementType.PACKAGE)   ——》包 

 注:可以指定多個(gè)位置,如:

@Target({ElementType.METHOD, ElementType.TYPE}),也就是此注解可以在方法和類上面使用

③、@Inherited:指定被修飾的Annotation將具有繼承性 

④、@Documented:指定被修飾的該Annotation可以被javadoc工具提取成文檔.

二、自定義注解開發(fā)

1、含義

使用@interface關(guān)鍵字, 其定義過程與定義接口非常類似, 需要注意的是:

Annotation的成員變量在Annotation定義中是以無參的方法形式來聲明的, 其方法名和返回值類型定義了該成員變量的名字和類型, 而且我們還可以使用default關(guān)鍵字為這個(gè)成員變量設(shè)定默認(rèn)值

2、演示

①、枚舉類:enum,指的是常量的集合

②、注解類

Ⅰ、演示@Retention(RetentionPolicy.SOURCE)注解:MyAnnotation.java

package com.lv.annotation;
import org.springframework.beans.factory.annotation.Autowired;
import java.lang.annotation.*;
/**
 * @author T440s
 */
 
 
//生成一個(gè)注釋
@Documented
//表示當(dāng)前注解可以打在什么東西上面,此處可以放在類上與方法上
@Target({ElementType.TYPE,ElementType.METHOD})
//指定被修飾的Annotation將具有繼承性
@Inherited
//注解僅存在于源碼中,在class字節(jié)碼文件中不包含
@Retention(RetentionPolicy.SOURCE)
public @interface MyAnnotation {
 
    String value() default "";
}

TestController.java:注意這引用了MyAnnotation注解

package com.lv.controller;
 
import com.lv.annotation.MyAnnotation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
 
@MyAnnotation
@Controller
public class TestController {
 
    @Autowired
    private String name;
 
    @MyAnnotation
    public void aa(){
 
    }
 
}

運(yùn)行后target層注解消失:注解僅存在于源碼中,在class字節(jié)碼文件中不包含

Ⅱ、MyAnnotation注解為@Retention(RetentionPolicy.RUNTIME)時(shí)

        ——注解會(huì)在class字節(jié)碼文件中存在,在運(yùn)行時(shí)可以通過反射獲取到

運(yùn)行test.java:

package com.lv.controller;
 
import java.lang.annotation.Annotation;
 
public class Test {
    public static void main(String[] args) {
//    反射
        for(Annotation a:TestController.class.getAnnotations()){
            System.out.println(a);
        }
 
    }
}

Ⅲ、取注解里的屬性值

 注解:MyAnnotation.java

String message() default "aaa";

拿值:

package com.lv.controller;
import com.lv.annotation.MyAnnotation;
import java.lang.annotation.Annotation;
public class Test {
    public static void main(String[] args) {
//    反射
        for(Annotation a:TestController.class.getAnnotations()){
            if(a instanceof MyAnnotation){
                System.out.println(((MyAnnotation) a).message());
            }
        }

    }
}

Ⅳ、判斷在該類有無該注解

 測(cè)試:

package com.lv.controller;
import com.lv.annotation.MyAnnotation;
import java.lang.annotation.Annotation;
public class Test {
    public static void main(String[] args) {
//        直接將MyAnnotation這注解取出
        MyAnnotation myAnnotation=TestController.class.getAnnotation(MyAnnotation.class);
        if(myAnnotation !=null){
            System.out.println(myAnnotation.message());
        }
 
    }
}

三、完成切面日志操作

當(dāng)我們?cè)趯懺鰟h改的時(shí)候,會(huì)有很多冗余的代碼,后期修改很麻煩,如:

 @RequestMapping("/add")
    public String add(){
        System.out.println("xxx在增加");
        System.out.println("增加成功");
        return "yes";
    }

我們就可以定義aop面向切面,將前面那部分放入前置通知,后面一部分后置通知

新建切面:LogAop.java

package com.lv.aop;
 
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
 
@Aspect
//類不被識(shí)別,將類變成一個(gè)組件
@Component
@Slf4j
 
public class LogAop {
//    指定切入的規(guī)則,".."代表可有參可無參
    @Pointcut("execution(* com.lv.controller.*Controller.*(..))")
    public  void logger(){}
 
//    環(huán)繞通知
    @Around("logger()")
    public Object around(ProceedingJoinPoint point){
        //        獲得方法名稱
        Signature methodName=point.getSignature();
//        日志輸出
        log.info(methodName+"進(jìn)來了");
        Long l1=System.currentTimeMillis();
//        讓方法執(zhí)行
        Object obj=null;
        try {
            obj=point.proceed(point.getArgs());
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        log.info(methodName+"走了"+"\t耗時(shí)"+(System.currentTimeMillis()-l1));
        return obj;
 
    }
}

使用jrebel運(yùn)行:

package com.lv.controller;
 
import com.lv.annotation.MyAnnotation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
 
@MyAnnotation
//直接返回json數(shù)據(jù)
@RestController
//返回頁面跳轉(zhuǎn)數(shù)據(jù)
//@Controller
public class TestController {
 
    @RequestMapping("/add")
    public String add(){
        return "yes";
    }
 
    @RequestMapping("/del")
    public String del(){
        return "yes";
    }
 
    @RequestMapping("/upd")
    public String upd(){
        return "yes";
    }
 
 
    @RequestMapping("/list")
    public String list(){
        return "yes";
    }
 
}

使用注解來開發(fā)aop日志:

新建注解類:MyLog.java

package com.lv.annotation;
 
import java.lang.annotation.*;
 
@Inherited
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyLog {
 
}

 同樣在切面類中,記得改變切入的規(guī)則

@Pointcut("@annotation(com.lv.annotation.MyLog)")

需要輸出日志的方法就將新建的注解加上

四、完成前端響應(yīng)反應(yīng)

傳入四個(gè)文件:

ResponseParse.java:

package com.lv.response;
 
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
 
/**
 * @author hgh
 */
//響應(yīng)增強(qiáng)類
@RestControllerAdvice
public class ResponseParse implements ResponseBodyAdvice {
 
    @Override
    public boolean supports(MethodParameter methodParameter, Class aClass) {
        //返回值決定他是否需要進(jìn)入beforeBodyWrite
        return methodParameter.getMethod().isAnnotationPresent(ResponseResult.class);
    }
 
    @Override
    public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
        //更改返回值
        if (o == null) {
            return Result.success();
        }
        if (o instanceof Integer) {
            return Result.failure(ResultCode.queryCode((Integer) o));
        }
        if (o instanceof ResultCode) {
            return Result.failure((ResultCode) o);
        }
        if (o instanceof Result) {
            return o;
        }
        return null;
    }
}

 ResponseResult.java:

package com.lv.response;
 
import java.lang.annotation.*;
 
/**
 * @author hgh
 */
@Retention(value = RetentionPolicy.RUNTIME)
@Documented
@Target({ElementType.METHOD})
public @interface ResponseResult {
 
}

Result.java:

package com.lv.response;
 
import lombok.Data;
 
import java.io.Serializable;
 
/**
 * 響應(yīng)對(duì)象封裝類
 *
 * @author hgh
 */
@Data
public class Result<T> implements Serializable {
 
    private final int code;
    private final String message;
    private final T data;
 
    /**
     * 私有構(gòu)造, 只允許通過static調(diào)用構(gòu)造
     *
     * @param resultCode 結(jié)果枚舉
     * @param data       響應(yīng)數(shù)據(jù)
     */
    private Result(ResultCode resultCode, T data) {
        this.code = resultCode.getCode();
        this.message = resultCode.getMessage();
        this.data = data;
    }
 
    /**
     * 成功調(diào)用返回的結(jié)果(無數(shù)據(jù)攜帶)
     *
     * @return Result
     */
    public static Result success() {
        return success(null);
    }
 
    /**
     * 成功調(diào)用返回的結(jié)果(數(shù)據(jù)攜帶)
     *
     * @return Result
     */
    public static <T> Result success(T data) {
        return new Result(ResultCode.SUCCESS, data);
    }
 
    /**
     * 失敗調(diào)用返回的結(jié)果(數(shù)據(jù)攜帶)
     *
     * @param resultCode 狀態(tài)枚舉
     * @param data       攜帶的數(shù)據(jù)
     * @return Result
     */
    public static <T> Result failure(ResultCode resultCode, T data) {
        return new Result(resultCode, data);
    }
 
    /**
     * 失敗調(diào)用返回的結(jié)果(無數(shù)據(jù)攜帶)
     *
     * @param resultCode 狀態(tài)枚舉
     * @return Result
     */
    public static Result failure(ResultCode resultCode) {
        return failure(resultCode, null);
    }
 
}

ResultCode.java:

package com.lv.response;
 
import java.io.Serializable;
 
/**
 * 響應(yīng)結(jié)果碼枚舉
 *
 * @author hgh
 */
 
public enum ResultCode implements Serializable {
 
    /* 正常狀態(tài) */
    SUCCESS(100, "成功"),
    FAILURE(101, "失敗"),
    UNKNOWN(102, "未知響應(yīng)"),
    /**
     * 用戶code范圍: 200~300;
     */
    USER_ACCOUNT_NOT_FIND(201, "用戶名不存在"),
    USER_ACCOUNT_DISABLED(202, "該用戶已被禁用"),
    USER_PASSWORD_NOT_MATCH(203, "該用戶密碼不一致"),
    USER_PERMISSION_ERROR(204, "該用戶不具備訪問權(quán)限"),
    USER_STATE_OFF_LINE(205, "該用戶未登錄");
 
    private final Integer code;
    private final String message;
 
    ResultCode(Integer code, String message) {
        this.code = code;
        this.message = message;
    }
 
    public Integer getCode() {
        return code;
    }
 
    public String getMessage() {
        return message;
    }
 
    public static ResultCode queryCode(Integer code) {
        for (ResultCode value : values()) {
            if (code.equals(value.code)) {
                return value;
            }
        }
        return UNKNOWN;
    }
 
}

測(cè)試:

package com.lv.controller;
 
import com.lv.annotation.MyAnnotation;
import com.lv.annotation.MyLog;
import com.lv.response.ResponseResult;
import com.lv.response.Result;
import com.lv.response.ResultCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
 
@MyAnnotation
//直接返回json數(shù)據(jù)
@RestController
//返回頁面跳轉(zhuǎn)數(shù)據(jù)
//@Controller
public class TestController {
 
    @MyLog
    @ResponseResult
    @RequestMapping("/add")
    public Result add(){
        return Result.success("yes");
    }
 
    @RequestMapping("/del")
    @ResponseResult
    public Object del(){
        return 201;
    }
 
    @RequestMapping("/upd")
    @ResponseResult
    public Object upd(){
        return ResultCode.USER_ACCOUNT_NOT_FIND;
    }
 
 
    @RequestMapping("/list")
    @ResponseResult
    public Object list(){
        return Result.success("yes");
    }
 
}

增加: 

刪除:

總結(jié)

到此這篇關(guān)于SpringBoot自定義注解的文章就介紹到這了,更多相關(guān)SpringBoot自定義注解內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 深入講解spring boot中servlet的啟動(dòng)過程與原理

    深入講解spring boot中servlet的啟動(dòng)過程與原理

    這篇文章主要給大家介紹了關(guān)于spring boot中servlet啟動(dòng)過程與原理的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-07-07
  • java發(fā)送郵件示例講解

    java發(fā)送郵件示例講解

    這篇文章主要為大家詳細(xì)介紹了java發(fā)送郵件示例的全過程,溫習(xí)郵件協(xié)議,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-03-03
  • SpringSecurity實(shí)現(xiàn)權(quán)限認(rèn)證與授權(quán)的使用示例

    SpringSecurity實(shí)現(xiàn)權(quán)限認(rèn)證與授權(quán)的使用示例

    本文主要介紹了SpringSecurity實(shí)現(xiàn)權(quán)限認(rèn)證與授權(quán)的使用示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-11-11
  • java郵件發(fā)送簡(jiǎn)單實(shí)現(xiàn)代碼

    java郵件發(fā)送簡(jiǎn)單實(shí)現(xiàn)代碼

    這篇文章主要為大家詳細(xì)介紹了java郵件發(fā)送簡(jiǎn)單實(shí)現(xiàn)代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-03-03
  • Intellij idea熱部署插件JRebel的使用

    Intellij idea熱部署插件JRebel的使用

    這篇文章主要介紹了Intellij idea熱部署插件JRebel的使用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • 使用Java注解模擬spring ioc容器過程解析

    使用Java注解模擬spring ioc容器過程解析

    這篇文章主要介紹了使用Java注解模擬spring ioc容器過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-07-07
  • elasticsearch的zenDiscovery和master選舉機(jī)制原理分析

    elasticsearch的zenDiscovery和master選舉機(jī)制原理分析

    這篇文章主要介紹了elasticsearch的zenDiscovery和master選舉機(jī)制原理分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-04-04
  • SpringSecurity獲取當(dāng)前登錄用戶的信息的幾種方法實(shí)現(xiàn)

    SpringSecurity獲取當(dāng)前登錄用戶的信息的幾種方法實(shí)現(xiàn)

    本文主要介紹了SpringSecurity中獲取當(dāng)前登錄用戶信息的多種方式,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-03-03
  • java微信公眾號(hào)支付示例詳解

    java微信公眾號(hào)支付示例詳解

    這篇文章主要為大家詳細(xì)介紹了java微信公眾號(hào)支付示例,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-12-12
  • Java實(shí)現(xiàn)markdown格式內(nèi)容轉(zhuǎn)換為word

    Java實(shí)現(xiàn)markdown格式內(nèi)容轉(zhuǎn)換為word

    這篇文章主要為大家簡(jiǎn)單介紹了如何利用Java實(shí)現(xiàn)markdown格式內(nèi)容轉(zhuǎn)換為word文檔,文中的示例代碼簡(jiǎn)潔易懂,有需要的小伙伴可以參考一下
    2025-03-03

最新評(píng)論

卢氏县| 方山县| 白城市| 垣曲县| 武邑县| 呼图壁县| 盐亭县| 永福县| 扶沟县| 龙南县| 明水县| 莱芜市| 如东县| 吴旗县| 安仁县| 新巴尔虎左旗| 汶上县| 秦皇岛市| 金门县| 龙胜| 怀集县| 禹城市| 嘉义市| 肇庆市| 赤水市| 文成县| 泸州市| 逊克县| 普定县| 阳东县| 湘乡市| 西宁市| 额济纳旗| 红原县| 隆德县| 建湖县| 苍梧县| 广汉市| 县级市| 黑水县| 郯城县|