摘要:但,結(jié)果同樣重要,加油。。而且可明確提出錯(cuò)誤信息。業(yè)務(wù)異常的自定義封裝類實(shí)現(xiàn)和一樣,為了空間就不展示了。數(shù)據(jù)庫(kù)異常在看兩個(gè)類,驗(yàn)證信息異常。那就是字符串工具類。字符串處理及轉(zhuǎn)換工具類,。
PayMap
PayMap是一個(gè)使用Java語(yǔ)言集成三方支付的小Demo,現(xiàn)已集成支付寶(國(guó)內(nèi)、國(guó)際、移動(dòng)端、PC端)、微信、銀聯(lián)(ACP、UPOP)、光大(網(wǎng)關(guān)、網(wǎng)頁(yè))、郵政支付,采用的技術(shù)棧為:SpringMVC+Spring+MyBatis+Shiro+RabbitMQ+Redis。
特性支持前面提到的各種**支付
支付請(qǐng)求調(diào)用支持HTTP和異步MQ
控制層統(tǒng)一異常處理
LogBack日志記錄
Redis緩存機(jī)制
Shiro安全機(jī)制
MyBatis代碼自動(dòng)生成
HTTP請(qǐng)求日志記錄
RESTful APIs
說(shuō)明1、本文項(xiàng)目來(lái)自Martin404,自己只是臨摹大佬的項(xiàng)目。
2、重要的是學(xué)習(xí)過(guò)程,而不是結(jié)果。但,結(jié)果同樣重要,加油。gogogo。
3、框架搭建就略過(guò)了。配置文件太多。遇到的時(shí)候貼出來(lái)。也收藏起來(lái),留著備用。
4、Gist、Insight.io for GitHub必備吧,劃詞翻譯不懂的單詞劃一劃。
5、在IDEA中我會(huì)注重代碼規(guī)范,但是這里為了節(jié)約地方,能省的就省略了。還請(qǐng)諒解。
6、代碼提交到這里了GitHub。根據(jù)提交記錄找自己想要的類庫(kù)。
7、重要的在后面,一切都只只是剛剛開(kāi)始(希望不要被屏蔽)!!gogogo
1、核心包~common因?yàn)闆](méi)有文檔,只能根據(jù)自己之前的經(jīng)驗(yàn)。先把必備的配置文件,包弄好。項(xiàng)目跑不起來(lái),沒(méi)關(guān)系。重要的是學(xué)習(xí),先從核心包,common開(kāi)始學(xué)習(xí)。配置文件就不貼了。需要的可以到GitHub去找。
我們先整體看一下結(jié)構(gòu)
1、就先從異常開(kāi)始吧,首先是定義,BaseException。為什么要這么定義呢?不知道大家有沒(méi)有見(jiàn)過(guò)BaseDao、BaseAction。主要原因是為了方便擴(kuò)展,父類不能實(shí)現(xiàn)的,在子類中加強(qiáng)。
回過(guò)頭來(lái)我們?cè)诳聪抡w繼承關(guān)系圖,Throwable應(yīng)該還有個(gè)Error錯(cuò)誤。兩者的區(qū)別在于后者是不可恢復(fù)的。這里的是運(yùn)行時(shí)異常。 還有一種區(qū)分是受檢查和非檢查的。比如數(shù)據(jù)庫(kù)連接關(guān)閉就是受檢查異常,數(shù)組越界異常是非檢查的。還有try{}catch{}finally{}這里不展開(kāi)了。在Spring框架中可以受檢查的包裝成非受檢查的。而且可明確提出錯(cuò)誤信息。
public class BaseException extends RuntimeException { public BaseException(String message) { super(message,new Throwable(message)); } public BaseException(Throwable cause) { super(cause); } public BaseException(String message,Throwable cause) { super(message,cause); } }
2、接下來(lái)就是定義它的子類。
/** * Created by guo on 3/2/2018. * 系統(tǒng)類異常 */ public class SystemException extends BaseException { //實(shí)現(xiàn)和BaseException一樣,構(gòu)造方法名字換下。為了空間就不展示了。 } --------------------------------------------------------- /** * 業(yè)務(wù)異常的自定義封裝類 */ public class BusinessException extends BaseException { //實(shí)現(xiàn)和BaseException一樣,為了空間就不展示了。 } --------------------------------------------------------- /** * 數(shù)據(jù)庫(kù)異常 */ public class DBException extends BaseException { }
3、在看兩個(gè)類,驗(yàn)證信息異常。后者估計(jì)大家用得著。我不會(huì)告訴你們Gist了。什么?你不懂?快去GItHub看看。收藏代碼的好地方。
/** * 驗(yàn)證異常,用于封裝 */ public class ValidationError { private String objectName; private String fieldName; private String defaultMessage; // Constructor 、Setter 、Getter 、ToString 略。為了節(jié)約地方。 } ---------------------------------------------------------------- /** * Created by guo on 3/2/2018. * 異常返回碼 */ public enum ResultCode { /** * 成功. ErrorCode : 0 */ SUCCESS("0", "成功"), /** * 未知異常. ErrorCode : 01 */ UnknownException("01", "未知異常"), /** * 系統(tǒng)異常. ErrorCode : 02 */ SystemException("02", "系統(tǒng)異常"), /** * 業(yè)務(wù)錯(cuò)誤. ErrorCode : 03 */ BusinessException("03", "業(yè)務(wù)錯(cuò)誤"), /** * 提示級(jí)錯(cuò)誤. ErrorCode : 04 */ InfoException("04", "提示級(jí)錯(cuò)誤"), /** * 數(shù)據(jù)庫(kù)操作異常. ErrorCode : 020001 */ DBException("020001", "數(shù)據(jù)庫(kù)操作異常"), /** * 參數(shù)驗(yàn)證錯(cuò)誤. ErrorCode : 040001 */ ParamException("040001", "參數(shù)驗(yàn)證錯(cuò)誤"), SystemMaintainException("11", "系統(tǒng)正在維護(hù)"); private String _code; private String _msg; // Constructor、Getter略 public static ResultCode getByCode(String code) { for (ResultCode ec : ResultCode.values()) { if (ec.getCode().equals(code)) { return ec; } } return null; } }
4、接下來(lái)看一些默認(rèn)設(shè)置。
public class ActionConstants { /** * 默認(rèn)值 - 執(zhí)行時(shí)失敗時(shí)ReturnContext的ReturnMsg */ public static final String DEFAULT_FAILED_RETURNMSG = "執(zhí)行失敗"; /** * 默認(rèn)值key - 執(zhí)行成功時(shí)ReturnContext的Returning */ public static final String DEFAULT_SUCCESS_RETURNMSG ="執(zhí)行成功"; } ------------------------------------------------------------------------- /** * 從SpringApplicationContext中設(shè)置的系統(tǒng)參數(shù) */ public class SystemConfig { //系統(tǒng)默認(rèn)的游客用戶名 private static String guestUsername = ""; private SystemConfig() {} //注意這里被私有化了。 public static void setGuestUsername(String guestUsername) { SystemConfig.guestUsername = guestUsername; } } ------------------- -------注意bean------------------------------------${shiro.guest.username}
5、這個(gè)也很重要,局部刷新。首先看下實(shí)現(xiàn)了Serializable,為什么呢?因?yàn)樗诰W(wǎng)絡(luò)中傳輸,所以需要序列成二進(jìn)制格式的。還有當(dāng)我們需要網(wǎng)絡(luò)上的一個(gè)對(duì)象時(shí),可以進(jìn)行反序列化,在創(chuàng)建對(duì)象。或者想把內(nèi)存中的對(duì)象保存在數(shù)據(jù)庫(kù)中或者一個(gè)文件中。這里涉及ObjectOutputStream類的writeObject()方法、ObjectInputStream類的writeObject()方法。還有需要serialvUID,但不是必須的,最好加上。
/** * AJAX調(diào)用返回對(duì)象 */ public class AjaxResult implements Serializable { //請(qǐng)求結(jié)果是否為成功 private String ErrorCode = ResultCode.SUCCESS.getCode(); //請(qǐng)求返回信息 private String Message = ActionConstants.DEFAULT_SUCCESS_RETURNMSG; //請(qǐng)求結(jié)果 private Object Date = null; //Setter、Getter、toString.... /** * 獲取正確結(jié)果模板 * //標(biāo)準(zhǔn)是這樣寫的 * @param message 請(qǐng)求返回信息 * @param obj 請(qǐng)求結(jié)果 * @return AjaxResult */ public static AjaxResult getOK(String message,Object obj) { AjaxResult result = new AjaxResult(); result.setMessage(message); result.setDate(obj); return result; } /** * 獲取正確結(jié)果模板 */ public static AjaxResult getOK(Object obj) { AjaxResult result = new AjaxResult(); result.setMessage(ActionConstants.DEFAULT_SUCCESS_RETURNMSG); result.setDate(obj); return result; } /** * 獲取正確結(jié)果模板 */ public static AjaxResult getOK() { return getOK(ActionConstants.DEFAULT_SUCCESS_RETURNMSG,null); } /** * 獲取錯(cuò)誤結(jié)果模板 */ public static AjaxResult getError(ResultCode errorCode,String message,Object obj) { AjaxResult result = new AjaxResult(); result.setErrorCode(errorCode.getCode()); result.setMessage(message); result.setDate(obj); return result; } /** * 獲取錯(cuò)誤結(jié)果模板 * * @return AjaxResult */ public static final AjaxResult getError(ResultCode resultCode) { AjaxResult result = new AjaxResult(); return getError(resultCode,resultCode.getMsg(),null); } }2、核心包~util
1、接下來(lái)我們看工具類,這個(gè)幾個(gè)非常有用。自己也收集了一些。先看日期吧,會(huì)拿出部分作為介紹。
(1)、首先我們看到DateUtils繼承了ProperyEditorSuppert。為什么要這么做?看名字叫屬性編輯支持。在Spring中我們可以使用屬性編輯器來(lái)將特定的字符串轉(zhuǎn)為對(duì)象:String-->Object.在JDK中用于將XML文件中字符串轉(zhuǎn)為特定的類型,同時(shí)提供了一個(gè)實(shí)現(xiàn)類,是他是他就是PropertEditorSuppert。在Spring注入式,遇到類型不一致,則回去調(diào)用相應(yīng)的屬性編輯器進(jìn)行轉(zhuǎn)換。如:setAsText(String str)、setValue().不然getValue()方法拿不到處理后的對(duì)象。
import org.joda.time.format.DateTimeFormat; //注意包名,大佬的付出 public class DateUtils extends PropertyEditorSupport { public static final DateTimeFormatter standard = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss"); public static final DateTimeFormatter yy_MM_dd = DateTimeFormat.forPattern("yyyy-MM-dd"); public static final DateTimeFormatter date_sdf_wz = DateTimeFormat.forPattern("yyyy年MM月dd日"); //還有需要轉(zhuǎn)換格式 ...................................常用的,其實(shí)有很多............................................. /** * 字符串轉(zhuǎn)為日期 */ public static Date str2Date(String str,DateTimeFormatter sdf) { if (str == null || "".equals(str)) { return null; } DateTime date; try { date = sdf.parseDateTime(str); return date.toDate(); } catch (IllegalArgumentException e) { String errorMessage = "yyyy-MM-dd HH:mm:ss"; if (sdf.equals(yy_MM_dd)) { errorMessage = "yyyy-MM-dd"; } throw new BusinessException("輸入的日期格式有誤,因?yàn)?" + errorMessage + ""格式"); //異常直接給自定義的。 } } /** * 指定日期的默認(rèn)顯示,具體格式為:年-月-日 * @param date 指定的日期 * @return 指定日期按“年-月-日”顯示 */ public static String formatDate(Date date) { return standard.print(date.getTime()); } /** * 返回UNIX時(shí)間戳-1970年至今的秒數(shù)(注意單位-不是毫秒) * @param str the str * @param format the format * @return the long */ public static long getUnixTimestamp(String str, DateTimeFormatter format) { DateTime dateTime = format.parseDateTime(str); return dateTime.getMillis() / 1000; } /** * 獲取給定日期之間的日期 */ public static ListgetRangeDates(Long startTime, Long endTime) { List dateList = new ArrayList<>(); DateTime startDt = new DateTime(startTime * 1000); DateTime endDt = new DateTime(endTime * 1000); endDt = endDt.withTimeAtStartOfDay(); //因?yàn)椴樵兘Y(jié)束時(shí)間不包含邊界,特殊處理一下 if (endTime * 1000 == endDt.getMillis()) { endDt = endDt.minusDays(1); } dateList.add(getTime(startTime, date_sdf_wz)); while (endDt.isAfter(startDt)) { startDt = startDt.plusDays(1); dateList.add(getTime(startDt.getMillis() / 1000, date_sdf_wz)); } return dateList; } /** * 返回時(shí)間間隔天數(shù) */ public static int getDateDiff(Long beginTime, Long endTime) { DateTime dateTime1 = new DateTime(beginTime * 1000); DateTime dateTime2 = new DateTime(endTime * 1000); return Days.daysBetween(dateTime1, dateTime2).getDays(); } }
(2)接下來(lái)我們看下ID生產(chǎn)策略,注意靜態(tài)代碼塊,還有這里用到了重入鎖ReentrantLock(),對(duì)資源進(jìn)行加鎖,同一時(shí)刻只會(huì)有一個(gè)線程能夠占有鎖.當(dāng)前鎖被線程占有時(shí),其他線程會(huì)進(jìn)入掛起狀態(tài),直到該鎖被釋放,其他掛起的線程會(huì)被喚醒并開(kāi)始新的競(jìng)爭(zhēng).,AtomicInteger并發(fā)條件下原子自增運(yùn)算。保證一致性。友情提示
/** * ID生成策略 */ public class IDGenerator { private static final DateFormat format = new SimpleDateFormat("yyyyMMddHHmmssSSS"); private static final Random r = new Random(); private static char[] A2Z = null; static { int j = 0; A2Z = new char[26]; for (int i = 65; i < 91; i++) { A2Z[j] = (char)i; j++; } } public static String getTargetId() { char[] temp = new char[5]; for (int i = 0; i < 5; i++) { temp[i] = A2Z[r.nextInt(26)]; } String string = new String(temp); Integer max = 999999; Integer min = 10000; int s = r.nextInt(max) % (max - min + 1) + min; return string + s; } public static String getTranSid() { Lock lock = new ReentrantLock(); lock.lock(); String temp = null; AtomicInteger atomicInteger = new AtomicInteger(); try { String currDate = format.format(new Date()); Integer max = 999; Integer min = 100; int s = r.nextInt(max) % (max - min + 1) + min; temp = currDate + String.valueOf(s); } finally { lock.unlock(); } return temp; } public static String getIcbcTimeStamp() { DateFormat dateFormatStamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Lock lock = new ReentrantLock(); lock.lock(); String temp = null; AtomicInteger atomicInteger = new AtomicInteger(); try { String currDate = dateFormatStamp.format(new Date()); Integer max = 999999; Integer min = 100000; int s = r.nextInt(max) % (max - min + 1) + min; temp = currDate + "." + String.valueOf(s); } finally { lock.unlock(); } return temp; } }
(3)、看一個(gè)加載配置文件的工具類
需要注意的是這里同樣用到了靜態(tài)代碼塊,在啟動(dòng)的時(shí)候就加載。還有就是反射機(jī)制,在這里用的是類的加載器完成的。其他可以用getClass(),Claass.forName();
還有一點(diǎn)就是Properties類,繼承自Hashtable,實(shí)現(xiàn)Map接口,可以和IO對(duì)象組合使用,實(shí)現(xiàn)數(shù)據(jù)的持久存儲(chǔ)。存儲(chǔ)鍵值對(duì),根據(jù)key找Value。
/** * Properties文件加載工具 */ public class PropertiedsUtil { public static Properties properties = new Properties(); public static ListconfigFile = Arrays.asList( "server_config.properties", "sys_config.properties"); static { try { for (String fileName : configFile) { InputStream in = PropertiedsUtil.class.getClassLoader().getResourceAsStream(fileName); properties.load(in); } }catch (IOException e) { throw new BusinessException("讀取配置文件錯(cuò)誤"); } } public static String getValue(String key) { return properties.getProperty(key, ""); } }
(4)、SqlSessionFactoryBean工具類
在 MyBatis 中,使用 SqlSessionFactoryBuilder創(chuàng)建SqlSessionFactory ,進(jìn)而來(lái)創(chuàng)建 SqlSession。一旦你獲得一個(gè) session 之后,你可以使用它來(lái)執(zhí)行映射語(yǔ)句,提交或回滾連接,最后,當(dāng)不再需要它的時(shí)候, 你可以關(guān)閉 session。
/** * Created by guo on 3/2/2018. * SqlSession工廠bean */ public class SqlSessionFactoryBeanUtil extends SqlSessionFactoryBean { //這里使用了日志記錄,方便查看。 private static Logger logger = LoggerFactory.getLogger(SqlSessionFactoryBeanUtil.class); @Override protected SqlSessionFactory buildSqlSessionFactory() throws IOException { try { return super.buildSqlSessionFactory(); //調(diào)用父類 }catch (NestedIOException e) { logger.error("ex:{}",e.getMessage()); throw new NestedIOException("Faild to parse mapping resource: " + e); }finally { ErrorContext.instance().reset(); } } }
(5)、最重要的一般壓低出現(xiàn)。那就是字符串工具類。這個(gè)有些多,挑常用的羅列出來(lái)。
/** * Created by guo on 3/2/2018. * 字符串處理及轉(zhuǎn)換工具類 */ public class StringUtil { private static Pattern numericPattern = Pattern.compile("^[0-9-]+$"); private static Pattern numericStringPattern = Pattern.compile("^[0-9--]+$"); private static Pattern floatNumericPattern = Pattern.compile("^[0-9-.]+$"); private static Pattern abcPattern = Pattern.compile("^[a-z|A-Z]+$"); public static final String splitStrPattern = ",|,|;|;|、|.|。|-|_|(|)|[|]|{|}||/| | |""; private static Logger logger = LoggerFactory.getLogger(StringUtil.class); /** * 判斷是否數(shù)字表示 * @param src 源字符串 * @return 是否數(shù)字的標(biāo)志 */ public static boolean isNumeric(String src) { boolean return_value = false; if (src != null && src.length() > 0) { Matcher m = numericPattern.matcher(src); if (m.find()) { return_value = true; } } return return_value; } /** * 判斷是否純字母組合 * @param src 源字符串 * @return 是否純字母組合的標(biāo)志 */ public static boolean isABC(String src) { boolean return_value = false; if (src != null && src.length() > 0) { Matcher m = abcPattern.matcher(src); if (m.find()) { return_value = true; } } return return_value; } /** * 判斷是否浮點(diǎn)數(shù)字表示 */ public static boolean isFloatNumeric(String src) {} -------------------------------截取------------------------------------------------------------ /** * 把string array or list用給定的符號(hào)symbol連接成一個(gè)字符串 */ public static String joinString(List array, String symbol) { String result = ""; if (array != null) { for (int i = 0; i < array.size(); i++) { String temp = array.get(i).toString(); if (temp != null && temp.trim().length() > 0) result += (temp + symbol); } if (result.length() > 1) result = result.substring(0, result.length() - 1); } return result; } /** * 截取字符,不轉(zhuǎn)碼 */ public static String subStrNotEncode(String subject, int size) { if (subject.length() > size) { subject = subject.substring(0, size); } return subject; } /** * 取得字符串的實(shí)際長(zhǎng)度(考慮了漢字的情況) */ public static int getStringLen(String SrcStr) { int return_value = 0; if (SrcStr != null) { char[] theChars = SrcStr.toCharArray(); for (int i = 0; i < theChars.length; i++) { return_value += (theChars[i] <= 255) ? 1 : 2; } } return return_value; } ---------------------------------分割、替換和轉(zhuǎn)換------------------------------------------- /** * 根據(jù)指定的字符把源字符串分割成一個(gè)數(shù)組 */ public static ListparseString2ListByCustomerPattern(String pattern, String src) { if (src == null) return null; List list = new ArrayList (); String[] result = src.split(pattern); for (int i = 0; i < result.length; i++) { list.add(result[i]); } return list; } /** * 字符串替換 */ public static String stringReplace(String str, String sr, String sd) { String regEx = sr; Pattern p = Pattern.compile(regEx, Pattern.CASE_INSENSITIVE); Matcher m = p.matcher(str); str = m.replaceAll(sd); return str; } /** * 格式化一個(gè)float */ public static String formatFloat(float f, String format) { DecimalFormat df = new DecimalFormat(format); return df.format(f); } /** * 把 名=值 參數(shù)表轉(zhuǎn)換成字符串 (a=1,b=2 =>a=1&b=2) */ public static String linkedHashMapToString(LinkedHashMap map) { if (map != null && map.size() > 0) { String result = ""; Iterator it = map.keySet().iterator(); while (it.hasNext()) { String name = (String) it.next(); String value = (String) map.get(name); result += (result.equals("")) ? "" : "&"; result += String.format("%s=%s", name, value); } return result; } return null; } /** * 轉(zhuǎn)換編碼 */ public static String changCoding(String s, String fencode, String bencode) { String str; try { if (StringUtil.isNotEmpty(s)) { str = new String(s.getBytes(fencode), bencode); } else { str = ""; } return str; } catch (UnsupportedEncodingException e) { return s; } }
下面的是轉(zhuǎn)換,具體的用到了再說(shuō)。
/** * 將字符串轉(zhuǎn)換成十六進(jìn)制編碼 */ public static String toHexString(String str) throws UnsupportedEncodingException { // 根據(jù)默認(rèn)編碼獲取字節(jié)數(shù)組 String hexString = "0123456789ABCDEF"; byte[] bytes = str.getBytes("GB2312"); StringBuilder sb = new StringBuilder(bytes.length * 2); // 將字節(jié)數(shù)組中每個(gè)字節(jié)拆解成2位16進(jìn)制整數(shù) for (byte b : bytes) { sb.append(Integer.toHexString(b + 0x800).substring(1)); } return sb.toString(); } /** * unicode 轉(zhuǎn)字符串 */ public static String unicode2String(String unicode) { StringBuffer string = new StringBuffer(); String[] hex = unicode.split("u"); for (int i = 1; i < hex.length; i++) { // 轉(zhuǎn)換出每一個(gè)代碼點(diǎn) int data = Integer.parseInt(hex[i], 16); // 追加成string string.append((char) data); } return string.toString(); }
gogogo...
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/68641.html
摘要:重要的是學(xué)習(xí)過(guò)程,而不是結(jié)果。但,結(jié)果同樣重要,加油。。在這提一點(diǎn),由于網(wǎng)絡(luò)原因等異常情況支付平臺(tái)可能出現(xiàn)多次發(fā)送支付結(jié)果的情況,通知回調(diào)接口商戶要注意做好接口冪等,其余的不再多說(shuō)。 7、sps.controller.base,front. 說(shuō)明 如果有幸能看到,其實(shí)只為自己記錄,回頭復(fù)習(xí)用 1、本文項(xiàng)目來(lái)自Martin404,自己只是臨摹大佬的項(xiàng)目。 2、重要的是學(xué)習(xí)過(guò)程,而不是結(jié)...
摘要:是一個(gè)使用語(yǔ)言集成三方支付的小,現(xiàn)已集成支付寶國(guó)內(nèi)國(guó)際移動(dòng)端端微信銀聯(lián)光大網(wǎng)關(guān)網(wǎng)頁(yè)郵政支付,采用的技術(shù)棧為。系統(tǒng)初始化監(jiān)聽(tīng)器在系統(tǒng)啟動(dòng)時(shí)運(yùn)行進(jìn)行一些初始化工作加載銀聯(lián)配置文件緩存初始化忽略過(guò)濾器我們先看關(guān)于日志的,真心看不懂,后面有一大堆。 PayMap PayMap是一個(gè)使用Java語(yǔ)言集成三方支付的小Demo,現(xiàn)已集成支付寶(國(guó)內(nèi)、國(guó)際、移動(dòng)端、PC端)、微信、銀聯(lián)(ACP、UPO...
摘要:是一個(gè)用開(kāi)發(fā)的一個(gè)企業(yè)級(jí)中后臺(tái)管理包含常用的業(yè)務(wù),組件,及數(shù)據(jù)流轉(zhuǎn)方案,前后端分離的開(kāi)發(fā)方式,按業(yè)務(wù)劃分的目錄結(jié)構(gòu),可以大大提高我們的開(kāi)發(fā)效率下面是整體的介紹,感興趣的同學(xué)可以去官網(wǎng)詳加了解。 dva-boot-admin 是一個(gè)用React開(kāi)發(fā)的一個(gè)企業(yè)級(jí)中后臺(tái)管理UI,包含常用的業(yè)務(wù),組件,及數(shù)據(jù)流轉(zhuǎn)方案,前后端分離的開(kāi)發(fā)方式,按業(yè)務(wù)劃分的目錄結(jié)構(gòu),可以大大提高我們的開(kāi)發(fā)效率 下面...
摘要:而調(diào)用后端服務(wù)就應(yīng)用了的高級(jí)特分布式配置管理平臺(tái)后端掘金輕量的分布式配置管理平臺(tái)。關(guān)于網(wǎng)絡(luò)深度解讀后端掘金什么是網(wǎng)絡(luò)呢總的來(lái)說(shuō),網(wǎng)絡(luò)中的容器們可以相互通信,網(wǎng)絡(luò)外的又訪問(wèn)不了這些容器。 在 Java 路上,我看過(guò)的一些書、源碼和框架(持續(xù)更新) - 后端 - 掘金簡(jiǎn)書 占小狼轉(zhuǎn)載請(qǐng)注明原創(chuàng)出處,謝謝!如果讀完覺(jué)得有收獲的話,歡迎點(diǎn)贊加關(guān)注 物有本末,事有終始,知所先后,則近道矣 ......
摘要:鑒于目前大多數(shù)服務(wù)器環(huán)境都是,提前接觸能夠相輔相成。正則也是必須要掌握的一個(gè)知識(shí)點(diǎn)。有多種創(chuàng)建多線程的方式,不過(guò)目前使用線程池的多一些。 原創(chuàng):小姐姐味道(微信公眾號(hào)ID:xjjdog),歡迎分享,轉(zhuǎn)載請(qǐng)保留出處。 你可能有所感悟。零散的資料讀了很多,但是很難有提升。到處是干貨,但是并沒(méi)什么用,簡(jiǎn)單來(lái)說(shuō)就是缺乏系統(tǒng)化。另外,噪音太多,雷同的框架一大把,我不至于全都要去學(xué)了吧。 這里,我...
閱讀 2555·2021-09-30 10:00
閱讀 3491·2021-09-22 10:54
閱讀 6212·2021-09-07 10:28
閱讀 2943·2019-08-29 13:53
閱讀 742·2019-08-29 12:42
閱讀 958·2019-08-26 13:51
閱讀 1258·2019-08-26 13:32
閱讀 3021·2019-08-26 10:39