<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
含義:Java註解是附加在程式碼中的一些元資訊,用於一些工具在編譯、 執行時進行解析和使用,起到說明、設定的功能。
@Override ——》重寫
@Deprecated ——》已過時
@SuppressWarnings(value = "unchecked") ——》壓制編輯器警告
含義:元註解用於修飾其他的註解(紀委:管幹部的幹部)
①、@Retention ——》定義註解的保留策略
@Retention(RetentionPolicy.SOURCE) //註解僅存在於原始碼中,在class位元組碼檔案中不包含
@Retention(RetentionPolicy.CLASS)//預設的保留策略,註解會在class位元組碼檔案中存在,但執行時無法獲得,
@Retention(RetentionPolicy.RUNTIME)//註解會在class位元組碼檔案中存在,在執行時可以通過反射獲取到
②、@Target ——》指定被修飾的Annotation可以放置的位置(被修飾的目標)
@Target(ElementType.TYPE) ——》介面、類
@Target(ElementType.FIELD) ——》屬性
@Target(ElementType.METHOD) ——》方法
@Target(ElementType.PARAMETER) ——》方法引數
@Target(ElementType.CONSTRUCTOR) ——》建構函式
@Target(ElementType.LOCAL_VARIABLE) ——》區域性變數
@Target(ElementType.ANNOTATION_TYPE) ——》註解
@Target(ElementType.PACKAGE) ——》包
注:可以指定多個位置,如:
@Target({ElementType.METHOD, ElementType.TYPE}),也就是此註解可以在方法和類上面使用
③、@Inherited:指定被修飾的Annotation將具有繼承性
④、@Documented:指定被修飾的該Annotation可以被javadoc工具提取成檔案.
使用@interface關鍵字, 其定義過程與定義介面非常類似, 需要注意的是:
Annotation的成員變數在Annotation定義中是以無參的方法形式來宣告的, 其方法名和返回值型別定義了該成員變數的名字和型別, 而且我們還可以使用default關鍵字為這個成員變數設定預設值
①、列舉類:enum,指的是常數的集合
②、註解類
Ⅰ、演示@Retention(RetentionPolicy.SOURCE)註解:MyAnnotation.java
package com.lv.annotation; import org.springframework.beans.factory.annotation.Autowired; import java.lang.annotation.*; /** * @author T440s */ //生成一個註釋 @Documented //表示當前註解可以打在什麼東西上面,此處可以放在類上與方法上 @Target({ElementType.TYPE,ElementType.METHOD}) //指定被修飾的Annotation將具有繼承性 @Inherited //註解僅存在於原始碼中,在class位元組碼檔案中不包含 @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(){ } }
執行後target層註解消失:註解僅存在於原始碼中,在class位元組碼檔案中不包含
Ⅱ、MyAnnotation註解為@Retention(RetentionPolicy.RUNTIME)時
——註解會在class位元組碼檔案中存在,在執行時可以通過反射獲取到
執行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()); } } } }
Ⅳ、判斷在該類有無該註解
測試:
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()); } } }
當我們在寫增刪改的時候,會有很多冗餘的程式碼,後期修改很麻煩,如:
@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 //類不被識別,將類變成一個元件 @Component @Slf4j public class LogAop { // 指定切入的規則,".."代表可有參可無參 @Pointcut("execution(* com.lv.controller.*Controller.*(..))") public void logger(){} // 環繞通知 @Around("logger()") public Object around(ProceedingJoinPoint point){ // 獲得方法名稱 Signature methodName=point.getSignature(); // 紀錄檔輸出 log.info(methodName+"進來了"); Long l1=System.currentTimeMillis(); // 讓方法執行 Object obj=null; try { obj=point.proceed(point.getArgs()); } catch (Throwable throwable) { throwable.printStackTrace(); } log.info(methodName+"走了"+"t耗時"+(System.currentTimeMillis()-l1)); return obj; } }
使用jrebel執行:
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資料 @RestController //返回頁面跳轉資料 //@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"; } }
使用註解來開發aop紀錄檔:
新建註解類:MyLog.java
package com.lv.annotation; import java.lang.annotation.*; @Inherited @Documented @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface MyLog { }
同樣在切面類中,記得改變切入的規則
@Pointcut("@annotation(com.lv.annotation.MyLog)")
需要輸出紀錄檔的方法就將新建的註解加上
傳入四個檔案:
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 */ //響應增強類 @RestControllerAdvice public class ResponseParse implements ResponseBodyAdvice { @Override public boolean supports(MethodParameter methodParameter, Class aClass) { //返回值決定他是否需要進入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; /** * 響應物件封裝類 * * @author hgh */ @Data public class Result<T> implements Serializable { private final int code; private final String message; private final T data; /** * 私有構造, 只允許通過static呼叫構造 * * @param resultCode 結果列舉 * @param data 響應資料 */ private Result(ResultCode resultCode, T data) { this.code = resultCode.getCode(); this.message = resultCode.getMessage(); this.data = data; } /** * 成功呼叫返回的結果(無資料攜帶) * * @return Result */ public static Result success() { return success(null); } /** * 成功呼叫返回的結果(資料攜帶) * * @return Result */ public static <T> Result success(T data) { return new Result(ResultCode.SUCCESS, data); } /** * 失敗呼叫返回的結果(資料攜帶) * * @param resultCode 狀態列舉 * @param data 攜帶的資料 * @return Result */ public static <T> Result failure(ResultCode resultCode, T data) { return new Result(resultCode, data); } /** * 失敗呼叫返回的結果(無資料攜帶) * * @param resultCode 狀態列舉 * @return Result */ public static Result failure(ResultCode resultCode) { return failure(resultCode, null); } }
ResultCode.java:
package com.lv.response; import java.io.Serializable; /** * 響應結果碼列舉 * * @author hgh */ public enum ResultCode implements Serializable { /* 正常狀態 */ SUCCESS(100, "成功"), FAILURE(101, "失敗"), UNKNOWN(102, "未知響應"), /** * 使用者code範圍: 200~300; */ USER_ACCOUNT_NOT_FIND(201, "使用者名稱不存在"), USER_ACCOUNT_DISABLED(202, "該使用者已被禁用"), USER_PASSWORD_NOT_MATCH(203, "該使用者密碼不一致"), USER_PERMISSION_ERROR(204, "該使用者不具備存取許可權"), 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; } }
測試:
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資料 @RestController //返回頁面跳轉資料 //@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"); } }
增加:
刪除:
到此這篇關於SpringBoot自定義註解的文章就介紹到這了,更多相關SpringBoot自定義註解內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45