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