摘要:閱讀原文造個輪子我學到了什么聽說的最多的是不是不要重復的造輪子不要被這句話蒙騙了,這句話應該還沒說完整,在什么情況下不要造輪子實際項目中由于工期和質量原因,肯定不希望你造輪子,你造輪子花費時間且質量不如現有的輪子。
閱讀原文:造個輪子,我學到了什么
聽說的最多的是不是“不要重復的造輪子”?不要被這句話蒙騙了,這句話應該還沒說完整,在什么情況下不要造輪子?
實際項目中由于工期和質量原因,肯定不希望你造輪子,你造輪子花費時間且質量不如現有的輪子。
但是!不造輪子怎么去裝X!不造輪子怎么去了解其中原理!不造輪子怎么成長!
那在造參數校驗器輪子的過程中我學到了什么呢?
注解的定義與使用
反射的應用
Spring AOP的使用
異常的拋出與處理
造之前的規劃雄心勃勃的規劃,開干!我一定比hibernate validator做的好!
我要支持:
屬性驗證
方法參數驗證
方法驗證
方法內主動驗證
注解你初見注解時,是不是有種疑惑?為什么在某個類或方法屬性上添加一個注解,它就能擁有某種功能呢?
那么我將為你慢慢解開這個迷惑。
注解就相當于一個標簽,它本身并沒有任何功能性,只是打個標簽說明一下這是什么。那它怎么實現的某些功能呢?這就要說說反射了,只有注解和反射雙劍合璧,才能發揮它的功效。我們先說注解,后說反射。
如何定義一個注解 格式自定義注解的格式為:
public @interface 注解名{注解體}
@interface用來聲明一個注解,并自動繼承java.lang.annotation.Annotation接口。
注解體中的類似方法定義的,我們稱為注解中的元素。
@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface NotNull{ String value() default ""; }注解元素
格式:權限修飾符 數據類型 元素名() default 默認值
權限修飾符:只能public和default(默認)
返回值類型:8種基本數據類型和String,Class,enum,Annotaion及他們的數組
默認值限制:編譯器對元素的默認值有些挑剔,元素的值不能為null并且不能有不確定的默認值(即要么有默認值,要么使用時提供值),所以一般我們在定義注解時便加上默認值。
元注解定義注解一定要使用到Java給我們提供的四種元注解,用于注解其他注解的。
@Target @Retention @Documented @Inherited
我們重點關注@Target和@Retention.
說明定義的注解所作用的范圍(可以用于修飾什么)。
取值(ElementType)有:
值 | 意義 |
---|---|
CONSTRUCTOR | 構造器聲明 |
FIELD | 屬性聲明(包括enum實例) |
LOCAL_VARIABLE | 局部變量聲明 |
METHOD | 方法聲明 |
PACKAGE | 包聲明 |
PARAMETER | 參數聲明 |
TYPE | 用于描述類、接口(包括注解類型) 或enum聲明 |
表示需要在什么級別保存該注釋信息,用于描述注解的生命周期(被描述的注解在什么范圍內有效)
取值(RetentionPoicy)有:
值 | 意義 |
---|---|
SOURCE | 在源文件中有效(即源文件保留) |
CLASS | 在class文件中有效(即class保留) |
RUNTIME | 在運行時有效(即運行時保留) |
參數校驗定義的常用注解:
注解 | 意義 |
---|---|
NotNull | 參數不能為空 |
On | 數值的范圍 |
OnMax | 最大值不能超過 |
OnMin | 最小值不能低于 |
郵箱格式 |
反射中牽涉的類有Class,Method,Parameter,Annotation,Field
類 | 獲取方式 |
---|---|
Class | Class.forName(""); clazz.getClass(); Type.class; |
Method | clazz.getMethods(); |
Parameter | method.getParameters(); constructor.getParameters(); |
Annotation | clazz.getAnnotations(); method.getAnnotations(); field.getAnnotations() |
Field | clazz.getFields(); |
用好反射的關鍵在于了解反射的API,之后我會多帶帶一篇講下我們常用的反射API。
Spring AOP的使用我將借助Spring AOP來實現找到這些注解的功能。我這里只講講淺顯一點的,因為很多人對于Spring AOP的使用還不了解。這個輪子是基于Spring Boot構建,所以我只講聲明式編程,就是注解實現的。
使用比較簡單,只需三步走:
定義切面類
指定切入點
定義通知類型
@Component //聲明這是一個組件 @Aspect //聲明這是一個切面 public class ServiceAspect { //定義切入點,沒有方法體 @Pointcut("@annotation(定義的注解)") public void pointcut(){ } /* * 前置通知,使用pointcut()上注冊的切入點 * * @param joinPoint 接受JoinPoint切入點對象,可以沒有該參數 */ @Before("pointcut()") public void before(JoinPoint joinPoint){ } //后置通知 @After("pointcut()") public void after(JoinPoint joinPoint){ } //環繞通知 @Around("pointcut()") public void around(JoinPoint joinPoint){ MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); //反射就此打開序幕 } //后置返回通知 @AfterReturning("pointcut()") public void afterReturn(JoinPoint joinPoint){ } //拋出異常后通知 @AfterThrowing(pointcut="pointcut()", throwing="ex") public void afterThrow(JoinPoint joinPoint, Exception ex){ } }
AOP底層原理是使用動態代理,動態代理有JDK動態代理和cglib動態代理,這里暫不細說了。
異常自定義異常類
public class FastValidatorException extends RuntimeException { public FastValidatorException(String message) { super(message); } }
設計時有兩種失敗模式:快速失敗和安全失敗
當參數校驗,不符合要求時,快速失敗將直接拋出此異常,安全失敗將收集所有失敗返回。
如:
private void emptyResult(String fieldName) { if (isFailFast) { throw new FastValidatorException(fieldName + "不能為空"); } else { formatResult(fieldName + "不能為空"); } } private void formatResult(String msg) { if (!msg.isEmpty()) { result.getErrors().add(msg); } }處理異常
如果使用快速失敗模式,那么使用者將要對異常做全局統一處理。
將參數異常類信息,封裝成比較友好的信息給前端。
@RestControllerAdvice public class ErrorHandler { @ExceptionHandler(FastValidatorException.class) public JSONResult handle(FastValidatorException ex) { return new JSONResult(ex.getMessage(), ex.getStatus()); } }造之后的感想
還是hibernate validator做的好!(捂臉哭) 我服!
but
造輪子能迫使我去了解更多的知識點,能迫使我去了解輪子的原理,也能加深我對知識的理解,順便還能吹吹!
做的過程中你會思考如何優化它,一遍遍的推倒重來,會想到用怎么來解耦?用什么提高擴展性,靈活性?
造輪子的意義在于能讓你不斷的思考和學習。無論造的好壞,行動就好。
輪子地址:https://github.com/flyhero/fa... 忘不吝指教!
發現這個面試視頻不錯,分享給大家,公眾號回復: 面試視頻
更多精彩技術文章盡在微信公眾號:碼上實戰
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/74142.html
摘要:用造個組件輪子吧閏土大叔如果你掌握了的組件知識,相關的指令事件,花點時間你也可以造出這么個入門級的小輪子。接下來,拋出造輪子實踐背后帶來的一些思考。以上三部分內容構成了的整個執行過程。 showImg(https://segmentfault.com/img/bV1Tnu?w=754&h=500); 前言 首先,向大家說聲抱歉。由于之前的井底之蛙,誤認為Vue.js還遠沒有覆蓋到二三線...
摘要:呵呵,你沒想到吧,這玩意兒竟然有第三集我靠,我自己都沒想到,讓我們悄悄的回顧一下前兩集完全沒想到,竟然會有第二集我厭倦了,那就造個輪子第二集痛點分析第一集在這里我厭倦了,那就造個輪子算了,我都懶得寫了,自己看吧,當然不看也無所謂,正式開始。 倉庫:215566435/rectx 前言 麻煩快去我的倉庫里面噴: 老子學不動了,求不要更新。 呵呵,你沒想到吧,這玩意兒竟然有第三集!我靠,我...
摘要:呵呵,你沒想到吧,這玩意兒竟然有第三集我靠,我自己都沒想到,讓我們悄悄的回顧一下前兩集完全沒想到,竟然會有第二集我厭倦了,那就造個輪子第二集痛點分析第一集在這里我厭倦了,那就造個輪子算了,我都懶得寫了,自己看吧,當然不看也無所謂,正式開始。 倉庫:215566435/rectx 前言 麻煩快去我的倉庫里面噴: 老子學不動了,求不要更新。 呵呵,你沒想到吧,這玩意兒竟然有第三集!我靠,我...
摘要:同時也新增了一個。將不同的配置文件用不同的對象進行管理。由于需要支持多個配置文件,所有需要定義一個抽象類供所有的配置管理實現。其實就是一個結構的緩存,用于存放所有的配置。總結這就是本次中的升級內容,包含了配置支持以及代碼重構。 showImg(https://segmentfault.com/img/remote/1460000016392132?w=2048&h=1365); 前言 ...
摘要:像操作系統一樣,你可以通過安裝軟件,成為適用于你的電腦。先進的技術方案,使得你無需擔心后期功能拓展與迭代問題,大大降低了維護成本。對于一個超過三年生命周期的項目來說,最適合不過。總之,是新的技術方向標,能讓每個藝術家像構建工程一樣構建程序。 這是我們團隊的一個非盈利項目,以Apache2.0協議開源...不限制商用 Notadd是什么 Notadd 是基于Laravel 和 Vue 的...
閱讀 2657·2023-04-26 00:42
閱讀 2808·2021-09-24 10:34
閱讀 3820·2021-09-24 09:48
閱讀 4156·2021-09-03 10:28
閱讀 2579·2019-08-30 15:56
閱讀 2775·2019-08-30 15:55
閱讀 3264·2019-08-29 12:46
閱讀 2248·2019-08-28 17:52