




版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
阿里巴巴Java開(kāi)發(fā)手冊(cè)1.4.0前言《阿里巴巴JavaJavaMySQL本手冊(cè)的旨在碼出高效,碼出質(zhì)量。現(xiàn)代軟件架構(gòu)的復(fù)雜性需要協(xié)同開(kāi)發(fā)完成,如何高效地協(xié)同呢?無(wú)規(guī)矩不成方圓,無(wú)規(guī)范難以協(xié)同,比如,制訂交通法規(guī)表面上是要限制行車(chē)權(quán),實(shí)際上是保障公眾的人身安全,試想如果沒(méi)有限速,沒(méi)有紅綠燈,誰(shuí)還敢上路行駛。對(duì)軟件來(lái)說(shuō),適當(dāng)?shù)囊?guī)范和標(biāo)準(zhǔn)絕不是消滅代碼內(nèi)容的創(chuàng)造性、優(yōu)雅性,而是限制過(guò)度個(gè)性化,以一種普遍認(rèn)可的統(tǒng)一方式一起做事,提升協(xié)作效率,降低溝通成本。代碼的字里行間流淌的是軟件系統(tǒng)的血液,質(zhì)量的提升是盡可能少踩坑,杜絕踩重復(fù)的坑,切實(shí)提升系統(tǒng)穩(wěn)定性,碼出質(zhì)量。目錄前言前言一、編程規(guī)約 1(一) 命名風(fēng)格 1(二) 常量定義 3(三) 代碼格式 4(四) OOP規(guī)約 6(五) 集合處理 9(六) 并發(fā)處理 12(七) 控制語(yǔ)句 14(八) 注釋規(guī)約 16(九) 其它 18二、異常日志 19(一) 異常處理 19三、單元測(cè)試 22四、安全規(guī)約 24五、MySQL數(shù)據(jù)庫(kù) 25三、單元測(cè)試 22四、安全規(guī)約 24五、MySQL數(shù)據(jù)庫(kù) 25(一) 建表規(guī)約 25(二) 索引規(guī)約 26(三) SQL語(yǔ)句 28(四) ORM映射 29六、工程結(jié)構(gòu) 31(一) 應(yīng)用分層 31(二) 二方庫(kù)依賴(lài) 32(三) 服務(wù)器 33七、設(shè)計(jì)規(guī)約 35附1:版本歷史 37附2:專(zhuān)有名詞解釋 38(PDF左側(cè)導(dǎo)航欄) 阿里巴巴Java開(kāi)發(fā)手冊(cè) PAGEPAGE32/38Java開(kāi)發(fā)手冊(cè)版本號(hào)制定團(tuán)隊(duì)更新日期備注1.4.0阿里巴巴集團(tuán)技術(shù)團(tuán)隊(duì)2018.5.20增加設(shè)計(jì)規(guī)約(詳盡版)一、編程規(guī)約(一命名風(fēng)格【強(qiáng)制】代碼中的命名均不能以下劃線(xiàn)或美元符號(hào)開(kāi)始,也不能以下劃線(xiàn)或美元符號(hào)結(jié)束反例:_name/name/$name/name_/name$/name 【強(qiáng)制】代碼中的命名嚴(yán)禁使用拼音與英文混合的方式,更不允許直接使用中文的方式。說(shuō)明:正確的英文拼寫(xiě)和語(yǔ)法可以讓閱讀者易于理解,避免歧義。注意,即使純拼音命名方式也要避免采用。正例:alibaba/taobao/youku/hangzhou等國(guó)際通用的名稱(chēng),可視同英文。反例:DaZhePromotion[打折]/getPingfenByName()[評(píng)分]/int某變量=3UpperCamelCaseDO/BO/DTO/VO/AO/PO/UID等。正例:MarcoPolo/UserDO/XmlService/TcpUdpDeal/TaPromotion反例:macroPolo/UserDo/XMLService/TCPUDPDeal/TAPromotionlowerCamelCase正例:localValue/getHttpMessage()/inputUserId正例:MAX_STOCK_COUNT反例:MAX_COUNTAbstractBase開(kāi)頭;Exception結(jié)尾;Test正例:int[]arrayDemo;反例:在main參數(shù)中,使用Stringargs[]來(lái)定義。POJOis反例:BooleanisDeletedisDeleted(),RPCdeleted出異常。單數(shù)形式,但是類(lèi)名如果有復(fù)數(shù)含義,類(lèi)名可以使用復(fù)數(shù)形式。正例:應(yīng)用工具類(lèi)包名為com.alibaba.ai.util、類(lèi)名為MessageUtils(此規(guī)則參考spring的框架結(jié)構(gòu))【強(qiáng)制】杜絕完全不規(guī)范的縮寫(xiě),避免望文不知義。AbsClass;condition組合來(lái)表達(dá)其意。正例:在JDK中,表達(dá)原子更新的類(lèi)名為:AtomicReferenceFieldUpdater。反例:變量inta的隨意命名方式。說(shuō)明:將設(shè)計(jì)模式體現(xiàn)在名字中,有利于閱讀者快速理解架構(gòu)設(shè)計(jì)理念。正例:publicclassOrderFactory;publicclassLoginProxy;publicclassResourceObserver;(publicJavadoc與接口方法相關(guān),并且是整個(gè)應(yīng)用的基礎(chǔ)常量。正例:接口方法簽名voidcommit();接口基礎(chǔ)常量StringCOMPANY="alibaba";反例:接口方法定義publicabstractvoidf();說(shuō)明:JDK8default認(rèn)實(shí)現(xiàn)。接口和實(shí)現(xiàn)類(lèi)的命名有兩套規(guī)則:ServiceDAOSOAImpl正例:CacheServiceImplCacheService接口。(通常是–able的形式正例:AbstractTranslator實(shí)現(xiàn)Translatable。Enum說(shuō)明:枚舉其實(shí)就是特殊的類(lèi),域成員均為常量,且構(gòu)造方法被默認(rèn)強(qiáng)制是私有。正例:ProcessStatusEnum的SUCCESS/UNKNOWN_REASON。【參考】各層命名規(guī)約:Service/DAOget做前綴。list做前綴,復(fù)數(shù)形式結(jié)尾如:listObjects。count做前綴。4)save/insert做前綴。5)remove/delete6)update做前綴。領(lǐng)域模型命名規(guī)約數(shù)據(jù)對(duì)象:xxxDO,xxx數(shù)據(jù)傳輸對(duì)象:xxxDTO,xxx展示對(duì)象:xxxVO,xxxPOJODO/DTO/BO/VOxxxPOJO。(二常量定義【強(qiáng)制】不允許任何魔法值(即未經(jīng)預(yù)先定義的常量)反例:Stringkey"Id#taobao_"+tradeId;cache.put(key,value);longLongLl1混淆,造成誤解。說(shuō)明:Longa2l;21Long2?【推薦】不要使用一個(gè)常量類(lèi)維護(hù)所有常量,要按常量功能進(jìn)行歸類(lèi),分開(kāi)維護(hù)。正例:CacheConsts下ConfigConsts下。內(nèi)共享常量、類(lèi)內(nèi)共享常量。client.jarconstant目錄下。constant目錄下。反例:易懂變量也要統(tǒng)一定義成應(yīng)用內(nèi)共享常量,兩位攻城師在兩個(gè)類(lèi)中分別定義了表示“是”的變量:A中:publicstaticfinalStringYESyes";類(lèi)B中:publicstaticfinalStringYES="y";A.YES.equals(B.YES)truefalse,導(dǎo)致線(xiàn)上問(wèn)題。constant目錄下。constant目錄下。privatestaticfinal定義。【推薦】enum類(lèi)型來(lái)定義。enum示一年中的第幾個(gè)季節(jié)。正例:publicenumSeasonEnum{SPRING(1),SUMMER(2),AUTUMN(3),WINTER(4);privateintseq;SeasonEnum(intseq){this.seq=seq;}}(三代碼格式{}是非空代碼塊則:左大括號(hào)前不換行。左大括號(hào)后換行。右大括號(hào)前換行。else等代碼則不換行表示終止的右大括號(hào)后必須換行。;5條下方正例提示。反例:ifab空格)【強(qiáng)制】if/for/while/switch/do【強(qiáng)制】任何二目、三目運(yùn)算符的左右兩邊都需要加一個(gè)空格。說(shuō)明:運(yùn)算符包括賦值運(yùn)算符=、邏輯運(yùn)算符&&、加減乘除符號(hào)等。4tab說(shuō)明:tab1tab4個(gè)空格。IDEAtab4個(gè)空格時(shí),Usetabcharactereclipseinsertspacesfortabs。正例:(1-5點(diǎn))publicstaticvoidmain(String[]args){//4個(gè)空格Stringsay="hello";//運(yùn)算符的左右必須有一個(gè)空格intflag=0;//iff與左括號(hào),0與右括號(hào)不需要空格if(flag==0){System.out.println(say);}//左大括號(hào)前加空格且不換行;左大括號(hào)后換行if(flag==1){System.out.println("world");//右大括號(hào)前換行,右大括號(hào)后有else,不用換行}else{System.out.println("ok");//在右大括號(hào)后直接結(jié)束,則必須換行}}正例://這是示例注釋?zhuān)?qǐng)注意在雙斜線(xiàn)之后有一個(gè)空格Stringygb=newString();12042)運(yùn)算符與下文一起換行。方法調(diào)用的點(diǎn)符號(hào)與下文一起換行。方法調(diào)用中的多個(gè)參數(shù)需要換行時(shí),在逗號(hào)后進(jìn)行。正例:StringBuffersb=newStringBuffer();//1204個(gè)空格,點(diǎn)號(hào)和方法名稱(chēng)一起換行sb.append("zi").append("xin")append("huang")append("huang")append("huang");反例:StringBuffersb=newStringBuffer();//120括號(hào)前換行sb.append("zi").append("xin")...append("huang");//120個(gè)字符,不要在逗號(hào)前換行method(args1,args2,args3,...,argsX);正例:args1,后邊必須要有一個(gè)空格。method(args1,args2,args3);【強(qiáng)制】IDEtextfileencodingUTF-8;IDEUnixWindows80行。80行。正例:代碼邏輯分清紅花和綠葉,個(gè)性和共性,綠葉邏輯單獨(dú)出來(lái)成為額外方法,使主干代碼更加清晰;共性邏輯抽取成為共性方法,便于復(fù)用和維護(hù)。正例:intone=1;longtwo=2L;floatthree=3F;StringBuffersb=newStringBuffer();說(shuō)明:sba、bc情況下,是非常累贅的事情。說(shuō)明:任何情形,沒(méi)有必要插入多個(gè)空行進(jìn)行隔開(kāi)。(四OOP規(guī)約本,直接用類(lèi)名來(lái)訪(fǎng)問(wèn)即可?!緩?qiáng)制】所有的覆寫(xiě)方法,必須加@Override注解。get0bject()@Override譯報(bào)錯(cuò)。JavaObject說(shuō)明:可變參數(shù)必須放置在參數(shù)列表的最后。(提倡同學(xué)們盡量不用可變參數(shù)編程)正例:publicList<User>listUsers(Stringtype,Long...ids){...}影響。接口過(guò)時(shí)必須加@Deprecated【強(qiáng)制】不能使用過(guò)時(shí)的類(lèi)或方法。說(shuō)明:.URLDecoderdecode(StringencodeStrdecode(StringsourceStringencode)【強(qiáng)制】Objectequalsequals。正例:"test".equals(object);反例:object.equals("test");說(shuō)明:java.util.Objects#equals(JDK7引入的工具類(lèi))【強(qiáng)制】所有的相同類(lèi)型的包裝類(lèi)對(duì)象之間值的比較equals說(shuō)明:Integervar=?在-128127范圍內(nèi)的賦值,Integer對(duì)象是在IntegerCache.cacheInteger值可以直接使用==進(jìn)行equals關(guān)于基本數(shù)據(jù)類(lèi)型與包裝數(shù)據(jù)類(lèi)型的使用標(biāo)準(zhǔn)如下:POJO【強(qiáng)制】RPC【推薦】所有的局部變量使用基本數(shù)據(jù)類(lèi)型。說(shuō)明:POJONPE正例:nullNPEx%,xRPC0%,這是不合理的,應(yīng)該顯示成中劃線(xiàn)。所以包裝nullDO/DTO/VOPOJO默認(rèn)值。反例:POJOgmtCreatenewDate(),serialVersionUID;如serialVersionUID值。說(shuō)明:serialVersionUIDinit方法中?!緩?qiáng)制】POJOtoStringIDE中的工具:sourcegeneratetoStringPOJOsuper.toString。POJOtoString()POJOxxxisXxx()getXxx()方法。說(shuō)明:xxxStringsplitIndexOutOfBoundsException的風(fēng)險(xiǎn)。說(shuō)明:Stringstr="a,b,c,,";String[]ary=str.split(",");//預(yù)期大于3,結(jié)果是3System.out.println(ary.length);16條規(guī)則。私有方法getter/setter方法。“模板設(shè)計(jì)模式”下的核心方法黑盒實(shí)現(xiàn);ServiceDAOgetter/setter【推薦】setterthis.成員名參數(shù)名。在getter/setter反例:publicIntegergetData()if(condition){returnthis.data+100;}else{returnthis.data-100;}}StringBuilderappend方法進(jìn)行擴(kuò)展。說(shuō)明:newStringBuilderappendtoStringStringStringstr="start";for(inti=0;i<100;i++)str=str+"hello";}finalfinal不允許被繼承的類(lèi),如:String類(lèi)。不允許修改引用的域?qū)ο蟆2辉试S被重寫(xiě)的方法,如:POJO類(lèi)的setter方法。不允許運(yùn)行過(guò)程中重新賦值的局部變量。final地進(jìn)行重構(gòu)。Objectclone說(shuō)明:cloneclone深度遍歷式拷貝?!就扑]】類(lèi)成員與方法訪(fǎng)問(wèn)控制從嚴(yán):newprivate。publicdefaultstaticprotected4)staticprivate。5)staticprivate。6)tected。說(shuō)明:任何類(lèi)、方法、參數(shù)、變量,嚴(yán)控訪(fǎng)問(wèn)范圍。過(guò)于寬泛的訪(fǎng)問(wèn)范圍,不利于模塊解耦。privatepublicservice成員(五集合處理hashCodeequalsequalshashCode。SethashCodeequalsSet存儲(chǔ)的對(duì)象必須重寫(xiě)這兩個(gè)方法。MaphashCodeequals。說(shuō)明:String重寫(xiě)了hashCodeequalsStringkey來(lái)使用。AraLst的suLst結(jié)果不可強(qiáng)轉(zhuǎn)成AryitCasatxeionjava.util.RandomAccessSubListcannotbecasttojava.util.ArrayList。suLstAraLstSuLstrryitAryitSubListsubList高度注意ConcurrentModificationException異常。toArray(Tarray)list.size()。toArray[list.size()]null正例:List<String>list=newArrayList<String>(2);list.add("guan");list.add("bao");String[]array=newString[list.size()];array=list.toArray(array);反例:toArrayObject[]ClassCastException錯(cuò)誤。Arrays.asList()add/remove/clearUnsupportedOperationException異常。aLstArasArysaist體現(xiàn)的是適配器模式,只是轉(zhuǎn)換接口,后臺(tái)的數(shù)據(jù)仍是數(shù)組。String[]str=newString[]{"you","wu"};Listlist=Arrays.asList(str);第一種情況:list.add("yangguanbao");運(yùn)行時(shí)異常。第二種情況:str[0]="gujin";那么list.get(0)也會(huì)隨之修改?!緩?qiáng)制】泛型通配符extendsT>add方法,而superT>get說(shuō)明:PECS(ProducerExtendsConsumerSuper)extendsT><?superT>。foreach循環(huán)里進(jìn)行元素的remove/addremoveIteratorIterator正例:List<String>list=newArrayList<>();list.add("1");list.add("2");Iterator<String>iterator=list.iterator();while(iterator.hasNext()){Stringitem=iterator.next();if(刪除元素的條件){iterator.remove();}}反例:for(Stringitem:list){if("1".equals(item))list.remove(item);}}說(shuō)明:以上代碼的執(zhí)行結(jié)果肯定會(huì)出乎大家的意料,那么試一下把“1”換成“2”,會(huì)是同樣的結(jié)果嗎?JDK7Arrays.sort,Collections.sortIllegalArgumentException異常。說(shuō)明:三個(gè)條件如下x,yy,xx>y,y>z,則x>z。x=y,則x,zy,z反例:下例中沒(méi)有處理相等的情況,實(shí)際使用中可能會(huì)出現(xiàn)異常:newComparator<Student>(){@Overridepublicintcompare(Studento1,Studento2)returno1.getId()>o2.getId()?1:}}; JDK7diamond說(shuō)明:diamond,直接使用<>來(lái)指代前邊已經(jīng)指定的類(lèi)型。正例://diamond方式HashMap<String,String>userCache=newHashMap<>(16);//全省略方式ArrayList<User>users=newArrayList(10);【推薦】集合初始化時(shí),指定集合初始值大小。說(shuō)明:HashMapHashMap(intinitialCapacity初始化。intaCpcy(需要存儲(chǔ)的元素個(gè)數(shù)/負(fù)載因子)+1(loaderfactor)0.75,16(。反例:HashMap10247次被迫擴(kuò)大,resizehashentrySetMap類(lèi)集合KVkeySet說(shuō)明:keySet2IteratorhashMapvalueentrySetkeyvalueentryJDK8Map.foreach方法。V值集合,是一個(gè)list集合對(duì)象;keySet()KSet集合對(duì)象;entrySet()K-V值組合集合。MapK/Vnull集合類(lèi)KeyValueSuper說(shuō)明Hashtable不允許為null不允許為nullDictionary線(xiàn)程安全ConcurrentHashMap不允許為null不允許為nullAbstractMap鎖分段技術(shù)(JDK8:CAS)TreeMap不允許為null允許為nullAbstractMap線(xiàn)程不安全HashMap允許為null允許為nullAbstractMap線(xiàn)程不安全HashMapConcurrentHashMapnull值,而事實(shí)上,nullNPE異常。(sort)(order)(unsort)和不穩(wěn)定性(unorder)序是一定的。如:ArrayListorder/unsort;HashMapunorder/unsort;TreeSet是order/sort。SetList的contains(六并發(fā)處理說(shuō)明:資源驅(qū)動(dòng)類(lèi)、工具類(lèi)、單例工廠類(lèi)都需要注意。正例:publicclassTimerTaskThreadextendsThreadpublicTimerTaskThread(){super.setName("TimerTaskThread");...}}【強(qiáng)制】線(xiàn)程資源必須通過(guò)線(xiàn)程池提供,不允許在應(yīng)用中自行顯式創(chuàng)建線(xiàn)程。者“過(guò)度切換”的問(wèn)題。ExecutorsThreadPoolExecutor說(shuō)明:ExecutorsFixedThreadPoolSingleThreadPool:允許的請(qǐng)求隊(duì)列長(zhǎng)度為Integer.MAX_VALUE,可能會(huì)堆積大量的請(qǐng)求,從而導(dǎo)致OOM。CachedThreadPoolScheduledThreadPool:允許的創(chuàng)建線(xiàn)程數(shù)量為Integer.MAX_VALUE,可能會(huì)創(chuàng)建大量的線(xiàn)程,從而導(dǎo)致OOM。【強(qiáng)制】SimpleDateFormatstaticstaticDateUtils正例:注意線(xiàn)程安全,使用DateUtils。亦推薦如下處理:privatestaticfinalThreadLocal<DateFormat>df=newThreadLocal<DateFormat>(){@OverrideprotectedDateFormatinitialValue(){returnnewSimpleDateFormat("yyyy-MM-dd");}};說(shuō)明:JDK8InstantDate,LocalDateTimeCalendar,DateTimeFormatterSimpleDateFormat,官方給出的解釋?zhuān)簊implebeautifulstrongimmutablethread-safe。;鎖區(qū)塊,就不要鎖整個(gè)方法體;能用對(duì)象鎖,就不要用類(lèi)鎖。說(shuō)明:盡可能使加鎖的代碼塊工作量盡可能的小,避免在鎖代碼塊中調(diào)用RPC方法。成死鎖。ABCA、B、Cversion作為更新依據(jù)。3次?!緩?qiáng)制】多線(xiàn)程并行處理定時(shí)任務(wù)時(shí),TimerTimeTaskScheduledExecutorServiceCountDownLatchcountDowncatchcountDown方法被執(zhí)行到,避免主線(xiàn)程無(wú)法執(zhí)行await說(shuō)明:try-catch到。Random實(shí)例被多線(xiàn)程使用,雖然共享該實(shí)例是線(xiàn)程安全的,但會(huì)因競(jìng)爭(zhēng)同一seed導(dǎo)致的性能下降。說(shuō)明:Randomjava.util.Random的實(shí)例或者M(jìn)ath.random()的方式。正例:JDK7APIThreadLocalRandom,而在JDK7【推薦】在并發(fā)場(chǎng)景下,通過(guò)雙重檢查鎖(double-checkedlocking)The"Double-CheckedLockingisBrokenDeclaration),推薦解決方案中較為簡(jiǎn)單一種(JDK5),將目標(biāo)屬性聲明為volatile。反例:classLazyInitDemo{privateHelperhelper=publicHelpergetHelper(){if(helper==null)synchronized(this)if(helper==null)helper=newHelper();}returnhelper;}//othermethodsandfields...}【參考】volatilecount++countnewAtomicInteger();count.addAndGet(1JDK8LongAdderAtomicLong(減少樂(lè)觀鎖的重試次數(shù))。HashMapresizeCPU開(kāi)發(fā)過(guò)程中可以使用其它數(shù)據(jù)結(jié)構(gòu)或加鎖來(lái)規(guī)避此風(fēng)險(xiǎn)。【參考】ThreadLocal無(wú)法解決共享對(duì)象的更新問(wèn)題,ThreadLocalstatic(要是這個(gè)線(xiàn)程內(nèi)定義的)都可以操控這個(gè)變量。(七控制語(yǔ)句switchcasebreak/returncase;switchdefaultif/else/for/while/do(condition)statements;【強(qiáng)制】在高并發(fā)場(chǎng)景中,避免使用”等于”說(shuō)明:如果并發(fā)控制沒(méi)有處理好,容易產(chǎn)生等值判斷被“擊穿”的情況,使用大于或小于的區(qū)間判斷條件來(lái)代替。0成了負(fù)數(shù),這樣的話(huà),活動(dòng)無(wú)法終止。if-else,這種方式可以改寫(xiě)成:if(condition){...returnobj;}//else;說(shuō)明:if()...elseif()...else...3層。3if-else其中衛(wèi)語(yǔ)句示例如下:publicvoidtoday()if(isBusy()){System.out.println(“changetime.”);return;}if(isFree()){System.out.println(“gototravel.”);return;}System.out.println(“stayathometolearnAlibabaJavaCodingGuidelines.”);return;}【推薦】除常用方法(getXxx/isXxx)復(fù)雜邏輯判斷的結(jié)果賦值給一個(gè)有意義的布爾變量名,以提高可讀性。if樣的條件執(zhí)行什么樣的語(yǔ)句,那么,如果閱讀者分析邏輯表達(dá)式錯(cuò)誤呢?正例://偽代碼如下finalbooleanexisted=(file.open(fileName,"w")!=null)&&(...)||if(existed){...}反例:if((file.open(fileName,"w")!=null)&&(...)||(...)){...}try-catch(try-catch是否可以移至循環(huán)體外?!就扑]】避免采用取反邏輯運(yùn)算符。說(shuō)明:正例:if(x628)x628。反例:if(!(x628))來(lái)表達(dá)x628?!就扑]】接口入?yún)⒈Wo(hù),這種場(chǎng)景常見(jiàn)的是用作批量操作的接口?!緟⒖肌肯铝星樾?,需要進(jìn)行參數(shù)校驗(yàn):調(diào)用頻次低的方法。數(shù)錯(cuò)誤導(dǎo)致中間執(zhí)行回退,或者錯(cuò)誤,那得不償失。需要極高穩(wěn)定性和可用性的方法。RPC/API/HTTP接口。敏感權(quán)限入口?!緟⒖肌肯铝星樾?,不需要進(jìn)行參數(shù)校驗(yàn):極有可能被循環(huán)調(diào)用的方法。但在方法說(shuō)明里必須注明外部參數(shù)檢查要求。DAOServiceDAOprivate數(shù)已經(jīng)做過(guò)檢查或者肯定不會(huì)有問(wèn)題,此時(shí)可以不校驗(yàn)參數(shù)。(八注釋規(guī)約Javadoc/**內(nèi)容*///xxx方式。IDEJavadocIDE閱讀效率?!緩?qiáng)制】所有的抽象方法(包括接口中的方法)Javadoc注釋、除了返回值、參數(shù)、異常說(shuō)明外,還必須指出該方法做什么事情,實(shí)現(xiàn)什么功能。說(shuō)明:對(duì)子類(lèi)的實(shí)現(xiàn)要求,或者調(diào)用注意事項(xiàng),請(qǐng)一并說(shuō)明。【強(qiáng)制】所有的類(lèi)都必須添加創(chuàng)建者和創(chuàng)建日期?!緩?qiáng)制】方法內(nèi)部單行注釋?zhuān)诒蛔⑨屨Z(yǔ)句上方另起一行,使用//使用/**/注釋?zhuān)⒁馀c代碼對(duì)齊?!緩?qiáng)制】所有的枚舉類(lèi)型字段必須要有注釋?zhuān)f(shuō)明每個(gè)數(shù)據(jù)項(xiàng)的用途?!就扑]】與其“半吊子”英文原文即可。反例:“TCP連接超時(shí)解釋成“傳輸控制協(xié)議連接超時(shí)”,理解反而費(fèi)腦筋。等的修改。就失去了導(dǎo)航的意義?!緟⒖肌恐?jǐn)慎注釋掉代碼。在上方詳細(xì)說(shuō)明,而不是簡(jiǎn)單地注釋掉。如果無(wú)用,則刪除。說(shuō)明:代碼被注釋掉有兩種可能性:1)后續(xù)會(huì)恢復(fù)此段代碼邏輯。2)永久不用。前者如果沒(méi)有備注信息,難以知曉注釋動(dòng)機(jī)。后者建議直接刪掉(代碼倉(cāng)庫(kù)保存了歷史代碼)。;;的,使其能夠快速接替自己的工作。一個(gè)極端:過(guò)多過(guò)濫的注釋?zhuān)a的邏輯一旦修改,修改注釋是相當(dāng)大的負(fù)擔(dān)。反例://putelephantintoput(elephant,fridge);elephant義清晰的代碼不需要額外的注釋。經(jīng)常清理此類(lèi)標(biāo)記。線(xiàn)上故障有時(shí)候就是來(lái)源于這些標(biāo)記處的代碼。1)待辦事宜(TODO):(標(biāo)記人,標(biāo)記時(shí)間,[預(yù)計(jì)處理時(shí)間])Javadoc(Javadoc標(biāo)簽。2)錯(cuò)誤,不能工作(FIXME):([預(yù)計(jì)處理時(shí)間])FIXME標(biāo)記某代碼是錯(cuò)誤的,而且不能工作,需要及時(shí)糾正的情況。(九其它說(shuō)明:不要在方法體內(nèi)定義:PatternpatternPpile(“規(guī)則”);velocityPOJOPOJOgetXxx()boolean基本數(shù)據(jù)類(lèi)型變量(booleanis前綴)isXxx()方法。說(shuō)明:BooleangetXxx()【強(qiáng)制】后臺(tái)輸送給頁(yè)面的變量必須加$!{var}——中間的感嘆號(hào)。說(shuō)明:varnull或者不存在,那么${var}Math.randomdouble0≤x<1(能夠取到零值,注意除零異常)x10RandomnextIntnextLong方法。System.currentTimeMillis而不是newDate().getTime();說(shuō)明:System.nanoTime()JDK8Instant類(lèi)。【推薦】不要在視圖模板中加入任何復(fù)雜的邏輯。說(shuō)明:根據(jù)MVC理論,視圖的職責(zé)是展示,不要搶模型和控制器的活。【推薦】任何數(shù)據(jù)結(jié)構(gòu)的構(gòu)造或初始化,都應(yīng)指定大小,避免數(shù)據(jù)結(jié)構(gòu)無(wú)限增長(zhǎng)吃光內(nèi)存。【推薦】及時(shí)清理不再使用的代碼段或配置信息。說(shuō)明:對(duì)于垃圾代碼或過(guò)時(shí)配置,堅(jiān)決清理干凈,避免程序過(guò)度臃腫,代碼冗余。個(gè)斜杠(///)來(lái)說(shuō)明注釋掉代碼的理由。二、異常日志(一異常處理【強(qiáng)制】JavaRuntimeExceptionNullPointerException,IndexOutOfBoundsException等等。說(shuō)明:catchNumberFormatException來(lái)實(shí)現(xiàn)。正例:if(obj!=null){...}反例:try{obj.method();}catch(NullPointerExceptione){…}【強(qiáng)制】異常不要用來(lái)做流程控制,條件控制。說(shuō)明:異常設(shè)計(jì)的初衷是解決程序運(yùn)行中的各種意外情況,且異常的處理效率比條件判斷方式要低很多?!緩?qiáng)制】catch時(shí)請(qǐng)分清穩(wěn)定代碼和非穩(wěn)定代碼,穩(wěn)定代碼指的是無(wú)論如何不會(huì)出錯(cuò)的代碼。catch于定位問(wèn)題,這是一種不負(fù)責(zé)任的表現(xiàn)。簡(jiǎn)單,在程序上作出分門(mén)別類(lèi)的判斷,并提示給用戶(hù)。內(nèi)容。try滾事務(wù)?!緩?qiáng)制】finallytry-catch。說(shuō)明:JDK7try-with-resources方式。finallyreturn。說(shuō)明:finallyreturntryreturn說(shuō)明:如果預(yù)期對(duì)方拋的是繡球,實(shí)際接到的是鉛球,就會(huì)產(chǎn)生意外情況?!就扑]】方法的nullnull值。本手冊(cè)明確NPE者來(lái)說(shuō),也并非高枕無(wú)憂(yōu),必須考慮到遠(yuǎn)程調(diào)用失敗、序列化失敗、運(yùn)行時(shí)異常等場(chǎng)景返回null的情況。NPENPE產(chǎn)生的場(chǎng)景:返回類(lèi)型為基本數(shù)據(jù)類(lèi)型,returnNPE反例:publicintf()returnInteger對(duì)象},如果為nullNPE。null。isNotEmptynull。NPE。SessionNPE檢查,避免空指針。obj.getA().getB().getC();NPE。正例:JDK8OptionalNPE問(wèn)題。unchecked/checkednewRuntimeException(),Exception/ServiceException等。http/api“錯(cuò)誤碼”;而應(yīng)用內(nèi)部推薦異常拋出;RPCResult方式isSuccess()、“錯(cuò)誤碼”、“錯(cuò)誤簡(jiǎn)短信息”。說(shuō)明:RPCResult使用拋異常返回方式,調(diào)用方如果沒(méi)有捕獲到就會(huì)產(chǎn)生運(yùn)行時(shí)錯(cuò)誤。newerrormessage的性能損耗也是問(wèn)題。【參考】避免出現(xiàn)重復(fù)的代碼(Don’tRepeatYourself)DRY原則。說(shuō)明:隨意復(fù)制和粘貼代碼,必然會(huì)導(dǎo)致代碼的重復(fù),在以后需要修改時(shí),需要修改所有的副本,容易遺漏。必要時(shí)抽取共性方法,或者抽象公共類(lèi),甚至是組件化。publicprivatebooleancheckParam(DTOdto){...}(二日志規(guī)約(Log4jLogback)APIimportorg.slf4j.Logger;importorg.slf4j.LoggerFactory;privatestaticfinalLoggerlogger=LoggerFactory.getLogger(Abc.class);15天,因?yàn)橛行┊惓>邆湟浴爸堋睘轭l次發(fā)生的特點(diǎn)?!緩?qiáng)制】應(yīng)用中的擴(kuò)展日志(如打點(diǎn)、臨時(shí)監(jiān)控、訪(fǎng)問(wèn)日志等)命名方式:appName_logType_logName.log。logType:stats/monitor/access;logName:正例:mppservermppserver_monitor_timeZoneConvert.log說(shuō)明:推薦對(duì)日志進(jìn)行分類(lèi),如將錯(cuò)誤日志和業(yè)務(wù)日志分開(kāi)存放,便于開(kāi)發(fā)人員查看,也便于通過(guò)日志對(duì)系統(tǒng)進(jìn)行及時(shí)監(jiān)控。trace/debug/info說(shuō)明:logger.debug("Processingtradewithididandsymbolsymbol);wansmoltoString()(條件)if(logger.isDebugEnabled()){logger.debug("Processingtradewithid:"+id+"andsymbol:"+symbol);}正例:(占位符)logger.debug("Processingtradewithid:{}andsymbol:{}",id,symbol);log4j.xmladditivity=false。正例:<loggername="com.taobao.dubbo.config"additivity="false">throws往上拋出。正例:logger.error(各類(lèi)參數(shù)或者對(duì)象toString()+"_"+e.getMessage(),e);debug日志;info;warn撐爆,并記得及時(shí)刪除這些觀察日志。說(shuō)明:大量地輸出無(wú)效日志,不利于系統(tǒng)性能提升,也不利于快速定位錯(cuò)誤點(diǎn)。記錄日志時(shí)請(qǐng)思考:這些日志真的有人看嗎?看到這條日志你能做什么?能不能給問(wèn)題排查帶來(lái)好處?warnerror說(shuō)明:注意日志輸出的級(jí)別,error級(jí)別只記錄系統(tǒng)邏輯出錯(cuò)、異常或者重要的錯(cuò)誤信息。使用全英文來(lái)注釋和描述日志錯(cuò)誤信息。三、單元測(cè)試AIR原則。說(shuō)明:?jiǎn)卧獪y(cè)試在線(xiàn)上運(yùn)行時(shí),感覺(jué)像空氣(AIR)一樣并不存在,但在測(cè)試質(zhì)量的保障上,卻是非常關(guān)鍵的。好的單元測(cè)試宏觀上來(lái)說(shuō),具有自動(dòng)化、獨(dú)立性、可重復(fù)執(zhí)行的特點(diǎn)。A:Automatic()I:Independent()R:Repeatable()System.outassert決不能互相調(diào)用,也不能依賴(lài)執(zhí)行的先后次序。反例:method2method1method2的輸入?!緩?qiáng)制】單元測(cè)試是可以重復(fù)執(zhí)行的,不能受到外界環(huán)境的影響。說(shuō)明:checkin果單測(cè)對(duì)外部環(huán)境(網(wǎng)絡(luò)、服務(wù)、中間件等)有依賴(lài),容易導(dǎo)致持續(xù)集成機(jī)制的不可用。SUTspringDI(內(nèi)存)Mock實(shí)現(xiàn)。別,一般是方法級(jí)別。說(shuō)明:只有測(cè)試粒度小才能在出錯(cuò)時(shí)盡快定位到出錯(cuò)位置。單測(cè)不負(fù)責(zé)檢查跨類(lèi)或者跨系統(tǒng)的交互邏輯,那是集成測(cè)試的領(lǐng)域?!緩?qiáng)制】核心業(yè)務(wù)、核心應(yīng)用、核心模塊的增量代碼確保單元測(cè)試通過(guò)。說(shuō)明:新增代碼及時(shí)補(bǔ)充單元測(cè)試,如果新增代碼影響了原有單元測(cè)試,請(qǐng)及時(shí)修正。srcts/aa100%DAOManagerServiceBCDEB:BorderC:CorrectD:DesignEEror(到預(yù)期的結(jié)果?;蛘咧苯硬僮鲾?shù)據(jù)庫(kù)把數(shù)據(jù)插入進(jìn)去,請(qǐng)使用程序插入或者導(dǎo)入數(shù)據(jù)的方式來(lái)準(zhǔn)備數(shù)據(jù)。反例:刪除某一行數(shù)據(jù)的單元測(cè)試,在數(shù)據(jù)庫(kù)中,先直接手動(dòng)增加一行作為刪除目標(biāo),但是這一行新增數(shù)據(jù)并不符合業(yè)務(wù)插入規(guī)則,導(dǎo)致測(cè)試結(jié)果異常。對(duì)單元測(cè)試產(chǎn)生的數(shù)據(jù)有明確的前后綴標(biāo)識(shí)。正例:RDCRDC_UNIT_TEST_書(shū)寫(xiě)不規(guī)范測(cè)試代碼。覆蓋所有測(cè)試用例。目提測(cè)前完成單元測(cè)試?!緟⒖肌繛榱烁奖愕剡M(jìn)行單元測(cè)試,業(yè)務(wù)代碼應(yīng)避免以下情況:構(gòu)造方法中做的事情過(guò)多。存在過(guò)多的全局變量和靜態(tài)方法。存在過(guò)多的外部依賴(lài)。存在過(guò)多的條件語(yǔ)句。說(shuō)明:多層條件語(yǔ)句建議使用衛(wèi)語(yǔ)句、策略模式、狀態(tài)模式等方式重構(gòu)。【參考】不要對(duì)單元測(cè)試存在如下誤解:那是測(cè)試同學(xué)干的事情。本文是開(kāi)發(fā)手冊(cè),凡是本文內(nèi)容都是與開(kāi)發(fā)同學(xué)強(qiáng)相關(guān)的。單元測(cè)試代碼是多余的。系統(tǒng)的整體功能與各單元部件的測(cè)試正常與否是強(qiáng)相關(guān)的。單元測(cè)試代碼不需要維護(hù)。一年半載后,那么單元測(cè)試幾乎處于廢棄狀態(tài)。單元測(cè)試與線(xiàn)上故障沒(méi)有辯證關(guān)系。好的單元測(cè)試能夠最大限度地規(guī)避線(xiàn)上故障。四、安全規(guī)約【強(qiáng)制】隸屬于用戶(hù)個(gè)人的頁(yè)面或者功能必須進(jìn)行權(quán)限控制校驗(yàn)。說(shuō)明:防止沒(méi)有做水平權(quán)限校驗(yàn)就可隨意訪(fǎng)問(wèn)、修改、刪除別人的數(shù)據(jù),比如查看他人的私信內(nèi)容、修改他人的訂單?!緩?qiáng)制】用戶(hù)敏感數(shù)據(jù)禁止直接展示,必須對(duì)展示數(shù)據(jù)進(jìn)行脫敏。說(shuō)明:中國(guó)大陸個(gè)人手機(jī)號(hào)碼顯示為:158****91194位,防止隱私泄露。SQLMETADATASQL注入,SQL說(shuō)明:忽略參數(shù)校驗(yàn)可能導(dǎo)致:pagesizeorderby任意重定向SQL注入反序列化注入ReDoS說(shuō)明:Java代碼用正則來(lái)驗(yàn)證客戶(hù)端的輸入,有些正則寫(xiě)法驗(yàn)證普通用戶(hù)輸入沒(méi)有問(wèn)題,但是如果攻擊人員使用的是特殊構(gòu)造的字符串來(lái)驗(yàn)證,有可能導(dǎo)致死循環(huán)的結(jié)果。HTML頁(yè)面輸出未經(jīng)安全過(guò)濾或未正確轉(zhuǎn)義的用戶(hù)數(shù)據(jù)?!緩?qiáng)制】表單、AJAXCSRF說(shuō)明:CSRF(Cross-siterequestforgery)跨站請(qǐng)求偽造是一類(lèi)常見(jiàn)編程漏洞。對(duì)于存在CSRF漏洞的應(yīng)用/URL不知情的情況下對(duì)數(shù)據(jù)庫(kù)中用戶(hù)參數(shù)進(jìn)行相應(yīng)修改。制,如數(shù)量限制、疲勞度控制、驗(yàn)證碼校驗(yàn),避免被濫刷而導(dǎo)致資損。說(shuō)明:如注冊(cè)時(shí)發(fā)送驗(yàn)證碼到手機(jī),如果沒(méi)有限制次數(shù)和頻率,那么可以利用此功能騷擾到其它用戶(hù),并造成短信平臺(tái)資源浪費(fèi)。濾等風(fēng)控策略。五、MySQL數(shù)據(jù)庫(kù)(一建表規(guī)約is_xxxunsignedtinyint(1表示是,0表示否。說(shuō)明:任何字段如果為非負(fù)數(shù),必須是unsigned。is<resultMap>設(shè)置is_xxxXxxtinyintis_xxx的命名方式是為了明確其取值含義與取值范圍。正例:表達(dá)邏輯刪除的字段名is_deleted,1表示刪除,0表示未刪除。,WindowsLinux正例:aliyun_admin,rdc_config,level3_name反例:AliyunAdmin,rdcConfig,level_3_name【強(qiáng)制】表名不使用復(fù)數(shù)名詞。說(shuō)明:DO形式,符合表達(dá)習(xí)慣。desc、rangematch、delayedMySQL官方保留字。pk_uk_字段名;idx_字段名。說(shuō)明:pk_primarykey;uk_uniquekey;idx_index的簡(jiǎn)稱(chēng)。decimalfloatdouble。說(shuō)明:floatdoubledecimalchar【強(qiáng)制】varchar5000text【強(qiáng)制】表必備三字段:idgmt_creategmt_modified。說(shuō)明:idbigintunsigned1。gmt_create,gmt_modifieddatetime【推薦】表的命名最好是加上“業(yè)務(wù)名稱(chēng)_表的作用”。正例:alipay_task/force_project/trade_config【推薦】庫(kù)名與應(yīng)用名稱(chēng)盡量一致?!就扑]】如果修改字段含義或?qū)ψ侄伪硎镜臓顟B(tài)追加時(shí),需要及時(shí)更新字段注釋?!就扑]】字段允許適當(dāng)冗余,以提高查詢(xún)性能,但必須考慮數(shù)據(jù)一致。冗余字段應(yīng)遵循:不是頻繁修改的字段。varchartext字段。正例:商品類(lèi)目名稱(chēng)使用頻率高,字段長(zhǎng)度短,名稱(chēng)基本一成不變,可在相關(guān)聯(lián)的表中冗余存儲(chǔ)類(lèi)目名稱(chēng),避免關(guān)聯(lián)查詢(xún)。5002GB說(shuō)明:如果預(yù)計(jì)三年后的數(shù)據(jù)量根本達(dá)不到這個(gè)級(jí)別,請(qǐng)不要在創(chuàng)建表時(shí)就分庫(kù)分表。索速度。正例:如下表,其中無(wú)符號(hào)值可以避免誤存負(fù)數(shù),且擴(kuò)大了表示范圍。對(duì)象年齡區(qū)間類(lèi)型字節(jié)表示范圍人150tinyintunsigned10255龜數(shù)百歲smallintunsigned2065535恐龍化石數(shù)千萬(wàn)年intunsigned4042.9億太陽(yáng)50億年bigintunsigned801019次方(二索引規(guī)約【強(qiáng)制】業(yè)務(wù)上具有唯一特性的字段,即使是多個(gè)字段的組合,也必須建成唯一索引。說(shuō)明:insert然有臟數(shù)據(jù)產(chǎn)生。joinjoin說(shuō)明:join也要注意表索引、SQL性能。varchar實(shí)際文本區(qū)分度決定索引長(zhǎng)度即可。2090%count(distinctleft(列名))/count(*)【強(qiáng)制】頁(yè)面搜索嚴(yán)禁左模糊或者全模糊,如果需要請(qǐng)走搜索引擎來(lái)解決。B-Tree引。orderby有序性。orderbyfile_sort正例:wherea=?andborderbyc索引:a_b_c反例:索引中有范圍查找,那么索引有序性無(wú)法利用,如:WHEREa>10ORDERBYb;索引a_b無(wú)法排序。【推薦】利用覆蓋索引來(lái)進(jìn)行查詢(xún)操作,避免回表。說(shuō)明:1111一下就好,這個(gè)目錄就是起到覆蓋索引的作用。explain的結(jié)果,extrausingindex?!就扑]】利用延遲關(guān)聯(lián)或者子查詢(xún)優(yōu)化超多分頁(yè)場(chǎng)景。說(shuō)明:MySQLoffsetoffset+NoffsetoffsetSQL改寫(xiě)。正例:idSELECTa.*FROM1a,(selectidfrom1where條件LIMIT100000,20bwherea.id=b.id【推薦】SQLrangerefconsts最好。說(shuō)明:consts(ref(normalindex)。range反例:explaintype=indexindex級(jí)range【推薦】建組合索引的時(shí)候,區(qū)分度最高的在最左邊。正例:whereaandb,如果aidx_a索引即可。說(shuō)明:存在非等號(hào)和等號(hào)混合時(shí),在建索引時(shí),請(qǐng)把等號(hào)條件的列前置。如:wherecdcdidx_d_c?!就扑]】防止因字段類(lèi)型不同造成的隱式轉(zhuǎn)換,導(dǎo)致索引失效?!緟⒖肌縿?chuàng)建索引時(shí)避免有如下極端誤解:寧濫勿缺。認(rèn)為一個(gè)查詢(xún)就需要建一個(gè)索引。寧缺勿濫。認(rèn)為索引會(huì)消耗空間、嚴(yán)重拖慢更新和新增速度。抵制惟一索引。認(rèn)為業(yè)務(wù)的惟一性一律需要在應(yīng)用層通過(guò)“先查后插”方式解決。(三SQL語(yǔ)句count(列名)count(常量)SQL92NULLNULL無(wú)關(guān)。說(shuō)明:count(*)NULLcount(列名)NULL值的行?!緩?qiáng)制】count(distinctcolNULLcount(distinctcol1,col2NULL0。NULLsum(col)sum()NPE問(wèn)題。正例:sumNPESELECTIF(ISNULL(SUM(g)),0,SUM(g))FROMtable;ISNULL()NULL說(shuō)明:NULLNULL。NULL<>NULLNULLfalse。NULL=NULLNULLtrue。NULL<>1NULLtrue。count0【強(qiáng)制】不得使用外鍵與級(jí)聯(lián),一切外鍵概念必須在應(yīng)用層解決。student_idstudent_idstudent_idstudent_id;【強(qiáng)制】禁止使用存儲(chǔ)過(guò)程,存儲(chǔ)過(guò)程難以調(diào)試和擴(kuò)展,更沒(méi)有移植性。【強(qiáng)制】數(shù)據(jù)訂正(特別是刪除、修改記錄操作)select無(wú)誤才能執(zhí)行更新語(yǔ)句。inin1000個(gè)之內(nèi)。utf-8說(shuō)明:SELECTLENGTH("輕松工作");返回為12SELECTCHARACTER_LENGTH("輕松工作");返回為4utf8mb4utf-8【參考】TRUNCATETABLEDELETETRUNCATE無(wú)事務(wù)且不觸發(fā)trigger,有可能造成事故,故不建議在開(kāi)發(fā)代碼中使用此語(yǔ)句。說(shuō)明:TRUNCATETABLE在功能上與不帶WHERE子句的DELETE語(yǔ)句相同。(四ORM映射*作為查詢(xún)的字段列表,需要哪些字段必須明確寫(xiě)明。2)resultMaptext類(lèi)型的字段。POJOisis_resultMap說(shuō)明:POJO類(lèi)以及數(shù)據(jù)庫(kù)字段定義規(guī)定,在<resultMap>中MyBatisGenerator生成的代碼中,需要進(jìn)行對(duì)應(yīng)的修改。resultClass要定義;POJO類(lèi)與之對(duì)應(yīng)。說(shuō)明:DOsql.xml不要使用${}SQL【強(qiáng)制】iBATISqueryForList(StringstatementName,intstart,intsize)薦使用。其實(shí)現(xiàn)方式是在數(shù)據(jù)庫(kù)取到statementName對(duì)應(yīng)的SQLsubListstart,size正例:Map<String,Object>map=newHashMap<>();map.put("start",start);map.put("size",size);HashMapHashtable說(shuō)明:resultClass=”Hashtable”,會(huì)置入字段名和屬性值,但是值的類(lèi)型不可控。gmt_modified字段值為當(dāng)前時(shí)間。POJOupdatetablesetc1=value1,c2=value2,c3=value3;SQL時(shí),不要更新無(wú)改動(dòng)的字段,一是易出錯(cuò);二是效率低;binlog存儲(chǔ)?!緟⒖肌緻TransactionalQPS,另外使用事務(wù)的地方需要考慮各方面的回滾方案,包括緩存回滾、搜索引擎回滾、消息補(bǔ)償、統(tǒng)計(jì)修正等。<isEqual>compareValuenull時(shí)執(zhí)行;<isNotNull>null值時(shí)執(zhí)行。六、工程結(jié)構(gòu)(一應(yīng)用分層【推薦】圖中默認(rèn)上層依賴(lài)于下層,箭頭關(guān)系表示可直接依賴(lài),如:開(kāi)放接口層可以依賴(lài)于WebService開(kāi)放接口層ServiceRPC接口Webhttp網(wǎng)關(guān)安全控制、流量控制等。終端顯示層velocity渲染,JS渲染,JSP渲染,移動(dòng)端展示等。Web層Service層Manager層對(duì)第三方平臺(tái)封裝的層,預(yù)處理返回結(jié)果及轉(zhuǎn)化異常信息;Service;DAODAODAO層MySQLOracle、Hbase外部接口或第三方平臺(tái)RPCHTTP接口?!緟⒖肌浚ǚ謱赢惓L幚硪?guī)約)DAOcatchcatch(Exceptione)thrownewDAOException(e)Manager/ServiceServiceManagerServiceServiceWeb和錯(cuò)誤信息方式返回。【參考】分層領(lǐng)域模型規(guī)約:DO(DataDAODTO(DataTransferObject)ServiceManager向外傳輸?shù)膶?duì)象。BO(BusinessObject)ServiceWebServiceVO(ViewObject)WebQuery2Map類(lèi)來(lái)傳輸。(二二方庫(kù)依賴(lài)GAVGroupID格式:com.{公司/BU}.[.]4級(jí)。{公司/BU}albbatoaomal/lepesU一級(jí)或com.alibaba.dubbo.registerArtifactID格式:產(chǎn)品線(xiàn)名-模塊名。語(yǔ)義不重復(fù)不遺漏,先到中央倉(cāng)庫(kù)去查證一下。正例:dubbo-client/fastjson-api/jstorm-toolVersion【強(qiáng)制】二方庫(kù)版本號(hào)命名方式:主版本號(hào).次版本號(hào).修訂號(hào)主版本號(hào)API次版本號(hào)API不兼容修改。修訂號(hào)BUG0.0.1合理的版本號(hào):1.3.4或1.4.0或2.0.0SNAPSHOT版本安全包除外)。SNAPSHOTjardependency:resolvedependency:tree<excludes>jar包。POJO對(duì)象?!緩?qiáng)制】依賴(lài)于一個(gè)二方庫(kù)群時(shí),必須定義一個(gè)統(tǒng)一的版本變量,避免版本號(hào)不一致。說(shuō)明:依賴(lài)springframework-core,-context,-beans,它們都是同一個(gè)版本,可以定義一個(gè)變量來(lái)保存版本:${spring.version},定義依賴(lài)的時(shí)候,引用該版本。pomGroupIdArtifactId,但是不同的Version。libpom<dependencies><dependencyManagement>語(yǔ)句塊中。scopepom<dependencies>pom的<dependencies>里的依賴(lài)都會(huì)自動(dòng)引入,并默認(rèn)被所有的子項(xiàng)目繼承?!就扑]】二方庫(kù)不要有配置項(xiàng),最低限度不要再增加配置項(xiàng)?!緟⒖肌繛楸苊鈶?yīng)用二方庫(kù)的依賴(lài)沖突問(wèn)題,二方庫(kù)發(fā)布者應(yīng)當(dāng)遵循以下原則:精簡(jiǎn)可控原則APIServiceAPIprovidedlog穩(wěn)定可追溯原則方便查到。除非用戶(hù)主動(dòng)升級(jí)版本,否則公共二方庫(kù)的行為不應(yīng)該發(fā)生變化。(三服務(wù)器TCPtime_wait超時(shí)時(shí)間。說(shuō)明:240time_waittime_wait正例:linux/etc/sysctl.conf(
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 心靈培育幼兒園教學(xué)工作計(jì)劃文檔
- 規(guī)范化證券市場(chǎng)對(duì)2025年考試的影響試題及答案
- 行政管理師證書(shū)考試內(nèi)部控制實(shí)踐試題及答案
- 軌道板預(yù)制施工作業(yè)指導(dǎo)書(shū)
- 2025年注會(huì)考試趨勢(shì)分析試題及答案
- 傳染病的微生物防控措施試題及答案
- 廣場(chǎng)幕墻結(jié)構(gòu)計(jì)算書(shū)
- 試題及答案:微生物學(xué)的多學(xué)科融合
- 要求內(nèi)容全面的國(guó)際金融理財(cái)師考試計(jì)劃試題及答案
- 省級(jí)課題申報(bào)書(shū)模板
- 天耀中華合唱簡(jiǎn)譜大劇院版
- 強(qiáng)制執(zhí)行股東分紅申請(qǐng)書(shū)
- 酒店前廳部溝通技巧
- 車(chē)隊(duì)事故分析報(bào)告總結(jié)
- 藥品追溯系統(tǒng)培訓(xùn)課件模板
- 工業(yè)園區(qū)的消防安全管理課件
- 2024信息安全意識(shí)培訓(xùn)ppt課件完整版含內(nèi)容
- 互聯(lián)網(wǎng)數(shù)據(jù)中心(IDC)業(yè)務(wù)介紹
- JGT366-2012 外墻保溫用錨栓
- 《界面圖標(biāo)設(shè)計(jì)》課件
- 法蘭快速接頭規(guī)格1
評(píng)論
0/150
提交評(píng)論