From d32b48dadb3bfc97e6ec5d61f9f5eb7c48f66ecf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E5=B0=8F=E6=96=9C?= <362294931@qq.com> Date: Sun, 9 Apr 2023 16:56:27 +0800 Subject: [PATCH 01/39] modify db --- ...01\347\232\204\345\205\263\347\263\273.md" | 18 ++++++++-- ...47\345\210\253\345\256\236\346\210\230.md" | 1 + ...33\346\227\245\345\277\227\344\273\254.md" | 12 +++++++ ...45\344\270\216\345\256\236\350\267\265.md" | 4 +-- ...30\345\202\250\345\216\237\347\220\206.md" | 33 ++++++++++++++++++- ...23\346\236\204\347\256\227\346\263\225.md" | 3 +- ...272\343\200\217MySQL\345\222\214InnoDB.md" | 2 +- ...30\345\214\226\345\274\200\345\247\213.md" | 14 ++++---- ...20\344\270\216\344\274\230\345\214\226.md" | 3 +- ...04\351\224\201\345\256\236\347\216\260.md" | 2 +- src/main/java/md/mdToc.java | 2 +- 11 files changed, 75 insertions(+), 19 deletions(-) diff --git "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232Innodb\344\270\255\347\232\204\344\272\213\345\212\241\351\232\224\347\246\273\347\272\247\345\210\253\345\222\214\351\224\201\347\232\204\345\205\263\347\263\273.md" "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232Innodb\344\270\255\347\232\204\344\272\213\345\212\241\351\232\224\347\246\273\347\272\247\345\210\253\345\222\214\351\224\201\347\232\204\345\205\263\347\263\273.md" index 41157d3..b796526 100644 --- "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232Innodb\344\270\255\347\232\204\344\272\213\345\212\241\351\232\224\347\246\273\347\272\247\345\210\253\345\222\214\351\224\201\347\232\204\345\205\263\347\263\273.md" +++ "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232Innodb\344\270\255\347\232\204\344\272\213\345\212\241\351\232\224\347\246\273\347\272\247\345\210\253\345\222\214\351\224\201\347\232\204\345\205\263\347\263\273.md" @@ -1,3 +1,17 @@ +# Table of Contents + + * [Innodbä¸çš„事务隔离级别和é”�的关系](#innodbä¸çš„事务隔离级别和é”�的关系) + * [事务ä¸çš„åŠ é”�æ–¹å¼�](#事务ä¸çš„åŠ é”�æ–¹å¼�) + * [MySQLä¸é”�çš„ç§�ç±»](#mysqlä¸é”�çš„ç§�ç±») + * [Read Committed(读å�–æ��交内容)](#read-committed(读å�–æ��交内容)) + * [Repeatable Read(å�¯é‡�读)](#repeatable-read(å�¯é‡�读)) + * [ä¸�å�¯é‡�å¤�读和幻读的区别](#ä¸�å�¯é‡�å¤�读和幻读的区别) + * [悲观é”�å’Œä¹�è§‚é”�](#悲观é”�å’Œä¹�è§‚é”�) + * [MVCC在MySQLçš„InnoDBä¸çš„实现](#mvcc在mysqlçš„innodbä¸çš„实现) + * [“读â€�与“读â€�的区别](#读与读的区别) + * [](#-2) + + 本文转自互è�”网 æœ¬ç³»åˆ—æ–‡ç« å°†æ•´ç�†åˆ°æˆ‘在GitHub上的《Javaé�¢è¯•指å�—》仓库,更多精彩内容请到我的仓库里查看 @@ -265,9 +279,9 @@ RC(ä¸�å�¯é‡�读)模å¼�下的展现 事务的隔离级别实际上都是定义了当å‰�读的级别,MySQL为了å‡�å°‘é”�处ç�†ï¼ˆåŒ…括ç‰å¾…其它é”�)的时间,æ��å�‡å¹¶å�‘能力,引入了快照读的概念,使得selectä¸�ç”¨åŠ é”�。而updateã€�insert这些“当å‰�读â€�,就需è¦�å�¦å¤–的模å�—æ�¥è§£å†³äº†ã€‚ -###写("当å‰�读")事务的隔离级别ä¸è™½ç„¶å�ªå®šä¹‰äº†è¯»æ•°æ�®çš„è¦�求,实际上这也å�¯ä»¥è¯´æ˜¯å†™æ•°æ�®çš„è¦�求。上文的“读â€�,实际是讲的快照读;而这里说的“写â€�就是当å‰�读了。为了解决当å‰�读ä¸çš„幻读问题,MySQL事务使用了Next-Keyé”�。 +写("当å‰�读")事务的隔离级别ä¸è™½ç„¶å�ªå®šä¹‰äº†è¯»æ•°æ�®çš„è¦�求,实际上这也å�¯ä»¥è¯´æ˜¯å†™æ•°æ�®çš„è¦�求。上文的“读â€�,实际是讲的快照读;而这里说的“写â€�就是当å‰�读了。为了解决当å‰�读ä¸çš„幻读问题,MySQL事务使用了Next-Keyé”�。 -####Next-Keyé”�Next-Keyé”�是行é”�å’ŒGAP(间隙é”�)的å�ˆå¹¶ï¼Œè¡Œé”�上文已ç»�介ç»�了,接下æ�¥è¯´ä¸‹GAPé—´éš™é”�。 +Next-Keyé”�Next-Keyé”�是行é”�å’ŒGAP(间隙é”�)的å�ˆå¹¶ï¼Œè¡Œé”�上文已ç»�介ç»�了,接下æ�¥è¯´ä¸‹GAPé—´éš™é”�。 行é”�å�¯ä»¥é˜²æ¢ä¸�å�Œäº‹åŠ¡ç‰ˆæœ¬çš„æ•°æ�®ä¿®æ”¹æ��äº¤æ—¶é€ æˆ�æ•°æ�®å†²çª�的情况。但如何é�¿å…�别的事务æ�’入数æ�®å°±æˆ�了问题。我们å�¯ä»¥çœ‹çœ‹RR级别和RC级别的对比 diff --git "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232MySQL\347\232\204\344\272\213\345\212\241\351\232\224\347\246\273\347\272\247\345\210\253\345\256\236\346\210\230.md" "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232MySQL\347\232\204\344\272\213\345\212\241\351\232\224\347\246\273\347\272\247\345\210\253\345\256\236\346\210\230.md" index 026a50a..d048c74 100644 --- "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232MySQL\347\232\204\344\272\213\345\212\241\351\232\224\347\246\273\347\272\247\345\210\253\345\256\236\346\210\230.md" +++ "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232MySQL\347\232\204\344\272\213\345\212\241\351\232\224\347\246\273\347\272\247\345\210\253\345\256\236\346\210\230.md" @@ -1,3 +1,4 @@ + # 目录 * [事务的基本è¦�ç´ ï¼ˆACID)](#事务的基本è¦�ç´ ï¼ˆacid)) * [事务的并å�‘问题](#事务的并å�‘问题) diff --git "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232MySQL\351\207\214\347\232\204\351\202\243\344\272\233\346\227\245\345\277\227\344\273\254.md" "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232MySQL\351\207\214\347\232\204\351\202\243\344\272\233\346\227\245\345\277\227\344\273\254.md" index 347ecee..3469a48 100644 --- "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232MySQL\351\207\214\347\232\204\351\202\243\344\272\233\346\227\245\345\277\227\344\273\254.md" +++ "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232MySQL\351\207\214\347\232\204\351\202\243\344\272\233\346\227\245\345\277\227\344\273\254.md" @@ -1,3 +1,15 @@ +# Table of Contents + +* [目录](#目录) + * [é‡�æ–°å¦ä¹ MySQLæ•°æ�®åº“10:MySQL里的那些日志们](#é‡�æ–°å¦ä¹ mysqlæ•°æ�®åº“10:mysql里的那些日志们) + * [1.MySQL日志文件系统的组æˆ�](#1mysql日志文件系统的组æˆ�) + * [2.错误日志](#2错误日志) + * [3.InnoDBä¸çš„æ—¥å¿—](#3innodbä¸çš„æ—¥å¿—) + * [4- 慢查询日志](#4--慢查询日志) + * [5.二进制日志](#5二进制日志) + * [总结](#总结) + + # 目录 * [é‡�æ–°å¦ä¹ MySQLæ•°æ�®åº“10:MySQL里的那些日志们](#é‡�æ–°å¦ä¹ mysqlæ•°æ�®åº“10:mysql里的那些日志们) * [1.MySQL日志文件系统的组æˆ�](#1mysql日志文件系统的组æˆ�) diff --git "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232Mysql\344\270\273\344\273\216\345\244\215\345\210\266\357\274\214\350\257\273\345\206\231\345\210\206\347\246\273\357\274\214\345\210\206\350\241\250\345\210\206\345\272\223\347\255\226\347\225\245\344\270\216\345\256\236\350\267\265.md" "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232Mysql\344\270\273\344\273\216\345\244\215\345\210\266\357\274\214\350\257\273\345\206\231\345\210\206\347\246\273\357\274\214\345\210\206\350\241\250\345\210\206\345\272\223\347\255\226\347\225\245\344\270\216\345\256\236\350\267\265.md" index 53a3fc9..6a2ae30 100644 --- "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232Mysql\344\270\273\344\273\216\345\244\215\345\210\266\357\274\214\350\257\273\345\206\231\345\210\206\347\246\273\357\274\214\345\210\206\350\241\250\345\210\206\345\272\223\347\255\226\347\225\245\344\270\216\345\256\236\350\267\265.md" +++ "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232Mysql\344\270\273\344\273\216\345\244\215\345\210\266\357\274\214\350\257\273\345\206\231\345\210\206\347\246\273\357\274\214\345\210\206\350\241\250\345\210\206\345\272\223\347\255\226\347\225\245\344\270\216\345\256\236\350\267\265.md" @@ -11,8 +11,6 @@ * [三ã€�Mycat 垂直切分ã€�水平切分实战](#三ã€�mycat-垂直切分ã€�水平切分实战) * [1ã€�垂直切分](#1ã€�垂直切分) * [2ã€�水平切分](#2ã€�水平切分) -* [range start-end ,data node index](#range-start-end-data-node-index) -* [K=1000,M=10000.](#k1000m10000) * [为什么需è¦�读写分离](#为什么需è¦�读写分离) * [MySQL主从å¤�制](#mysql主从å¤�制) * [Mycat读写分离设置](#mycat读写分离设置) @@ -627,4 +625,4 @@ Mycatçš„é…�置有很多,ä¸�è¿‡å› ä¸ºæˆ‘ä»¬å�ªæ˜¯ä½¿ç”¨Mycat的读写分类的 å‰�é�¢å·²ç»�å·®ä¸�å¤šéƒ½è§£é‡Šæ¸…æ¥šäº†ï¼Œå› ä¸ºæˆ‘å�ªæ˜¯ç”¨çš„基本的主从å¤�制,所以我的将`dataHost`çš„`balance`设置æˆ�了3 -å�¯åЍmycat,然å�Žç”¨æ•°æ�®åº“连接工具连接到mycat,å�¯ä»¥æµ‹è¯•是å�¦é…�ç½®æˆ�功,最简å�•的就是通过修改从库的数æ�®ï¼Œè¿™æ ·æ–¹ä¾¿æŸ¥çœ‹åˆ°åº•是è¿�行到哪个库上é�¢äº†ï¼Œå�¦å¤–由于我是基于dockerå�¯åŠ¨çš„mycat,所以如果是直接在系统ä¸è¿�行的mycat的,å�¯ä»¥åŽ»çœ‹å®˜æ–¹æ–‡æ¡£ï¼Œçœ‹çœ‹åˆ°åº•æ€Žä¹ˆå�¯åЍmycat \ No newline at end of file +å�¯åЍmycat,然å�Žç”¨æ•°æ�®åº“连接工具连接到mycat,å�¯ä»¥æµ‹è¯•是å�¦é…�ç½®æˆ�功,最简å�•的就是通过修改从库的数æ�®ï¼Œè¿™æ ·æ–¹ä¾¿æŸ¥çœ‹åˆ°åº•是è¿�行到哪个库上é�¢äº†ï¼Œå�¦å¤–由于我是基于dockerå�¯åŠ¨çš„mycat,所以如果是直接在系统ä¸è¿�行的mycat的,å�¯ä»¥åŽ»çœ‹å®˜æ–¹æ–‡æ¡£ï¼Œçœ‹çœ‹åˆ°åº•æ€Žä¹ˆå�¯åЍmycat diff --git "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232Mysql\345\255\230\345\202\250\345\274\225\346\223\216\344\270\216\346\225\260\346\215\256\345\255\230\345\202\250\345\216\237\347\220\206.md" "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232Mysql\345\255\230\345\202\250\345\274\225\346\223\216\344\270\216\346\225\260\346\215\256\345\255\230\345\202\250\345\216\237\347\220\206.md" index 64db961..4763b48 100644 --- "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232Mysql\345\255\230\345\202\250\345\274\225\346\223\216\344\270\216\346\225\260\346\215\256\345\255\230\345\202\250\345\216\237\347\220\206.md" +++ "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232Mysql\345\255\230\345\202\250\345\274\225\346\223\216\344\270\216\346\225\260\346\215\256\345\255\230\345\202\250\345\216\237\347\220\206.md" @@ -1,3 +1,34 @@ +# Table of Contents + + * [**一ã€� MySQL记录å˜å‚¨ï¼ˆé¡µä¸ºå�•ä½�)**](#一ã€�-mysql记录å˜å‚¨ï¼ˆé¡µä¸ºå�•ä½�)) + * [**页头**](#页头) + * [**虚记录**](#虚记录) + * [**è®°å½•å †**](#è®°å½•å †) + * [**自由空间链表**](#自由空间链表) + * [**未分é…�空间**](#未分é…�空间) + * [**Slot区**](#slot区) + * [**页内记录维护**](#页内记录维护) + * [**二ã€� MySQL InnoDBå˜å‚¨å¼•擎内å˜ç®¡ç�†**](#二ã€�-mysql-innodbå˜å‚¨å¼•擎内å˜ç®¡ç�†) + * [**预分é…�内å˜ç©ºé—´**](#预分é…�内å˜ç©ºé—´) + * [**æ•°æ�®ä»¥é¡µä¸ºå�•ä½�åŠ è½½ (å‡�å°‘io访问次数)**](#æ•°æ�®ä»¥é¡µä¸ºå�•ä½�åŠ è½½-(å‡�å°‘io访问次数)) + * [**æ•°æ�®å†…外å˜äº¤æ�¢**](#æ•°æ�®å†…外å˜äº¤æ�¢) + * [**页é�¢ç®¡ç�†**](#页é�¢ç®¡ç�†) + * [**页é�¢æ·˜æ±°**](#页é�¢æ·˜æ±°) + * [**全表扫æ��对内å˜çš„å½±å“�?**](#全表扫æ��对内å˜çš„å½±å“�?) + * [**页é�¢æ·˜æ±°**](#页é�¢æ·˜æ±°-1) + * [**ä½�置移动**](#ä½�置移动) + * [**三ã€�MySQL事务实现原ç�†**](#三ã€�mysql事务实现原ç�†) + * [**1ã€�事务特性**](#1ã€�事务特性) + * [**2ã€�å¹¶å�‘问题**](#2ã€�å¹¶å�‘问题) + * [**3ã€�隔离级别**](#3ã€�隔离级别) + * [**MySQL事务实现原ç�†ï¼ˆäº‹åŠ¡ç®¡ç�†æœºåˆ¶ï¼‰**](#mysql事务实现原ç�†ï¼ˆäº‹åŠ¡ç®¡ç�†æœºåˆ¶ï¼‰) + * [**1ã€�MVCC 多版本并å�‘控制**](#1ã€�mvcc-多版本并å�‘控制) + * [**2ã€�undo log**](#2ã€�undo-log) + * [**3ã€�redo log**](#3ã€�redo-log) + * [**æ„�义**](#æ„�义) + * [**å››ã€�MySQLé”�实现原ç�†**](#å››ã€�mysqlé”�实现原ç�†) + + ## **一ã€� MySQL记录å˜å‚¨ï¼ˆé¡µä¸ºå�•ä½�)**  @@ -255,4 +286,4 @@ RR级别下 æ»é”�åœ¨åº“è¡¨ä¸æœ‰è®°å½•,通过kill 那个é”�åˆ é™¤ã€‚ - \ No newline at end of file + diff --git "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232Mysql\347\264\242\345\274\225\345\256\236\347\216\260\345\216\237\347\220\206\345\222\214\347\233\270\345\205\263\346\225\260\346\215\256\347\273\223\346\236\204\347\256\227\346\263\225.md" "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232Mysql\347\264\242\345\274\225\345\256\236\347\216\260\345\216\237\347\220\206\345\222\214\347\233\270\345\205\263\346\225\260\346\215\256\347\273\223\346\236\204\347\256\227\346\263\225.md" index c404f1e..7bd83de 100644 --- "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232Mysql\347\264\242\345\274\225\345\256\236\347\216\260\345\216\237\347\220\206\345\222\214\347\233\270\345\205\263\346\225\260\346\215\256\347\273\223\346\236\204\347\256\227\346\263\225.md" +++ "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232Mysql\347\264\242\345\274\225\345\256\236\347\216\260\345\216\237\347\220\206\345\222\214\347\233\270\345\205\263\346\225\260\346\215\256\347\273\223\346\236\204\347\256\227\346\263\225.md" @@ -1,3 +1,4 @@ + # 目录 * [MySQL索引](#mysql索引) @@ -904,4 +905,4 @@ title的选择性ä¸�è¶³0.0001(精确值为0.00001579),所以实在没有 [5] Codd, E. F. (1970). "A relational model of data for large shared data banks". Communications of the ACM, , Vol. 13, No. 6, pp. 377-387 -[6] MySQL5.1å�‚考手册 - [http://dev.mysql.com/doc/refman/5.1/zh/index.html](http://dev.mysql.com/doc/refman/5.1/zh/index.html "http://dev.mysql.com/doc/refman/5.1/zh/index.html") \ No newline at end of file +[6] MySQL5.1å�‚考手册 - [http://dev.mysql.com/doc/refman/5.1/zh/index.html](http://dev.mysql.com/doc/refman/5.1/zh/index.html "http://dev.mysql.com/doc/refman/5.1/zh/index.html") diff --git "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232\343\200\216\346\265\205\345\205\245\346\265\205\345\207\272\343\200\217MySQL\345\222\214InnoDB.md" "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232\343\200\216\346\265\205\345\205\245\346\265\205\345\207\272\343\200\217MySQL\345\222\214InnoDB.md" index d8eaa99..8e3991b 100644 --- "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232\343\200\216\346\265\205\345\205\245\346\265\205\345\207\272\343\200\217MySQL\345\222\214InnoDB.md" +++ "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232\343\200\216\346\265\205\345\205\245\346\265\205\345\207\272\343\200\217MySQL\345\222\214InnoDB.md" @@ -22,7 +22,7 @@ * [ä¸�å�¯é‡�å¤�读](#ä¸�å�¯é‡�å¤�读) * [幻读](#幻读) * [总结](#总结) - * [[Innodb与Myisam引擎的区别与应用场景](https://www.cnblogs.com/changna1314/p/6878900.html)](#[innodb与myisam引擎的区别与应用场景]httpswwwcnblogscomchangna1314p6878900html) + * [Innodb与Myisam引擎的区别与应用场景](#[innodb与myisam引擎的区别与应用场景]) 本文转自互è�”网 diff --git "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232\344\273\216\345\256\236\350\267\265sql\350\257\255\345\217\245\344\274\230\345\214\226\345\274\200\345\247\213.md" "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232\344\273\216\345\256\236\350\267\265sql\350\257\255\345\217\245\344\274\230\345\214\226\345\274\200\345\247\213.md" index 7155755..f3bd6d8 100644 --- "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232\344\273\216\345\256\236\350\267\265sql\350\257\255\345\217\245\344\274\230\345\214\226\345\274\200\345\247\213.md" +++ "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232\344\273\216\345\256\236\350\267\265sql\350\257\255\345\217\245\344\274\230\345\214\226\345\274\200\345\247\213.md" @@ -8,9 +8,9 @@ * [InnoDB](#innodb) * [0ã€�自己写的海é‡�æ•°æ�®sql优化实践](#0ã€�自己写的海é‡�æ•°æ�®sql优化实践) * [mysql百万级分页优化](#mysql百万级分页优化) - * [  普通分页](#  普通分页) - * [   优化分页](#  -优化分页) -* [  总结](#  总结) + * [普通分页](#普通分页) + * [优化分页](#优化分页) +* [总结](#总结) 本文转自互è�”网 @@ -667,7 +667,7 @@ SELECT s.* from Student s INNER JOIN SC sc on sc.s_id = s.s_id where sc.c_id=0 ## mysql百万级分页优化 -###   普通分页 +### 普通分页 æ•°æ�®åˆ†é¡µåœ¨ç½‘页ä¸å��分多è§�,分页一般都是limit start,offset,ç„¶å�Žæ ¹æ�®é¡µç �page计算start @@ -681,7 +681,7 @@ SELECT * from user limit **100001**,**20**; //time **0**.151s explain SELECT * f  -###    优化分页 +### 优化分页 使用主键索引æ�¥ä¼˜åŒ–æ•°æ�®åˆ†é¡µ @@ -693,10 +693,10 @@ SELECT * from user limit **100001**,**20**; //time **0**.151s explain SELECT * f  -##   总结 +## 总结 在数æ�®é‡�比较大的时候,我们尽é‡�去利用索引æ�¥ä¼˜åŒ–è¯å�¥ã€‚上é�¢çš„优化方法如果idä¸�是主键索引,查询效率比第一ç§�还è¦�低点。我们å�¯ä»¥å…ˆä½¿ç”¨explainæ�¥åˆ†æž�è¯å�¥ï¼ŒæŸ¥çœ‹è¯å�¥çš„æ‰§è¡Œé¡ºåº�和执行性能。 -转载于:https://my.oschina.net/alicoder/blog/3097141 \ No newline at end of file +转载于:https://my.oschina.net/alicoder/blog/3097141 diff --git "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232\346\240\271\346\215\256MySQL\347\264\242\345\274\225\345\216\237\347\220\206\350\277\233\350\241\214\345\210\206\346\236\220\344\270\216\344\274\230\345\214\226.md" "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232\346\240\271\346\215\256MySQL\347\264\242\345\274\225\345\216\237\347\220\206\350\277\233\350\241\214\345\210\206\346\236\220\344\270\216\344\274\230\345\214\226.md" index e90f560..3dd0dbf 100644 --- "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232\346\240\271\346\215\256MySQL\347\264\242\345\274\225\345\216\237\347\220\206\350\277\233\350\241\214\345\210\206\346\236\220\344\270\216\344\274\230\345\214\226.md" +++ "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232\346\240\271\346\215\256MySQL\347\264\242\345\274\225\345\216\237\347\220\206\350\277\233\350\241\214\345\210\206\346\236\220\344\270\216\344\274\230\345\214\226.md" @@ -1,5 +1,4 @@ # 目录 - * [一:Mysql原ç�†ä¸Žæ…¢æŸ¥è¯¢](#一:mysql原ç�†ä¸Žæ…¢æŸ¥è¯¢) * [一个慢查询引å�‘çš„æ€�考](#一个慢查询引å�‘çš„æ€�考) * [二:索引建立](#二:索引建立) @@ -523,4 +522,4 @@ title的选择性ä¸�è¶³0.0001(精确值为0.00001579),所以实在没有 æ¤æ—¶MySQLä¸�å¾—ä¸�为了将新记录æ�’到å�ˆé€‚ä½�置而移动数æ�®ï¼Œç”šè‡³ç›®æ ‡é¡µé�¢å�¯èƒ½å·²ç»�被回写到ç£�盘上而从缓å˜ä¸æ¸…æŽ‰ï¼Œæ¤æ—¶å�ˆè¦�从ç£�盘上读回æ�¥ï¼Œè¿™å¢žåŠ äº†å¾ˆå¤šå¼€é”€ï¼Œå�Œæ—¶é¢‘ç¹�的移动ã€�分页æ“�ä½œé€ æˆ�了大é‡�的碎片,得到了ä¸�够紧凑的索引结构,å�Žç»ä¸�å¾—ä¸�通过OPTIMIZE TABLEæ�¥é‡�建表并优化填充页é�¢ã€‚ -å› æ¤ï¼Œå�ªè¦�å�¯ä»¥ï¼Œè¯·å°½é‡�在InnoDBä¸Šé‡‡ç”¨è‡ªå¢žå—æ®µå�šä¸»é”®ã€‚ \ No newline at end of file +å› æ¤ï¼Œå�ªè¦�å�¯ä»¥ï¼Œè¯·å°½é‡�在InnoDBä¸Šé‡‡ç”¨è‡ªå¢žå—æ®µå�šä¸»é”®ã€‚ diff --git "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232\350\257\246\350\247\243MyIsam\344\270\216InnoDB\345\274\225\346\223\216\347\232\204\351\224\201\345\256\236\347\216\260.md" "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232\350\257\246\350\247\243MyIsam\344\270\216InnoDB\345\274\225\346\223\216\347\232\204\351\224\201\345\256\236\347\216\260.md" index 473146f..3b3fb32 100644 --- "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232\350\257\246\350\247\243MyIsam\344\270\216InnoDB\345\274\225\346\223\216\347\232\204\351\224\201\345\256\236\347\216\260.md" +++ "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232\350\257\246\350\247\243MyIsam\344\270\216InnoDB\345\274\225\346\223\216\347\232\204\351\224\201\345\256\236\347\216\260.md" @@ -326,4 +326,4 @@ InnoDB在ç»�大部分情况会使用行级é”�ï¼Œå› ä¸ºäº‹åŠ¡å’Œè¡Œé”�往往是 2ã€�在å�Œä¸€ä¸ªäº‹åŠ¡ä¸ï¼Œå°½å�¯èƒ½å�šåˆ°ä¸€æ¬¡é”�定所需è¦�的所有资æº�,å‡�å°‘æ»é”�产生概率; -3ã€�对于é�žå¸¸å®¹æ˜“产生æ»é”�的业务部分,å�¯ä»¥å°�试使用å�‡çº§é”�定颗粒度,通过表级é”�定æ�¥å‡�å°‘æ»é”�产生的概率; \ No newline at end of file +3ã€�对于é�žå¸¸å®¹æ˜“产生æ»é”�的业务部分,å�¯ä»¥å°�试使用å�‡çº§é”�定颗粒度,通过表级é”�定æ�¥å‡�å°‘æ»é”�产生的概率; diff --git a/src/main/java/md/mdToc.java b/src/main/java/md/mdToc.java index 05650b7..6dbcab7 100644 --- a/src/main/java/md/mdToc.java +++ b/src/main/java/md/mdToc.java @@ -4,7 +4,7 @@ public class mdToc { public static void main(String[] args) { - String path = "D:\\idea_project\\javaTutorial\\docs\\big-backEnd\\temp"; + String path = "D:\\idea_project\\javaTutorial\\docs\\database"; AtxMarkdownToc.newInstance().genTocDir(path); } } From 19319b2c0b986bc5eee13bc6fe868aa5364046cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E5=B0=8F=E6=96=9C?= <362294931@qq.com> Date: Sun, 9 Apr 2023 17:10:48 +0800 Subject: [PATCH 02/39] modify distributed mds --- ReadMe.md | 2 +- ...46\344\271\240\346\200\273\347\273\223.md" | 20 +++++------ ...45\237\272\347\241\200 \357\274\232CAP.md" | 27 +++++++++----- ...46\200\247\343\200\201PC\345\222\214PC.md" | 23 ++++++++---- ...13\344\273\266\351\241\272\345\272\217.md" | 21 +++++++---- ...5\237\272\347\241\200\357\274\232Paxos.md" | 16 ++++++--- ...241\200\357\274\232Raft\343\200\201Zab.md" | 19 +++++++--- ...17\350\260\203\346\234\215\345\212\241.md" | 25 ++++++++----- ...76\345\222\214\347\247\237\347\272\246.md" | 16 ++++++--- ...15\345\222\214\344\274\230\345\214\226.md" | 20 +++++++---- ...06\350\256\272\346\200\273\347\273\223.md" | 0 ...44\270\200\350\207\264\346\200\247hash.md" | 35 +++++++------------ ...43\345\206\263\346\226\271\346\241\210.md" | 1 + ...03\345\274\217\344\272\213\345\212\241.md" | 22 ++++++------ ...6\201\257\346\212\200\346\234\257Kafka.md" | 20 +++++------ ...40\347\247\215\346\226\271\346\241\210.md" | 16 ++++----- ...00\344\275\263\345\256\236\350\267\265.md" | 8 ++--- src/main/java/md/mdToc.java | 2 +- 18 files changed, 177 insertions(+), 116 deletions(-) rename "docs/distributed/\345\210\206\345\270\203\345\274\217\347\220\206\350\256\272\346\200\273\347\273\223.md" => "docs/distributed/practice/\345\210\206\345\270\203\345\274\217\347\220\206\350\256\272\346\200\273\347\273\223.md" (100%) diff --git a/ReadMe.md b/ReadMe.md index dc53ae6..484bbda 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -317,7 +317,7 @@ todo * [分布å¼�系统ç�†è®ºè¿›é˜¶ï¼šPaxoså�˜ç§�和优化 ](docs/distributed/basic/分布å¼�系统ç�†è®ºè¿›é˜¶ï¼šPaxoså�˜ç§�和优化.md) * [分布å¼�系统ç�†è®ºåŸºç¡€ï¼šzookeeper分布å¼�å��è°ƒæœ�务 ](docs/distributed/basic/分布å¼�系统ç�†è®ºåŸºç¡€ï¼šzookeeper分布å¼�å��è°ƒæœ�务.md) -* [分布å¼�技术实践总结](docs/distributed/分布å¼�ç�†è®ºæ€»ç»“.md) +* [分布å¼�技术实践总结](docs/distributed/practice/分布å¼�ç�†è®ºæ€»ç»“.md) ### 技术 * [æ�žæ‡‚分布å¼�技术:分布å¼�系统的一些基本概念](docs/distributed/practice/æ�žæ‡‚分布å¼�技术:分布å¼�系统的一些基本概念.md ) diff --git "a/docs/cs/operating-system/Linux\345\206\205\346\240\270\344\270\216\345\237\272\347\241\200\345\221\275\344\273\244\345\255\246\344\271\240\346\200\273\347\273\223.md" "b/docs/cs/operating-system/Linux\345\206\205\346\240\270\344\270\216\345\237\272\347\241\200\345\221\275\344\273\244\345\255\246\344\271\240\346\200\273\347\273\223.md" index 4a366fc..3cf91e6 100644 --- "a/docs/cs/operating-system/Linux\345\206\205\346\240\270\344\270\216\345\237\272\347\241\200\345\221\275\344\273\244\345\255\246\344\271\240\346\200\273\347\273\223.md" +++ "b/docs/cs/operating-system/Linux\345\206\205\346\240\270\344\270\216\345\237\272\347\241\200\345\221\275\344\273\244\345\255\246\344\271\240\346\200\273\347\273\223.md" @@ -309,7 +309,7 @@ linux使用inodeæ�¥æ ‡è¯†ä»»æ„�一个文件。inodeå˜å‚¨é™¤äº†æ–‡ä»¶å��以外 -
#include+#includessize_t write(int filedes, void *buf, size_t nbytes); // 返回:若æˆ�功则返回写入的å—节数,若出错则返回-1 // filedes:文件æ��述符 // buf:待写入数æ�®ç¼“å˜åŒº // nbytes:è¦�写入的å—节数
1 ssize_t /* Write "n" bytes to a descriptor. */
+ 1 ssize_t /* Write "n" bytes to a descriptor. */
2 writen(int fd, const void *vptr, size_t n)
3 {
4 size_t nleft;
@@ -335,7 +335,7 @@ linux使用inodeæ�¥æ ‡è¯†ä»»æ„�一个文件。inodeå˜å‚¨é™¤äº†æ–‡ä»¶å��以外
18 nleft -= nwritten; 19 ptr += nwritten; 20 } 21 return(n); 22 } 23 /* end writen */
24
25 void
-26 Writen(int fd, void *ptr, size_t nbytes) 27 { 28 if (writen(fd, ptr, nbytes) != nbytes) 29 err_sys("writen error"); 30 }
+26 Writen(int fd, void *ptr, size_t nbytes) 27 { 28 if (writen(fd, ptr, nbytes) != nbytes) 29 err_sys("writen error"); 30 }目录

@@ -349,7 +349,7 @@ linux使用inodeæ�¥æ ‡è¯†ä»»æ„�一个文件。inodeå˜å‚¨é™¤äº†æ–‡ä»¶å��以外
-#include+#includessize_t read(int filedes, void *buf, size_t nbytes); // 返回:若æˆ�功则返回读到的å—节数,若已到文件末尾则返回0,若出错则返回-1 // filedes:文件æ��述符 // buf:读å�–æ•°æ�®ç¼“å˜åŒº // nbytes:è¦�读å�–çš„å—节数
1 ssize_t /* Read "n" bytes from a descriptor. */
+ 1 ssize_t /* Read "n" bytes from a descriptor. */
2 readn(int fd, void *vptr, size_t n)
3 {
4 size_t nleft;
@@ -390,7 +390,7 @@ linux使用inodeæ�¥æ ‡è¯†ä»»æ„�一个文件。inodeå˜å‚¨é™¤äº†æ–‡ä»¶å��以外
23 } 24 /* end readn */
25
26 ssize_t 27 Readn(int fd, void *ptr, size_t nbytes) 28 { 29 ssize_t n; 30
-31 if ( (n = readn(fd, ptr, nbytes)) < 0) 32 err_sys("readn error"); 33 return(n); 34 }
+31 if ( (n = readn(fd, ptr, nbytes)) < 0) 32 err_sys("readn error"); 33 return(n); 34 }目录

@@ -406,7 +406,7 @@ linux使用inodeæ�¥æ ‡è¯†ä»»æ„�一个文件。inodeå˜å‚¨é™¤äº†æ–‡ä»¶å��以外
-#include+#includessize_t write(int fd, const void *buf, size_t count);
# 获�socket的��/接�缓冲区的大�:(��的值是在Linux 2.6.38 x86_64上测试的结果)+# 获�socket的��/接�缓冲区的大�:(��的值是在Linux 2.6.38 x86_64上测试的结果)目录 -
sysctl net.core.wmem_default #126976 -sysctl net.core.wmem_max     #131071+sysctl net.core.wmem_default #126976 +sysctl net.core.wmem_max     #131071目录 diff --git "a/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200 \357\274\232CAP.md" "b/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200 \357\274\232CAP.md" index 8d61a51..268f008 100644 --- "a/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200 \357\274\232CAP.md" +++ "b/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200 \357\274\232CAP.md" @@ -1,3 +1,14 @@ +# Table of Contents + + * [**引言**](#引言) + * [**CAP定ç�†**](#cap定ç�†) + * [**CAP的工程å�¯ç¤º**](#cap的工程å�¯ç¤º) + * [**1ã€�关于 P çš„ç�†è§£**](#1ã€�关于-p-çš„ç�†è§£) + * [**2ã€�CAé�ž0/1的选择**](#2ã€�caé�ž01的选择) + * [**3ã€�跳出CAP**](#3ã€�跳出cap) + * [**å°�结**](#å°�结) + + 本文转自:https://www.cnblogs.com/bangerlee/p/5328888.html æœ¬ç³»åˆ—æ–‡ç« å°†æ•´ç�†åˆ°æˆ‘在GitHub上的《Javaé�¢è¯•指å�—》仓库,更多精彩内容请到我的仓库里查看 @@ -17,11 +28,11 @@ å¦‚æžœå¯¹æœ¬ç³»åˆ—æ–‡ç« æœ‰ä»€ä¹ˆå»ºè®®ï¼Œæˆ–è€…æ˜¯æœ‰ä»€ä¹ˆç–‘é—®çš„è¯�,也å�¯ä»¥å…³æ³¨å…¬ä¼—å�·ã€�Java技术江湖】è�”ç³»ä½œè€…ï¼Œæ¬¢è¿Žä½ å�‚与本系列å�šæ–‡çš„åˆ›ä½œå’Œä¿®è®¢ã€‚ -**引言** +## **引言** CAP是分布å¼�系统ã€�特别是分布å¼�å˜å‚¨é¢†åŸŸä¸è¢«è®¨è®ºæœ€å¤šçš„ç�†è®ºï¼Œâ€œ[什么是CAP定ç�†ï¼Ÿ](https://www.quora.com/What-Is-CAP-Theorem-1)â€�在Quora 分布å¼�系统分类下排å�� FAQ çš„ No.1。CAP在程åº�员ä¸ä¹Ÿæœ‰è¾ƒå¹¿çš„æ™®å�Šï¼Œå®ƒä¸�仅仅是“Cã€�Aã€�Pä¸�能å�Œæ—¶æ»¡è¶³ï¼Œæœ€å¤šå�ªèƒ½3选2â€�,以下å°�试综å�ˆå�„方观点,从å�‘展历å�²ã€�工程实践ç‰è§’度讲述CAPç�†è®ºã€‚希望大家é€�过本文对CAPç�†è®ºæœ‰æ›´å¤šåœ°äº†è§£å’Œè®¤è¯†ã€‚ -**CAP定ç�†** +## **CAP定ç�†** CAPç”±[Eric Brewer](https://en.wikipedia.org/wiki/Eric_Brewer_(scientist))在2000å¹´PODC会议上æ��出[1][2],是Eric Brewer在Inktomi[3]æœŸé—´ç ”å�‘æ�œç´¢å¼•擎ã€�分布å¼�webç¼“å˜æ—¶å¾—出的关于数æ�®ä¸€è‡´æ€§(consistency)ã€�æœ�务å�¯ç”¨æ€§(availability)ã€�分区容错性(partition-tolerance)的猜想: @@ -38,13 +49,13 @@ Cã€�Aã€�P三者最多å�ªèƒ½æ»¡è¶³å…¶ä¸ä¸¤ä¸ªï¼Œå’ŒFLP定ç�†ä¸€æ ·ï¼ŒCAP定ç�†  -**CAP的工程å�¯ç¤º** +## **CAP的工程å�¯ç¤º** CAPç�†è®ºæ��出7ã€�8å¹´å�Žï¼ŒNoSql圈将CAPç�†è®ºå½“ä½œå¯¹æŠ—ä¼ ç»Ÿå…³ç³»åž‹æ•°æ�®åº“çš„ä¾�æ�®ã€�é˜�明自己放宽对数æ�®ä¸€è‡´æ€§(consistency)è¦�求的æ£ç¡®æ€§[6],éš�å�Žå¼•起了大范围关于CAPç�†è®ºçš„讨论。 CAPç�†è®ºçœ‹ä¼¼ç»™æˆ‘们出了一é�“3选2的选择题,但在工程实践ä¸å˜åœ¨å¾ˆå¤šçŽ°å®žé™�制æ�¡ä»¶ï¼Œéœ€è¦�我们å�šæ›´å¤šåœ°è€ƒé‡�与æ�ƒè¡¡ï¼Œé�¿å…�进入CAP认识误区[7]。 -**1ã€�关于 P çš„ç�†è§£** +### **1ã€�关于 P çš„ç�†è§£** Partitionå—é�¢æ„�æ€�是网络分区,å�³å› ç½‘ç»œå› ç´ å°†ç³»ç»Ÿåˆ†éš”ä¸ºå¤šä¸ªå�•独的部分,有人å�¯èƒ½ä¼šè¯´ï¼Œç½‘络分区的情况å�‘生概率é�žå¸¸å°�啊,是ä¸�是ä¸�用考虑P,ä¿�è¯�CA就好[8]。è¦�ç�†è§£P,我们看回CAPè¯�明[4]ä¸P的定义: @@ -56,7 +67,7 @@ Partitionå—é�¢æ„�æ€�是网络分区,å�³å› ç½‘ç»œå› ç´ å°†ç³»ç»Ÿåˆ†éš”ä¸ºå¤š > In a network subject to communication failures, it is impossible for any web service to implement an atomic read/write shared memory that guarantees a response to every request. -**2ã€�CAé�ž0/1的选择** +### **2ã€�CAé�ž0/1的选择** P 是必选项,那3选2的选择题ä¸�å°±å�˜æˆ�æ•°æ�®ä¸€è‡´æ€§(consistency)ã€�æœ�务å�¯ç”¨æ€§(availability) 2选1?工程实践ä¸ä¸€è‡´æ€§æœ‰ä¸�å�Œç¨‹åº¦ï¼Œå�¯ç”¨æ€§ä¹Ÿæœ‰ä¸�å�Œç‰çº§ï¼Œåœ¨ä¿�è¯�分区容错性的å‰�æ��下,放宽约æ�Ÿå�Žå�¯ä»¥å…¼é¡¾ä¸€è‡´æ€§å’Œå�¯ç”¨æ€§ï¼Œä¸¤è€…ä¸�是é�žæ¤å�³å½¼[12]。 @@ -71,7 +82,7 @@ CAP定ç�†è¯�明ä¸çš„一致性指强一致性,强一致性è¦�求多节点组 工程实践ä¸ï¼Œè¾ƒå¸¸è§�çš„å�šæ³•æ˜¯é€šè¿‡å¼‚æ¥æ‹·è´�副本(asynchronous replication)ã€�quorum/NRW,实现在调用端看æ�¥æ•°æ�®å¼ºä¸€è‡´ã€�被调端最终一致,在调用端看æ�¥æœ�务å�¯ç”¨ã€�被调端å…�许部分节点ä¸�å�¯ç”¨(或被网络分隔)的效果[15]。 -**3ã€�跳出CAP** +### **3ã€�跳出CAP** CAPç�†è®ºå¯¹å®žçŽ°åˆ†å¸ƒå¼�系统具有指导æ„�义,但CAPç�†è®ºå¹¶æ²¡æœ‰æ¶µç›–分布å¼�工程实践ä¸çš„æ‰€æœ‰é‡�è¦�å› ç´ ã€‚ @@ -79,7 +90,7 @@ CAPç�†è®ºå¯¹å®žçŽ°åˆ†å¸ƒå¼�系统具有指导æ„�义,但CAPç�†è®ºå¹¶æ²¡æœ‰æ¶µ 延时与数æ�®ä¸€è‡´æ€§ä¹Ÿæ˜¯ä¸€å¯¹â€œå†¤å®¶â€�,如果è¦�达到强一致性ã€�多个副本数æ�®ä¸€è‡´ï¼Œå¿…ç„¶å¢žåŠ å»¶æ—¶ã€‚åŠ ä¸Šå»¶æ—¶çš„è€ƒé‡�,我们得到一个CAPç�†è®ºçš„修改版本PACELC[17]:如果出现P(网络分区),如何在A(æœ�务å�¯ç”¨æ€§)ã€�C(æ•°æ�®ä¸€è‡´æ€§)之间选择;å�¦åˆ™ï¼Œå¦‚何在L(å»¶æ—¶)ã€�C(æ•°æ�®ä¸€è‡´æ€§)之间选择。 -**å°�结** +### **å°�结** 以上介ç»�了CAPç�†è®ºçš„æº�èµ·å’Œå�‘展,介ç»�了CAPç�†è®ºç»™åˆ†å¸ƒå¼�系统工程实践带æ�¥çš„å�¯ç¤ºã€‚ @@ -125,4 +136,4 @@ CAPç�†è®ºå¯¹åˆ†å¸ƒå¼�系统实现有é�žå¸¸é‡�大的影å“�,我们å�¯ä»¥æ ¹æ�® [19] [How to beat the CAP theorem](http://nathanmarz.com/blog/how-to-beat-the-cap-theorem.html), nathanmarz , 2011 -[20] [The CAP FAQ](https://github.com/henryr/cap-faq), Henry Robinson \ No newline at end of file +[20] [The CAP FAQ](https://github.com/henryr/cap-faq), Henry Robinson diff --git "a/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\357\274\232 \344\270\200\350\207\264\346\200\247\343\200\201PC\345\222\214PC.md" "b/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\357\274\232 \344\270\200\350\207\264\346\200\247\343\200\201PC\345\222\214PC.md" index 8041d4d..9b94bed 100644 --- "a/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\357\274\232 \344\270\200\350\207\264\346\200\247\343\200\201PC\345\222\214PC.md" +++ "b/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\357\274\232 \344\270\200\350\207\264\346\200\247\343\200\201PC\345\222\214PC.md" @@ -1,3 +1,12 @@ +# Table of Contents + + * [**引言**](#引言) + * [**一致性(consensus)**](#一致性consensus) + * [**2PC**](#2pc) + * [**3PC**](#3pc) + * [**å°�结**](#å°�结) + + 本文转自 https://www.cnblogs.com/bangerlee/p/5268485.html æœ¬ç³»åˆ—æ–‡ç« å°†æ•´ç�†åˆ°æˆ‘在GitHub上的《Javaé�¢è¯•指å�—》仓库,更多精彩内容请到我的仓库里查看 @@ -31,7 +40,7 @@ 一致性是分布å¼�ç�†è®ºä¸çš„æ ¹æœ¬æ€§é—®é¢˜ï¼Œè¿‘å�Šä¸ªä¸–纪以æ�¥ï¼Œç§‘å¦å®¶ä»¬å›´ç»•ç�€ä¸€è‡´æ€§é—®é¢˜æ��出了很多ç�†è®ºæ¨¡åž‹ï¼Œä¾�æ�®è¿™äº›ç�†è®ºæ¨¡åž‹ï¼Œä¸šç•Œä¹Ÿå‡ºçŽ°äº†å¾ˆå¤šå·¥ç¨‹å®žè·µæŠ•å½±ã€‚ä¸‹é�¢æˆ‘们从一致性问题ã€�特定æ�¡ä»¶ä¸‹è§£å†³ä¸€è‡´æ€§é—®é¢˜çš„两ç§�方法(2PCã€�3PC)入门,了解最基础的分布å¼�系统ç�†è®ºã€‚ -**一致性(consensus)** +### **一致性(consensus)** 何为一致性问题?简å�•而言,一致性问题就是相互独立的节点之间如何达æˆ�一项决议的问题。分布å¼�系统ä¸ï¼Œè¿›è¡Œæ•°æ�®åº“事务æ��交(commit transaction)ã€�Leader选举ã€�åº�列å�·ç”Ÿæˆ�ç‰éƒ½ä¼šé�‡åˆ°ä¸€è‡´æ€§é—®é¢˜ã€‚这个问题在我们的日常生活ä¸ä¹Ÿå¾ˆå¸¸è§�,比如牌å�‹æ€Žä¹ˆå•†å®šå‡ ç‚¹åœ¨å“ªæ‰“å‡ åœˆéº»å°†ï¼š @@ -60,7 +69,7 @@ _《赌圣》,1990_ -
我: è€�王,今晚7点è€�地方,æ�“够48圈ä¸�è§�ä¸�æ•£ï¼� +我: è€�王,今晚7点è€�地方,æ�“够48圈ä¸�è§�ä¸�æ•£ï¼� …… (第二天凌晨3点) éš”å£�è€�王: 没问题ï¼� // 消æ�¯å»¶è¿Ÿ 我: …… @@ -71,7 +80,7 @@ _《赌圣》,1990_ 我: …… ----------------------------------------------- 我: è€�æ�Žå¤´ï¼Œä»Šæ™š7点è€�地方,æ�“够48圈ä¸�è§�ä¸�æ•£ï¼� -è€�æ�Ž: 必须的,大ä¿�å�¥èµ°èµ·ï¼� // 拜å� åºå°†å†› (这是è¦�打麻将呢?还是è¦�大ä¿�å�¥ï¼Ÿè¿˜æ˜¯ä¸€è¾¹æ‰“麻将一边大ä¿�å�¥â€¦â€¦ï¼‰+è€�æ�Ž: 必须的,大ä¿�å�¥èµ°èµ·ï¼� // 拜å� åºå°†å†› (这是è¦�打麻将呢?还是è¦�大ä¿�å�¥ï¼Ÿè¿˜æ˜¯ä¸€è¾¹æ‰“麻将一边大ä¿�å�¥â€¦â€¦ï¼‰ç›®å½• @@ -94,7 +103,7 @@ FLP定ç�†æ˜¯åˆ†å¸ƒå¼�系统ç�†è®ºä¸çš„基础ç�†è®ºï¼Œæ£å¦‚物ç�†å¦ä¸çš„能 _《怦然心动 (Flipped)》,2010_ å·¥ç¨‹å®žè·µä¸Šæ ¹æ�®å…·ä½“的业务场景,或ä¿�è¯�强一致(safety),或在节点宕机ã€�网络分化的时候ä¿�è¯�å�¯ç”¨(liveness)。2PCã€�3PC是相对简å�•的解决一致性问题的å��议,下é�¢æˆ‘们就æ�¥äº†è§£2PCå’Œ3PC。 -**2PC** +### **2PC** 2PC(tow phase commit)两阶段æ��交[5]顾å��æ€�义它分æˆ�两个阶段,先由一方进行æ��è®®(propose)并收集其他节点的å��馈(vote),å†�æ ¹æ�®å��馈决定æ��交(commit)æˆ–ä¸æ¢(abort)事务。我们将æ��议的节点称为å��调者(coordinator),其他å�‚与决议节点称为å�‚与者(participants, 或cohorts): @@ -116,7 +125,7 @@ coordinator如果在å�‘èµ·æ��è®®å�Žå®•机,那么participant将进入阻塞(blo 从coordinator接收到一次事务请求ã€�å�‘èµ·æ��议到事务完æˆ�,ç»�过2PCå��è®®å�Žå¢žåŠ äº†2次RTT(propose+commit),带æ�¥çš„æ—¶å»¶(latency)å¢žåŠ ç›¸å¯¹è¾ƒå°‘ã€‚ -**3PC** +### **3PC** 3PC(three phase commit)å�³ä¸‰é˜¶æ®µæ��交[6][7],既然2PCå�¯ä»¥åœ¨å¼‚æ¥ç½‘络+节点宕机æ�¢å¤�的模型下实现一致性,那还需è¦�3PCå�šä»€ä¹ˆï¼Œ3PC是什么鬼? @@ -141,7 +150,7 @@ participant如果在ä¸�å�Œé˜¶æ®µå®•机,我们æ�¥çœ‹çœ‹3PC如何应对: å› ä¸ºæœ‰äº†å‡†å¤‡æ��交(prepare to commit)阶段,3PC的事务处ç�†å»¶æ—¶ä¹Ÿå¢žåŠ äº†1个RTT,å�˜ä¸º3个RTT(propose+precommit+commit),但是它防æ¢participant宕机å�Žæ•´ä¸ªç³»ç»Ÿè¿›å…¥é˜»å¡žæ€�,增强了系统的å�¯ç”¨æ€§ï¼Œå¯¹ä¸€äº›çŽ°å®žä¸šåŠ¡åœºæ™¯æ˜¯é�žå¸¸å€¼å¾—的。 -**å°�结** +### **å°�结** 以上介ç»�了分布å¼�系统ç�†è®ºä¸çš„部分基础知识,é˜�述了一致性(consensus)的定义和实现一致性所è¦�é�¢ä¸´çš„问题,最å�Žè®¨è®ºåœ¨å¼‚æ¥ç½‘络(asynchronous)ã€�节点宕机æ�¢å¤�(fail-recover)模型下2PCã€�3PC怎么解决一致性问题。 @@ -159,4 +168,4 @@ participant如果在ä¸�å�Œé˜¶æ®µå®•机,我们æ�¥çœ‹çœ‹3PC如何应对: [6][Consensus Protocols: Three-phase Commit](http://the-paper-trail.org/blog/consensus-protocols-three-phase-commit/),Henry Robinson, 2008 -[7][Three-phase commit protocol](https://en.wikipedia.org/wiki/Three-phase_commit_protocol),Wikipedia \ No newline at end of file +[7][Three-phase commit protocol](https://en.wikipedia.org/wiki/Three-phase_commit_protocol),Wikipedia diff --git "a/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\357\274\232 \346\227\266\351\227\264\343\200\201\346\227\266\351\222\237\345\222\214\344\272\213\344\273\266\351\241\272\345\272\217.md" "b/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\357\274\232 \346\227\266\351\227\264\343\200\201\346\227\266\351\222\237\345\222\214\344\272\213\344\273\266\351\241\272\345\272\217.md" index 47b12a6..47d52a7 100644 --- "a/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\357\274\232 \346\227\266\351\227\264\343\200\201\346\227\266\351\222\237\345\222\214\344\272\213\344\273\266\351\241\272\345\272\217.md" +++ "b/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\357\274\232 \346\227\266\351\227\264\343\200\201\346\227\266\351\222\237\345\222\214\344\272\213\344\273\266\351\241\272\345\272\217.md" @@ -1,3 +1,12 @@ +# Table of Contents + + * [**物ç�†æ—¶é’Ÿ vs 逻辑时钟**](#物ç�†æ—¶é’Ÿ-vs-逻辑时钟) + * [**Lamport timestamps**](#lamport-timestamps) + * [**Vector clock**](#vector-clock) + * [**Version vector**](#version-vector) + * [**å°�结**](#å°�结) + + 转自:https://www.cnblogs.com/bangerlee/p/5448766.html æœ¬ç³»åˆ—æ–‡ç« å°†æ•´ç�†åˆ°æˆ‘在GitHub上的《Javaé�¢è¯•指å�—》仓库,更多精彩内容请到我的仓库里查看 @@ -21,7 +30,7 @@ çŽ°å®žç”Ÿæ´»ä¸æ—¶é—´æ˜¯å¾ˆé‡�è¦�的概念,时间å�¯ä»¥è®°å½•事情å�‘生的时刻ã€�比较事情å�‘生的先å�Žé¡ºåº�。分布å¼�系统的一些场景也需è¦�记录和比较ä¸�å�ŒèŠ‚ç‚¹é—´äº‹ä»¶å�‘生的顺åº�,但ä¸�å�ŒäºŽæ—¥å¸¸ç”Ÿæ´»ä½¿ç”¨ç‰©ç�†æ—¶é’Ÿè®°å½•时间,分布å¼�系统使用逻辑时钟记录事件顺åº�关系,下é�¢æˆ‘们æ�¥çœ‹åˆ†å¸ƒå¼�系统ä¸å‡ ç§�常è§�的逻辑时钟。 -**物ç�†æ—¶é’Ÿ vs 逻辑时钟** +## **物ç�†æ—¶é’Ÿ vs 逻辑时钟** å�¯èƒ½æœ‰äººä¼šé—®ï¼Œä¸ºä»€ä¹ˆåˆ†å¸ƒå¼�系统ä¸�使用物ç�†æ—¶é’Ÿ(physical clock)记录事件?æ¯�个事件对应打上一个时间戳,当需è¦�比较顺åº�的时候比较相应时间戳就好了。 @@ -29,7 +38,7 @@  -**Lamport timestamps** +## **Lamport timestamps** [Leslie](https://en.wikipedia.org/wiki/Leslie_Cheung)[Lamport](https://en.wikipedia.org/wiki/Leslie_Lamport)在1978å¹´æ��出逻辑时钟的概念,并æ��述了一ç§�逻辑时钟的表示方法,这个方法被称为Lamport时间戳(Lamport timestamps)[3]。 @@ -50,7 +59,7 @@ _图1: Lamport timestamps space time (图片æ�¥æº�: wikipedia)_ 通过以上定义,我们å�¯ä»¥å¯¹æ‰€æœ‰äº‹ä»¶æŽ’åº�ã€�获得事件的[å…¨åº�关系](https://en.wikipedia.org/wiki/Total_order)(total order)。上图例å�,我们å�¯ä»¥ä»ŽC1到A4进行排åº�。 -**Vector clock** +## **Vector clock** Lamport时间戳帮助我们得到事件顺åº�关系,但还有一ç§�顺åº�关系ä¸�能用Lamport时间戳很好地表示出æ�¥ï¼Œé‚£å°±æ˜¯å�Œæ—¶å�‘生关系(concurrent)[4]。例如图1ä¸äº‹ä»¶B4和事件C3æ²¡æœ‰å› æžœå…³ç³»ï¼Œå±žäºŽå�Œæ—¶å�‘生事件,但Lamport时间戳定义两者有先å�Žé¡ºåº�。 @@ -64,7 +73,7 @@ _图2: Vector clock space time (_图片æ�¥æº�: wikipedia)__ 如果Tb[Q] > Ta[Q] 并且 Tb[P] < Ta[P],则认为aã€�bå�Œæ—¶å�‘生,记作 a <-> b。例如图2ä¸èŠ‚ç‚¹B上的第4个事件 (A:2,B:4,C:1) 与节点C上的第2个事件 (B:3,C:2) æ²¡æœ‰å› æžœå…³ç³»ã€�属于å�Œæ—¶å�‘生事件。 -**Version vector** +## **Version vector** 基于Vector clock我们å�¯ä»¥èŽ·å¾—ä»»æ„�两个事件的顺åº�关系,结果或为先å�Žé¡ºåº�或为å�Œæ—¶å�‘生,识别事件顺åº�åœ¨å·¥ç¨‹å®žè·µä¸æœ‰å¾ˆé‡�è¦�的引申应用,最常è§�的应用是å�‘现数æ�®å†²çª�(detect conflict)。 @@ -85,7 +94,7 @@ Vector clockå�ªç”¨äºŽå�‘现数æ�®å†²çª�,ä¸�能解决数æ�®å†²çª�。如何解 解决该问题的方法是使用server idå�–代client id创建vector (å› ä¸ºserver的数é‡�相对client稳定),或设定最大的sizeã€�如果超过该size值则淘汰最旧的vectorä¿¡æ�¯[10][13]。 -**å°�结** +## **å°�结** 以上介ç»�了分布å¼�系统里逻辑时钟的表示方法,通过Lamport timestampså�¯ä»¥å»ºç«‹äº‹ä»¶çš„å…¨åº�关系,通过Vector clockå�¯ä»¥æ¯”较任æ„�两个事件的顺åº�å…³ç³»å¹¶ä¸”èƒ½è¡¨ç¤ºæ— å› æžœå…³ç³»çš„äº‹ä»¶ï¼Œå°†Vector clock的方法用于å�‘现数æ�®ç‰ˆæœ¬å†²çª�,于是有了Version vector。 @@ -113,4 +122,4 @@ Vector clockå�ªç”¨äºŽå�‘现数æ�®å†²çª�,ä¸�能解决数æ�®å†²çª�。如何解 [12][Why Vector Clocks Are Hard](http://basho.com/posts/technical/why-vector-clocks-are-hard/), Justin Sheehy, 2010 -[13][Causality Is Expensive (and What To Do About It)](http://www.bailis.org/blog/causality-is-expensive-and-what-to-do-about-it/), Peter Bailis ,2014 \ No newline at end of file +[13][Causality Is Expensive (and What To Do About It)](http://www.bailis.org/blog/causality-is-expensive-and-what-to-do-about-it/), Peter Bailis ,2014 diff --git "a/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\357\274\232Paxos.md" "b/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\357\274\232Paxos.md" index 5171749..030e7ac 100644 --- "a/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\357\274\232Paxos.md" +++ "b/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\357\274\232Paxos.md" @@ -1,3 +1,11 @@ +# Table of Contents + + * [**引言**](#引言) + * [**Basic Paxos**](#basic-paxos) + * [**Multi Paxos**](#multi-paxos) + * [**å°�结**](#å°�结) + + 本文转自:https://www.cnblogs.com/bangerlee/p/5655754.html æœ¬ç³»åˆ—æ–‡ç« å°†æ•´ç�†åˆ°æˆ‘在GitHub上的《Javaé�¢è¯•指å�—》仓库,更多精彩内容请到我的仓库里查看 @@ -23,7 +31,7 @@ Paxoså��è®®å�Œæ—¶å�ˆä»¥å…¶â€œè‰°æ·±æ™¦æ¶©â€�著称,下é�¢ç»“å�ˆ[Paxos Made Simple](http://research.microsoft.com/en-us/um/people/lamport/pubs/paxos-simple.pdf)ã€�[The Part-Time Parliament](http://research.microsoft.com/en-us/um/people/lamport/pubs/lamport-paxos.pdf)两篇论文,å°�试通过Paxos推演ã€�å¦ä¹ 和了解Paxoså��议。 -**Basic Paxos** +## **Basic Paxos** 何为一致性问题?简å�•而言,一致性问题是在节点宕机ã€�消æ�¯æ— åº�ç‰åœºæ™¯å�¯èƒ½å‡ºçŽ°çš„æƒ…å†µä¸‹ï¼Œç›¸äº’ç‹¬ç«‹çš„èŠ‚ç‚¹ä¹‹é—´å¦‚ä½•è¾¾æˆ�决议的问题,作为解决一致性问题的å��议,Paxosçš„æ ¸å¿ƒæ˜¯èŠ‚ç‚¹é—´å¦‚ä½•ç¡®å®šå¹¶å�ªç¡®å®šä¸€ä¸ªå€¼(value)。 @@ -125,7 +133,7 @@ _(注: å¸Œè…Šå—æ¯�ß表示多轮决议的集å�ˆï¼Œå—æ¯�B表示一轮决议)_ 最å�Žæˆ‘们å†�引入一个新的角色:learner,learnerä¾�附于acceptorï¼Œç”¨äºŽä¹ å¾—å·²ç¡®å®šçš„å†³è®®ã€‚ä»¥ä¸Šå†³è®®è¿‡ç¨‹éƒ½å�ªè¦�求acceptor多数派å�‚与,而我们希望尽é‡�所有acceptor的状æ€�一致。如果部分acceptorå› å®•æœºç‰åŽŸå› æœªçŸ¥æ™“å·²ç¡®å®šå†³è®®ï¼Œå®•æœºæ�¢å¤�å�Žå�¯ç»�本机learner采用pull的方å¼�从其他acceptorä¹ å¾—ã€‚ -**Multi Paxos** +## **Multi Paxos** 通过以上æ¥éª¤åˆ†å¸ƒå¼�系统已ç»�能确定一个值,“å�ªç¡®å®šä¸€ä¸ªå€¼æœ‰ä»€ä¹ˆç”¨ï¼Ÿè¿™å�¯è§£å†³ä¸�了我é�¢ä¸´çš„问题。â€� ä½ å¿ƒä¸å�¯èƒ½æœ‰è¿™æ ·çš„疑问。 @@ -139,7 +147,7 @@ _(注: å¸Œè…Šå—æ¯�ß表示多轮决议的集å�ˆï¼Œå—æ¯�B表示一轮决议)_ proposer leader在Multi Paxosä¸è¿˜æœ‰åŠ©äºŽæ��å�‡æ€§èƒ½ï¼Œå¸¸æ€�下统一由leaderå�‘èµ·æ��议,å�¯èŠ‚çœ�prepareæ¥éª¤(leaderä¸�用问询acceptor曾接å�—过的ID最大的æ��è®®ã€�å�ªæœ‰leaderæ��议也ä¸�需è¦�acceptor进行promise)直至å�‘生leader宕机ã€�é‡�新选主。 -**å°�结** +## **å°�结** 以上介ç»�了Paxos的推演过程ã€�如何在Basic Paxos的基础上通过状æ€�机构建Multi Paxos。Paxoså��议比较“艰深晦涩â€�ï¼Œä½†å¤šè¯»å‡ é��论文一般能ç�†è§£å…¶å†…涵,更难的是如何将Paxos真æ£åº”用到工程实践。 @@ -155,4 +163,4 @@ proposer leader在Multi Paxosä¸è¿˜æœ‰åŠ©äºŽæ��å�‡æ€§èƒ½ï¼Œå¸¸æ€�下统一由lea [《分布å¼�系统ç�†è®ºåŸºç¡€ - æ—¶é—´ã€�时钟和事件顺åº�》](http://www.cnblogs.com/bangerlee/p/5448766.html) -[《分布å¼�系统ç�†è®ºåŸºç¡€ - CAP》](http://www.cnblogs.com/bangerlee/p/5328888.html) \ No newline at end of file +[《分布å¼�系统ç�†è®ºåŸºç¡€ - CAP》](http://www.cnblogs.com/bangerlee/p/5328888.html) diff --git "a/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\357\274\232Raft\343\200\201Zab.md" "b/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\357\274\232Raft\343\200\201Zab.md" index a03b394..a774ab2 100644 --- "a/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\357\274\232Raft\343\200\201Zab.md" +++ "b/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\357\274\232Raft\343\200\201Zab.md" @@ -1,3 +1,12 @@ +# Table of Contents + + * [**引言**](#引言) + * [**Raft**](#raft) + * [**Zab**](#zab) + * [**Paxosã€�Raftã€�Zabå†�比较**](#paxosã€�raftã€�zabå†�比较) + * [**å°�结**](#å°�结) + + 本文转自:[https://www.cnblogs.com/bangerlee/p/5991417.html](https://www.cnblogs.com/bangerlee/p/5991417.html) æœ¬ç³»åˆ—æ–‡ç« å°†æ•´ç�†åˆ°æˆ‘在GitHub上的《Javaé�¢è¯•指å�—》仓库,更多精彩内容请到我的仓库里查看 @@ -22,7 +31,7 @@ [《分布å¼�系统ç�†è®ºè¿›é˜¶ - Paxos》](http://www.cnblogs.com/bangerlee/p/5655754.html)介ç»�了一致性å��è®®Paxos,今天我们æ�¥å¦ä¹ å�¦å¤–两个常è§�的一致性å��议——Raftå’ŒZab。通过与Paxos对比,了解Raftå’ŒZabçš„æ ¸å¿ƒæ€�想ã€�åŠ æ·±å¯¹ä¸€è‡´æ€§å��议的认识。 -**Raft** +## **Raft** Paxoså��å�‘于ç�†è®ºã€�对如何应用到工程实践æ��å�Šè¾ƒå°‘。ç�†è§£çš„éš¾åº¦åŠ ä¸ŠçŽ°å®žçš„éª¨æ„Ÿï¼Œåœ¨ç”Ÿäº§çŽ¯å¢ƒä¸åŸºäºŽPaxos实现一个æ£ç¡®çš„分布å¼�系统é�žå¸¸éš¾[1]: @@ -51,7 +60,7 @@ Raft[2](#)在2013å¹´æ��出,æ��出的时间虽然ä¸�长,但已ç»�有很多系 Paxosä¸Leaderçš„å˜åœ¨æ˜¯ä¸ºäº†æ��å�‡å†³è®®æ•ˆçŽ‡ï¼ŒLeaderçš„æœ‰æ— å’Œæ•°ç›®å¹¶ä¸�å½±å“�决议一致性,Raftè¦�求具备唯一Leader,并把一致性问题具体化为ä¿�æŒ�日志副本的一致性,以æ¤å®žçŽ°ç›¸è¾ƒPaxos而言更容易ç�†è§£ã€�æ›´å®¹æ˜“å®žçŽ°çš„ç›®æ ‡ã€‚ -**Zab** +## **Zab** Zab[5](#)的全称是Zookeeper atomic broadcast protocol,是Zookeeper内部用到的一致性å��议。相比Paxos,Zab最大的特点是ä¿�è¯�强一致性(strong consistency,或å�«çº¿æ€§ä¸€è‡´æ€§linearizable consistency)。 @@ -85,7 +94,7 @@ Zab䏿¯�个事务对应一个zxid,它由两部分组æˆ�:
Annotation[] annotations = field.getDeclaredAnnotations();
+Field field = ... //获�方法对象目录
+Annotation[] annotations = field.getDeclaredAnnotations();
for(Annotation annotation : annotations){
if(annotation instanceof MyAnnotation){
@@ -418,8 +418,8 @@ for(Annotation annotation : annotations){
ä½ å�¯ä»¥åƒ�è¿™æ ·è®¿é—®æŒ‡å®šçš„å�˜é‡�注解:
```
-Field field = ...//获�方法对象
-
+Field field = ...//获�方法对象目录
+
Annotation annotation = field.getAnnotation(MyAnnotation.class);
if(annotation instanceof MyAnnotation){
diff --git a/src/main/java/md/mdToc.java b/src/main/java/md/mdToc.java
index 6dbcab7..a5216f0 100644
--- a/src/main/java/md/mdToc.java
+++ b/src/main/java/md/mdToc.java
@@ -4,7 +4,7 @@
public class mdToc {
public static void main(String[] args) {
- String path = "D:\\idea_project\\javaTutorial\\docs\\database";
+ String path = "D:\\idea_project\\JavaTutorial\\docs\\distributed\\basic";
AtxMarkdownToc.newInstance().genTocDir(path);
}
}
From 33753f61770dfef23ad54e1e4342f54df88d7fb7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=BB=84=E5=B0=8F=E6=96=9C?= <362294931@qq.com>
Date: Sun, 9 Apr 2023 17:15:21 +0800
Subject: [PATCH 03/39] modify distributed mds
---
ReadMe.md | 2 +-
...06\350\256\272\346\200\273\347\273\223.md" | 11 ++++++-
...06\344\270\216\345\256\236\350\267\265.md" | 3 +-
...6\210\220Redis\347\274\223\345\255\230.md" | 2 ++
...01\347\250\213\350\257\246\350\247\243.md" | 30 ++++++++++++++++++-
...57\345\217\212\345\256\236\350\267\265.md" | 3 +-
...41\347\220\206\345\256\236\346\210\230.md" | 4 ++-
...03\345\274\217\344\272\213\345\212\241.md" | 1 +
...44\270\200\350\207\264\346\200\247hash.md" | 20 ++++++++++++-
...57\274\214Raft\347\256\227\346\263\225.md" | 4 ++-
...43\345\206\263\346\226\271\346\241\210.md" | 15 +++++++++-
...72\346\234\254\346\246\202\345\277\265.md" | 1 +
...0\203\346\234\215\345\212\241zookeeper.md" | 11 ++++++-
...03\345\274\217\344\272\213\345\212\241.md" | 16 ++++++++++
...6\201\257\346\212\200\346\234\257Kafka.md" | 17 ++++++++++-
...40\347\247\215\346\226\271\346\241\210.md" | 12 ++++++++
...40\344\275\225\350\200\214\347\224\237.md" | 4 +--
...60\347\232\204\345\245\227\350\267\257.md" | 3 +-
...37\346\210\220\346\226\271\346\241\210.md" | 23 ++++++++------
src/main/java/md/mdToc.java | 2 +-
20 files changed, 160 insertions(+), 24 deletions(-)
rename "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\206\345\270\203\345\274\217ID\347\224\237\346\210\220\346\226\271\346\241\210.md" => "docs/distributed/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\206\345\270\203\345\274\217ID\347\224\237\346\210\220\346\226\271\346\241\210.md" (94%)
diff --git a/ReadMe.md b/ReadMe.md
index 484bbda..ee75d4c 100644
--- a/ReadMe.md
+++ b/ReadMe.md
@@ -334,7 +334,7 @@ todo
[//]: # (* [�懂分布�技术:Nginx负载�衡原�与实践 ]docs/distributed/practice/�懂分布�技术:Nginx负载�衡原�与实践.md)
* [�懂分布�技术:LVS实现负载�衡的原�与实践 ](docs/distributed/practice/�懂分布�技术:LVS实现负载�衡的原�与实践.md )
* [�懂分布�技术:分布�session解决方案与一致性hash](docs/distributed/practice/�懂分布�技术:分布�session解决方案与一致性hash.md)
-* [�懂分布�技术:分布�ID生�方案 ](docs/distributed/practice/�懂分布�技术:分布�ID生�方案.md )
+* [�懂分布�技术:分布�ID生�方案 ](docs/distributed/�懂分布�技术:分布�ID生�方案.md )
* [æ�žæ‡‚分布å¼�技术:缓å˜çš„那些事](docs/distributed/practice/æ�žæ‡‚分布å¼�技术:缓å˜çš„那些事.md)
* [æ�žæ‡‚分布å¼�技术:SpringBoot使用注解集æˆ�Redis缓å˜](docs/distributed/practice/æ�žæ‡‚分布å¼�技术:SpringBoot使用注解集æˆ�Redis缓å˜.md)
* [æ�žæ‡‚分布å¼�æŠ€æœ¯ï¼šç¼“å˜æ›´æ–°çš„套路 ](docs/distributed/practice/æ�žæ‡‚分布å¼�æŠ€æœ¯ï¼šç¼“å˜æ›´æ–°çš„套路.md )
diff --git "a/docs/distributed/practice/\345\210\206\345\270\203\345\274\217\347\220\206\350\256\272\346\200\273\347\273\223.md" "b/docs/distributed/practice/\345\210\206\345\270\203\345\274\217\347\220\206\350\256\272\346\200\273\347\273\223.md"
index ff2647f..d7b5027 100644
--- "a/docs/distributed/practice/\345\210\206\345\270\203\345\274\217\347\220\206\350\256\272\346\200\273\347\273\223.md"
+++ "b/docs/distributed/practice/\345\210\206\345\270\203\345\274\217\347\220\206\350\256\272\346\200\273\347\273\223.md"
@@ -1,3 +1,12 @@
+# Table of Contents
+
+ * [å…ã€�Raft](#å…ã€�raft)
+ * [�个 Candidate 的竞选](#�个-candidate-的竞选)
+ * [多个 Candidate 竞选](#多个-candidate-竞选)
+ * [æ•°æ�®å�Œæ¥](#æ•°æ�®å�Œæ¥)
+ * [�考](#�考)
+
+
## å…ã€�Raft
Raft 也是分布�一致性�议,主�是用�竞选主节点。
@@ -63,4 +72,4 @@ Raft 也是分布�一致性�议,主�是用�竞选主节点。
- [深入�解分布�事务](https://juejin.im/entry/577c6f220a2b5800573492be)
- [What is CAP theorem in distributed database system?](http://www.colooshiki.com/index.php/2017/04/20/what-is-cap-theorem-in-distributed-database-system/)
- [NEAT ALGORITHMS - PAXOS](http://harry.me/blog/2014/12/27/neat-algorithms-paxos/)
-- [Paxos By Example](https://angus.nyc/2012/paxos-by-example/)
\ No newline at end of file
+- [Paxos By Example](https://angus.nyc/2012/paxos-by-example/)
diff --git "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232LVS\345\256\236\347\216\260\350\264\237\350\275\275\345\235\207\350\241\241\347\232\204\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265.md" "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232LVS\345\256\236\347\216\260\350\264\237\350\275\275\345\235\207\350\241\241\347\232\204\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265.md"
index 29837ba..6983151 100644
--- "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232LVS\345\256\236\347\216\260\350\264\237\350\275\275\345\235\207\350\241\241\347\232\204\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265.md"
+++ "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232LVS\345\256\236\347\216\260\350\264\237\350\275\275\345\235\207\350\241\241\347\232\204\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265.md"
@@ -1,3 +1,4 @@
+
# 目录
* [负载�衡的原�](#负载�衡的原�)
@@ -555,4 +556,4 @@ public class TestIpHash {
}
}
-````
\ No newline at end of file
+````
diff --git "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232SpringBoot\344\275\277\347\224\250\346\263\250\350\247\243\351\233\206\346\210\220Redis\347\274\223\345\255\230.md" "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232SpringBoot\344\275\277\347\224\250\346\263\250\350\247\243\351\233\206\346\210\220Redis\347\274\223\345\255\230.md"
index 5bc10ee..adb2c2c 100644
--- "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232SpringBoot\344\275\277\347\224\250\346\263\250\350\247\243\351\233\206\346\210\220Redis\347\274\223\345\255\230.md"
+++ "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232SpringBoot\344\275\277\347\224\250\346\263\250\350\247\243\351\233\206\346\210\220Redis\347\274\223\345\255\230.md"
@@ -1,3 +1,5 @@
+
+
# 目录
* [Redis�置](#redis�置)
diff --git "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232ZAB\345\215\217\350\256\256\346\246\202\350\277\260\344\270\216\351\200\211\344\270\273\346\265\201\347\250\213\350\257\246\350\247\243.md" "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232ZAB\345\215\217\350\256\256\346\246\202\350\277\260\344\270\216\351\200\211\344\270\273\346\265\201\347\250\213\350\257\246\350\247\243.md"
index 01a7be8..4a62581 100644
--- "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232ZAB\345\215\217\350\256\256\346\246\202\350\277\260\344\270\216\351\200\211\344\270\273\346\265\201\347\250\213\350\257\246\350\247\243.md"
+++ "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232ZAB\345\215\217\350\256\256\346\246\202\350\277\260\344\270\216\351\200\211\344\270\273\346\265\201\347\250\213\350\257\246\350\247\243.md"
@@ -1,3 +1,31 @@
+# Table of Contents
+
+ * [ZAB�议](#zab�议)
+ * [消æ�¯å¹¿æ’模å¼�](#消æ�¯å¹¿æ’模å¼�)
+ * [崩溃��](#崩溃��)
+ * [æ•°æ�®å�Œæ¥](#æ•°æ�®å�Œæ¥)
+ * [ZAB�议原�](#zab�议原�)
+ * [Zookeeperè®¾è®¡ç›®æ ‡](#zookeeperè®¾è®¡ç›®æ ‡)
+* [ZAB与FastLeaderElection选主算法�程详解](#zab与fastleaderelection选主算法�程详解)
+ * [选择机制ä¸çš„æ¦‚念](#选择机制ä¸çš„æ¦‚念)
+ * [�务器ID](#�务器id)
+ * [数�ID](#数�id)
+ * [逻辑时钟](#逻辑时钟)
+ * [选举状�](#选举状�)
+ * [选举消�内容](#选举消�内容)
+ * [选举�程图](#选举�程图)
+ * [åˆ¤æ–æ˜¯å�¦å·²ç»�胜出](#åˆ¤æ–æ˜¯å�¦å·²ç»�胜出)
+ * [选举�程简述](#选举�程简述)
+ * [å‡ ç§�领导选举场景](#å‡ ç§�领导选举场景)
+ * [集群�动领导选举](#集群�动领导选举)
+ * [Follower��](#follower��)
+ * [Leader��](#leader��)
+* [一致性��](#一致性��)
+ * [Commit过的数��丢失](#commit过的数��丢失)
+ * [未Commit过的消�对客户端���")未Commit过的消�对客户端���](#未commit过的消�对客户端���未commit过的消�对客户端���)
+* [总结](#总结)
+
+
本文内容å�‚考网络,侵åˆ
æœ¬ç³»åˆ—æ–‡ç« å°†æ•´ç�†åˆ°æˆ‘在GitHub上的《Javaé�¢è¯•指å�—》仓库,更多精彩内容请到我的仓库里查看
@@ -348,4 +376,4 @@ ZABå��è®®ä¿�è¯�了在Leader选举的过程ä¸ï¼Œå·²ç»�被Commit的数æ�®ä¸�会
* 由于使用主从å¤�制模å¼�,所有的写æ“�作都è¦�ç”±Leader主导完æˆ�,而读æ“�作å�¯é€šè¿‡ä»»æ„�节点完æˆ�ï¼Œå› æ¤Zookeeper读性能远好于写性能,更适å�ˆè¯»å¤šå†™å°‘的场景
* 虽然使用主从å¤�制模å¼�,å�Œä¸€æ—¶é—´å�ªæœ‰ä¸€ä¸ªLeader,但是Failover机制ä¿�è¯�了集群ä¸�å˜åœ¨å�•点失败(SPOF)的问题
* ZABå��è®®ä¿�è¯�了Failover过程ä¸çš„æ•°æ�®ä¸€è‡´æ€§
-* �务器收到数��先写本地文件�进行处�,��了数�的�久性
\ No newline at end of file
+* �务器收到数��先写本地文件�进行处�,��了数�的�久性
diff --git "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232Zookeeper\345\205\270\345\236\213\345\272\224\347\224\250\345\234\272\346\231\257\345\217\212\345\256\236\350\267\265.md" "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232Zookeeper\345\205\270\345\236\213\345\272\224\347\224\250\345\234\272\346\231\257\345\217\212\345\256\236\350\267\265.md"
index 7e5a1bf..e007cd6 100644
--- "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232Zookeeper\345\205\270\345\236\213\345\272\224\347\224\250\345\234\272\346\231\257\345\217\212\345\256\236\350\267\265.md"
+++ "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232Zookeeper\345\205\270\345\236\213\345\272\224\347\224\250\345\234\272\346\231\257\345\217\212\345\256\236\350\267\265.md"
@@ -1,3 +1,4 @@
+
# 目录
* [一.ZooKeeper典型应用场景实践](#一zookeeper典型应用场景实践)
@@ -479,4 +480,4 @@ Master选举
第二类,和分布å¼�é”�æœ�务ä¸çš„æŽ§åˆ¶æ—¶åº�场景基本原ç�†ä¸€è‡´ï¼Œå…¥åˆ—有编å�·ï¼Œå‡ºåˆ—按编å�·ã€‚
-å�Œæ¥é˜Ÿåˆ—。一个job由多个task组æˆ�,å�ªæœ‰æ‰€æœ‰ä»»åŠ¡å®Œæˆ�å�Žï¼Œjobæ‰�è¿�行完æˆ�。å�¯ä¸ºjob创建一个/job目录,然å�Žåœ¨è¯¥ç›®å½•下,为æ¯�个完æˆ�çš„task创建一个临时znode,一旦临时节点数目达到task总数,则jobè¿�行完æˆ�。
\ No newline at end of file
+å�Œæ¥é˜Ÿåˆ—。一个job由多个task组æˆ�,å�ªæœ‰æ‰€æœ‰ä»»åŠ¡å®Œæˆ�å�Žï¼Œjobæ‰�è¿�行完æˆ�。å�¯ä¸ºjob创建一个/job目录,然å�Žåœ¨è¯¥ç›®å½•下,为æ¯�个完æˆ�çš„task创建一个临时znode,一旦临时节点数目达到task总数,则jobè¿�行完æˆ�。
diff --git "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232Zookeeper\347\232\204\351\205\215\347\275\256\344\270\216\351\233\206\347\276\244\347\256\241\347\220\206\345\256\236\346\210\230.md" "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232Zookeeper\347\232\204\351\205\215\347\275\256\344\270\216\351\233\206\347\276\244\347\256\241\347\220\206\345\256\236\346\210\230.md"
index 70fce53..a810400 100644
--- "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232Zookeeper\347\232\204\351\205\215\347\275\256\344\270\216\351\233\206\347\276\244\347\256\241\347\220\206\345\256\236\346\210\230.md"
+++ "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232Zookeeper\347\232\204\351\205\215\347\275\256\344\270\216\351\233\206\347\276\244\347\256\241\347\220\206\345\256\236\346\210\230.md"
@@ -1,3 +1,5 @@
+
+
# 目录
* [4.1 �置文件](#41-�置文件)
@@ -347,4 +349,4 @@ server.3=127.0.0.1:2890:3890
)
-å�¯è§�,关é—zk3以å�Žï¼Œç”±äºŽé›†ç¾¤ä¸çš„å�¯ç”¨Serverå�ªå‰©ä¸‹ä¸€å�°ï¼ˆè¾¾ä¸�到集群总数的å�Šæ•°ä»¥ä¸Šï¼‰ï¼Œ**集群将处于ä¸�å�¯ç”¨çš„状æ€�。**
\ No newline at end of file
+å�¯è§�,关é—zk3以å�Žï¼Œç”±äºŽé›†ç¾¤ä¸çš„å�¯ç”¨Serverå�ªå‰©ä¸‹ä¸€å�°ï¼ˆè¾¾ä¸�到集群总数的å�Šæ•°ä»¥ä¸Šï¼‰ï¼Œ**集群将处于ä¸�å�¯ç”¨çš„状æ€�。**
diff --git "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\344\275\277\347\224\250RocketMQ\344\272\213\345\212\241\346\266\210\346\201\257\350\247\243\345\206\263\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md" "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\344\275\277\347\224\250RocketMQ\344\272\213\345\212\241\346\266\210\346\201\257\350\247\243\345\206\263\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md"
index 15d55a7..decea79 100644
--- "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\344\275\277\347\224\250RocketMQ\344\272\213\345\212\241\346\266\210\346\201\257\350\247\243\345\206\263\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md"
+++ "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\344\275\277\347\224\250RocketMQ\344\272\213\345\212\241\346\266\210\346\201\257\350\247\243\345\206\263\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md"
@@ -1,3 +1,4 @@
+
# 目录
* [åˆ�æ¥è®¤è¯†RocketMQçš„æ ¸å¿ƒæ¨¡å�—](#åˆ�æ¥è®¤è¯†rocketmqçš„æ ¸å¿ƒæ¨¡å�—)
diff --git "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\206\345\270\203\345\274\217session\350\247\243\345\206\263\346\226\271\346\241\210\344\270\216\344\270\200\350\207\264\346\200\247hash.md" "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\206\345\270\203\345\274\217session\350\247\243\345\206\263\346\226\271\346\241\210\344\270\216\344\270\200\350\207\264\346\200\247hash.md"
index 08a10af..2c8510e 100644
--- "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\206\345\270\203\345\274\217session\350\247\243\345\206\263\346\226\271\346\241\210\344\270\216\344\270\200\350\207\264\346\200\247hash.md"
+++ "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\206\345\270\203\345\274\217session\350\247\243\345\206\263\346\226\271\346\241\210\344\270\216\344\270\200\350\207\264\346\200\247hash.md"
@@ -1,3 +1,21 @@
+# Table of Contents
+
+* [一�问题的�出](#一�问题的�出)
+ * [1. 什么是Session?](#1-什么是session?)
+ * [2. 什么是Session一致性问题?](#2-什么是session一致性问题?)
+* [二�Session一致性解决方案](#二�session一致性解决方案)
+ * [1. Session Stiky](#1-session-stiky)
+ * [2. Session Replication](#2-session-replication)
+ * [3. Sessionæ•°æ�®é›†ä¸å˜å‚¨](#3-sessionæ•°æ�®é›†ä¸å˜å‚¨)
+ * [4. Cookie Based](#4-cookie-based)
+* [三�总结](#三�总结)
+ * [一致性Hash概述](#一致性hash概述)
+ * [一致性hash的特性](#一致性hash的特性)
+ * [虚拟节点](#虚拟节点)
+ * [�匀一致性hash](#�匀一致性hash)
+ * [总结](#总结)
+
+
本文内容å�‚考网络,侵åˆ
@@ -182,4 +200,4 @@ hash环上顺时针从整数0å¼€å§‹ï¼Œä¸€ç›´åˆ°æœ€å¤§æ£æ•´æ•°ï¼Œæˆ‘ä»¬æ ¹æ�®å››
## 总结
-在分布å¼�系统ä¸ä¸€è‡´æ€§hashèµ·ç�€ä¸�å�¯å¿½ç•¥çš„地ä½�ï¼Œæ— è®ºæ˜¯åˆ†å¸ƒå¼�缓å˜ï¼Œè¿˜æ˜¯åˆ†å¸ƒå¼�Rpc框架的负载å�‡è¡¡ç–略都有所使用。
\ No newline at end of file
+在分布å¼�系统ä¸ä¸€è‡´æ€§hashèµ·ç�€ä¸�å�¯å¿½ç•¥çš„地ä½�ï¼Œæ— è®ºæ˜¯åˆ†å¸ƒå¼�缓å˜ï¼Œè¿˜æ˜¯åˆ†å¸ƒå¼�Rpc框架的负载å�‡è¡¡ç–略都有所使用。
diff --git "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\206\345\270\203\345\274\217\344\270\200\350\207\264\346\200\247\345\215\217\350\256\256\344\270\216Paxos\357\274\214Raft\347\256\227\346\263\225.md" "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\206\345\270\203\345\274\217\344\270\200\350\207\264\346\200\247\345\215\217\350\256\256\344\270\216Paxos\357\274\214Raft\347\256\227\346\263\225.md"
index 18256b0..c4a809d 100644
--- "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\206\345\270\203\345\274\217\344\270\200\350\207\264\346\200\247\345\215\217\350\256\256\344\270\216Paxos\357\274\214Raft\347\256\227\346\263\225.md"
+++ "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\206\345\270\203\345\274\217\344\270\200\350\207\264\346\200\247\345\215\217\350\256\256\344\270\216Paxos\357\274\214Raft\347\256\227\346\263\225.md"
@@ -1,3 +1,5 @@
+
+
# 目录
* [2PC](#2pc)
@@ -481,4 +483,4 @@ Leader 会ç‰å¾…大多数的 Follower 也进行了修改,然å�Žæ‰�将修改æ��
What is CAP theorem in distributed database system?
NEAT ALGORITHMS - PAXOS
Raft: Understandable Distributed Consensus
- Paxos By Example
\ No newline at end of file
+ Paxos By Example
diff --git "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\345\270\270\347\224\250\350\247\243\345\206\263\346\226\271\346\241\210.md" "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\345\270\270\347\224\250\350\247\243\345\206\263\346\226\271\346\241\210.md"
index fde3361..21a891b 100644
--- "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\345\270\270\347\224\250\350\247\243\345\206\263\346\226\271\346\241\210.md"
+++ "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\345\270\270\347\224\250\350\247\243\345\206\263\346\226\271\346\241\210.md"
@@ -1,3 +1,16 @@
+# Table of Contents
+
+* [一�概述](#一�概述)
+* [二��论](#二��论)
+ * [2.1�二阶段�交](#21�二阶段�交)
+ * [2.2�三阶段�交](#22�三阶段�交)
+ * [2.3�TCC柔性事务](#23�tcc柔性事务)
+ * [2.4�Seata](#24�seata)
+* [三�应用场景](#三�应用场景)
+* [四�总结](#四�总结)
+* [五ã€�å�‚考æº�ç �](#五ã€�å�‚考æº�ç �)
+
+
> æ•°æ�®ä¸�ä¼šæ— ç¼˜æ— æ•…ä¸¢å¤±ï¼Œä¹Ÿä¸�会莫å��其妙增åŠ
@@ -155,4 +168,4 @@ CREATE TABLE `tb_notice_message` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT
编程文档:https://gitee.com/cicadasmile/butte-java-note应用仓库:https://gitee.com/cicadasmile/butte-flyer-parent
```
-本文转载自 https://mp.weixin.qq.com/s/xa9Giv9xdSM3AahwN3WckQ
\ No newline at end of file
+本文转载自 https://mp.weixin.qq.com/s/xa9Giv9xdSM3AahwN3WckQ
diff --git "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\232\204\344\270\200\344\272\233\345\237\272\346\234\254\346\246\202\345\277\265.md" "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\232\204\344\270\200\344\272\233\345\237\272\346\234\254\346\246\202\345\277\265.md"
index d364788..e3e51ac 100644
--- "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\232\204\344\270\200\344\272\233\345\237\272\346\234\254\346\246\202\345\277\265.md"
+++ "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\232\204\344\270\200\344\272\233\345\237\272\346\234\254\346\246\202\345\277\265.md"
@@ -1,3 +1,4 @@
+
# 目录
* [1�分布�](#1�分布�)
* [2�集群(Cluster)](#2�集群(cluster))
diff --git "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\235\346\216\242\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241zookeeper.md" "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\235\346\216\242\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241zookeeper.md"
index f25a7d8..f8699df 100644
--- "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\235\346\216\242\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241zookeeper.md"
+++ "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\235\346\216\242\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241zookeeper.md"
@@ -1,3 +1,12 @@
+# Table of Contents
+
+* [目录](#目录)
+ * [��的邮件](#��的邮件)
+ * [�王的Master选举](#�王的master选举)
+ * [�蔡的分布��](#�蔡的分布��)
+ * [Zookeeper](#zookeeper)
+
+
# 目录
本文转自:微信公众å�·ã€�ç �农翻身】
@@ -152,4 +161,4 @@ Zookeeper æ‰€ä½¿ç”¨çš„æ ‘å½¢ç»“æž„å’Œè‡ªå·±æƒ³è±¡çš„é�žå¸¸ç±»ä¼¼ï¼Œæ›´é‡�è¦�çš„
_�记:本文从使用者的角度�述了Zookeeper有什么用处,至于它内部是如何工作,那是�外一个Big topic了,我们以��讲。___
-(完)
\ No newline at end of file
+(完)
diff --git "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\346\265\205\346\236\220\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md" "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\346\265\205\346\236\220\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md"
index a8b04d7..147a92e 100644
--- "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\346\265\205\346\236\220\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md"
+++ "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\346\265\205\346\236\220\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md"
@@ -1,3 +1,19 @@
+# Table of Contents
+
+* [目录](#目录)
+ * [什么是事务?](#什么是事务?)
+ * [事务的四大特性 ACID](#事务的四大特性-acid)
+ * [事务的隔离级别](#事务的隔离级别)
+ * [事务并�执行会出现的问题](#事务并�执行会出现的问题)
+ * [数�库的四�隔离级别](#数�库的四�隔离级别)
+ * [什么是分布�事务?](#什么是分布�事务?)
+ * [CAP�论](#cap�论)
+ * [BASE�论](#base�论)
+ * [分布�事务�议](#分布�事务�议)
+ * [2PC](#2pc)
+ * [3PC](#3pc)
+
+
# 目录
本文转载自 linkedkeeper.com
diff --git "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\346\266\210\346\201\257\346\212\200\346\234\257Kafka.md" "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\346\266\210\346\201\257\346\212\200\346\234\257Kafka.md"
index 36240f2..7e54e71 100644
--- "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\346\266\210\346\201\257\346\212\200\346\234\257Kafka.md"
+++ "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\346\266\210\346\201\257\346\212\200\346\234\257Kafka.md"
@@ -1,3 +1,18 @@
+# Table of Contents
+
+* [目录](#目录)
+ * [**Kafka的基本介�**](#kafka的基本介�)
+ * [**Kafka的设计原�分�**](#kafka的设计原�分�)
+ * [**Kafkaæ•°æ�®ä¼ 输的事务特点**](#kafkaæ•°æ�®ä¼ 输的事务特点)
+ * [**Kafka消æ�¯å˜å‚¨æ ¼å¼�**](#kafka消æ�¯å˜å‚¨æ ¼å¼�)
+ * [**副本(replication)ç–ç•¥**](#副本(replication)ç–ç•¥)
+ * [**Kafka消�分组,消�消费原�**](#kafka消�分组,消�消费原�)
+ * [**Push vs. Pull**](#push-vs-pull)
+ * [**Kafak顺�写入与数�读�**](#kafak顺�写入与数�读�)
+ * [**消费者(读�数�)**](#消费者(读�数�))
+ * [**Reference**](#reference)
+
+
# 目录
本文转载自 linkedkeeper.com
@@ -281,4 +296,4 @@ https://my.oschina.net/silence88/blog/856195
https://toutiao.io/posts/508935/app_preview
-è½¬è½½è¯·å¹¶æ ‡æ³¨: “本文转载自 linkedkeeper.com â€�
\ No newline at end of file
+è½¬è½½è¯·å¹¶æ ‡æ³¨: “本文转载自 linkedkeeper.com â€�
diff --git "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\351\224\201\347\232\204\345\207\240\347\247\215\346\226\271\346\241\210.md" "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\351\224\201\347\232\204\345\207\240\347\247\215\346\226\271\346\241\210.md"
index 904e4b9..701bde3 100644
--- "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\351\224\201\347\232\204\345\207\240\347\247\215\346\226\271\346\241\210.md"
+++ "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\351\224\201\347\232\204\345\207\240\347\247\215\346\226\271\346\241\210.md"
@@ -1,3 +1,15 @@
+# Table of Contents
+
+* [目录](#目录)
+ * [�言](#�言)
+ * [分布�一致性问题](#分布�一致性问题)
+ * [分布��需�具备哪些�件](#分布��需�具备哪些�件)
+ * [分布��实现方�](#分布��实现方�)
+ * [解决上述问题有两�方案](#解决上述问题有两�方案)
+ * [zookeeper分布��](#zookeeper分布��)
+ * [�结](#�结)
+
+
# 目录
本文内容å�‚考网络,侵åˆ
diff --git "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\346\266\210\346\201\257\351\230\237\345\210\227\345\233\240\344\275\225\350\200\214\347\224\237.md" "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\346\266\210\346\201\257\351\230\237\345\210\227\345\233\240\344\275\225\350\200\214\347\224\237.md"
index c2dd051..b47f00d 100644
--- "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\346\266\210\346\201\257\351\230\237\345\210\227\345\233\240\344\275\225\350\200\214\347\224\237.md"
+++ "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\346\266\210\346\201\257\351\230\237\345\210\227\345\233\240\344\275\225\350\200\214\347\224\237.md"
@@ -1,5 +1,5 @@
-#目录
+# 目录
* [何时需�消�队列](#何时需�消�队列)
* [解耦](#解耦)
* [最终一致性](#最终一致性)
@@ -404,4 +404,4 @@ Future future = request(server);//server立刻返回future return future
# 总结
-本文从为何使用消æ�¯é˜Ÿåˆ—开始讲起,然å�Žä¸»è¦�介ç»�了如何从零开始设计一个消æ�¯é˜Ÿåˆ—,包括RPCã€�事务ã€�最终一致性ã€�广æ’ã€�消æ�¯ç¡®è®¤ç‰å…³é”®é—®é¢˜ã€‚并对消æ�¯é˜Ÿåˆ—çš„pushã€�pull模型å�šäº†ç®€è¦�分æž�,最å�Žä»Žæ‰¹é‡�和异æ¥è§’度,分æž�了消æ�¯é˜Ÿåˆ—性能优化的æ€�路。下篇会ç�€é‡�介ç»�一些高级è¯�题,如å˜å‚¨ç³»ç»Ÿçš„设计ã€�æµ�控和错峰的设计ã€�公平调度ç‰ã€‚希望通过这些,让大家对消æ�¯é˜Ÿåˆ—有个æ��纲挈领的整体认识,并给自主开å�‘消æ�¯é˜Ÿåˆ—æ��ä¾›æ€�路。å�¦å¤–,本文主è¦�是æº�自自己在开å�‘消æ�¯é˜Ÿåˆ—ä¸çš„æ€�考和读æº�ç �时的体会,比较ä¸�"官方",也难å…�会å˜åœ¨ä¸€äº›æ¼�洞,欢迎大家多多交æµ�。
\ No newline at end of file
+本文从为何使用消æ�¯é˜Ÿåˆ—开始讲起,然å�Žä¸»è¦�介ç»�了如何从零开始设计一个消æ�¯é˜Ÿåˆ—,包括RPCã€�事务ã€�最终一致性ã€�广æ’ã€�消æ�¯ç¡®è®¤ç‰å…³é”®é—®é¢˜ã€‚并对消æ�¯é˜Ÿåˆ—çš„pushã€�pull模型å�šäº†ç®€è¦�分æž�,最å�Žä»Žæ‰¹é‡�和异æ¥è§’度,分æž�了消æ�¯é˜Ÿåˆ—性能优化的æ€�路。下篇会ç�€é‡�介ç»�一些高级è¯�题,如å˜å‚¨ç³»ç»Ÿçš„设计ã€�æµ�控和错峰的设计ã€�公平调度ç‰ã€‚希望通过这些,让大家对消æ�¯é˜Ÿåˆ—有个æ��纲挈领的整体认识,并给自主开å�‘消æ�¯é˜Ÿåˆ—æ��ä¾›æ€�路。å�¦å¤–,本文主è¦�是æº�自自己在开å�‘消æ�¯é˜Ÿåˆ—ä¸çš„æ€�考和读æº�ç �时的体会,比较ä¸�"官方",也难å…�会å˜åœ¨ä¸€äº›æ¼�洞,欢迎大家多多交æµ�。
diff --git "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\347\274\223\345\255\230\346\233\264\346\226\260\347\232\204\345\245\227\350\267\257.md" "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\347\274\223\345\255\230\346\233\264\346\226\260\347\232\204\345\245\227\350\267\257.md"
index 61ed18f..77fc50a 100644
--- "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\347\274\223\345\255\230\346\233\264\346\226\260\347\232\204\345\245\227\350\267\257.md"
+++ "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\347\274\223\345\255\230\346\233\264\346\226\260\347\232\204\345\245\227\350\267\257.md"
@@ -1,3 +1,4 @@
+
# 目录
* [ç¼“å˜æ›´æ–°çš„套路](#ç¼“å˜æ›´æ–°çš„套路)
@@ -106,4 +107,4 @@ Write Back套路,一å�¥è¯´å°±æ˜¯ï¼Œåœ¨æ›´æ–°æ•°æ�®çš„æ—¶å€™ï¼Œå�ªæ›´æ–°ç¼“å˜
4)上é�¢ï¼Œæˆ‘们没有考虑缓å˜ï¼ˆCache)和æŒ�久层(Repository)的整体事务的问题。比如,更新Cacheæˆ�功,更新数æ�®åº“失败了怎么å�—?或是å��过æ�¥ã€‚å…³äºŽè¿™ä¸ªäº‹ï¼Œå¦‚æžœä½ éœ€è¦�å¼ºä¸€è‡´æ€§ï¼Œä½ éœ€è¦�使用“两阶段æ��交å��è®®â€�——prepare, commit/rollback,比如Java 7 çš„[XAResource](http://docs.oracle.com/javaee/7/api/javax/transaction/xa/XAResource.html),还有MySQL 5.7的 [XA Transaction](http://dev.mysql.com/doc/refman/5.7/en/xa.html),有些cache也支æŒ�XA,比如[EhCache](http://www.ehcache.org/documentation/3.0/xa.html)。当然,XAè¿™æ ·çš„å¼ºä¸€è‡´æ€§çš„çŽ©æ³•ä¼šå¯¼è‡´æ€§èƒ½ä¸‹é™�,关于分布å¼�的事务的相关è¯�é¢˜ï¼Œä½ å�¯ä»¥çœ‹çœ‹ã€Š[分布å¼�系统的事务处ç�†](https://coolshell.cn/articles/10910.html)》一文。
-(全文完)
\ No newline at end of file
+(全文完)
diff --git "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\206\345\270\203\345\274\217ID\347\224\237\346\210\220\346\226\271\346\241\210.md" "b/docs/distributed/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\206\345\270\203\345\274\217ID\347\224\237\346\210\220\346\226\271\346\241\210.md"
similarity index 94%
rename from "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\206\345\270\203\345\274\217ID\347\224\237\346\210\220\346\226\271\346\241\210.md"
rename to "docs/distributed/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\206\345\270\203\345\274\217ID\347\224\237\346\210\220\346\226\271\346\241\210.md"
index 2ea07c4..95caec7 100644
--- "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\206\345\270\203\345\274\217ID\347\224\237\346\210\220\346\226\271\346\241\210.md"
+++ "b/docs/distributed/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\206\345\270\203\345\274\217ID\347\224\237\346\210\220\346\226\271\346\241\210.md"
@@ -1,6 +1,12 @@
-# 目录
+# Table of Contents
+
+ * [**一�需求缘起**](#一�需求缘起)
+ * [**二�常�方法��足与优化**](#二�常�方法��足与优化)
+ * [**方法二:�点批�ID生��务**](#方法二:�点批�id生��务)
+ * [**方法三:uuid/guid**](#方法三:uuidguid)
+ * [**方法四:�当�毫秒数**](#方法四:�当�毫秒数)
+
-* [分布�ID生�器 | 架构师之路](#分布�id生�器--架构师之路)
本文内容å�‚考网络,侵åˆ
@@ -19,11 +25,10 @@
å¦‚æžœå¯¹æœ¬ç³»åˆ—æ–‡ç« æœ‰ä»€ä¹ˆå»ºè®®ï¼Œæˆ–è€…æ˜¯æœ‰ä»€ä¹ˆç–‘é—®çš„è¯�,也å�¯ä»¥å…³æ³¨å…¬ä¼—å�·ã€�Java技术江湖】è�”ç³»ä½œè€…ï¼Œæ¬¢è¿Žä½ å�‚与本系列å�šæ–‡çš„åˆ›ä½œå’Œä¿®è®¢ã€‚
-## 分布�ID生�器 | 架构师之路
转自:58沈剑架构师之路2017-06-25
-**一�需求缘起**
+## **一�需求缘起**
å‡ ä¹Žæ‰€æœ‰çš„ä¸šåŠ¡ç³»ç»Ÿï¼Œéƒ½æœ‰ç”Ÿæˆ�ä¸€ä¸ªå”¯ä¸€è®°å½•æ ‡è¯†çš„éœ€æ±‚ï¼Œä¾‹å¦‚ï¼š
@@ -65,7 +70,7 @@ select message-id/ (order by message-id)/limit 100
这也是本文è¦�è®¨è®ºçš„æ ¸å¿ƒé—®é¢˜ï¼š**如何高效生æˆ�趋势有åº�的全局唯一ID。**
-**二�常�方法��足与优化**
+## **二�常�方法��足与优化**
**方法一:使用数�库的auto_increment�生�全局唯一递增ID**
@@ -103,7 +108,7 @@ select message-id/ (order by message-id)/limit 100
为了解决上述两个问题,引出了第二个常�的方案。
-**方法二:�点批�ID生��务**
+## **方法二:�点批�ID生��务**
分布å¼�系统之所以难,很é‡�è¦�çš„åŽŸå› ä¹‹ä¸€æ˜¯â€œæ²¡æœ‰ä¸€ä¸ªå…¨å±€æ—¶é’Ÿï¼Œéš¾ä»¥ä¿�è¯�ç»�对的时åº�â€�,è¦�想ä¿�è¯�ç»�对的时åº�,还是å�ªèƒ½ä½¿ç”¨å�•点æœ�务,用本地时钟ä¿�è¯�“ç»�对时åº�â€�。
@@ -143,7 +148,7 @@ ID生��务�设�次批�拉�6个ID,�务访问数�库,将当�
�外,ID-gen-service也�以实施水平扩展,以解决上述缺点(3),但会引�一致性问题,具体解决方案详�《》。
-**方法三:uuid/guid**
+## **方法三:uuid/guid**
�管是通过数�库,还是通过�务�生�ID,业务方Application都需�进行一次远程调用,比较耗时。
@@ -165,7 +170,7 @@ string ID =GenUUID();
* uuid过长,往往用å—符串表示,作为主键建立索引查询效率低,常è§�优化方案为“转化为两个uint64æ•´æ•°å˜å‚¨â€�或者“折å�Šå˜å‚¨â€�(折å�Šå�Žä¸�能ä¿�è¯�唯一性)
-**方法四:�当�毫秒数**
+## **方法四:�当�毫秒数**
uuid是一个本地算法,生æˆ�æ€§èƒ½é«˜ï¼Œä½†æ— æ³•ä¿�è¯�趋势递增,且作为å—符串ID检索效率低,有没有一ç§�能ä¿�è¯�递增的本地算法呢?
@@ -237,4 +242,4 @@ snowflake是twitterå¼€æº�的分布å¼�ID生æˆ�算法,其**æ ¸å¿ƒæ€�想为,**
**缺点**:
-* 由于“没有一个全局时钟�,���务器分�的ID是�对递增的,但从全局看,生�的ID�是趋势递增的(有些�务器的时间早,有些�务器的时间晚)
\ No newline at end of file
+* 由于“没有一个全局时钟�,���务器分�的ID是�对递增的,但从全局看,生�的ID�是趋势递增的(有些�务器的时间早,有些�务器的时间晚)
diff --git a/src/main/java/md/mdToc.java b/src/main/java/md/mdToc.java
index a5216f0..f449fef 100644
--- a/src/main/java/md/mdToc.java
+++ b/src/main/java/md/mdToc.java
@@ -4,7 +4,7 @@
public class mdToc {
public static void main(String[] args) {
- String path = "D:\\idea_project\\JavaTutorial\\docs\\distributed\\basic";
+ String path = "D:\\idea_project\\JavaTutorial\\docs\\distributed\\practice\\temp";
AtxMarkdownToc.newInstance().genTocDir(path);
}
}
From a157e8e8bcd13569a8213dee30d22c5865a292b5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=BB=84=E5=B0=8F=E6=96=9C?= <362294931@qq.com>
Date: Sun, 9 Apr 2023 17:16:51 +0800
Subject: [PATCH 04/39] modify distributed mds
---
ReadMe.md | 4 ++--
...47\224\237\346\210\220\346\226\271\346\241\210.md" | 0
...45\256\236\350\267\265\346\200\273\347\273\223.md" | 11 -----------
...47\220\206\350\256\272\346\200\273\347\273\223.md" | 0
4 files changed, 2 insertions(+), 13 deletions(-)
rename "docs/distributed/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\206\345\270\203\345\274\217ID\347\224\237\346\210\220\346\226\271\346\241\210.md" => "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\206\345\270\203\345\274\217ID\347\224\237\346\210\220\346\226\271\346\241\210.md" (100%)
rename "docs/distributed/practice/\345\210\206\345\270\203\345\274\217\347\220\206\350\256\272\346\200\273\347\273\223.md" => "docs/distributed/\345\210\206\345\270\203\345\274\217\347\220\206\350\256\272\346\200\273\347\273\223.md" (100%)
diff --git a/ReadMe.md b/ReadMe.md
index ee75d4c..dc53ae6 100644
--- a/ReadMe.md
+++ b/ReadMe.md
@@ -317,7 +317,7 @@ todo
* [分布�系统�论进阶:Paxos��和优化 ](docs/distributed/basic/分布�系统�论进阶:Paxos��和优化.md)
* [分布�系统�论基础:zookeeper分布��调�务 ](docs/distributed/basic/分布�系统�论基础:zookeeper分布��调�务.md)
-* [分布�技术实践总结](docs/distributed/practice/分布��论总结.md)
+* [分布�技术实践总结](docs/distributed/分布��论总结.md)
### 技术
* [�懂分布�技术:分布�系统的一些基本概念](docs/distributed/practice/�懂分布�技术:分布�系统的一些基本概念.md )
@@ -334,7 +334,7 @@ todo
[//]: # (* [�懂分布�技术:Nginx负载�衡原�与实践 ]docs/distributed/practice/�懂分布�技术:Nginx负载�衡原�与实践.md)
* [�懂分布�技术:LVS实现负载�衡的原�与实践 ](docs/distributed/practice/�懂分布�技术:LVS实现负载�衡的原�与实践.md )
* [�懂分布�技术:分布�session解决方案与一致性hash](docs/distributed/practice/�懂分布�技术:分布�session解决方案与一致性hash.md)
-* [�懂分布�技术:分布�ID生�方案 ](docs/distributed/�懂分布�技术:分布�ID生�方案.md )
+* [�懂分布�技术:分布�ID生�方案 ](docs/distributed/practice/�懂分布�技术:分布�ID生�方案.md )
* [æ�žæ‡‚分布å¼�技术:缓å˜çš„那些事](docs/distributed/practice/æ�žæ‡‚分布å¼�技术:缓å˜çš„那些事.md)
* [æ�žæ‡‚分布å¼�技术:SpringBoot使用注解集æˆ�Redis缓å˜](docs/distributed/practice/æ�žæ‡‚分布å¼�技术:SpringBoot使用注解集æˆ�Redis缓å˜.md)
* [æ�žæ‡‚分布å¼�æŠ€æœ¯ï¼šç¼“å˜æ›´æ–°çš„套路 ](docs/distributed/practice/æ�žæ‡‚分布å¼�æŠ€æœ¯ï¼šç¼“å˜æ›´æ–°çš„套路.md )
diff --git "a/docs/distributed/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\206\345\270\203\345\274\217ID\347\224\237\346\210\220\346\226\271\346\241\210.md" "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\206\345\270\203\345\274\217ID\347\224\237\346\210\220\346\226\271\346\241\210.md"
similarity index 100%
rename from "docs/distributed/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\206\345\270\203\345\274\217ID\347\224\237\346\210\220\346\226\271\346\241\210.md"
rename to "docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\206\345\270\203\345\274\217ID\347\224\237\346\210\220\346\226\271\346\241\210.md"
diff --git "a/docs/distributed/\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\345\256\236\350\267\265\346\200\273\347\273\223.md" "b/docs/distributed/\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\345\256\236\350\267\265\346\200\273\347\273\223.md"
index d73b1e8..8fb1dc1 100644
--- "a/docs/distributed/\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\345\256\236\350\267\265\346\200\273\347\273\223.md"
+++ "b/docs/distributed/\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\345\256\236\350\267\265\346\200\273\347\273\223.md"
@@ -25,17 +25,6 @@
* [好了,最�是数�库层](#好了,最�是数�库层)
* [总结](#总结)
-
-
----
-title: 分布�技术实践总结
-date: 2018-07-08 22:15:36
-tags:
-- 分布�系统
- categories:
-- �端
-- 技术总结
----
本文基于之å‰�的分布å¼�系统ç�†è®ºç³»åˆ—æ–‡ç« æ€»ç»“è€Œæˆ�,本部分主è¦�是实践内容,详细内容å�¯è§�我的专æ �:分布å¼�系统ç�†è®ºä¸Žå®žè·µ
https://blog.csdn.net/column/details/24090.html
diff --git "a/docs/distributed/practice/\345\210\206\345\270\203\345\274\217\347\220\206\350\256\272\346\200\273\347\273\223.md" "b/docs/distributed/\345\210\206\345\270\203\345\274\217\347\220\206\350\256\272\346\200\273\347\273\223.md"
similarity index 100%
rename from "docs/distributed/practice/\345\210\206\345\270\203\345\274\217\347\220\206\350\256\272\346\200\273\347\273\223.md"
rename to "docs/distributed/\345\210\206\345\270\203\345\274\217\347\220\206\350\256\272\346\200\273\347\273\223.md"
From 0de98139346d866e2f40af3170994567f6defaa2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=BB=84=E5=B0=8F=E6=96=9C?= <362294931@qq.com>
Date: Sun, 9 Apr 2023 17:19:22 +0800
Subject: [PATCH 05/39] modify mds toc
---
...207\357\274\232\344\273\200\344\271\210\346\230\257Redis.md" | 2 +-
...\215\256\347\273\223\346\236\204\346\246\202\350\247\210.md" | 2 +-
...\216ACID\347\211\271\346\200\247\344\273\213\347\273\215.md" | 2 +-
...\204\350\257\246\350\247\243\342\200\224\342\200\224dict.md" | 2 +-
...04\350\257\246\350\247\243\342\200\224\342\200\224intset.md" | 2 +-
...350\257\246\350\247\243\342\200\224\342\200\224quicklist.md" | 2 +-
...6\204\350\257\246\350\247\243\342\200\224\342\200\224sds.md" | 2 +-
...\350\257\246\350\247\243\342\200\224\342\200\224skiplist.md" | 2 +-
...4\350\257\246\350\247\243\342\200\224\342\200\224ziplist.md" | 2 +-
...\274\217\351\224\201\350\277\233\345\214\226\345\217\262.md" | 2 +-
...\236\204\346\274\224\350\277\233\345\256\236\344\276\213.md" | 2 +-
...\214\226\345\210\260\347\241\254\347\233\230\344\270\255.md" | 2 +-
...\234\237\345\210\240\351\231\244\347\255\226\347\225\245.md" | 2 +-
...220Redis\344\270\273\344\273\216\345\244\215\345\210\266.md" | 2 +-
...\204\346\225\260\346\215\256\347\273\223\346\236\204robj.md" | 2 +-
"docs/cs/algorithms/\345\211\221\346\214\207offer.md" | 2 +-
...\273\234\345\255\246\344\271\240\346\200\273\347\273\223.md" | 2 +-
...\273\244\345\255\246\344\271\240\346\200\273\347\273\223.md" | 2 +-
...\273\237\345\255\246\344\271\240\346\200\273\347\273\223.md" | 2 +-
...\222\214\351\224\201\347\232\204\345\205\263\347\263\273.md" | 2 +-
...\202\243\344\272\233\346\227\245\345\277\227\344\273\254.md" | 2 +-
...\215\256\345\255\230\345\202\250\345\216\237\347\220\206.md" | 2 +-
...\206\350\256\272\345\237\272\347\241\200 \357\274\232CAP.md" | 2 +-
...\200\350\207\264\346\200\247\343\200\201PC\345\222\214PC.md" | 2 +-
...\222\214\344\272\213\344\273\266\351\241\272\345\272\217.md" | 2 +-
...206\350\256\272\345\237\272\347\241\200\357\274\232Paxos.md" | 2 +-
...2\345\237\272\347\241\200\357\274\232Raft\343\200\201Zab.md" | 2 +-
...\274\217\345\215\217\350\260\203\346\234\215\345\212\241.md" | 2 +-
...\225\260\346\264\276\345\222\214\347\247\237\347\272\246.md" | 2 +-
...\217\230\347\247\215\345\222\214\344\274\230\345\214\226.md" | 2 +-
...\270\273\346\265\201\347\250\213\350\257\246\350\247\243.md" | 2 +-
...74\217ID\347\224\237\346\210\220\346\226\271\346\241\210.md" | 2 +-
...\210\344\270\216\344\270\200\350\207\264\346\200\247hash.md" | 2 +-
...\224\250\350\247\243\345\206\263\346\226\271\346\241\210.md" | 2 +-
...345\215\217\350\260\203\346\234\215\345\212\241zookeeper.md" | 2 +-
...\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md" | 2 +-
...217\346\266\210\346\201\257\346\212\200\346\234\257Kafka.md" | 2 +-
...\232\204\345\207\240\347\247\215\346\226\271\346\241\210.md" | 2 +-
...\274\217\347\220\206\350\256\272\346\200\273\347\273\223.md" | 2 +-
...\210\260\345\210\206\345\270\203\345\274\217\357\274\211.md" | 2 +-
...\240\241\346\213\233\346\200\273\347\273\223\357\274\211.md" | 2 +-
...60 Java \350\277\231\346\235\241\350\267\257\357\274\237.md" | 2 +-
...\271\240\350\265\204\346\272\220\346\270\205\345\215\225.md" | 2 +-
...\277\231\344\270\200\345\274\240\345\233\276\357\274\201.md" | 2 +-
...\235\242\347\273\217\345\244\247\345\220\210\351\233\206.md" | 2 +-
docs/hxx/think/copy.md | 2 +-
"docs/hxx/\347\224\265\345\255\220\344\271\246.md" | 2 +-
docs/interview/BATJ-Experience/alipay-pinduoduo-toutiao.md | 2 +-
...3(\345\267\262\346\213\277\345\217\243\345\244\264offer).md" | 2 +-
...42\351\230\277\351\207\214,\347\273\210\350\216\267offer.md" | 2 +-
...\277\203\346\212\200\346\234\257\346\200\273\347\273\223.md" | 2 +-
docs/interview/PreparingForInterview/JavaInterviewLibrary.md | 2 +-
docs/interview/PreparingForInterview/JavaProgrammerNeedKnow.md | 2 +-
docs/interview/PreparingForInterview/interviewPrepare.md | 2 +-
...\257\245\345\246\202\344\275\225\345\233\236\347\255\224.md" | 2 +-
...\232\204\347\256\200\345\216\206\344\271\213\351\201\223.md" | 2 +-
...\247\201\351\227\256\351\242\230\346\200\273\347\273\223.md" | 2 +-
"docs/java/jvm/JVM\346\200\273\347\273\223.md" | 2 +-
58 files changed, 58 insertions(+), 58 deletions(-)
diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\345\274\200\347\257\207\357\274\232\344\273\200\344\271\210\346\230\257Redis.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\345\274\200\347\257\207\357\274\232\344\273\200\344\271\210\346\230\257Redis.md"
index fe6dad0..51ba773 100644
--- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\345\274\200\347\257\207\357\274\232\344\273\200\344\271\210\346\230\257Redis.md"
+++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\345\274\200\347\257\207\357\274\232\344\273\200\344\271\210\346\230\257Redis.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [redis å¦ä¹ 笔记](#redis-å¦ä¹ 笔记)
* [redis 是什么?](#redis-是什么)
diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis \347\232\204\345\237\272\347\241\200\346\225\260\346\215\256\347\273\223\346\236\204\346\246\202\350\247\210.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis \347\232\204\345\237\272\347\241\200\346\225\260\346\215\256\347\273\223\346\236\204\346\246\202\350\247\210.md"
index 57151b7..9102d4d 100644
--- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis \347\232\204\345\237\272\347\241\200\346\225\260\346\215\256\347\273\223\346\236\204\346\246\202\350\247\210.md"
+++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis \347\232\204\345\237\272\347\241\200\346\225\260\346\215\256\347\273\223\346\236\204\346\246\202\350\247\210.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [SDS](#sds)
* [链表](#链表)
diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\344\272\213\345\212\241\346\265\205\346\236\220\344\270\216ACID\347\211\271\346\200\247\344\273\213\347\273\215.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\344\272\213\345\212\241\346\265\205\346\236\220\344\270\216ACID\347\211\271\346\200\247\344\273\213\347\273\215.md"
index 1ec7a8e..f9aef55 100644
--- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\344\272\213\345\212\241\346\265\205\346\236\220\344\270\216ACID\347\211\271\346\200\247\344\273\213\347\273\215.md"
+++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\344\272\213\345\212\241\346\265\205\346\236\220\344\270\216ACID\347\211\271\346\200\247\344\273\213\347\273\215.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [事务](#事务)
* [用法](#用法)
diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224dict.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224dict.md"
index b5918f8..97fbd0e 100644
--- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224dict.md"
+++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224dict.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [dict的数�结构定义](#dict的数�结构定义)
* [dict的创建(dictCreate)](#dict的创建(dictcreate))
diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224intset.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224intset.md"
index b1a6fc3..95204c4 100644
--- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224intset.md"
+++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224intset.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [intset数�结构简介](#intset数�结构简介)
* [intsetçš„æŸ¥æ‰¾å’Œæ·»åŠ æ“�作](#intsetçš„æŸ¥æ‰¾å’Œæ·»åŠ æ“�作)
diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224quicklist.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224quicklist.md"
index 9070b83..80bba2e 100644
--- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224quicklist.md"
+++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224quicklist.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [quicklist概述](#quicklist概述)
* [quicklist的数�结构定义](#quicklist的数�结构定义)
diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224sds.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224sds.md"
index 3c940c8..f9d1726 100644
--- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224sds.md"
+++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224sds.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [�言](#�言)
* [sds的数�结构定义](#sds的数�结构定义)
diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224skiplist.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224skiplist.md"
index d463e4a..d419a09 100644
--- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224skiplist.md"
+++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224skiplist.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [skiplist数�结构简介](#skiplist数�结构简介)
* [skiplist的算法性能分�](#skiplist的算法性能分�)
diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224ziplist.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224ziplist.md"
index d1130f9..ea7ce4b 100644
--- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224ziplist.md"
+++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224ziplist.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [什么是ziplist](#什么是ziplist)
* [ziplist的数�结构定义](#ziplist的数�结构定义)
diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\345\210\206\345\270\203\345\274\217\351\224\201\350\277\233\345\214\226\345\217\262.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\345\210\206\345\270\203\345\274\217\351\224\201\350\277\233\345\214\226\345\217\262.md"
index 9f3d353..628426d 100644
--- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\345\210\206\345\270\203\345\274\217\351\224\201\350\277\233\345\214\226\345\217\262.md"
+++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\345\210\206\345\270\203\345\274\217\351\224\201\350\277\233\345\214\226\345\217\262.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [Redis分布��进化�](#redis分布��进化�)
* [�个版本的Redis分布��](#�个版本的redis分布��)
diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\351\233\206\347\276\244\346\234\272\345\210\266\345\217\212\344\270\200\344\270\252Redis\346\236\266\346\236\204\346\274\224\350\277\233\345\256\236\344\276\213.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\351\233\206\347\276\244\346\234\272\345\210\266\345\217\212\344\270\200\344\270\252Redis\346\236\266\346\236\204\346\274\224\350\277\233\345\256\236\344\276\213.md"
index dc6c078..5d84b69 100644
--- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\351\233\206\347\276\244\346\234\272\345\210\266\345\217\212\344\270\200\344\270\252Redis\346\236\266\346\236\204\346\274\224\350\277\233\345\256\236\344\276\213.md"
+++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\351\233\206\347\276\244\346\234\272\345\210\266\345\217\212\344\270\200\344\270\252Redis\346\236\266\346\236\204\346\274\224\350\277\233\345\256\236\344\276\213.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [Replication(主从�制)](#replication(主从�制))
* [�置主�务器](#�置主�务器)
diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232\344\275\277\347\224\250\345\277\253\347\205\247\345\222\214AOF\345\260\206Redis\346\225\260\346\215\256\346\214\201\344\271\205\345\214\226\345\210\260\347\241\254\347\233\230\344\270\255.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232\344\275\277\347\224\250\345\277\253\347\205\247\345\222\214AOF\345\260\206Redis\346\225\260\346\215\256\346\214\201\344\271\205\345\214\226\345\210\260\347\241\254\347\233\230\344\270\255.md"
index 119f43b..92e1875 100644
--- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232\344\275\277\347\224\250\345\277\253\347\205\247\345\222\214AOF\345\260\206Redis\346\225\260\346\215\256\346\214\201\344\271\205\345\214\226\345\210\260\347\241\254\347\233\230\344\270\255.md"
+++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232\344\275\277\347\224\250\345\277\253\347\205\247\345\222\214AOF\345\260\206Redis\346\225\260\346\215\256\346\214\201\344\271\205\345\214\226\345\210\260\347\241\254\347\233\230\344\270\255.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [�言](#�言)
* [快照�久化](#快照�久化)
diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232\346\225\260\346\215\256\345\272\223redisDb\344\270\216\351\224\256\350\277\207\346\234\237\345\210\240\351\231\244\347\255\226\347\225\245.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232\346\225\260\346\215\256\345\272\223redisDb\344\270\216\351\224\256\350\277\207\346\234\237\345\210\240\351\231\244\347\255\226\347\225\245.md"
index d176fc1..3f14892 100644
--- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232\346\225\260\346\215\256\345\272\223redisDb\344\270\216\351\224\256\350\277\207\346\234\237\345\210\240\351\231\244\347\255\226\347\225\245.md"
+++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232\346\225\260\346\215\256\345\272\223redisDb\344\270\216\351\224\256\350\277\207\346\234\237\345\210\240\351\231\244\347\255\226\347\225\245.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [一. 数�库](#一-数�库)
* [二�切�数�库原�](#二�切�数�库原�)
diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232\346\265\205\346\236\220Redis\344\270\273\344\273\216\345\244\215\345\210\266.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232\346\265\205\346\236\220Redis\344\270\273\344\273\216\345\244\215\345\210\266.md"
index d23323b..393e8ac 100644
--- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232\346\265\205\346\236\220Redis\344\270\273\344\273\216\345\244\215\345\210\266.md"
+++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232\346\265\205\346\236\220Redis\344\270\273\344\273\216\345\244\215\345\210\266.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [Redis�制概论](#redis�制概论)
* [Redis�制方�](#redis�制方�)
diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232\350\277\236\346\216\245\345\272\225\345\261\202\344\270\216\350\241\250\351\235\242\347\232\204\346\225\260\346\215\256\347\273\223\346\236\204robj.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232\350\277\236\346\216\245\345\272\225\345\261\202\344\270\216\350\241\250\351\235\242\347\232\204\346\225\260\346\215\256\347\273\223\346\236\204robj.md"
index ffc8fe4..e8823f6 100644
--- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232\350\277\236\346\216\245\345\272\225\345\261\202\344\270\216\350\241\250\351\235\242\347\232\204\346\225\260\346\215\256\347\273\223\346\236\204robj.md"
+++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232\350\277\236\346\216\245\345\272\225\345\261\202\344\270\216\350\241\250\351\235\242\347\232\204\346\225\260\346\215\256\347\273\223\346\236\204robj.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [robj的数�结构定义](#robj的数�结构定义)
* [string robj的编ç �过程](#string-robj的编ç �过程)
diff --git "a/docs/cs/algorithms/\345\211\221\346\214\207offer.md" "b/docs/cs/algorithms/\345\211\221\346\214\207offer.md"
index 3147337..7952448 100644
--- "a/docs/cs/algorithms/\345\211\221\346\214\207offer.md"
+++ "b/docs/cs/algorithms/\345\211\221\346\214\207offer.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [数论和数å—规律](#数论和数å—规律)
* [从1到næ•´æ•°ä¸1出现的次数](#从1到næ•´æ•°ä¸1出现的次数)
diff --git "a/docs/cs/network/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\345\255\246\344\271\240\346\200\273\347\273\223.md" "b/docs/cs/network/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\345\255\246\344\271\240\346\200\273\347\273\223.md"
index 0ee5021..6f4ee49 100644
--- "a/docs/cs/network/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\345\255\246\344\271\240\346\200\273\347\273\223.md"
+++ "b/docs/cs/network/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\345\255\246\344\271\240\346\200\273\347\273\223.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [网�和路由器](#网�和路由器)
* [交�机](#交�机)
diff --git "a/docs/cs/operating-system/Linux\345\206\205\346\240\270\344\270\216\345\237\272\347\241\200\345\221\275\344\273\244\345\255\246\344\271\240\346\200\273\347\273\223.md" "b/docs/cs/operating-system/Linux\345\206\205\346\240\270\344\270\216\345\237\272\347\241\200\345\221\275\344\273\244\345\255\246\344\271\240\346\200\273\347\273\223.md"
index 3cf91e6..4dd7996 100644
--- "a/docs/cs/operating-system/Linux\345\206\205\346\240\270\344\270\216\345\237\272\347\241\200\345\221\275\344\273\244\345\255\246\344\271\240\346\200\273\347\273\223.md"
+++ "b/docs/cs/operating-system/Linux\345\206\205\346\240\270\344\270\216\345\237\272\347\241\200\345\221\275\344\273\244\345\255\246\344\271\240\346\200\273\347\273\223.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [文件系统和VFS](#文件系统和vfs)
* [进程和线程](#进程和线程)
diff --git "a/docs/cs/operating-system/\346\223\215\344\275\234\347\263\273\347\273\237\345\255\246\344\271\240\346\200\273\347\273\223.md" "b/docs/cs/operating-system/\346\223\215\344\275\234\347\263\273\347\273\237\345\255\246\344\271\240\346\200\273\347\273\223.md"
index 97cd45f..4c97490 100644
--- "a/docs/cs/operating-system/\346\223\215\344\275\234\347\263\273\347\273\237\345\255\246\344\271\240\346\200\273\347\273\223.md"
+++ "b/docs/cs/operating-system/\346\223\215\344\275\234\347\263\273\347\273\237\345\255\246\344\271\240\346\200\273\347\273\223.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [CPU](#cpu)
* [程�执行过程](#程�执行过程)
diff --git "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232Innodb\344\270\255\347\232\204\344\272\213\345\212\241\351\232\224\347\246\273\347\272\247\345\210\253\345\222\214\351\224\201\347\232\204\345\205\263\347\263\273.md" "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232Innodb\344\270\255\347\232\204\344\272\213\345\212\241\351\232\224\347\246\273\347\272\247\345\210\253\345\222\214\351\224\201\347\232\204\345\205\263\347\263\273.md"
index b796526..5223578 100644
--- "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232Innodb\344\270\255\347\232\204\344\272\213\345\212\241\351\232\224\347\246\273\347\272\247\345\210\253\345\222\214\351\224\201\347\232\204\345\205\263\347\263\273.md"
+++ "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232Innodb\344\270\255\347\232\204\344\272\213\345\212\241\351\232\224\347\246\273\347\272\247\345\210\253\345\222\214\351\224\201\347\232\204\345\205\263\347\263\273.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [Innodbä¸çš„事务隔离级别和é”�的关系](#innodbä¸çš„事务隔离级别和é”�的关系)
* [事务ä¸çš„åŠ é”�æ–¹å¼�](#事务ä¸çš„åŠ é”�æ–¹å¼�)
diff --git "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232MySQL\351\207\214\347\232\204\351\202\243\344\272\233\346\227\245\345\277\227\344\273\254.md" "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232MySQL\351\207\214\347\232\204\351\202\243\344\272\233\346\227\245\345\277\227\344\273\254.md"
index 3469a48..6f69233 100644
--- "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232MySQL\351\207\214\347\232\204\351\202\243\344\272\233\346\227\245\345\277\227\344\273\254.md"
+++ "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232MySQL\351\207\214\347\232\204\351\202\243\344\272\233\346\227\245\345\277\227\344\273\254.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [目录](#目录)
* [é‡�æ–°å¦ä¹ MySQLæ•°æ�®åº“10:MySQL里的那些日志们](#é‡�æ–°å¦ä¹ mysqlæ•°æ�®åº“10:mysql里的那些日志们)
diff --git "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232Mysql\345\255\230\345\202\250\345\274\225\346\223\216\344\270\216\346\225\260\346\215\256\345\255\230\345\202\250\345\216\237\347\220\206.md" "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232Mysql\345\255\230\345\202\250\345\274\225\346\223\216\344\270\216\346\225\260\346\215\256\345\255\230\345\202\250\345\216\237\347\220\206.md"
index 4763b48..3d694e3 100644
--- "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232Mysql\345\255\230\345\202\250\345\274\225\346\223\216\344\270\216\346\225\260\346\215\256\345\255\230\345\202\250\345\216\237\347\220\206.md"
+++ "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232Mysql\345\255\230\345\202\250\345\274\225\346\223\216\344\270\216\346\225\260\346\215\256\345\255\230\345\202\250\345\216\237\347\220\206.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [**一ã€� MySQL记录å˜å‚¨ï¼ˆé¡µä¸ºå�•ä½�)**](#一ã€�-mysql记录å˜å‚¨ï¼ˆé¡µä¸ºå�•ä½�))
* [**页头**](#页头)
diff --git "a/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200 \357\274\232CAP.md" "b/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200 \357\274\232CAP.md"
index 268f008..545e034 100644
--- "a/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200 \357\274\232CAP.md"
+++ "b/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200 \357\274\232CAP.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [**引言**](#引言)
* [**CAP定�**](#cap定�)
diff --git "a/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\357\274\232 \344\270\200\350\207\264\346\200\247\343\200\201PC\345\222\214PC.md" "b/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\357\274\232 \344\270\200\350\207\264\346\200\247\343\200\201PC\345\222\214PC.md"
index 9b94bed..b2ac551 100644
--- "a/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\357\274\232 \344\270\200\350\207\264\346\200\247\343\200\201PC\345\222\214PC.md"
+++ "b/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\357\274\232 \344\270\200\350\207\264\346\200\247\343\200\201PC\345\222\214PC.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [**引言**](#引言)
* [**一致性(consensus)**](#一致性consensus)
diff --git "a/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\357\274\232 \346\227\266\351\227\264\343\200\201\346\227\266\351\222\237\345\222\214\344\272\213\344\273\266\351\241\272\345\272\217.md" "b/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\357\274\232 \346\227\266\351\227\264\343\200\201\346\227\266\351\222\237\345\222\214\344\272\213\344\273\266\351\241\272\345\272\217.md"
index 47d52a7..d8f2e21 100644
--- "a/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\357\274\232 \346\227\266\351\227\264\343\200\201\346\227\266\351\222\237\345\222\214\344\272\213\344\273\266\351\241\272\345\272\217.md"
+++ "b/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\357\274\232 \346\227\266\351\227\264\343\200\201\346\227\266\351\222\237\345\222\214\344\272\213\344\273\266\351\241\272\345\272\217.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [**物�时钟 vs 逻辑时钟**](#物�时钟-vs-逻辑时钟)
* [**Lamport timestamps**](#lamport-timestamps)
diff --git "a/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\357\274\232Paxos.md" "b/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\357\274\232Paxos.md"
index 030e7ac..603d2d2 100644
--- "a/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\357\274\232Paxos.md"
+++ "b/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\357\274\232Paxos.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [**引言**](#引言)
* [**Basic Paxos**](#basic-paxos)
diff --git "a/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\357\274\232Raft\343\200\201Zab.md" "b/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\357\274\232Raft\343\200\201Zab.md"
index a774ab2..4530e9d 100644
--- "a/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\357\274\232Raft\343\200\201Zab.md"
+++ "b/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\357\274\232Raft\343\200\201Zab.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [**引言**](#引言)
* [**Raft**](#raft)
diff --git "a/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\357\274\232zookeeper\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241.md" "b/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\357\274\232zookeeper\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241.md"
index 1696d11..4dd3007 100644
--- "a/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\357\274\232zookeeper\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241.md"
+++ "b/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\357\274\232zookeeper\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [**ZK API**](#zk-api)
* [**ZK应用场景**](#zk应用场景)
diff --git "a/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\357\274\232\351\200\211\344\270\276\343\200\201\345\244\232\346\225\260\346\264\276\345\222\214\347\247\237\347\272\246.md" "b/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\357\274\232\351\200\211\344\270\276\343\200\201\345\244\232\346\225\260\346\264\276\345\222\214\347\247\237\347\272\246.md"
index 5c388e5..1455063 100644
--- "a/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\357\274\232\351\200\211\344\270\276\343\200\201\345\244\232\346\225\260\346\264\276\345\222\214\347\247\237\347\272\246.md"
+++ "b/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\345\237\272\347\241\200\357\274\232\351\200\211\344\270\276\343\200\201\345\244\232\346\225\260\346\264\276\345\222\214\347\247\237\347\272\246.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [**选举(electioin)**](#选举electioin)
* [**多数派(quorum)**](#多数派quorum)
diff --git "a/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\350\277\233\351\230\266\357\274\232Paxos\345\217\230\347\247\215\345\222\214\344\274\230\345\214\226.md" "b/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\350\277\233\351\230\266\357\274\232Paxos\345\217\230\347\247\215\345\222\214\344\274\230\345\214\226.md"
index 1af9cc3..abc4289 100644
--- "a/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\350\277\233\351\230\266\357\274\232Paxos\345\217\230\347\247\215\345\222\214\344\274\230\345\214\226.md"
+++ "b/docs/distributed/basic/\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\220\206\350\256\272\350\277\233\351\230\266\357\274\232Paxos\345\217\230\347\247\215\345\222\214\344\274\230\345\214\226.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [**引言**](#引言)
* [**Multi Paxos**](#multi-paxos)
* [**Fast Paxos**](#fast-paxos)
diff --git "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232ZAB\345\215\217\350\256\256\346\246\202\350\277\260\344\270\216\351\200\211\344\270\273\346\265\201\347\250\213\350\257\246\350\247\243.md" "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232ZAB\345\215\217\350\256\256\346\246\202\350\277\260\344\270\216\351\200\211\344\270\273\346\265\201\347\250\213\350\257\246\350\247\243.md"
index 4a62581..5212a27 100644
--- "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232ZAB\345\215\217\350\256\256\346\246\202\350\277\260\344\270\216\351\200\211\344\270\273\346\265\201\347\250\213\350\257\246\350\247\243.md"
+++ "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232ZAB\345\215\217\350\256\256\346\246\202\350\277\260\344\270\216\351\200\211\344\270\273\346\265\201\347\250\213\350\257\246\350\247\243.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [ZAB�议](#zab�议)
* [消æ�¯å¹¿æ’模å¼�](#消æ�¯å¹¿æ’模å¼�)
diff --git "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\206\345\270\203\345\274\217ID\347\224\237\346\210\220\346\226\271\346\241\210.md" "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\206\345\270\203\345\274\217ID\347\224\237\346\210\220\346\226\271\346\241\210.md"
index 95caec7..1563d5a 100644
--- "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\206\345\270\203\345\274\217ID\347\224\237\346\210\220\346\226\271\346\241\210.md"
+++ "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\206\345\270\203\345\274\217ID\347\224\237\346\210\220\346\226\271\346\241\210.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [**一�需求缘起**](#一�需求缘起)
* [**二�常�方法��足与优化**](#二�常�方法��足与优化)
diff --git "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\206\345\270\203\345\274\217session\350\247\243\345\206\263\346\226\271\346\241\210\344\270\216\344\270\200\350\207\264\346\200\247hash.md" "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\206\345\270\203\345\274\217session\350\247\243\345\206\263\346\226\271\346\241\210\344\270\216\344\270\200\350\207\264\346\200\247hash.md"
index 2c8510e..50e6f52 100644
--- "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\206\345\270\203\345\274\217session\350\247\243\345\206\263\346\226\271\346\241\210\344\270\216\344\270\200\350\207\264\346\200\247hash.md"
+++ "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\206\345\270\203\345\274\217session\350\247\243\345\206\263\346\226\271\346\241\210\344\270\216\344\270\200\350\207\264\346\200\247hash.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [一�问题的�出](#一�问题的�出)
* [1. 什么是Session?](#1-什么是session?)
diff --git "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\345\270\270\347\224\250\350\247\243\345\206\263\346\226\271\346\241\210.md" "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\345\270\270\347\224\250\350\247\243\345\206\263\346\226\271\346\241\210.md"
index 21a891b..77adff5 100644
--- "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\345\270\270\347\224\250\350\247\243\345\206\263\346\226\271\346\241\210.md"
+++ "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\345\270\270\347\224\250\350\247\243\345\206\263\346\226\271\346\241\210.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [一�概述](#一�概述)
* [二��论](#二��论)
diff --git "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\235\346\216\242\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241zookeeper.md" "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\235\346\216\242\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241zookeeper.md"
index f8699df..45da3d8 100644
--- "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\235\346\216\242\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241zookeeper.md"
+++ "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\345\210\235\346\216\242\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\346\234\215\345\212\241zookeeper.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [目录](#目录)
* [��的邮件](#��的邮件)
diff --git "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\346\265\205\346\236\220\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md" "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\346\265\205\346\236\220\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md"
index 147a92e..3f1f40d 100644
--- "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\346\265\205\346\236\220\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md"
+++ "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\346\265\205\346\236\220\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [目录](#目录)
* [什么是事务?](#什么是事务?)
diff --git "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\346\266\210\346\201\257\346\212\200\346\234\257Kafka.md" "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\346\266\210\346\201\257\346\212\200\346\234\257Kafka.md"
index 7e54e71..28fc2ff 100644
--- "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\346\266\210\346\201\257\346\212\200\346\234\257Kafka.md"
+++ "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\346\266\210\346\201\257\346\212\200\346\234\257Kafka.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [目录](#目录)
* [**Kafka的基本介�**](#kafka的基本介�)
diff --git "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\351\224\201\347\232\204\345\207\240\347\247\215\346\226\271\346\241\210.md" "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\351\224\201\347\232\204\345\207\240\347\247\215\346\226\271\346\241\210.md"
index 701bde3..b9e4ea5 100644
--- "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\351\224\201\347\232\204\345\207\240\347\247\215\346\226\271\346\241\210.md"
+++ "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\346\265\205\350\260\210\345\210\206\345\270\203\345\274\217\351\224\201\347\232\204\345\207\240\347\247\215\346\226\271\346\241\210.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [目录](#目录)
* [�言](#�言)
diff --git "a/docs/distributed/\345\210\206\345\270\203\345\274\217\347\220\206\350\256\272\346\200\273\347\273\223.md" "b/docs/distributed/\345\210\206\345\270\203\345\274\217\347\220\206\350\256\272\346\200\273\347\273\223.md"
index d7b5027..9e341f3 100644
--- "a/docs/distributed/\345\210\206\345\270\203\345\274\217\347\220\206\350\256\272\346\200\273\347\273\223.md"
+++ "b/docs/distributed/\345\210\206\345\270\203\345\274\217\347\220\206\350\256\272\346\200\273\347\273\223.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [å…ã€�Raft](#å…ã€�raft)
* [�个 Candidate 的竞选](#�个-candidate-的竞选)
diff --git "a/docs/hxx/java/Java\345\220\216\347\253\257\345\267\245\347\250\213\345\270\210\345\277\205\345\244\207\344\271\246\345\215\225\357\274\210\344\273\216Java\345\237\272\347\241\200\345\210\260\345\210\206\345\270\203\345\274\217\357\274\211.md" "b/docs/hxx/java/Java\345\220\216\347\253\257\345\267\245\347\250\213\345\270\210\345\277\205\345\244\207\344\271\246\345\215\225\357\274\210\344\273\216Java\345\237\272\347\241\200\345\210\260\345\210\206\345\270\203\345\274\217\357\274\211.md"
index 7b4490d..65b42bb 100644
--- "a/docs/hxx/java/Java\345\220\216\347\253\257\345\267\245\347\250\213\345\270\210\345\277\205\345\244\207\344\271\246\345\215\225\357\274\210\344\273\216Java\345\237\272\347\241\200\345\210\260\345\210\206\345\270\203\345\274\217\357\274\211.md"
+++ "b/docs/hxx/java/Java\345\220\216\347\253\257\345\267\245\347\250\213\345\270\210\345\277\205\345\244\207\344\271\246\345\215\225\357\274\210\344\273\216Java\345\237\272\347\241\200\345\210\260\345\210\206\345\270\203\345\274\217\357\274\211.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [网络](#网络)
* [1 TCP/IP�一](#1-tcpip�一)
diff --git "a/docs/hxx/java/Java\345\267\245\347\250\213\345\270\210\344\277\256\347\202\274\344\271\213\350\267\257\357\274\210\346\240\241\346\213\233\346\200\273\347\273\223\357\274\211.md" "b/docs/hxx/java/Java\345\267\245\347\250\213\345\270\210\344\277\256\347\202\274\344\271\213\350\267\257\357\274\210\346\240\241\346\213\233\346\200\273\347\273\223\357\274\211.md"
index 1432c75..221cd8f 100644
--- "a/docs/hxx/java/Java\345\267\245\347\250\213\345\270\210\344\277\256\347\202\274\344\271\213\350\267\257\357\274\210\346\240\241\346\213\233\346\200\273\347\273\223\357\274\211.md"
+++ "b/docs/hxx/java/Java\345\267\245\347\250\213\345\270\210\344\277\256\347\202\274\344\271\213\350\267\257\357\274\210\346\240\241\346\213\233\346\200\273\347\273\223\357\274\211.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [�言](#�言)
* [大妿—¶æœŸçš„迷茫与å�šå®š](#大妿—¶æœŸçš„迷茫与å�šå®š)
diff --git "a/docs/hxx/java/\344\270\272\344\273\200\344\271\210\346\210\221\344\274\232\351\200\211\346\213\251\350\265\260 Java \350\277\231\346\235\241\350\267\257\357\274\237.md" "b/docs/hxx/java/\344\270\272\344\273\200\344\271\210\346\210\221\344\274\232\351\200\211\346\213\251\350\265\260 Java \350\277\231\346\235\241\350\267\257\357\274\237.md"
index c72b4dd..ed2fe79 100644
--- "a/docs/hxx/java/\344\270\272\344\273\200\344\271\210\346\210\221\344\274\232\351\200\211\346\213\251\350\265\260 Java \350\277\231\346\235\241\350\267\257\357\274\237.md"
+++ "b/docs/hxx/java/\344\270\272\344\273\200\344\271\210\346\210\221\344\274\232\351\200\211\346\213\251\350\265\260 Java \350\277\231\346\235\241\350\267\257\357\274\237.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [谈谈我的技术方�选择](#谈谈我的技术方�选择)
* [谈谈�个技术方�的�景](#谈谈�个技术方�的�景)
diff --git "a/docs/hxx/java/\344\275\240\344\270\215\345\217\257\351\224\231\350\277\207\347\232\204Java\345\255\246\344\271\240\350\265\204\346\272\220\346\270\205\345\215\225.md" "b/docs/hxx/java/\344\275\240\344\270\215\345\217\257\351\224\231\350\277\207\347\232\204Java\345\255\246\344\271\240\350\265\204\346\272\220\346\270\205\345\215\225.md"
index b4a6a53..0b41820 100644
--- "a/docs/hxx/java/\344\275\240\344\270\215\345\217\257\351\224\231\350\277\207\347\232\204Java\345\255\246\344\271\240\350\265\204\346\272\220\346\270\205\345\215\225.md"
+++ "b/docs/hxx/java/\344\275\240\344\270\215\345\217\257\351\224\231\350\277\207\347\232\204Java\345\255\246\344\271\240\350\265\204\346\272\220\346\270\205\345\215\225.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [Java入门å¦ä¹ 资æº�](#java入门å¦ä¹ 资æº�)
* [Javaå�Žç«¯æŠ€æœ¯ä¸“æ �](#javaå�Žç«¯æŠ€æœ¯ä¸“æ �)
diff --git "a/docs/hxx/java/\346\203\263\344\272\206\350\247\243Java\345\220\216\347\253\257\345\255\246\344\271\240\350\267\257\347\272\277\357\274\237\344\275\240\345\217\252\351\234\200\350\246\201\350\277\231\344\270\200\345\274\240\345\233\276\357\274\201.md" "b/docs/hxx/java/\346\203\263\344\272\206\350\247\243Java\345\220\216\347\253\257\345\255\246\344\271\240\350\267\257\347\272\277\357\274\237\344\275\240\345\217\252\351\234\200\350\246\201\350\277\231\344\270\200\345\274\240\345\233\276\357\274\201.md"
index 202769b..3da5c3d 100644
--- "a/docs/hxx/java/\346\203\263\344\272\206\350\247\243Java\345\220\216\347\253\257\345\255\246\344\271\240\350\267\257\347\272\277\357\274\237\344\275\240\345\217\252\351\234\200\350\246\201\350\277\231\344\270\200\345\274\240\345\233\276\357\274\201.md"
+++ "b/docs/hxx/java/\346\203\263\344\272\206\350\247\243Java\345\220\216\347\253\257\345\255\246\344\271\240\350\267\257\347\272\277\357\274\237\344\275\240\345\217\252\351\234\200\350\246\201\350\277\231\344\270\200\345\274\240\345\233\276\357\274\201.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [](#[]httpsmmbizqpiccnmmbiz_jpgxhh0sksqzpniac1cdgficiqdtr2poaq2jmvd3jnkuoiabzxgzdjh9pcics0rckcgawvgvnm7zh2lvlodkatzanldzg640wx_fmtjpegtpwebpwxfrom5wx_lazy1wx_co1)
* [�言](#�言)
diff --git "a/docs/hxx/java/\346\210\221\347\232\204Java\347\247\213\346\213\233\351\235\242\347\273\217\345\244\247\345\220\210\351\233\206.md" "b/docs/hxx/java/\346\210\221\347\232\204Java\347\247\213\346\213\233\351\235\242\347\273\217\345\244\247\345\220\210\351\233\206.md"
index 3b54d0f..cbe57c4 100644
--- "a/docs/hxx/java/\346\210\221\347\232\204Java\347\247\213\346\213\233\351\235\242\347\273\217\345\244\247\345\220\210\351\233\206.md"
+++ "b/docs/hxx/java/\346\210\221\347\232\204Java\347\247\213\346\213\233\351\235\242\347\273\217\345\244\247\345\220\210\351\233\206.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [阿里��  ](#阿里��  )
* [腾讯��  ](#腾讯��  )
diff --git a/docs/hxx/think/copy.md b/docs/hxx/think/copy.md
index c62954a..813a411 100644
--- a/docs/hxx/think/copy.md
+++ b/docs/hxx/think/copy.md
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [微信公众�](#微信公众�)
* [个人公众�:黄�斜](#个人公众�:黄�斜)
diff --git "a/docs/hxx/\347\224\265\345\255\220\344\271\246.md" "b/docs/hxx/\347\224\265\345\255\220\344\271\246.md"
index 5e77629..b80bf2e 100644
--- "a/docs/hxx/\347\224\265\345\255\220\344\271\246.md"
+++ "b/docs/hxx/\347\224\265\345\255\220\344\271\246.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [《�鸟程�员�长之路:从技术�白到阿里巴巴Java工程师》](#《�鸟程�员�长之路:从技术�白到阿里巴巴java工程师》)
* [Javaå¦ä¹ ](#javaå¦ä¹ )
diff --git a/docs/interview/BATJ-Experience/alipay-pinduoduo-toutiao.md b/docs/interview/BATJ-Experience/alipay-pinduoduo-toutiao.md
index 1db1539..27df6fa 100644
--- a/docs/interview/BATJ-Experience/alipay-pinduoduo-toutiao.md
+++ b/docs/interview/BATJ-Experience/alipay-pinduoduo-toutiao.md
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [2019年蚂�金��头��拼多多的�试总结](#2019年蚂�金��头��拼多多的�试总结)
* [准备过程](#准备过程)
diff --git "a/docs/interview/BATJ-Experience/\350\232\202\350\232\201\351\207\221\346\234\215\345\256\236\344\271\240\347\224\237\351\235\242\347\273\217\346\200\273\347\273\223(\345\267\262\346\213\277\345\217\243\345\244\264offer).md" "b/docs/interview/BATJ-Experience/\350\232\202\350\232\201\351\207\221\346\234\215\345\256\236\344\271\240\347\224\237\351\235\242\347\273\217\346\200\273\347\273\223(\345\267\262\346\213\277\345\217\243\345\244\264offer).md"
index 95f8403..61fb537 100644
--- "a/docs/interview/BATJ-Experience/\350\232\202\350\232\201\351\207\221\346\234\215\345\256\236\344\271\240\347\224\237\351\235\242\347\273\217\346\200\273\347\273\223(\345\267\262\346\213\277\345\217\243\345\244\264offer).md"
+++ "b/docs/interview/BATJ-Experience/\350\232\202\350\232\201\351\207\221\346\234\215\345\256\236\344\271\240\347\224\237\351\235\242\347\273\217\346\200\273\347\273\223(\345\267\262\346\213\277\345\217\243\345\244\264offer).md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [一� (37 分钟左�)](#一�-37-分钟左�)
* [二� (33 分钟左�)](#二�-33-分钟左�)
diff --git "a/docs/interview/BATJ-Experience/\351\235\242\351\230\277\351\207\214,\347\273\210\350\216\267offer.md" "b/docs/interview/BATJ-Experience/\351\235\242\351\230\277\351\207\214,\347\273\210\350\216\267offer.md"
index 5a6e7e3..b06c915 100644
--- "a/docs/interview/BATJ-Experience/\351\235\242\351\230\277\351\207\214,\347\273\210\350\216\267offer.md"
+++ "b/docs/interview/BATJ-Experience/\351\235\242\351\230\277\351\207\214,\347\273\210\350\216\267offer.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [�言](#�言)
* [一�(技术�)](#一�技术�)
diff --git "a/docs/interview/InterviewQuestions/Java\346\240\270\345\277\203\346\212\200\346\234\257\346\200\273\347\273\223.md" "b/docs/interview/InterviewQuestions/Java\346\240\270\345\277\203\346\212\200\346\234\257\346\200\273\347\273\223.md"
index d624749..bc89b6d 100644
--- "a/docs/interview/InterviewQuestions/Java\346\240\270\345\277\203\346\212\200\346\234\257\346\200\273\347\273\223.md"
+++ "b/docs/interview/InterviewQuestions/Java\346\240\270\345\277\203\346\212\200\346\234\257\346\200\273\347\273\223.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [Java基础å¦ä¹ 总结](#java基础å¦ä¹ 总结)
* [��对象三大特性](#��对象三大特性)
diff --git a/docs/interview/PreparingForInterview/JavaInterviewLibrary.md b/docs/interview/PreparingForInterview/JavaInterviewLibrary.md
index e3d4e1d..2325618 100644
--- a/docs/interview/PreparingForInterview/JavaInterviewLibrary.md
+++ b/docs/interview/PreparingForInterview/JavaInterviewLibrary.md
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [知识点相关](#知识点相关)
* [1.JavaGuide](#1javaguide)
diff --git a/docs/interview/PreparingForInterview/JavaProgrammerNeedKnow.md b/docs/interview/PreparingForInterview/JavaProgrammerNeedKnow.md
index 417d1f9..3997584 100644
--- a/docs/interview/PreparingForInterview/JavaProgrammerNeedKnow.md
+++ b/docs/interview/PreparingForInterview/JavaProgrammerNeedKnow.md
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [Question1:我是å�Œé�ž/三本/ä¸“ç§‘å¦æ ¡çš„,我有机会进入大厂å�—?](#question1我是å�Œé�žä¸‰æœ¬ä¸“ç§‘å¦æ ¡çš„,我有机会进入大厂å�—?)
* [Question2:é�žè®¡ç®—机专业的å¦ç”Ÿèƒ½å¦å¥½Javaå�Žå�°å�—?我能进大厂å�—?](#question2é�žè®¡ç®—机专业的å¦ç”Ÿèƒ½å¦å¥½javaå�Žå�°å�—?我能进大厂å�—?)
diff --git a/docs/interview/PreparingForInterview/interviewPrepare.md b/docs/interview/PreparingForInterview/interviewPrepare.md
index 89a3dc6..72201be 100644
--- a/docs/interview/PreparingForInterview/interviewPrepare.md
+++ b/docs/interview/PreparingForInterview/interviewPrepare.md
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [1 如何获�大厂�试机会?](#1-如何获�大厂�试机会?)
* [2 �试�的准备](#2--�试�的准备)
diff --git "a/docs/interview/PreparingForInterview/\345\246\202\346\236\234\351\235\242\350\257\225\345\256\230\351\227\256\344\275\240\342\200\234\344\275\240\346\234\211\344\273\200\344\271\210\351\227\256\351\242\230\351\227\256\346\210\221\345\220\227\357\274\237\342\200\235\346\227\266\357\274\214\344\275\240\350\257\245\345\246\202\344\275\225\345\233\236\347\255\224.md" "b/docs/interview/PreparingForInterview/\345\246\202\346\236\234\351\235\242\350\257\225\345\256\230\351\227\256\344\275\240\342\200\234\344\275\240\346\234\211\344\273\200\344\271\210\351\227\256\351\242\230\351\227\256\346\210\221\345\220\227\357\274\237\342\200\235\346\227\266\357\274\214\344\275\240\350\257\245\345\246\202\344\275\225\345\233\236\347\255\224.md"
index 0dc99b2..c1f742b 100644
--- "a/docs/interview/PreparingForInterview/\345\246\202\346\236\234\351\235\242\350\257\225\345\256\230\351\227\256\344\275\240\342\200\234\344\275\240\346\234\211\344\273\200\344\271\210\351\227\256\351\242\230\351\227\256\346\210\221\345\220\227\357\274\237\342\200\235\346\227\266\357\274\214\344\275\240\350\257\245\345\246\202\344\275\225\345\233\236\347\255\224.md"
+++ "b/docs/interview/PreparingForInterview/\345\246\202\346\236\234\351\235\242\350\257\225\345\256\230\351\227\256\344\275\240\342\200\234\344\275\240\346\234\211\344\273\200\344\271\210\351\227\256\351\242\230\351\227\256\346\210\221\345\220\227\357\274\237\342\200\235\346\227\266\357\274\214\344\275\240\350\257\245\345\246\202\344\275\225\345\233\236\347\255\224.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [这个问题对最终�试结果的影�到底大�大?](#这个问题对最终�试结果的影�到底大�大)
* [真诚一点,��问太 Low 的问题](#真诚一点��问太-low-的问题)
diff --git "a/docs/interview/PreparingForInterview/\347\250\213\345\272\217\345\221\230\347\232\204\347\256\200\345\216\206\344\271\213\351\201\223.md" "b/docs/interview/PreparingForInterview/\347\250\213\345\272\217\345\221\230\347\232\204\347\256\200\345\216\206\344\271\213\351\201\223.md"
index 096ecaf..f391399 100644
--- "a/docs/interview/PreparingForInterview/\347\250\213\345\272\217\345\221\230\347\232\204\347\256\200\345\216\206\344\271\213\351\201\223.md"
+++ "b/docs/interview/PreparingForInterview/\347\250\213\345\272\217\345\221\230\347\232\204\347\256\200\345\216\206\344\271\213\351\201\223.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [程åº�å‘˜ç®€åŽ†å°±è¯¥è¿™æ ·å†™](#程åº�å‘˜ç®€åŽ†å°±è¯¥è¿™æ ·å†™)
* [为什么说简历很��?](#为什么说简历很��?)
diff --git "a/docs/interview/PreparingForInterview/\347\276\216\345\233\242\351\235\242\350\257\225\345\270\270\350\247\201\351\227\256\351\242\230\346\200\273\347\273\223.md" "b/docs/interview/PreparingForInterview/\347\276\216\345\233\242\351\235\242\350\257\225\345\270\270\350\247\201\351\227\256\351\242\230\346\200\273\347\273\223.md"
index 4e62535..8b51c2a 100644
--- "a/docs/interview/PreparingForInterview/\347\276\216\345\233\242\351\235\242\350\257\225\345\270\270\350\247\201\351\227\256\351\242\230\346\200\273\347\273\223.md"
+++ "b/docs/interview/PreparingForInterview/\347\276\216\345\233\242\351\235\242\350\257\225\345\270\270\350\247\201\351\227\256\351\242\230\346\200\273\347\273\223.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [一 基础篇](#一-基础篇)
* [1. `System.out.println(3|9)`输出什么?](#1-`systemoutprintln39`输出什么)
diff --git "a/docs/java/jvm/JVM\346\200\273\347\273\223.md" "b/docs/java/jvm/JVM\346\200\273\347\273\223.md"
index 9a1cdad..60b89e6 100644
--- "a/docs/java/jvm/JVM\346\200\273\347\273\223.md"
+++ "b/docs/java/jvm/JVM\346\200\273\347\273\223.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [JVM介ç»�å’Œæº�ç �](#jvm介ç»�å’Œæº�ç �)
* [JVMå†…å˜æ¨¡åž‹](#jvmå†…å˜æ¨¡åž‹)
From 88e6f706f84c4d40ec55bdd0f35d732f550f72a8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=BB=84=E5=B0=8F=E6=96=9C?= <362294931@qq.com>
Date: Sun, 9 Apr 2023 17:52:09 +0800
Subject: [PATCH 06/39] modify jvm mds
---
ReadMe.md | 4 +-
...37\345\214\226\346\212\200\346\234\257.md" | 2 +-
...23\346\236\204\346\246\202\350\247\210.md" | 2 +-
...\247\243\342\200\224\342\200\224intset.md" | 8 +-
...247\243\342\200\224\342\200\224ziplist.md" | 6 +-
...01\350\277\233\345\214\226\345\217\262.md" | 6 +-
...60\347\241\254\347\233\230\344\270\255.md" | 16 ++--
...33\346\227\245\345\277\227\344\273\254.md" | 12 ---
...23\346\236\204\347\256\227\346\263\225.md" | 2 +-
...60\347\232\204\345\245\227\350\267\257.md" | 2 +-
...33\346\200\273\347\273\223\357\274\211.md" | 10 +-
...04\346\272\220\346\270\205\345\215\225.md" | 24 ++---
...17\345\244\247\345\220\210\351\233\206.md" | 24 ++---
.../\347\224\265\345\255\220\344\271\246.md" | 12 +--
...67\346\261\202\350\275\254\345\217\221.md" | 4 +-
...5\277\265\344\270\216DispatcherServlet.md" | 2 +-
...274\232Mybatis\345\205\245\351\227\250.md" | 2 +-
...5\273\272\345\267\245\345\205\267Maven.md" | 4 +-
...\215\347\275\256\347\232\204SpringBoot.md" | 14 +--
"docs/java/basic/javac\345\222\214javap.md" | 9 +-
...47\350\241\214\351\241\272\345\272\217.md" | 2 +-
.../\345\244\232\347\272\277\347\250\213.md" | 4 +-
...55\347\232\204\345\233\236\350\260\203.md" | 5 +-
...16\346\257\224\350\276\203\345\231\250.md" | 12 +--
...36\347\216\260\345\216\237\347\220\206.md" | 9 +-
...71\263\351\224\201\357\274\214Condtion.md" | 4 +-
...27\346\263\225\345\211\226\346\236\220.md" | 6 +-
...56\345\255\227\350\247\243\346\236\220.md" | 11 ++-
...ap\345\205\250\350\247\243\346\236\220.md" | 12 +--
...20\347\240\201\345\210\206\346\236\220.md" | 12 +--
...357\274\214CAS\346\223\215\344\275\234.md" | 1 -
...345\255\230\346\250\241\345\236\213JMM.md" | 2 +-
...20\347\240\201\345\256\236\347\216\260.md" | 12 +--
...46\344\271\240\346\200\273\347\273\223.md" | 1 -
...76\350\256\241\346\250\241\345\274\217.md" | 91 +++++++++++++------
...70\347\224\250\345\267\245\345\205\267.md" | 23 ++++-
...03\344\274\230\345\256\236\350\267\265.md" | 37 ++++----
...75\345\231\250\345\256\236\347\216\260.md" | 2 +-
...06\345\222\214\347\256\227\346\263\225.md" | 2 +-
...14\346\234\237\344\274\230\345\214\226.md" | 6 +-
...\345\217\212GC\345\256\236\350\267\265.md" | 2 +-
...26\347\250\213\346\250\241\345\236\213.md" | 4 +-
...\345\222\214\345\274\202\346\255\245IO.md" | 8 +-
...7\250\213\346\241\206\346\236\266Netty.md" | 2 +-
src/main/java/md/mdToc.java | 2 +-
45 files changed, 234 insertions(+), 203 deletions(-)
rename "docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232GC\350\260\203\344\274\230\346\200\235\350\267\257\344\270\216\345\270\270\347\224\250\345\267\245\345\205\267.md" => "docs/java/jvm/temp/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232GC\350\260\203\344\274\230\346\200\235\350\267\257\344\270\216\345\270\270\347\224\250\345\267\245\345\205\267.md" (98%)
rename "docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232JVM\345\270\270\347\224\250\345\217\202\346\225\260\344\273\245\345\217\212\350\260\203\344\274\230\345\256\236\350\267\265.md" => "docs/java/jvm/temp/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232JVM\345\270\270\347\224\250\345\217\202\346\225\260\344\273\245\345\217\212\350\260\203\344\274\230\345\256\236\350\267\265.md" (98%)
diff --git a/ReadMe.md b/ReadMe.md
index dc53ae6..1a6c3a5 100644
--- a/ReadMe.md
+++ b/ReadMe.md
@@ -204,11 +204,11 @@ todo
* [深入ç�†è§£JVM虚拟机:JNDI,OSGI,Tomcatç±»åŠ è½½å™¨å®žçŽ°](docs/java/jvm/深入ç�†è§£JVM虚拟机:JNDI,OSGI,Tomcatç±»åŠ è½½å™¨å®žçŽ°.md)
* [深入了解JVM虚拟机:Java的编译期优化与�行期优化](docs/java/jvm/深入�解JVM虚拟机:Java的编译期优化与�行期优化.md)
* [深入ç�†è§£JVM虚拟机:JVM监控工具与诊æ–实践](docs/java/jvm/深入ç�†è§£JVM虚拟机:JVM监控工具与诊æ–实践.md)
-* [深入�解JVM虚拟机:JVM常用�数以�调优实践](docs/java/jvm/深入�解JVM虚拟机:JVM常用�数以�调优实践.md)
+* [深入�解JVM虚拟机:JVM常用�数以�调优实践](docs/java/jvm/temp/深入�解JVM虚拟机:JVM常用�数以�调优实践.md)
* [深入ç�†è§£JVM虚拟机:Java内å˜å¼‚常原ç�†ä¸Žå®žè·µ](docs/java/jvm/深入ç�†è§£JVM虚拟机:Java内å˜å¼‚常原ç�†ä¸Žå®žè·µ.md)
* [深入�解JVM虚拟机:JVM性能管�神器VisualVM介�与实战](docs/java/jvm/深入�解JVM虚拟机:JVM性能管�神器VisualVM介�与实战.md)
* [深入�解JVM虚拟机:�谈四�引用�GC实践](docs/java/jvm/深入�解JVM虚拟机:�谈四�引用�GC实践.md)
-* [深入�解JVM虚拟机:GC调优�路与常用工具](docs/java/jvm/深入�解JVM虚拟机:GC调优�路与常用工具.md)
+* [深入�解JVM虚拟机:GC调优�路与常用工具](docs/java/jvm/temp/深入�解JVM虚拟机:GC调优�路与常用工具.md)
### Java网络编程
diff --git "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\210\357\274\232\347\231\275\350\257\235\350\231\232\346\213\237\345\214\226\346\212\200\346\234\257.md" "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\210\357\274\232\347\231\275\350\257\235\350\231\232\346\213\237\345\214\226\346\212\200\346\234\257.md"
index ec768cb..7896eb0 100644
--- "a/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\210\357\274\232\347\231\275\350\257\235\350\231\232\346\213\237\345\214\226\346\212\200\346\234\257.md"
+++ "b/docs/big-backEnd/\345\220\216\347\253\257\346\212\200\346\234\257\346\235\202\350\260\210\357\274\232\347\231\275\350\257\235\350\231\232\346\213\237\345\214\226\346\212\200\346\234\257.md"
@@ -103,7 +103,7 @@
å¯¹äºŽè™šæ‹Ÿæœºå†…æ ¸æ�¥è®²ï¼Œå�ªè¦�å°†æ ‡å¿—ä½�设为虚拟机状æ€�,则å�¯ä»¥ç›´æŽ¥åœ¨CPU上执行大部分的指令,ä¸�需è¦�虚拟化软件在ä¸é—´è½¬è¿°ï¼Œé™¤é�žé�‡åˆ°ç‰¹åˆ«æ•�感的指令,æ‰�需è¦�å°†æ ‡å¿—ä½�设为物ç�†æœºå†…æ ¸æ€�è¿�è¡Œï¼Œè¿™æ ·å¤§å¤§æ��高了效率。
-所以安装虚拟机的时候,务必è¦�将物ç�†CPUçš„è¿™ä¸ªæ ‡å¿—ä½�打开,是å�¦æ‰“开对于Intelå�¯ä»¥æŸ¥çœ‹grep "vmx" /proc/cpuinfo,对于AMDå�¯ä»¥æŸ¥çœ‹grep "svm" /proc/cpuinfo
+所以安装虚拟机的时候,务必è¦�将物ç�†CPUçš„è¿™ä¸ªæ ‡å¿—ä½�打开,是å�¦æ‰“开对于Intelå�¯ä»¥æŸ¥çœ‹grep"vmx" /proc/cpuinfo,对于AMDå�¯ä»¥æŸ¥çœ‹grep "svm" /proc/cpuinfo
这��硬件辅助虚拟化。
diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis \347\232\204\345\237\272\347\241\200\346\225\260\346\215\256\347\273\223\346\236\204\346\246\202\350\247\210.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis \347\232\204\345\237\272\347\241\200\346\225\260\346\215\256\347\273\223\346\236\204\346\246\202\350\247\210.md"
index 9102d4d..9d78bed 100644
--- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis \347\232\204\345\237\272\347\241\200\346\225\260\346\215\256\347\273\223\346\236\204\346\246\202\350\247\210.md"
+++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis \347\232\204\345\237\272\347\241\200\346\225\260\346\215\256\347\273\223\346\236\204\346\246\202\350\247\210.md"
@@ -114,7 +114,7 @@ Redisçš„å—典由三个基础的数æ�®ç»“构组æˆ�。最底层的å�•ä½�是哈希
union { void *val; uint64_t u64; int64_t s64; } v; // 指�下个哈希表节点,形�链表
struct dictEntry *next; } dictEntry;
````
-实际上哈希表节点就是一个å�•项列表的节点。ä¿�å˜äº†ä¸€ä¸‹ä¸‹ä¸€ä¸ªèŠ‚ç‚¹çš„æŒ‡é’ˆã€‚ key 就是节点的键,v是这个节点的值。这个 v æ—¢å�¯ä»¥æ˜¯ä¸€ä¸ªæŒ‡é’ˆï¼Œä¹Ÿå�¯ä»¥æ˜¯ä¸€ä¸ªÂ `uint64_t`或者 `int64_t` 整数。*next 指å�‘下一个节点。
+实际上哈希表节点就是一个å�•项列表的节点。ä¿�å˜äº†ä¸€ä¸‹ä¸‹ä¸€ä¸ªèŠ‚ç‚¹çš„æŒ‡é’ˆã€‚ key 就是节点的键,v是这个节点的值。这个 v æ—¢å�¯ä»¥æ˜¯ä¸€ä¸ªæŒ‡é’ˆï¼Œä¹Ÿå�¯ä»¥æ˜¯ä¸€ä¸ª`uint64_t`或者`int64_t`整数。*next 指å�‘下一个节点。
通过一个哈希表的数组把�个节点链接起�:
````
diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224intset.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224intset.md"
index 95204c4..b8ffc6e 100644
--- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224intset.md"
+++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224intset.md"
@@ -84,7 +84,7 @@ typedef struct intset {
* `encoding`: æ•°æ�®ç¼–ç �,表示intsetä¸çš„æ¯�个数æ�®å…ƒç´ ç”¨å‡ ä¸ªå—节æ�¥å˜å‚¨ã€‚它有三ç§�å�¯èƒ½çš„å�–值:INTSET_ENC_INT16表示æ¯�ä¸ªå…ƒç´ ç”¨2个å—节å˜å‚¨ï¼ŒINTSET_ENC_INT32表示æ¯�ä¸ªå…ƒç´ ç”¨4个å—节å˜å‚¨ï¼ŒINTSET_ENC_INT64表示æ¯�ä¸ªå…ƒç´ ç”¨8个å—节å˜å‚¨ã€‚å› æ¤ï¼Œintsetä¸å˜å‚¨çš„æ•´æ•°æœ€å¤šå�ªèƒ½å� 用64bit。
* `length`: 表示intsetä¸çš„å…ƒç´ ä¸ªæ•°ã€‚`encoding`å’Œ`length`ä¸¤ä¸ªå—æ®µæž„æˆ�了intset的头部(header)。
-* `contents`: 是一个柔性数组([flexible array member](https://en.wikipedia.org/wiki/Flexible_array_member)),表示intsetçš„headerå�Žé�¢ç´§è·Ÿç�€æ•°æ�®å…ƒç´ 。这个数组的总长度(å�³æ€»å—节数)ç‰äºŽ`encoding * length`。柔性数组在Redis的很多数æ�®ç»“构的定义ä¸éƒ½å‡ºçŽ°è¿‡ï¼ˆä¾‹å¦‚[sds](http://zhangtielei.com/posts/blog-redis-sds.html), [quicklist](http://zhangtielei.com/posts/blog-redis-quicklist.html), [skiplist](http://zhangtielei.com/posts/blog-redis-skiplist.html)),用于表达一个å��ç§»é‡�。`contents`需è¦�å�•独为其分é…�空间,这部分内å˜ä¸�包å�«åœ¨intset结构当ä¸ã€‚
+* `contents`: 是一个柔性数组([flexible array member](https://en.wikipedia.org/wiki/Flexible_array_member)),表示intsetçš„headerå�Žé�¢ç´§è·Ÿç�€æ•°æ�®å…ƒç´ 。这个数组的总长度(å�³æ€»å—节数)ç‰äºŽ`encoding * length`。柔性数组在Redis的很多数æ�®ç»“构的定义ä¸éƒ½å‡ºçŽ°è¿‡ï¼ˆä¾‹å¦‚[sds](http://zhangtielei.com/posts/blog-redis-sds.html),[quicklist](http://zhangtielei.com/posts/blog-redis-quicklist.html),[skiplist](http://zhangtielei.com/posts/blog-redis-skiplist.html)),用于表达一个å��ç§»é‡�。`contents`需è¦�å�•独为其分é…�空间,这部分内å˜ä¸�包å�«åœ¨intset结构当ä¸ã€‚
å…¶ä¸éœ€è¦�注æ„�的是,intsetå�¯èƒ½ä¼šéš�ç�€æ•°æ�®çš„æ·»åŠ è€Œæ”¹å�˜å®ƒçš„æ•°æ�®ç¼–ç �:
@@ -97,7 +97,7 @@ typedef struct intset {
在上图ä¸ï¼š
-* 新创建的intsetå�ªæœ‰ä¸€ä¸ªheader,总共8个å—节。其ä¸`encoding` = 2, `length` = 0。
+* 新创建的intsetå�ªæœ‰ä¸€ä¸ªheader,总共8个å—节。其ä¸`encoding`= 2,`length`= 0。
* æ·»åŠ 13, 5ä¸¤ä¸ªå…ƒç´ ä¹‹å�Žï¼Œå› 为它们是比较å°�的整数,都能使用2个å—节表示,所以`encoding`ä¸�å�˜ï¼Œå€¼è¿˜æ˜¯2。
* å½“æ·»åŠ 32768的时候,它ä¸�å†�能用2个å—节æ�¥è¡¨ç¤ºäº†ï¼ˆ2个å—节能表达的数æ�®èŒƒå›´æ˜¯-215~215-1,而32768ç‰äºŽ215ï¼Œè¶…å‡ºèŒƒå›´äº†ï¼‰ï¼Œå› æ¤`encoding`å¿…é¡»å�‡çº§åˆ°INTSET_ENC_INT32(值为4),å�³ç”¨4个å—èŠ‚è¡¨ç¤ºä¸€ä¸ªå…ƒç´ ã€‚
* åœ¨æ·»åŠ æ¯�ä¸ªå…ƒç´ çš„è¿‡ç¨‹ä¸ï¼Œintset始终ä¿�æŒ�从å°�到大有åº�。
@@ -247,11 +247,11 @@ intset *intsetAdd(intset *is, int64_t value, uint8_t *success) {
* `sadd`用于分别å�‘集å�ˆ`s1`å’Œ`s2`䏿·»åŠ å…ƒç´ ã€‚æ·»åŠ çš„å…ƒç´ æ—¢æœ‰æ•°å—,也有é�žæ•°å—(â€�aâ€�å’Œâ€�bâ€�)。
* `sismember`ç”¨äºŽåˆ¤æ–æŒ‡å®šçš„å…ƒç´ æ˜¯å�¦åœ¨é›†å�ˆå†…å˜åœ¨ã€‚
-* `sinter`, `sunion`和`sdiff`分别用于计算集�的交集�并集和差集。
+* `sinter`,`sunion`和`sdiff`分别用于计算集�的交集�并集和差集。
我们å‰�é�¢æ��到过,set的底层实现,éš�ç�€å…ƒç´ 类型是å�¦æ˜¯æ•´åž‹ä»¥å�Šæ·»åŠ çš„å…ƒç´ çš„æ•°ç›®å¤šå°‘ï¼Œè€Œæœ‰æ‰€å�˜åŒ–。例如,具体到上述命令的执行过程ä¸ï¼Œé›†å�ˆ`s1`的底层数æ�®ç»“构会å�‘生如下å�˜åŒ–:
-* 在开始执行完`sadd s1 13 5`之å�Žï¼Œç”±äºŽæ·»åŠ çš„éƒ½æ˜¯æ¯”è¾ƒå°�的整数,所以`s1`底层是一个intset,其数æ�®ç¼–ç �`encoding` = 2。
+* 在开始执行完`sadd s1 13 5`之å�Žï¼Œç”±äºŽæ·»åŠ çš„éƒ½æ˜¯æ¯”è¾ƒå°�的整数,所以`s1`底层是一个intset,其数æ�®ç¼–ç �`encoding`= 2。
* 在执行完`sadd s1 32768 10 100000`之å�Žï¼Œ`s1`底层ä»�然是一个intset,但其数æ�®ç¼–ç �`encoding`从2å�‡çº§åˆ°äº†4。
* 在执行完`sadd s1 a b`之å�Žï¼Œç”±äºŽæ·»åŠ çš„å…ƒç´ ä¸�å†�是数å—,`s1`底层的实现会转æˆ�一个dict。
diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224ziplist.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224ziplist.md"
index ea7ce4b..85e3de6 100644
--- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224ziplist.md"
+++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\345\206\205\351\203\250\346\225\260\346\215\256\347\273\223\346\236\204\350\257\246\350\247\243\342\200\224\342\200\224ziplist.md"
@@ -69,7 +69,7 @@ ziplist的数�结构组�是本文�讨论的�点。实际上,ziplist还
* ``: 表示真æ£å˜æ”¾æ•°æ�®çš„æ•°æ�®é¡¹ï¼Œé•¿åº¦ä¸�定。一个数æ�®é¡¹ï¼ˆentry)也有它自己的内部结构,这个ç¨�å�Žå†�解释。
* ``: ziplist最å�Ž1个å—节,是一个结æ�Ÿæ ‡è®°ï¼Œå€¼å›ºå®šç‰äºŽ255。
-上é�¢çš„定义ä¸è¿˜å€¼å¾—注æ„�的一点是:``, ``, ``既然å� æ�®å¤šä¸ªå—节,那么在å˜å‚¨çš„æ—¶å€™å°±æœ‰å¤§ç«¯ï¼ˆbig endian)和å°�端(little endian)的区别。ziplist采å�–的是å°�端模å¼�æ�¥å˜å‚¨ï¼Œè¿™åœ¨ä¸‹é�¢æˆ‘们介ç»�具体例å�的时候还会å†�详细解释。
+上é�¢çš„定义ä¸è¿˜å€¼å¾—注æ„�的一点是:``,``,``既然å� æ�®å¤šä¸ªå—节,那么在å˜å‚¨çš„æ—¶å€™å°±æœ‰å¤§ç«¯ï¼ˆbig endian)和å°�端(little endian)的区别。ziplist采å�–的是å°�端模å¼�æ�¥å˜å‚¨ï¼Œè¿™åœ¨ä¸‹é�¢æˆ‘们介ç»�具体例å�的时候还会å†�详细解释。
我们��看一下�一个数�项``的构�:
@@ -207,7 +207,7 @@ static unsigned char *__ziplistInsert(unsigned char *zl, unsigned char *p, unsig
* 这个函数是在指定的ä½�ç½®pæ�’入一段新的数æ�®ï¼Œå¾…æ�’入数æ�®çš„地å�€æŒ‡é’ˆæ˜¯s,长度为slen。æ�’å…¥å�Žå½¢æˆ�一个新的数æ�®é¡¹ï¼Œå� æ�®åŽŸæ�¥pçš„é…�置,原æ�¥ä½�于pä½�置的数æ�®é¡¹ä»¥å�Šå�Žé�¢çš„æ‰€æœ‰æ•°æ�®é¡¹ï¼Œéœ€è¦�统一å�‘å�Žç§»åŠ¨ï¼Œç»™æ–°æ�’入的数æ�®é¡¹ç•™å‡ºç©ºé—´ã€‚å�‚æ•°p指å�‘的是ziplist䏿Ÿ�一个数æ�®é¡¹çš„èµ·å§‹ä½�置,或者在å�‘尾端æ�’入的时候,它指å�‘ziplist的结æ�Ÿæ ‡è®°``。
* 函数开始先计算出待æ�’å…¥ä½�ç½®å‰�一个数æ�®é¡¹çš„长度`prevlen`。这个长度è¦�å˜å…¥æ–°æ�’入的数æ�®é¡¹çš„``å—æ®µã€‚
-* ç„¶å�Žè®¡ç®—当å‰�æ•°æ�®é¡¹å� 用的总å—节数`reqlen`,它包å�«ä¸‰éƒ¨åˆ†ï¼š``, ``和真æ£çš„æ•°æ�®ã€‚å…¶ä¸çš„æ•°æ�®éƒ¨åˆ†ä¼šé€šè¿‡è°ƒç”¨`zipTryEncoding`å…ˆæ�¥å°�试转æˆ�整数。
+* ç„¶å�Žè®¡ç®—当å‰�æ•°æ�®é¡¹å� 用的总å—节数`reqlen`,它包å�«ä¸‰éƒ¨åˆ†ï¼š``,``和真æ£çš„æ•°æ�®ã€‚å…¶ä¸çš„æ•°æ�®éƒ¨åˆ†ä¼šé€šè¿‡è°ƒç”¨`zipTryEncoding`å…ˆæ�¥å°�试转æˆ�整数。
* 由于æ�’入导致的ziplist对于内å˜çš„æ–°å¢žéœ€æ±‚,除了待æ�’入数æ�®é¡¹å� 用的`reqlen`之外,还è¦�考虑原æ�¥pä½�置的数æ�®é¡¹ï¼ˆçŽ°åœ¨è¦�排在待æ�’入数æ�®é¡¹ä¹‹å�Žï¼‰çš„``å—æ®µçš„å�˜åŒ–。本æ�¥å®ƒä¿�å˜çš„æ˜¯å‰�一项的总长度,现在å�˜æˆ�了ä¿�å˜å½“å‰�æ�’入的数æ�®é¡¹çš„æ€»é•¿åº¦ã€‚è¿™æ ·å®ƒçš„``å—æ®µæœ¬èº«éœ€è¦�çš„å˜å‚¨ç©ºé—´ä¹Ÿå�¯èƒ½å�‘生å�˜åŒ–,这个å�˜åŒ–å�¯èƒ½æ˜¯å�˜å¤§ä¹Ÿå�¯èƒ½æ˜¯å�˜å°�。这个å�˜åŒ–了多少的值`nextdiff`,是调用`zipPrevLenByteDiff`计算出æ�¥çš„。如果å�˜å¤§äº†ï¼Œ`nextdiff`是æ£å€¼ï¼Œå�¦åˆ™æ˜¯è´Ÿå€¼ã€‚
* 现在很容易算出æ�¥æ�’å…¥å�Žæ–°çš„ziplist需è¦�多少å—节了,然å�Žè°ƒç”¨`ziplistResize`æ�¥é‡�新调整大å°�。ziplistResize的实现里会调用allocatorçš„`zrealloc`,它有å�¯èƒ½ä¼šé€ æˆ�æ•°æ�®æ‹·è´�。
* 现在é¢�外的空间有了,接下æ�¥å°±æ˜¯å°†åŽŸæ�¥pä½�置的数æ�®é¡¹ä»¥å�Šå�Žé�¢çš„æ‰€æœ‰æ•°æ�®éƒ½å�‘å�ŽæŒªåŠ¨ï¼Œå¹¶ä¸ºå®ƒè®¾ç½®æ–°çš„``å—æ®µã€‚æ¤å¤–,还å�¯èƒ½éœ€è¦�调整ziplistçš„``å—æ®µã€‚
@@ -223,7 +223,7 @@ hash是Redisä¸å�¯ä»¥ç”¨æ�¥å˜å‚¨ä¸€ä¸ªå¯¹è±¡ç»“构的比较ç�†æƒ³çš„æ•°æ�®ç±»
实际上,hashéš�ç�€æ•°æ�®çš„增大,其底层数æ�®ç»“构的实现是会å�‘生å�˜åŒ–的,当然å˜å‚¨æ•ˆçŽ‡ä¹Ÿå°±ä¸�å�Œã€‚在field比较少,å�„个value值也比较å°�的时候,hash采用ziplistæ�¥å®žçŽ°ï¼›è€Œéš�ç�€field增多和value值增大,hashå�¯èƒ½ä¼šå�˜æˆ�dictæ�¥å®žçŽ°ã€‚å½“hash底层å�˜æˆ�dictæ�¥å®žçŽ°çš„æ—¶å€™ï¼Œå®ƒçš„å˜å‚¨æ•ˆçŽ‡å°±æ²¡æ³•è·Ÿé‚£äº›åº�列化方å¼�相比了。
-当我们为�个key第一次执行 `hset key field value` 命令的时候,Redis会创建一个hash结构,这个新创建的hash底层就是一个ziplist。
+当我们为�个key第一次执行`hset key field value`命令的时候,Redis会创建一个hash结构,这个新创建的hash底层就是一个ziplist。
diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\345\210\206\345\270\203\345\274\217\351\224\201\350\277\233\345\214\226\345\217\262.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\345\210\206\345\270\203\345\274\217\351\224\201\350\277\233\345\214\226\345\217\262.md"
index 628426d..4a2ea7d 100644
--- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\345\210\206\345\270\203\345\274\217\351\224\201\350\277\233\345\214\226\345\217\262.md"
+++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232Redis\345\210\206\345\270\203\345\274\217\351\224\201\350\277\233\345\214\226\345\217\262.md"
@@ -101,7 +101,7 @@ release(){
tryLock(){ SETNX Key 1 Seconds}release(){ DELETE Key}
```
-Redis 2.6.12版本å�ŽSETNXå¢žåŠ è¿‡æœŸæ—¶é—´å�‚æ•°ï¼Œè¿™æ ·å°±è§£å†³äº†ä¸¤æ�¡å‘½ä»¤æ— 法ä¿�è¯�原å�性的问题。但是设想下é�¢ä¸€ä¸ªåœºæ™¯ï¼šÂ
+Redis 2.6.12版本å�ŽSETNXå¢žåŠ è¿‡æœŸæ—¶é—´å�‚æ•°ï¼Œè¿™æ ·å°±è§£å†³äº†ä¸¤æ�¡å‘½ä»¤æ— 法ä¿�è¯�原å�性的问题。但是设想下é�¢ä¸€ä¸ªåœºæ™¯ï¼š
1\. C1æˆ�功获å�–到了é”�,之å�ŽC1å› ä¸ºGC进入ç‰å¾…æˆ–è€…æœªçŸ¥åŽŸå› å¯¼è‡´ä»»åŠ¡æ‰§è¡Œè¿‡é•¿ï¼Œæœ€å�Žåœ¨é”�失效å‰�C1没有主动释放é”�
@@ -167,7 +167,7 @@ release(){
```
-Redis 2.6.12å�Ž[SET](https://redis.io/commands/set)å�Œæ ·æ��供了一个NXå�‚数,ç‰å�ŒäºŽSETNX命令,官方文档上æ��醒å�Žé�¢çš„版本有å�¯èƒ½åŽ»æŽ‰[SETNX](https://redis.io/commands/setnx), [SETEX](https://redis.io/commands/setex), [PSETEX](https://redis.io/commands/psetex),并用SET命令代替,å�¦å¤–一个优化是使用一个自增的唯一UniqId代替时间戳æ�¥è§„é�¿V3.0æ��到的时钟问题。
+Redis 2.6.12å�Ž[SET](https://redis.io/commands/set)å�Œæ ·æ��供了一个NXå�‚数,ç‰å�ŒäºŽSETNX命令,官方文档上æ��醒å�Žé�¢çš„版本有å�¯èƒ½åŽ»æŽ‰[SETNX](https://redis.io/commands/setnx),[SETEX](https://redis.io/commands/setex),[PSETEX](https://redis.io/commands/psetex),并用SET命令代替,å�¦å¤–一个优化是使用一个自增的唯一UniqId代替时间戳æ�¥è§„é�¿V3.0æ��到的时钟问题。
这个方案是目å‰�最优的分布å¼�é”�方案,但是如果在Redis集群环境下ä¾�ç„¶å˜åœ¨é—®é¢˜ï¼š
@@ -175,7 +175,7 @@ Redis 2.6.12å�Ž[SET](https://redis.io/commands/set)å�Œæ ·æ��供了一个NXå�‚æ•°
### 分布�Redis�:Redlock
-V3.1的版本仅在å�•实例的场景下是安全的,针对如何实现分布å¼�Redisçš„é”�,国外的分布å¼�专家有过激烈的讨论, antirezæ��出了分布å¼�é”�算法Redlock,在[distlock](https://redis.io/topics/distlock)è¯�题下å�¯ä»¥çœ‹åˆ°å¯¹Redlock的详细说明,下é�¢æ˜¯Redlockç®—æ³•çš„ä¸€ä¸ªä¸æ–‡è¯´æ˜Žï¼ˆå¼•用)
+V3.1的版本仅在å�•实例的场景下是安全的,针对如何实现分布å¼�Redisçš„é”�,国外的分布å¼�专家有过激烈的讨论,antirezæ��出了分布å¼�é”�算法Redlock,在[distlock](https://redis.io/topics/distlock)è¯�题下å�¯ä»¥çœ‹åˆ°å¯¹Redlock的详细说明,下é�¢æ˜¯Redlockç®—æ³•çš„ä¸€ä¸ªä¸æ–‡è¯´æ˜Žï¼ˆå¼•用)
�设有N个独立的Redis节点
diff --git "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232\344\275\277\347\224\250\345\277\253\347\205\247\345\222\214AOF\345\260\206Redis\346\225\260\346\215\256\346\214\201\344\271\205\345\214\226\345\210\260\347\241\254\347\233\230\344\270\255.md" "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232\344\275\277\347\224\250\345\277\253\347\205\247\345\222\214AOF\345\260\206Redis\346\225\260\346\215\256\346\214\201\344\271\205\345\214\226\345\210\260\347\241\254\347\233\230\344\270\255.md"
index 92e1875..b239d06 100644
--- "a/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232\344\275\277\347\224\250\345\277\253\347\205\247\345\222\214AOF\345\260\206Redis\346\225\260\346\215\256\346\214\201\344\271\205\345\214\226\345\210\260\347\241\254\347\233\230\344\270\255.md"
+++ "b/docs/cache/\346\216\242\347\264\242Redis\350\256\276\350\256\241\344\270\216\345\256\236\347\216\260\357\274\232\344\275\277\347\224\250\345\277\253\347\205\247\345\222\214AOF\345\260\206Redis\346\225\260\346\215\256\346\214\201\344\271\205\345\214\226\345\210\260\347\241\254\347\233\230\344\270\255.md"
@@ -39,7 +39,7 @@
```
-Redis给我们æ��供了两ç§�ä¸�å�Œæ–¹å¼�çš„æŒ�久化方法:快照(Snapshotting) 和 å�ªè¿½åŠ æ–‡ä»¶ï¼ˆappend-only-file)。
+Redis给我们æ��供了两ç§�ä¸�å�Œæ–¹å¼�çš„æŒ�久化方法:快照(Snapshotting)和å�ªè¿½åŠ æ–‡ä»¶ï¼ˆappend-only-file)。
(1)��简介
@@ -71,17 +71,17 @@ appendonly no #是�使用AOF�久化appendfsync everysec #多久执行一
一�创建快照的方�:
-(1)客户端通过�Redis��`BGSAVE` 命令�创建快照。
+(1)客户端通过�Redis��`BGSAVE`命令�创建快照。
使用BGSAVE的时候,Redis会调用forkæ�¥åˆ›å»ºä¸€ä¸ªå�进程,然å�Žå�进程负责将快照写到硬盘ä¸ï¼Œè€Œçˆ¶è¿›ç¨‹åˆ™ç»§ç»å¤„ç�†å‘½ä»¤è¯·æ±‚。
使用场景:
-如果用户使用了save设置,例如:`save 60 1000` ,那么从Redis最近一次创建快照之�开始计算,当“60秒之内有1000次写入�作�这个�件满足的时候,Redis就会自动触�BGSAVE命令。
+如果用户使用了save设置,例如:`save 60 1000`,那么从Redis最近一次创建快照之�开始计算,当“60秒之内有1000次写入�作�这个�件满足的时候,Redis就会自动触�BGSAVE命令。
如果用户使用了多个save设置,那么当任�一个save�置满足�件的时候,Redis都会触�一次BGSAVE命令。
-(2)客户端通过�Redis��`SAVE` 命令�创建快照。
+(2)客户端通过�Redis��`SAVE`命令�创建快照。
接收到SAVE命令的Redisæœ�务器在快照创建完毕之å‰�å°†ä¸�å†�å“�应任何其他命令的请求。SAVE命令并ä¸�常用,我们通常å�ªåœ¨æ²¡æœ‰è¶³å¤Ÿçš„内å˜åŽ»æ‰§è¡ŒBGSAVE命令的时候æ‰�会使用SAVE命令,或者å�³ä½¿ç‰å¾…æŒ�久化æ“�ä½œæ‰§è¡Œå®Œæ¯•ä¹Ÿæ— æ‰€è°“çš„æƒ…å†µä¸‹ï¼Œæ‰�会使用这个命令;
@@ -149,7 +149,7 @@ Redis以æ¯�ç§’å�Œæ¥ä¸€æ¬¡AOF文件的性能和ä¸�使用任何æŒ�久化特性时
三��写/压缩AOF文件
-éš�ç�€æ•°æ�®é‡�的增大,AOF的文件å�¯èƒ½ä¼šå¾ˆå¤§ï¼Œè¿™æ ·åœ¨æ¯�次进行数æ�®æ�¢å¤�的时候就会进行很长的时间,为了解决日益增大的AOF文件,用户å�¯ä»¥å�‘Rediså�‘é€�`BGREWRITEAOF` 命令,这个命令会通过移除AOF文件ä¸çš„冗余命令æ�¥é‡�写AOF文件,是AOF文件的体检å�˜å¾—å°½å�¯èƒ½çš„å°�。
+éš�ç�€æ•°æ�®é‡�的增大,AOF的文件å�¯èƒ½ä¼šå¾ˆå¤§ï¼Œè¿™æ ·åœ¨æ¯�次进行数æ�®æ�¢å¤�的时候就会进行很长的时间,为了解决日益增大的AOF文件,用户å�¯ä»¥å�‘Rediså�‘é€�`BGREWRITEAOF`命令,这个命令会通过移除AOF文件ä¸çš„冗余命令æ�¥é‡�写AOF文件,是AOF文件的体检å�˜å¾—å°½å�¯èƒ½çš„å°�。
BGREWRITEAOF的工作原ç�†å’ŒBGSAVE的原ç�†å¾ˆåƒ�:Redis会创建一个å�进程,然å�Žç”±å�进程负责对AOF文件的é‡�写æ“�作。
@@ -157,7 +157,7 @@ BGREWRITEAOF的工作原ç�†å’ŒBGSAVE的原ç�†å¾ˆåƒ�:Redis会创建一个å�è¿›
四�触��写/压缩AOF文件�件设定
-AOF通过设置`auto-aof-rewrite-percentage` 和 `auto-aof-rewrite-min-size` 选项�自动执行BGREWRITEAOF。
+AOF通过设置`auto-aof-rewrite-percentage`和`auto-aof-rewrite-min-size`选项�自动执行BGREWRITEAOF。
其具体�义,通过实例�以看出,如下�置:
@@ -167,7 +167,7 @@ auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb
表示当�AOF的文件体积大于64MB,并且AOF文件的体积比上一次�写之�的体积�大了至少一�(100%)的时候,Redis将执行�写BGREWRITEAOF命令。
-如果AOFé‡�写执行的过于频ç¹�çš„è¯�,å�¯ä»¥å°†`auto-aof-rewrite-percentage` 选项的值设置为100以上,这ç§�最å�¶å�‘å°±å�¯ä»¥è®©Redis在AOF文件的体积å�˜å¾—更大之å�Žæ‰�执行é‡�写æ“�作,ä¸�过,这也使得在进行数æ�®æ�¢å¤�的时候执行的时间å�˜å¾—æ›´åŠ é•¿ä¸€äº›ã€‚
+如果AOFé‡�写执行的过于频ç¹�çš„è¯�,å�¯ä»¥å°†`auto-aof-rewrite-percentage`选项的值设置为100以上,这ç§�最å�¶å�‘å°±å�¯ä»¥è®©Redis在AOF文件的体积å�˜å¾—更大之å�Žæ‰�执行é‡�写æ“�作,ä¸�过,这也使得在进行数æ�®æ�¢å¤�的时候执行的时间å�˜å¾—æ›´åŠ é•¿ä¸€äº›ã€‚
## 验�快照文件和AOF文件
@@ -179,7 +179,7 @@ redis-check-aofredis-check-dump
他们�以�系统�生故障的时候,检查快照和AOF文件的状�,并对有需�的情况对文件进行修�。
-如果用户在�行redis-check-aof命令的时候,指定了`--fix` �数,那么程�将对AOF文件进行修�。
+如果用户在�行redis-check-aof命令的时候,指定了`--fix`�数,那么程�将对AOF文件进行修�。
程åº�ä¿®å¤�AOF文件的方法很简å�•:他会扫æ��给定的AOF文件,寻找ä¸�æ£ç¡®æˆ–者ä¸�完整的命令,当å�‘现第一个出现错误命令的时候,程åº�ä¼šåˆ é™¤å‡ºé”™å‘½ä»¤ä»¥å�Šå‡ºé”™å‘½ä»¤ä¹‹å�Žçš„æ‰€æœ‰å‘½ä»¤ï¼Œå�ªä¿�留那些ä½�于出错命令之å‰�çš„æ£ç¡®å‘½ä»¤ã€‚å¤§éƒ¨åˆ†æƒ…å†µï¼Œè¢«åˆ é™¤çš„éƒ½æ˜¯AOF文件末尾的ä¸�完整的写命令。
diff --git "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232MySQL\351\207\214\347\232\204\351\202\243\344\272\233\346\227\245\345\277\227\344\273\254.md" "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232MySQL\351\207\214\347\232\204\351\202\243\344\272\233\346\227\245\345\277\227\344\273\254.md"
index 6f69233..347ecee 100644
--- "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232MySQL\351\207\214\347\232\204\351\202\243\344\272\233\346\227\245\345\277\227\344\273\254.md"
+++ "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232MySQL\351\207\214\347\232\204\351\202\243\344\272\233\346\227\245\345\277\227\344\273\254.md"
@@ -1,15 +1,3 @@
-# 目录
-
-* [目录](#目录)
- * [é‡�æ–°å¦ä¹ MySQLæ•°æ�®åº“10:MySQL里的那些日志们](#é‡�æ–°å¦ä¹ mysqlæ•°æ�®åº“10:mysql里的那些日志们)
- * [1.MySQL日志文件系统的组�](#1mysql日志文件系统的组�)
- * [2.错误日志](#2错误日志)
- * [3.InnoDBä¸çš„æ—¥å¿—](#3innodbä¸çš„æ—¥å¿—)
- * [4- 慢查询日志](#4--慢查询日志)
- * [5.二进制日志](#5二进制日志)
- * [总结](#总结)
-
-
# 目录
* [é‡�æ–°å¦ä¹ MySQLæ•°æ�®åº“10:MySQL里的那些日志们](#é‡�æ–°å¦ä¹ mysqlæ•°æ�®åº“10:mysql里的那些日志们)
* [1.MySQL日志文件系统的组�](#1mysql日志文件系统的组�)
diff --git "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232Mysql\347\264\242\345\274\225\345\256\236\347\216\260\345\216\237\347\220\206\345\222\214\347\233\270\345\205\263\346\225\260\346\215\256\347\273\223\346\236\204\347\256\227\346\263\225.md" "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232Mysql\347\264\242\345\274\225\345\256\236\347\216\260\345\216\237\347\220\206\345\222\214\347\233\270\345\205\263\346\225\260\346\215\256\347\273\223\346\236\204\347\256\227\346\263\225.md"
index 7bd83de..b522104 100644
--- "a/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232Mysql\347\264\242\345\274\225\345\256\236\347\216\260\345\216\237\347\220\206\345\222\214\347\233\270\345\205\263\346\225\260\346\215\256\347\273\223\346\236\204\347\256\227\346\263\225.md"
+++ "b/docs/database/\351\207\215\346\226\260\345\255\246\344\271\240MySQL\346\225\260\346\215\256\345\272\223\357\274\232Mysql\347\264\242\345\274\225\345\256\236\347\216\260\345\216\237\347\220\206\345\222\214\347\233\270\345\205\263\346\225\260\346\215\256\347\273\223\346\236\204\347\256\227\346\263\225.md"
@@ -905,4 +905,4 @@ title的选择性�足0.0001(精确值为0.00001579),所以实在没有
[5] Codd, E. F. (1970). "A relational model of data for large shared data banks". Communications of the ACM, , Vol. 13, No. 6, pp. 377-387
-[6] MySQL5.1�考手册 - [http://dev.mysql.com/doc/refman/5.1/zh/index.html](http://dev.mysql.com/doc/refman/5.1/zh/index.html "http://dev.mysql.com/doc/refman/5.1/zh/index.html")
+[6] MySQL5.1�考手册 -[http://dev.mysql.com/doc/refman/5.1/zh/index.html](http://dev.mysql.com/doc/refman/5.1/zh/index.html "http://dev.mysql.com/doc/refman/5.1/zh/index.html")
diff --git "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\347\274\223\345\255\230\346\233\264\346\226\260\347\232\204\345\245\227\350\267\257.md" "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\347\274\223\345\255\230\346\233\264\346\226\260\347\232\204\345\245\227\350\267\257.md"
index 77fc50a..22c4550 100644
--- "a/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\347\274\223\345\255\230\346\233\264\346\226\260\347\232\204\345\245\227\350\267\257.md"
+++ "b/docs/distributed/practice/\346\220\236\346\207\202\345\210\206\345\270\203\345\274\217\346\212\200\346\234\257\357\274\232\347\274\223\345\255\230\346\233\264\346\226\260\347\232\204\345\245\227\350\267\257.md"
@@ -105,6 +105,6 @@ Write Back套路,一å�¥è¯´å°±æ˜¯ï¼Œåœ¨æ›´æ–°æ•°æ�®çš„æ—¶å€™ï¼Œå�ªæ›´æ–°ç¼“å˜
3)在软件开å�‘或设计ä¸ï¼Œæˆ‘é�žå¸¸å»ºè®®åœ¨ä¹‹å‰�先去å�‚考一下已有的设计和æ€�路,**看看相应的guideline,best practice或design pattern,å�ƒé€�了已有的这些东西,å†�决定是å�¦è¦�é‡�æ–°å�‘明轮å�**。å�ƒä¸‡ä¸�è¦�似是而é�žåœ°ï¼Œæƒ³å½“ç„¶çš„å�šè½¯ä»¶è®¾è®¡ã€‚
-4)上é�¢ï¼Œæˆ‘们没有考虑缓å˜ï¼ˆCache)和æŒ�久层(Repository)的整体事务的问题。比如,更新Cacheæˆ�功,更新数æ�®åº“失败了怎么å�—?或是å��过æ�¥ã€‚å…³äºŽè¿™ä¸ªäº‹ï¼Œå¦‚æžœä½ éœ€è¦�å¼ºä¸€è‡´æ€§ï¼Œä½ éœ€è¦�使用“两阶段æ��交å��è®®â€�——prepare, commit/rollback,比如Java 7 çš„[XAResource](http://docs.oracle.com/javaee/7/api/javax/transaction/xa/XAResource.html),还有MySQL 5.7的 [XA Transaction](http://dev.mysql.com/doc/refman/5.7/en/xa.html),有些cache也支æŒ�XA,比如[EhCache](http://www.ehcache.org/documentation/3.0/xa.html)。当然,XAè¿™æ ·çš„å¼ºä¸€è‡´æ€§çš„çŽ©æ³•ä¼šå¯¼è‡´æ€§èƒ½ä¸‹é™�,关于分布å¼�的事务的相关è¯�é¢˜ï¼Œä½ å�¯ä»¥çœ‹çœ‹ã€Š[分布å¼�系统的事务处ç�†](https://coolshell.cn/articles/10910.html)》一文。
+4)上é�¢ï¼Œæˆ‘们没有考虑缓å˜ï¼ˆCache)和æŒ�久层(Repository)的整体事务的问题。比如,更新Cacheæˆ�功,更新数æ�®åº“失败了怎么å�—?或是å��过æ�¥ã€‚å…³äºŽè¿™ä¸ªäº‹ï¼Œå¦‚æžœä½ éœ€è¦�å¼ºä¸€è‡´æ€§ï¼Œä½ éœ€è¦�使用“两阶段æ��交å��è®®â€�——prepare, commit/rollback,比如Java 7 çš„[XAResource](http://docs.oracle.com/javaee/7/api/javax/transaction/xa/XAResource.html),还有MySQL 5.7çš„[XA Transaction](http://dev.mysql.com/doc/refman/5.7/en/xa.html),有些cache也支æŒ�XA,比如[EhCache](http://www.ehcache.org/documentation/3.0/xa.html)。当然,XAè¿™æ ·çš„å¼ºä¸€è‡´æ€§çš„çŽ©æ³•ä¼šå¯¼è‡´æ€§èƒ½ä¸‹é™�,关于分布å¼�的事务的相关è¯�é¢˜ï¼Œä½ å�¯ä»¥çœ‹çœ‹ã€Š[分布å¼�系统的事务处ç�†](https://coolshell.cn/articles/10910.html)》一文。
(全文完)
diff --git "a/docs/hxx/java/Java\345\267\245\347\250\213\345\270\210\344\277\256\347\202\274\344\271\213\350\267\257\357\274\210\346\240\241\346\213\233\346\200\273\347\273\223\357\274\211.md" "b/docs/hxx/java/Java\345\267\245\347\250\213\345\270\210\344\277\256\347\202\274\344\271\213\350\267\257\357\274\210\346\240\241\346\213\233\346\200\273\347\273\223\357\274\211.md"
index 221cd8f..cd1bd87 100644
--- "a/docs/hxx/java/Java\345\267\245\347\250\213\345\270\210\344\277\256\347\202\274\344\271\213\350\267\257\357\274\210\346\240\241\346\213\233\346\200\273\347\273\223\357\274\211.md"
+++ "b/docs/hxx/java/Java\345\267\245\347\250\213\345\270\210\344\277\256\347\202\274\344\271\213\350\267\257\357\274\210\346\240\241\346\213\233\346\200\273\347\273\223\357\274\211.md"
@@ -173,7 +173,7 @@
具体的��都比较长,这里大概介�一下�试的情况,然�我会放上��的链接供大家查阅。
-**1 阿里é�¢ç»�** Â
+**1 阿里��**
[阿里ä¸é—´ä»¶ç ”å�‘é�¢ç»�](http://mp.weixin.qq.com/s?__biz=MzUyMDc5MTYxNA==&mid=2247483852&idx=1&sn=9ec90620478b35d63a4a971a2222095d&chksm=f9e5b29dce923b8b2b080151e4b6b78373ee3f3e6f75b69252fc00b1a009d85c6f96944ed6e6&scene=21#wechat_redirect)
@@ -189,7 +189,7 @@
阿里的é�¢è¯•体验还是比较好的,至少ä¸�è¦�求手写算法,但是é�žå¸¸æ³¨é‡�Java基础,ä¸é—´ä»¶éƒ¨é—¨è¿˜ä¼šç‰¹åˆ«å®‰æŽ’Java基础笔试。
-**2 腾讯é�¢ç»�** Â
+**2 腾讯��**
[è…¾è®¯ç ”å�‘é�¢ç»�](http://mp.weixin.qq.com/s?__biz=MzUyMDc5MTYxNA==&mid=2247483849&idx=1&sn=f81fd42954589fb2deaf128026ddd856&chksm=f9e5b298ce923b8ef02ae36f7e9029fef0ddb7d5ae456dfa9d64c0073bebaacfb78fac4c8035&scene=21#wechat_redirect)
@@ -201,7 +201,7 @@ SNG的部门æ�žäº†æˆ‘的简历,开始了é�¢è¯•ï¼Œä»–ä»¬çš„æŠ€æœ¯æ ˆä¸»è¦�是Ja
腾讯的�试一如既往地注�考查网络和�作系统,并且喜欢问Linux底层的一些知识,在这方�我还是有很多�足的。
-**3 百度é�¢ç»�** Â
+**3 百度��**
[ç™¾åº¦ç ”å�‘é�¢ç»�](http://mp.weixin.qq.com/s?__biz=MzUyMDc5MTYxNA==&mid=2247483857&idx=1&sn=214b0f93db93407a7ac5a5149778cbad&chksm=f9e5b280ce923b96fcd535b2ef639fee2de78f12aa961d525b21760b11a3b95c0879113c2944&scene=21#wechat_redirect)
@@ -213,7 +213,7 @@ SNG的部门æ�žäº†æˆ‘的简历,开始了é�¢è¯•ï¼Œä»–ä»¬çš„æŠ€æœ¯æ ˆä¸»è¦�是Ja
百度的é�¢è¯•é£Žæ ¼é�žå¸¸ç»Ÿä¸€ï¼Œæ¯�次é�¢è¯•基本都è¦�到电脑上写算法,所以那段时间写算法写的头皮å�‘麻。
-**4 网易é�¢ç»�** Â
+**4 网易��**
[ç½‘æ˜“ç ”å�‘é�¢ç»�](http://mp.weixin.qq.com/s?__biz=MzUyMDc5MTYxNA==&mid=2247483875&idx=1&sn=fa9eaedd9cc3da172ad71d360c46a054&chksm=f9e5b2b2ce923ba443b91d56b24486d22b15bea16a4788e5ed3421906e84f8edd9ee10b2b306&scene=21#wechat_redirect)
@@ -225,7 +225,7 @@ SNG的部门æ�žäº†æˆ‘的简历,开始了é�¢è¯•ï¼Œä»–ä»¬çš„æŠ€æœ¯æ ˆä¸»è¦�是Ja
网易的é�¢è¯•比我想象ä¸çš„è¦�难,é�¢è¯•å®˜ä¼šé—®çš„é—®é¢˜éƒ½æ¯”è¾ƒæ·±ï¼Œå¹¶ä¸”ä¼šè®©ä½ å†™ä¸€äº›ç»“å�ˆå®žè·µçš„代ç �。
-**5 头æ�¡é�¢ç»�** Â
+**5 头���**
[今日头æ�¡ç ”å�‘é�¢ç»�](http://mp.weixin.qq.com/s?__biz=MzUyMDc5MTYxNA==&mid=2247483869&idx=1&sn=eedb7aebcb90cf3d4fe2450ef2d99947&chksm=f9e5b28cce923b9a9b0852a1c998ec014eb1aeb0442916c9028da276be8db0b2934c92292961&scene=21#wechat_redirect)
diff --git "a/docs/hxx/java/\344\275\240\344\270\215\345\217\257\351\224\231\350\277\207\347\232\204Java\345\255\246\344\271\240\350\265\204\346\272\220\346\270\205\345\215\225.md" "b/docs/hxx/java/\344\275\240\344\270\215\345\217\257\351\224\231\350\277\207\347\232\204Java\345\255\246\344\271\240\350\265\204\346\272\220\346\270\205\345\215\225.md"
index 0b41820..2885cab 100644
--- "a/docs/hxx/java/\344\275\240\344\270\215\345\217\257\351\224\231\350\277\207\347\232\204Java\345\255\246\344\271\240\350\265\204\346\272\220\346\270\205\345\215\225.md"
+++ "b/docs/hxx/java/\344\275\240\344\270\215\345\217\257\351\224\231\350\277\207\347\232\204Java\345\255\246\344\271\240\350\265\204\346\272\220\346\270\205\345\215\225.md"
@@ -38,25 +38,25 @@ https://blog.csdn.net/a724888
总的æ�¥è¯´ç®—是比较全é�¢äº†ï¼Œå�šå�Žç«¯æ–¹å�‘çš„å�Œå¦å�¯ä»¥å�‚考一下。
-深入浅出Javaæ ¸å¿ƒæŠ€æœ¯Â Â
+深入浅出Javaæ ¸å¿ƒæŠ€æœ¯
https://blog.csdn.net/column/details/21930.html
本专æ �主è¦�介ç»�Java基础,并且会结å�ˆå®žçŽ°åŽŸç�†ä»¥å�Šå…·ä½“实例æ�¥è®²è§£ã€‚å�Œæ—¶è¿˜ä»‹ç»�了Java集å�ˆç±»ï¼Œè®¾è®¡æ¨¡å¼�以å�ŠJava8的相关知识。
-深入ç�†è§£JVM虚拟机 Â
+深入�解JVM虚拟机
https://blog.csdn.net/column/details/21960.html
å¸¦ä½ èµ°è¿›JVM的世界,整å�ˆé«˜è´¨é‡�æ–‡ç« ä»¥é˜�述虚拟机的原ç�†å�Šç›¸å…³æŠ€æœ¯ï¼Œè®©å¼€å�‘者更好地了解Java的底层è¿�行原ç�†ä»¥å�Šç›¸åº”的调优方法。
-Javaå¹¶å�‘指å�— Â
+Java并�指�
https://blog.csdn.net/column/details/21961.html
本专æ �主è¦�介ç»�Javaå¹¶å�‘编程相关的基本原ç�†ä»¥å�Šè¿›é˜¶çŸ¥è¯†ã€‚主è¦�包括Java多线程基础,Javaå¹¶å�‘编程基本原ç�†ä»¥å�ŠJUCå¹¶å�‘包的使用和æº�ç �è§£æž�。
-Java网络编程与NIO Â
+Java网络编程与NIO
https://blog.csdn.net/column/details/21963.html
@@ -64,7 +64,7 @@ Java网络编程一直是很é‡�è¦�çš„ä¸€éƒ¨åˆ†å†…å®¹ï¼Œå…¶ä¸æ¶‰å�Šäº†socketçš„
了解这部分知识对于�解网络编程有很多帮助。�外还补充了两个涉�NIO的��技术:Tomcat和Netty。
-JavaWeb技术世界 Â
+JavaWeb技术世界
https://blog.csdn.net/column/details/21850.html
@@ -72,7 +72,7 @@ https://blog.csdn.net/column/details/21850.html
我们ä¸�ä»…è¦�了解怎么使用它们,更è¦�去了解它们为什么出现,其ä¸ä¸€äº›æŠ€æœ¯çš„实现原ç�†æ˜¯ä»€ä¹ˆã€‚
-Spring与SpringMVCæº�ç �è§£æž� Â
+Spring与SpringMVCæº�ç �è§£æž�
https://blog.csdn.net/column/details/21851.html
@@ -108,7 +108,7 @@ https://blog.csdn.net/column/details/25481.html
## Java工程师书�
-我之å‰�ä¸“é—¨å†™äº†ä¸€ç¯‡æ–‡ç« ä»‹ç»�了Java工程师的书å�•,å�¯ä»¥è¿™é‡Œé‡�点列举一些好书,推è��给大家。 Â
+我之å‰�ä¸“é—¨å†™äº†ä¸€ç¯‡æ–‡ç« ä»‹ç»�了Java工程师的书å�•,å�¯ä»¥è¿™é‡Œé‡�点列举一些好书,推è��给大家。
完整内容å�¯ä»¥å�‚è€ƒè¿™ç¯‡æ–‡ç« ï¼š
@@ -126,15 +126,15 @@ Java工程师必备书�
《Javaæ ¸å¿ƒæŠ€æœ¯å�·ä¸€ã€‹ 这本书还是比较适å�ˆå…¥é—¨çš„,当然,这ç§�厚皮书è¦�看完还是很有难度的,ä¸�过比起上é�¢é‚£æœ¬è¦�简å�•一些
-《深入ç�†è§£JVM虚拟机》 这本书是Javaå¼€å�‘者必须看的书,很多jvmçš„æ–‡ç« éƒ½æ˜¯æ��å�–这本书的内容。JVM是Java虚拟机,赋予了Java程åº�生命,所以好好看看把,我自己就已ç»�看了三é��了。 Â
+《深入ç�†è§£JVM虚拟机》 这本书是Javaå¼€å�‘者必须看的书,很多jvmçš„æ–‡ç« éƒ½æ˜¯æ��å�–这本书的内容。JVM是Java虚拟机,赋予了Java程åº�生命,所以好好看看把,我自己就已ç»�看了三é��了。
《Javaå¹¶å�‘编程艺术》 这本书是国内作者写的Javaå¹¶å�‘书ç±�,比上é�¢é‚£ä¸€æœ¬æ›´ç®€å�•易懂,适å�ˆä½œä¸ºå¹¶å�‘编程的入门书ç±�,当然,å¦ä¹ å¹¶å�‘原ç�†ä¹‹å‰�,还是先把Java的多线程æ�žæ‡‚å�§ã€‚
-《深入JavaWeb技术内幕》 这本书是Java Web的集大æˆ�之作,涵盖了大部分Java Webå¼€å�‘的知识点,ä¸�è¿‡ä¸€æœ¬ä¹¦æ˜¾ç„¶æ— æ³•æŠŠæ‰€æœ‰ç»†èŠ‚éƒ½è®²å®Œï¼Œä½†æ˜¯ä½œä¸ºJava Web的入门或者进阶书ç±�æ�¥çœ‹çš„è¯�还是很ä¸�错的。 Â
+《深入JavaWeb技术内幕》 这本书是Java Web的集大æˆ�之作,涵盖了大部分Java Webå¼€å�‘的知识点,ä¸�è¿‡ä¸€æœ¬ä¹¦æ˜¾ç„¶æ— æ³•æŠŠæ‰€æœ‰ç»†èŠ‚éƒ½è®²å®Œï¼Œä½†æ˜¯ä½œä¸ºJava Web的入门或者进阶书ç±�æ�¥çœ‹çš„è¯�还是很ä¸�错的。
《Redis设计与实现》 该书全é�¢è€Œå®Œæ•´åœ°è®²è§£äº† Redis 的内部è¿�行机制,对 Redis 的大多数å�•机功能以å�Šæ‰€æœ‰å¤šæœºåŠŸèƒ½çš„å®žçŽ°åŽŸç�†è¿›è¡Œäº†ä»‹ç»�。这本书把Redis的基本原ç�†è®²çš„一清二楚,包括数æ�®ç»“构,æŒ�久化,集群ç‰å†…容,有空应该看看。
-《大型网站技术架构》 这本淘å®�系技术指å�—还是é�žå¸¸å€¼å¾—推崇的,å�¯ä»¥è¯´æ˜¯æŠŠå¤§åž‹ç½‘站的现代架构进行了一次简å�•的总结,内容涵盖了å�„æ–¹é�¢ï¼Œä¸»è¦�讲的是概念,很适å�ˆæ²¡æŽ¥è§¦è¿‡æž¶æž„çš„å�Œå¦å…¥é—¨ã€‚看完以å�Žä½ 会觉得å�Žç«¯æŠ€æœ¯åŽŸæ�¥è¿™ä¹ˆå�šå¤§ç²¾æ·±ã€‚ Â
+《大型网站技术架构》 这本淘å®�系技术指å�—还是é�žå¸¸å€¼å¾—推崇的,å�¯ä»¥è¯´æ˜¯æŠŠå¤§åž‹ç½‘站的现代架构进行了一次简å�•的总结,内容涵盖了å�„æ–¹é�¢ï¼Œä¸»è¦�讲的是概念,很适å�ˆæ²¡æŽ¥è§¦è¿‡æž¶æž„çš„å�Œå¦å…¥é—¨ã€‚看完以å�Žä½ 会觉得å�Žç«¯æŠ€æœ¯åŽŸæ�¥è¿™ä¹ˆå�šå¤§ç²¾æ·±ã€‚
《分布å¼�æœ�务框架原ç�†ä¸Žå®žè·µã€‹ 上é�¢é‚£æœ¬ä¹¦è®²çš„æ˜¯åˆ†å¸ƒå¼�架构的实践,而这本书更专注于分布å¼�æœ�务的原ç�†è®²è§£å’Œå¯¹åº”实践,很好地讲述了分布å¼�æœ�务的基本概念,相关技术,以å�Šè§£å†³æ–¹æ¡ˆç‰ï¼Œå¯¹äºŽæƒ³è¦�å¦ä¹ 分布å¼�æœ�务框架的å�Œå¦æ�¥è¯´æ˜¯æœ¬å¥½ä¹¦ã€‚
@@ -176,9 +176,9 @@ https://www.zhihu.com/people/h2pl
## 技术大牛推�
-1 江å�—白衣这ä½�大大ç»�对是我的Javaå�¯è’™å¯¼å¸ˆï¼Œä»–推è��çš„Javaå�Žç«¯ä¹¦æž¶è®©æˆ‘å�—益匪浅。 Â
+1 江�白衣这�大大�对是我的Java�蒙导师,他推�的Java�端书架让我�益匪浅。
-2 ç �农翻身刘欣,一ä½�工作15å¹´çš„IBMæž¶æž„å¸ˆï¼Œç”¨æœ€æµ…æ˜¾æ˜“æ‡‚çš„æ–‡ç« è®²è§£æŠ€æœ¯çš„é‚£äº›äº‹ï¼ŒåŠ›è��ï¼Œä»–çš„æ–‡ç« å¸®æˆ‘è§£å†³äº†å¾ˆå¤šå›°æƒ‘ã€‚Â Â
+2 ç �农翻身刘欣,一ä½�工作15å¹´çš„IBMæž¶æž„å¸ˆï¼Œç”¨æœ€æµ…æ˜¾æ˜“æ‡‚çš„æ–‡ç« è®²è§£æŠ€æœ¯çš„é‚£äº›äº‹ï¼ŒåŠ›è��ï¼Œä»–çš„æ–‡ç« å¸®æˆ‘è§£å†³äº†å¾ˆå¤šå›°æƒ‘ã€‚
3 CoolShell陈皓�师的�客相信大家都看过,干货很多,酷壳应该算是国内最有影�力的个人�客了。
diff --git "a/docs/hxx/java/\346\210\221\347\232\204Java\347\247\213\346\213\233\351\235\242\347\273\217\345\244\247\345\220\210\351\233\206.md" "b/docs/hxx/java/\346\210\221\347\232\204Java\347\247\213\346\213\233\351\235\242\347\273\217\345\244\247\345\220\210\351\233\206.md"
index cbe57c4..ca3dce9 100644
--- "a/docs/hxx/java/\346\210\221\347\232\204Java\347\247\213\346\213\233\351\235\242\347\273\217\345\244\247\345\220\210\351\233\206.md"
+++ "b/docs/hxx/java/\346\210\221\347\232\204Java\347\247\213\346\213\233\351\235\242\347\273\217\345\244\247\345\220\210\351\233\206.md"
@@ -1,11 +1,11 @@
# 目录
-* [阿里��  ](#阿里��  )
-* [腾讯��  ](#腾讯��  )
-* [百度��  ](#百度��  )
-* [网易��  ](#网易��  )
-* [头���  ](#头���  )
-* [快手&拼多多��  ](#快手拼多多��  )
+* [阿里��](#阿里��)
+* [腾讯��](#腾讯��)
+* [百度��](#百度��)
+* [网易��](#网易��)
+* [头���](#头���)
+* [快手&拼多多��](#快手拼多多��)
* [京东&美团��](#京东美团��)
* [斗鱼��](#斗鱼��)
* [有赞��](#有赞��)
@@ -20,7 +20,7 @@

-# 阿里é�¢ç»� Â
+# 阿里��
[阿里ä¸é—´ä»¶ç ”å�‘é�¢ç»�](http://mp.weixin.qq.com/s?__biz=MzUyMDc5MTYxNA==&mid=2247483852&idx=1&sn=9ec90620478b35d63a4a971a2222095d&chksm=f9e5b29dce923b8b2b080151e4b6b78373ee3f3e6f75b69252fc00b1a009d85c6f96944ed6e6&scene=21#wechat_redirect)
@@ -36,7 +36,7 @@
阿里的é�¢è¯•体验还是比较好的,至少ä¸�è¦�求手写算法,但是é�žå¸¸æ³¨é‡�Java基础,ä¸é—´ä»¶éƒ¨é—¨è¿˜ä¼šç‰¹åˆ«å®‰æŽ’Java基础笔试。
-# 腾讯é�¢ç»� Â
+# 腾讯��
[è…¾è®¯ç ”å�‘é�¢ç»�](http://mp.weixin.qq.com/s?__biz=MzUyMDc5MTYxNA==&mid=2247483849&idx=1&sn=f81fd42954589fb2deaf128026ddd856&chksm=f9e5b298ce923b8ef02ae36f7e9029fef0ddb7d5ae456dfa9d64c0073bebaacfb78fac4c8035&scene=21#wechat_redirect)
@@ -48,7 +48,7 @@ SNG的部门æ�žäº†æˆ‘的简历,开始了é�¢è¯•ï¼Œä»–ä»¬çš„æŠ€æœ¯æ ˆä¸»è¦�是Ja
腾讯的�试一如既往地注�考查网络和�作系统,并且喜欢问Linux底层的一些知识,在这方�我还是有很多�足的。
-# 百度é�¢ç»� Â
+# 百度��
[ç™¾åº¦ç ”å�‘é�¢ç»�](http://mp.weixin.qq.com/s?__biz=MzUyMDc5MTYxNA==&mid=2247483857&idx=1&sn=214b0f93db93407a7ac5a5149778cbad&chksm=f9e5b280ce923b96fcd535b2ef639fee2de78f12aa961d525b21760b11a3b95c0879113c2944&scene=21#wechat_redirect)
@@ -60,7 +60,7 @@ SNG的部门æ�žäº†æˆ‘的简历,开始了é�¢è¯•ï¼Œä»–ä»¬çš„æŠ€æœ¯æ ˆä¸»è¦�是Ja
百度的é�¢è¯•é£Žæ ¼é�žå¸¸ç»Ÿä¸€ï¼Œæ¯�次é�¢è¯•基本都è¦�到电脑上写算法,所以那段时间写算法写的头皮å�‘麻。
-# 网易é�¢ç»� Â
+# 网易��
[ç½‘æ˜“ç ”å�‘é�¢ç»�](http://mp.weixin.qq.com/s?__biz=MzUyMDc5MTYxNA==&mid=2247483875&idx=1&sn=fa9eaedd9cc3da172ad71d360c46a054&chksm=f9e5b2b2ce923ba443b91d56b24486d22b15bea16a4788e5ed3421906e84f8edd9ee10b2b306&scene=21#wechat_redirect)
@@ -72,7 +72,7 @@ SNG的部门æ�žäº†æˆ‘的简历,开始了é�¢è¯•ï¼Œä»–ä»¬çš„æŠ€æœ¯æ ˆä¸»è¦�是Ja
网易的é�¢è¯•比我想象ä¸çš„è¦�难,é�¢è¯•å®˜ä¼šé—®çš„é—®é¢˜éƒ½æ¯”è¾ƒæ·±ï¼Œå¹¶ä¸”ä¼šè®©ä½ å†™ä¸€äº›ç»“å�ˆå®žè·µçš„代ç �。
-# 头æ�¡é�¢ç»� Â
+# 头���
[今日头æ�¡ç ”å�‘é�¢ç»�](http://mp.weixin.qq.com/s?__biz=MzUyMDc5MTYxNA==&mid=2247483869&idx=1&sn=eedb7aebcb90cf3d4fe2450ef2d99947&chksm=f9e5b28cce923b9a9b0852a1c998ec014eb1aeb0442916c9028da276be8db0b2934c92292961&scene=21#wechat_redirect)
@@ -82,7 +82,7 @@ SNG的部门æ�žäº†æˆ‘的简历,开始了é�¢è¯•ï¼Œä»–ä»¬çš„æŠ€æœ¯æ ˆä¸»è¦�是Ja
ç„¶å�Žå°±å¼€å§‹äº†ä¸€ä¸‹å�ˆçš„视频é�¢è¯•,一共三轮技术é�¢è¯•,æ¯�一轮都è¦�写代ç �ï¼Œé—®é—®é¢˜çš„é£Žæ ¼æœ‰ç‚¹åƒ�腾讯,也喜欢问一些底层知识,让我有点懵逼。
-# 快手&拼多多é�¢ç»� Â
+# 快手&拼多多��
[拼多多&å¿«æ‰‹ç ”å�‘é�¢ç»�](http://mp.weixin.qq.com/s?__biz=MzUyMDc5MTYxNA==&mid=2247483878&idx=1&sn=aaafff4b1171361ccd1d94708d2beaa0&chksm=f9e5b2b7ce923ba10140dff71dd3a0f9a20593434a32cec66929116bba196dc7496abf502884&scene=21#wechat_redirect)
diff --git "a/docs/hxx/\347\224\265\345\255\220\344\271\246.md" "b/docs/hxx/\347\224\265\345\255\220\344\271\246.md"
index b80bf2e..5908230 100644
--- "a/docs/hxx/\347\224\265\345\255\220\344\271\246.md"
+++ "b/docs/hxx/\347\224\265\345\255\220\344\271\246.md"
@@ -45,7 +45,7 @@
### 新手上路
- [用大白è¯�å‘Šè¯‰ä½ ï¼šJava å�Žç«¯åˆ°åº•是在å�šä»€ä¹ˆï¼Ÿ](http://mp.weixin.qq.com/s?__biz=MzUyOTk5NDQwOA==&mid=2247485885&idx=1&sn=0b3e02d09559ad0fe371ce915a77d7e0&chksm=fa59ce7acd2e476c501ca68b311de5abaf8021c5baa96fa24e0ca621acaaf4b1c64e2e16f3cb&scene=21#wechat_redirect)
+[用大白è¯�å‘Šè¯‰ä½ ï¼šJava å�Žç«¯åˆ°åº•是在å�šä»€ä¹ˆï¼Ÿ](http://mp.weixin.qq.com/s?__biz=MzUyOTk5NDQwOA==&mid=2247485885&idx=1&sn=0b3e02d09559ad0fe371ce915a77d7e0&chksm=fa59ce7acd2e476c501ca68b311de5abaf8021c5baa96fa24e0ca621acaaf4b1c64e2e16f3cb&scene=21#wechat_redirect)
[Java工程师å¦ä¹ 指å�—(入门篇)](http://mp.weixin.qq.com/s?__biz=MzUyOTk5NDQwOA==&mid=2247484573&idx=2&sn=7baf8dfe36357264ab25010429644792&chksm=fa59c35acd2e4a4c24c5b55003136b6b8c5e778273714093b2df7a016d3bb0ed0c774573a7a4&scene=21#wechat_redirect)
@@ -198,15 +198,15 @@
[马云退��,在年会上说了最��的三件事](http://mp.weixin.qq.com/s?__biz=MzUyOTk5NDQwOA==&mid=2247486268&idx=1&sn=dd13517634cd4f72f824278f93edebef&chksm=fa59ccfbcd2e45ed522c377ab3fa4554632f36c836e9b2e1490fb4748f4c0cdee9a4a99c91a6&scene=21#wechat_redirect)
- [é‚£äº›æ‹¼å‘½åŠ ç�的程åº�员们,å�Žæ�¥éƒ½æ€Žä¹ˆæ ·äº†ï¼Ÿ](http://mp.weixin.qq.com/s?__biz=MzUyOTk5NDQwOA==&mid=2247485861&idx=1&sn=e90ac488593b4b7adb4ac46303e715be&chksm=fa59ce62cd2e477410c26233ed6518e34fdd772e27ea7538bddfac36a549a50cab29b27881f4&scene=21#wechat_redirect)
+[é‚£äº›æ‹¼å‘½åŠ ç�的程åº�员们,å�Žæ�¥éƒ½æ€Žä¹ˆæ ·äº†ï¼Ÿ](http://mp.weixin.qq.com/s?__biz=MzUyOTk5NDQwOA==&mid=2247485861&idx=1&sn=e90ac488593b4b7adb4ac46303e715be&chksm=fa59ce62cd2e477410c26233ed6518e34fdd772e27ea7538bddfac36a549a50cab29b27881f4&scene=21#wechat_redirect)
- [互�网浪潮之下,�� 90 �所�临的困境](http://mp.weixin.qq.com/s?__biz=MzUyOTk5NDQwOA==&mid=2247485843&idx=1&sn=492c9d3f7c9e32de9da7d833013cb9b9&chksm=fa59ce54cd2e4742939a5eb42a470bf282dbc79cb6f38ac9ec0112af5282091a9f2cd3615104&scene=21#wechat_redirect)
+[互�网浪潮之下,�� 90 �所�临的困境](http://mp.weixin.qq.com/s?__biz=MzUyOTk5NDQwOA==&mid=2247485843&idx=1&sn=492c9d3f7c9e32de9da7d833013cb9b9&chksm=fa59ce54cd2e4742939a5eb42a470bf282dbc79cb6f38ac9ec0112af5282091a9f2cd3615104&scene=21#wechat_redirect)
- [程�员的工资到底花到哪里去了?](http://mp.weixin.qq.com/s?__biz=MzUyOTk5NDQwOA==&mid=2247485826&idx=1&sn=cc13da981115341666ae919dd2646cb4&chksm=fa59ce45cd2e475344776b1f7f52a6d281d96210e21229c5d2f300cfad585f712b636cf60427&scene=21#wechat_redirect)
+[程�员的工资到底花到哪里去了?](http://mp.weixin.qq.com/s?__biz=MzUyOTk5NDQwOA==&mid=2247485826&idx=1&sn=cc13da981115341666ae919dd2646cb4&chksm=fa59ce45cd2e475344776b1f7f52a6d281d96210e21229c5d2f300cfad585f712b636cf60427&scene=21#wechat_redirect)
- [互�网公�里都有哪些潜规则?](http://mp.weixin.qq.com/s?__biz=MzUyOTk5NDQwOA==&mid=2247485819&idx=1&sn=816e20fa37a2abd99fa714c1c13e0402&chksm=fa59cebccd2e47aa8572071dadbb301008cd425cf0de4d71978af82b44bd3554faacfa8ad462&scene=21#wechat_redirect)
+[互�网公�里都有哪些潜规则?](http://mp.weixin.qq.com/s?__biz=MzUyOTk5NDQwOA==&mid=2247485819&idx=1&sn=816e20fa37a2abd99fa714c1c13e0402&chksm=fa59cebccd2e47aa8572071dadbb301008cd425cf0de4d71978af82b44bd3554faacfa8ad462&scene=21#wechat_redirect)
- [大厂程�员的一天是如何度过的?](http://mp.weixin.qq.com/s?__biz=MzUyOTk5NDQwOA==&mid=2247485803&idx=1&sn=5814daaa71fb164d33d858311708f1c3&chksm=fa59ceaccd2e47baf573c73fcefbdc93e74becd8b9d4c533cf79404a3f90b2b6cdb46eee4e40&scene=21#wechat_redirect)
+[大厂程�员的一天是如何度过的?](http://mp.weixin.qq.com/s?__biz=MzUyOTk5NDQwOA==&mid=2247485803&idx=1&sn=5814daaa71fb164d33d858311708f1c3&chksm=fa59ceaccd2e47baf573c73fcefbdc93e74becd8b9d4c533cf79404a3f90b2b6cdb46eee4e40&scene=21#wechat_redirect)
### �场心得:
diff --git "a/docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232DispatcherServlet\347\232\204\345\210\235\345\247\213\345\214\226\344\270\216\350\257\267\346\261\202\350\275\254\345\217\221.md" "b/docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232DispatcherServlet\347\232\204\345\210\235\345\247\213\345\214\226\344\270\216\350\257\267\346\261\202\350\275\254\345\217\221.md"
index df95f75..6390f87 100644
--- "a/docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232DispatcherServlet\347\232\204\345\210\235\345\247\213\345\214\226\344\270\216\350\257\267\346\261\202\350\275\254\345\217\221.md"
+++ "b/docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232DispatcherServlet\347\232\204\345\210\235\345\247\213\345\214\226\344\270\216\350\257\267\346\261\202\350\275\254\345\217\221.md"
@@ -160,12 +160,12 @@ initFrameworkServlet()方法是一个没有任何实现的空方法,除去一
this.webApplicationContext = initWebApplicationContext();
```
-这一å�¥ç®€å�•直白的代ç �,é�“ç ´äº†FrameworkServlet这个类,在SpringMVC类体系ä¸çš„设计目的,它是 用æ�¥æŠ½ç¦»å‡ºå»ºç«‹Â WebApplicationContext 上下文这个过程的。
+这一å�¥ç®€å�•直白的代ç �,é�“ç ´äº†FrameworkServlet这个类,在SpringMVC类体系ä¸çš„设计目的,它是用æ�¥æŠ½ç¦»å‡ºå»ºç«‹WebApplicationContext上下文这个过程的。
initWebApplicationContext()方法,�装了建立Spring容器上下文的整个过程,方法内的逻辑如下:
1. 获å�–ç”±ContextLoaderListeneråˆ�始化并注册在ServletContextä¸çš„æ ¹ä¸Šä¸‹æ–‡ï¼Œè®°ä¸ºrootContext
-2. 如果webApplicationContextå·²ç»�ä¸�为空,表示这个Servlet类是通过编程å¼�注册到容器ä¸çš„(Servlet 3.0+ä¸çš„ServletContext.addServlet() ),上下文也由编程å¼�ä¼ å…¥ã€‚è‹¥è¿™ä¸ªä¼ å…¥çš„ä¸Šä¸‹æ–‡è¿˜æ²¡è¢«åˆ�始化,将rootContext上下文设置为它的父上下文,然å�Žå°†å…¶åˆ�始化,å�¦åˆ™ç›´æŽ¥ä½¿ç”¨ã€‚
+2. 如果webApplicationContextå·²ç»�ä¸�为空,表示这个Servlet类是通过编程å¼�注册到容器ä¸çš„(Servlet 3.0+ä¸çš„ServletContext.addServlet()),上下文也由编程å¼�ä¼ å…¥ã€‚è‹¥è¿™ä¸ªä¼ å…¥çš„ä¸Šä¸‹æ–‡è¿˜æ²¡è¢«åˆ�始化,将rootContext上下文设置为它的父上下文,然å�Žå°†å…¶åˆ�始化,å�¦åˆ™ç›´æŽ¥ä½¿ç”¨ã€‚
3. 通过wacå�˜é‡�的引用是å�¦ä¸ºnull,判æ–第2æ¥ä¸æ˜¯å�¦å·²ç»�完æˆ�上下文的设置(å�³ä¸Šä¸‹æ–‡æ˜¯å�¦å·²ç»�用编程å¼�æ–¹å¼�ä¼ å…¥ï¼‰ï¼Œå¦‚æžœwac==nullæˆ�立,说明该Servletä¸�是由编程å¼�注册到容器ä¸çš„ã€‚æ¤æ—¶ä»¥contextAttribute属性的值为键,在ServletContext䏿Ÿ¥æ‰¾ä¸Šä¸‹æ–‡ï¼ŒæŸ¥æ‰¾å¾—到,说明上下文已ç»�以别的方å¼�åˆ�始化并注册在contextAttribute下,直接使用。
4. 检查wacå�˜é‡�的引用是å�¦ä¸ºnull,如果wac==nullæˆ�立,说明2ã€�3两æ¥ä¸çš„上下文åˆ�始化ç–略都没æˆ�åŠŸï¼Œæ¤æ—¶è°ƒç”¨createWebApplicationContext(rootContext),建立一个全新的以rootContext为父上下文的上下文,作为SpringMVCé…�ç½®å…ƒç´ çš„å®¹å™¨ä¸Šä¸‹æ–‡ã€‚å¤§å¤šæ•°æƒ…å†µä¸‹æˆ‘ä»¬æ‰€ä½¿ç”¨çš„ä¸Šä¸‹æ–‡ï¼Œå°±æ˜¯è¿™ä¸ªæ–°å»ºçš„ä¸Šä¸‹æ–‡ã€‚
5. 以上三ç§�åˆ�始化上下文的ç–略,都会回调onRefresh(ApplicationContext context)方法(回调的方å¼�æ ¹æ�®ä¸�å�Œç–略有ä¸�å�Œï¼‰ï¼ŒonRefresh方法在DispatcherServletç±»ä¸è¢«è¦†å†™ï¼Œä»¥ä¸Šé�¢å¾—到的上下文为ä¾�托,完æˆ�SpringMVCä¸é»˜è®¤å®žçŽ°ç±»çš„åˆ�始化。
diff --git "a/docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232SpringMVC\350\256\276\350\256\241\347\220\206\345\277\265\344\270\216DispatcherServlet.md" "b/docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232SpringMVC\350\256\276\350\256\241\347\220\206\345\277\265\344\270\216DispatcherServlet.md"
index 665ed2f..a33c502 100644
--- "a/docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232SpringMVC\350\256\276\350\256\241\347\220\206\345\277\265\344\270\216DispatcherServlet.md"
+++ "b/docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232SpringMVC\350\256\276\350\256\241\347\220\206\345\277\265\344\270\216DispatcherServlet.md"
@@ -106,7 +106,7 @@ HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;
}
```
-是的,第一æ¥å¤„ç�†å°±è¿™ä¹ˆç®€å�•的完æˆ�了。一个web请求ç»�过处ç�†å�Žï¼Œä¼šå¾—到一个HandlerExecutionChain对象,这就是SpringMVC对URlæ˜ å°„ç»™å‡ºçš„å›žç”。需è¦�ç•™æ„�的是,HandlerMapping接å�£çš„getHandler方法å�‚数是HttpServletRequest,这æ„�味ç�€ï¼ŒHandlerMapping的实现类å�¯ä»¥åˆ©ç”¨HttpServletRequestä¸çš„ 所有信æ�¯æ�¥å�šå‡ºè¿™ä¸ªHandlerExecutionChain对象的生æˆ�â€�决ç–“。这包括,请求头ã€�url路径ã€�cookieã€�sessionã€�å�‚æ•°ç‰ç‰ä¸€åˆ‡ä½ 从一个web请求ä¸å�¯ä»¥å¾—到的任何东西(最常用的是url路径)。
+是的,第一æ¥å¤„ç�†å°±è¿™ä¹ˆç®€å�•的完æˆ�了。一个web请求ç»�过处ç�†å�Žï¼Œä¼šå¾—到一个HandlerExecutionChain对象,这就是SpringMVC对URlæ˜ å°„ç»™å‡ºçš„å›žç”。需è¦�ç•™æ„�的是,HandlerMapping接å�£çš„getHandler方法å�‚数是HttpServletRequest,这æ„�味ç�€ï¼ŒHandlerMapping的实现类å�¯ä»¥åˆ©ç”¨HttpServletRequestä¸çš„æ‰€æœ‰ä¿¡æ�¯æ�¥å�šå‡ºè¿™ä¸ªHandlerExecutionChain对象的生æˆ�â€�决ç–“。这包括,请求头ã€�url路径ã€�cookieã€�sessionã€�å�‚æ•°ç‰ç‰ä¸€åˆ‡ä½ 从一个web请求ä¸å�¯ä»¥å¾—到的任何东西(最常用的是url路径)。
SpirngMVC的第一个扩展点,就出现在这里。我们å�¯ä»¥ç¼–写任æ„�çš„HandlerMapping实现类,ä¾�æ�®ä»»ä½•ç–ç•¥æ�¥å†³å®šä¸€ä¸ªweb请求到HandlerExecutionChain对象的生æˆ�。å�¯ä»¥è¯´ï¼Œä»Žç¬¬ä¸€ä¸ªæ ¸å¿ƒæŽ¥å�£çš„声明开始,SpringMVC就把自己的ç�µæ´»æ€§å’Œé‡Žå¿ƒæš´éœ²æ— 疑:哥玩的就是â€�Open-Closed“。
diff --git "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232Mybatis\345\205\245\351\227\250.md" "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232Mybatis\345\205\245\351\227\250.md"
index 77b8926..fa50a2b 100644
--- "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232Mybatis\345\205\245\351\227\250.md"
+++ "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232Mybatis\345\205\245\351\227\250.md"
@@ -252,7 +252,7 @@ Mybatis通过执行器与Mappered Statement的结�实现与数�库的交互
## 测试工程æ�建
-1. 新建maven工程
+1.新建maven工程

diff --git "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232\344\273\216\346\211\213\345\212\250\347\274\226\350\257\221\346\211\223\345\214\205\345\210\260\351\241\271\347\233\256\346\236\204\345\273\272\345\267\245\345\205\267Maven.md" "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232\344\273\216\346\211\213\345\212\250\347\274\226\350\257\221\346\211\223\345\214\205\345\210\260\351\241\271\347\233\256\346\236\204\345\273\272\345\267\245\345\205\267Maven.md"
index d04ef0d..7f80e4f 100644
--- "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232\344\273\216\346\211\213\345\212\250\347\274\226\350\257\221\346\211\223\345\214\205\345\210\260\351\241\271\347\233\256\346\236\204\345\273\272\345\267\245\345\205\267Maven.md"
+++ "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232\344\273\216\346\211\213\345\212\250\347\274\226\350\257\221\346\211\223\345\214\205\345\210\260\351\241\271\347\233\256\346\236\204\345\273\272\345\267\245\345\205\267Maven.md"
@@ -90,7 +90,7 @@ Maven�仅是构建工具,还是一个�赖管�工具和项目管�工具
[](http://upload-images.jianshu.io/upload_images/5811881-7482108a7ff71031.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240 "image.png")
-三:最å�Žè®¾ç½®ä¸€ä¸‹çŽ¯å¢ƒå�˜é‡�,将Maven安装é…�置到æ“�作系统环境ä¸ï¼Œä¸»è¦�就是é…�ç½®M2_HOME 和PATH两项,如图
+三:最å�Žè®¾ç½®ä¸€ä¸‹çŽ¯å¢ƒå�˜é‡�,将Maven安装é…�置到æ“�作系统环境ä¸ï¼Œä¸»è¦�就是é…�ç½®M2_HOMEå’ŒPATH两项,如图
[](http://upload-images.jianshu.io/upload_images/5811881-ffdf167e64415703.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240 "image.png")
都�定�,验�一下,打开doc输入 mvn -v如何得到下�信�就说明�置�功了
@@ -187,7 +187,7 @@ nameå…ƒç´ ç”Ÿå‘½äº†ä¸€ä¸ªå¯¹äºŽç”¨æˆ·æ›´ä¸ºå�‹å¥½çš„项目å��称,虽然这ä¸�
ä¾�赖范围就是用æ�¥æŽ§åˆ¶ä¾�赖和三ç§�classpath(编译classpath,测试classpathã€�è¿�行classpath)的关系,Mavenæœ‰å¦‚ä¸‹å‡ ç§�ä¾�赖范围:
* compile:编译ä¾�赖范围。如果没有指定,就会默认使用该ä¾�赖范围。使用æ¤ä¾�赖范围的Mavenä¾�赖,对于编译ã€�测试ã€�è¿�行三ç§�classpath都有效。典型的例å�是spring-code,在编译ã€�测试和è¿�行的时候都需è¦�使用该ä¾�赖。
-* test: 测试ä¾�赖范围。使用次ä¾�赖范围的Mavenä¾�赖,å�ªå¯¹äºŽæµ‹è¯•classpath有效,在编译主代ç �或者è¿�è¡Œé¡¹ç›®çš„ä½¿ç”¨æ—¶å°†æ— æ³•ä½¿ç”¨æ¤ä¾�赖。典型的例å�是Jnuit,它å�ªæœ‰åœ¨ç¼–译测试代ç �å�Šè¿�行测试的时候æ‰�需è¦�。
+* test:测试ä¾�赖范围。使用次ä¾�赖范围的Mavenä¾�赖,å�ªå¯¹äºŽæµ‹è¯•classpath有效,在编译主代ç �或者è¿�è¡Œé¡¹ç›®çš„ä½¿ç”¨æ—¶å°†æ— æ³•ä½¿ç”¨æ¤ä¾�赖。典型的例å�是Jnuit,它å�ªæœ‰åœ¨ç¼–译测试代ç �å�Šè¿�行测试的时候æ‰�需è¦�。
* provided:å·²æ��ä¾›ä¾�赖范围。使用æ¤ä¾�赖范围的Mavenä¾�赖,对于编译和测试classpath有效,但在è¿�è¡Œæ—¶å€™æ— æ•ˆã€‚å…¸åž‹çš„ä¾‹å�是servlet-api,编译和测试项目的时候需è¦�该ä¾�赖,但在è¿�行项目的时候,由于容器以å�Šæ��供,就ä¸�需è¦�Mavené‡�å¤�地引入一é��。
* runtime:è¿�行时ä¾�赖范围。使用æ¤ä¾�赖范围的Mavenä¾�赖,对于测试和è¿�行classpath有效,但在编译主代ç �æ—¶æ— æ•ˆã€‚å…¸åž‹çš„ä¾‹å�是JDBC驱动实现,项目主代ç �的编译å�ªéœ€è¦�JDKæ��供的JDBC接å�£ï¼Œå�ªæœ‰åœ¨æ‰§è¡Œæµ‹è¯•或者è¿�行项目的时候æ‰�需è¦�实现上述接å�£çš„具体JDBC驱动。
* system:系统ä¾�赖范围。该ä¾�赖与三ç§�classpath的关系,和providedä¾�赖范围完全一致,但是,使用system范围的ä¾�赖时必须通过systemPathå…ƒç´ æ˜¾ç¤ºåœ°æŒ‡å®šä¾�赖文件的路径。由于æ¤ç±»ä¾�èµ–ä¸�是通过Maven仓库解æž�的,而且往往与本机系统绑定,å�¯èƒ½æž„æˆ�构建的ä¸�å�¯ç§»æ¤�ï¼Œå› æ¤åº”该谨慎使用。systemPathå…ƒç´ å�¯ä»¥å¼•用环境å�˜é‡�,如:
diff --git "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232\346\236\201\347\256\200\351\205\215\347\275\256\347\232\204SpringBoot.md" "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232\346\236\201\347\256\200\351\205\215\347\275\256\347\232\204SpringBoot.md"
index 8384ba1..adaa923 100644
--- "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232\346\236\201\347\256\200\351\205\215\347\275\256\347\232\204SpringBoot.md"
+++ "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232\346\236\201\347\256\200\351\205\215\347\275\256\347\232\204SpringBoot.md"
@@ -120,7 +120,7 @@ public class HelloController {
@RequestMapping("/hello") public String hello() { return "Hello Spring Boot!"; }}
```
-* **@RestController 注解:** 该注解是 @Controller 和 @ResponseBody 注解的�体版
+* **@RestController 注解:**该注解是 @Controller 和 @ResponseBody 注解的�体版
#### 第三æ¥ï¼šåˆ©ç”¨ IDEA å�¯åЍ Spring Boot
@@ -163,7 +163,7 @@ public class HelloController {
org.springframework.boot spring-boot-maven-plugin
```
-我们å�¯ä»¥çœ‹åˆ°ä¸€ä¸ªæ¯”è¾ƒé™Œç”Ÿä¸€äº›çš„æ ‡ç¾Â ``Â ï¼Œè¿™ä¸ªæ ‡ç¾æ˜¯åœ¨é…�ç½® Spring Boot 的父级ä¾�赖:
+我们å�¯ä»¥çœ‹åˆ°ä¸€ä¸ªæ¯”è¾ƒé™Œç”Ÿä¸€äº›çš„æ ‡ç¾``ï¼Œè¿™ä¸ªæ ‡ç¾æ˜¯åœ¨é…�ç½® Spring Boot 的父级ä¾�赖:
```
@@ -176,12 +176,12 @@ public class HelloController {
#### 应用入�类
-Spring Boot 项目通常有一个å��为 *Application 的入å�£ç±»ï¼Œå…¥å�£ç±»é‡Œæœ‰ä¸€ä¸ª main 方法, **这个 main æ–¹æ³•å…¶å®žå°±æ˜¯ä¸€ä¸ªæ ‡å‡†çš„ Javay 应用的入å�£æ–¹æ³•。**
+Spring Boot 项目通常有一个å��为 *Application 的入å�£ç±»ï¼Œå…¥å�£ç±»é‡Œæœ‰ä¸€ä¸ª main 方法,**这个 main æ–¹æ³•å…¶å®žå°±æ˜¯ä¸€ä¸ªæ ‡å‡†çš„ Javay 应用的入å�£æ–¹æ³•。**
-**@SpringBootApplication** 是 Spring Boot çš„æ ¸å¿ƒæ³¨è§£ï¼Œå®ƒæ˜¯ä¸€ä¸ªç»„å�ˆæ³¨è§£ï¼Œè¯¥æ³¨è§£ç»„å�ˆäº†ï¼š**@Configurationã€�@EnableAutoConfigurationã€�@ComponentScanï¼›** 若ä¸�是用 @SpringBootApplication 注解也å�¯ä»¥ä½¿ç”¨è¿™ä¸‰ä¸ªæ³¨è§£ä»£æ›¿ã€‚
+**@SpringBootApplication**是 Spring Boot çš„æ ¸å¿ƒæ³¨è§£ï¼Œå®ƒæ˜¯ä¸€ä¸ªç»„å�ˆæ³¨è§£ï¼Œè¯¥æ³¨è§£ç»„å�ˆäº†ï¼š**@Configurationã€�@EnableAutoConfigurationã€�@ComponentScanï¼›**è‹¥ä¸�是用 @SpringBootApplication 注解也å�¯ä»¥ä½¿ç”¨è¿™ä¸‰ä¸ªæ³¨è§£ä»£æ›¿ã€‚
* å…¶ä¸ï¼Œ**@EnableAutoConfiguration 让 Spring Boot æ ¹æ�®ç±»è·¯å¾„ä¸çš„ jar 包ä¾�赖为当å‰�项目进行自动é…�ç½®**ï¼Œä¾‹å¦‚ï¼Œæ·»åŠ äº† spring-boot-starter-web ä¾�èµ–ï¼Œä¼šè‡ªåŠ¨æ·»åŠ Tomcat å’Œ Spring MVC çš„ä¾�赖,那么 Spring Boot 会对 Tomcat å’Œ Spring MVC 进行自动é…�置。
-* **Spring Boot 还会自动扫� @SpringBootApplication 所在类的�级包以�下级包里的 Bean** ,所以入�类建议就�置在 grounpID + arctifactID 组�的包�下(这里为 cn.wmyskxz.springboot 包)
+* **Spring Boot 还会自动扫� @SpringBootApplication 所在类的�级包以�下级包里的 Bean**,所以入�类建议就�置在 grounpID + arctifactID 组�的包�下(这里为 cn.wmyskxz.springboot 包)
#### Spring Boot 的�置文件
@@ -209,7 +209,7 @@ Spring Boot 的全局�置文件的作用是对一些默认�置的�置值

-* **注æ„�:** 我们并没有在 yml æ–‡ä»¶ä¸æ³¨æ˜Žå±žæ€§çš„类型,而是在使用的时候定义的。
+* **注æ„�:**我们并没有在 yml æ–‡ä»¶ä¸æ³¨æ˜Žå±žæ€§çš„类型,而是在使用的时候定义的。
ä½ ä¹Ÿå�¯ä»¥åœ¨é…�置文件ä¸ä½¿ç”¨å½“å‰�é…�置:
@@ -219,7 +219,7 @@ Spring Boot 的全局�置文件的作用是对一些默认�置的�置值

-* **问题:**Â è¿™æ ·å†™é…�置文件ç¹�ç��而且å�¯èƒ½ä¼šé€ æˆ�ç±»çš„è‡ƒè‚¿ï¼Œå› ä¸ºæœ‰è®¸è®¸å¤šå¤šçš„ @Value 注解。
+* **问题:**è¿™æ ·å†™é…�置文件ç¹�ç��而且å�¯èƒ½ä¼šé€ æˆ�ç±»çš„è‡ƒè‚¿ï¼Œå› ä¸ºæœ‰è®¸è®¸å¤šå¤šçš„ @Value 注解。
> * �装�置信�
diff --git "a/docs/java/basic/javac\345\222\214javap.md" "b/docs/java/basic/javac\345\222\214javap.md"
index 5f85010..f797af7 100644
--- "a/docs/java/basic/javac\345\222\214javap.md"
+++ "b/docs/java/basic/javac\345\222\214javap.md"
@@ -18,14 +18,7 @@
* [-encoding](#-encoding)
* [-verbose](#-verbose)
* [其他命令](#其他命令)
- * [使用javac构建项目](#使用javac构建项目)
- * [](#)
-* [java文件列表目录](#java文件列表目录)
- * [放入列表文件ä¸](#放入列表文件ä¸)
- * [生�bin目录](#生�bin目录)
- * [列表](#列表)
- * [通过-cp指定所有的引用jar包,将src下的所有java文件进行编译](#通过-cp指定所有的引用jar包,将src下的所有java文件进行编译)
- * [通过-cp指定所有的引用jar包,指定入�函数�行](#通过-cp指定所有的引用jar包,指定入�函数�行)
+ * [使用javac构建项目](#使用javac构建项目)
* [javap 的使用](#javap-的使用)
* [å�‚è€ƒæ–‡ç« ](#å�‚è€ƒæ–‡ç« )
diff --git "a/docs/java/basic/\344\273\243\347\240\201\345\235\227\345\222\214\344\273\243\347\240\201\346\211\247\350\241\214\351\241\272\345\272\217.md" "b/docs/java/basic/\344\273\243\347\240\201\345\235\227\345\222\214\344\273\243\347\240\201\346\211\247\350\241\214\351\241\272\345\272\217.md"
index 2e51bc0..7ebb784 100644
--- "a/docs/java/basic/\344\273\243\347\240\201\345\235\227\345\222\214\344\273\243\347\240\201\346\211\247\350\241\214\351\241\272\345\272\217.md"
+++ "b/docs/java/basic/\344\273\243\347\240\201\345\235\227\345\222\214\344\273\243\347\240\201\346\211\247\350\241\214\351\241\272\345\272\217.md"
@@ -38,7 +38,7 @@
## Javaä¸çš„æž„é€ æ–¹æ³•
### æž„é€ æ–¹æ³•ç®€ä»‹
-æž„é€ æ–¹æ³•æ˜¯ç±»çš„ä¸€ç§�特殊方法,用æ�¥åˆ�始化类的一个新的对象。[Java](http://c.biancheng.net/java/) ä¸çš„æ¯�ä¸ªç±»éƒ½æœ‰ä¸€ä¸ªé»˜è®¤çš„æž„é€ æ–¹æ³•ï¼Œå®ƒå¿…é¡»å…·æœ‰å’Œç±»å��相å�Œçš„å��ç§°ï¼Œè€Œä¸”æ²¡æœ‰è¿”å›žç±»åž‹ã€‚æž„é€ æ–¹æ³•çš„é»˜è®¤è¿”å›žç±»åž‹å°±æ˜¯å¯¹è±¡ç±»åž‹æœ¬èº«ï¼Œå¹¶ä¸”æž„é€ æ–¹æ³•ä¸�能被 staticã€�finalã€�synchronizedã€�abstract å’Œ native 修饰。
+æž„é€ æ–¹æ³•æ˜¯ç±»çš„ä¸€ç§�特殊方法,用æ�¥åˆ�始化类的一个新的对象。[Java](http://c.biancheng.net/java/)ä¸çš„æ¯�ä¸ªç±»éƒ½æœ‰ä¸€ä¸ªé»˜è®¤çš„æž„é€ æ–¹æ³•ï¼Œå®ƒå¿…é¡»å…·æœ‰å’Œç±»å��相å�Œçš„å��ç§°ï¼Œè€Œä¸”æ²¡æœ‰è¿”å›žç±»åž‹ã€‚æž„é€ æ–¹æ³•çš„é»˜è®¤è¿”å›žç±»åž‹å°±æ˜¯å¯¹è±¡ç±»åž‹æœ¬èº«ï¼Œå¹¶ä¸”æž„é€ æ–¹æ³•ä¸�能被 staticã€�finalã€�synchronizedã€�abstract å’Œ native 修饰。
æ��ç¤ºï¼šæž„é€ æ–¹æ³•ç”¨äºŽåˆ�始化一个新对象,所以用 static 修饰没有æ„�ä¹‰ï¼›æž„é€ æ–¹æ³•ä¸�能被å�类继承,所以用 final å’Œ abstract 修饰没有æ„�义;多个线程ä¸�会å�Œæ—¶åˆ›å»ºå†…å˜åœ°å�€ç›¸å�Œçš„å�Œä¸€ä¸ªå¯¹è±¡ï¼Œæ‰€ä»¥ç”¨ synchronized 修饰没有必è¦�。
diff --git "a/docs/java/basic/\345\244\232\347\272\277\347\250\213.md" "b/docs/java/basic/\345\244\232\347\272\277\347\250\213.md"
index e40b5d0..35e3ada 100644
--- "a/docs/java/basic/\345\244\232\347\272\277\347\250\213.md"
+++ "b/docs/java/basic/\345\244\232\347\272\277\347\250\213.md"
@@ -80,7 +80,7 @@ Java 给多线程编程�供了内置的支�。 一�线程指的是进程
* **新建状�:**
- 使用 **new** 关键å—和 **Thread** 类或其å�类建立一个线程对象å�Žï¼Œè¯¥çº¿ç¨‹å¯¹è±¡å°±å¤„于新建状æ€�。它ä¿�æŒ�这个状æ€�直到程åº� **start()** 这个线程。
+ 使用**new**关键å—å’Œ**Thread**类或其å�类建立一个线程对象å�Žï¼Œè¯¥çº¿ç¨‹å¯¹è±¡å°±å¤„于新建状æ€�。它ä¿�æŒ�这个状æ€�直到程åº�**start()**这个线程。
* **就绪状�:**
@@ -88,7 +88,7 @@ Java 给多线程编程�供了内置的支�。 一�线程指的是进程
* **�行状�:**
- 如果就绪状æ€�的线程获å�– CPU 资æº�,就å�¯ä»¥æ‰§è¡ŒÂ **run()**ï¼Œæ¤æ—¶çº¿ç¨‹ä¾¿å¤„于è¿�行状æ€�。处于è¿�行状æ€�的线程最为å¤�æ�‚,它å�¯ä»¥å�˜ä¸ºé˜»å¡žçжæ€�ã€�就绪状æ€�å’Œæ»äº¡çжæ€�。
+ 如果就绪状æ€�的线程获å�– CPU 资æº�,就å�¯ä»¥æ‰§è¡Œ**run()**ï¼Œæ¤æ—¶çº¿ç¨‹ä¾¿å¤„于è¿�行状æ€�。处于è¿�行状æ€�的线程最为å¤�æ�‚,它å�¯ä»¥å�˜ä¸ºé˜»å¡žçжæ€�ã€�就绪状æ€�å’Œæ»äº¡çжæ€�。
* **阻塞状�:**
diff --git "a/docs/java/basic/\350\247\243\350\257\273Java\344\270\255\347\232\204\345\233\236\350\260\203.md" "b/docs/java/basic/\350\247\243\350\257\273Java\344\270\255\347\232\204\345\233\236\350\260\203.md"
index 8a672ed..57e5237 100644
--- "a/docs/java/basic/\350\247\243\350\257\273Java\344\270\255\347\232\204\345\233\236\350\260\203.md"
+++ "b/docs/java/basic/\350\247\243\350\257\273Java\344\270\255\347\232\204\345\233\236\350\260\203.md"
@@ -3,9 +3,8 @@
* [多线程ä¸çš„“回调â€�](#多线程ä¸çš„回调)
* [Java回调机制实战](#java回调机制实战)
* [实例一 : å�Œæ¥è°ƒç”¨](#实例一-:-å�Œæ¥è°ƒç”¨)
- * [1.1 å�Œæ¥è°ƒç”¨ä»£ç �](#11-å�Œæ¥è°ƒç”¨ä»£ç �)
- * [实例二:由浅入深](#实例二:由浅入深)
- * [实例三:Tom�题](#实例三:tom�题)
+ * [实例二:由浅入深](#实例二:由浅入深)
+ * [实例三:Tom�题](#实例三:tom�题)
* [å�‚è€ƒæ–‡ç« ](#å�‚è€ƒæ–‡ç« )
diff --git "a/docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\243\357\274\232Iterator\357\274\214fail-fast\346\234\272\345\210\266\344\270\216\346\257\224\350\276\203\345\231\250.md" "b/docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\243\357\274\232Iterator\357\274\214fail-fast\346\234\272\345\210\266\344\270\216\346\257\224\350\276\203\345\231\250.md"
index c89b6ae..95169c6 100644
--- "a/docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\243\357\274\232Iterator\357\274\214fail-fast\346\234\272\345\210\266\344\270\216\346\257\224\350\276\203\345\231\250.md"
+++ "b/docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\243\357\274\232Iterator\357\274\214fail-fast\346\234\272\345\210\266\344\270\216\346\257\224\350\276\203\345\231\250.md"
@@ -6,12 +6,12 @@
* [fail-fast示例](#fail-fast示例)
* [fail-fastäº§ç”ŸåŽŸå› ](#fail-fastäº§ç”ŸåŽŸå› )
* [fail-fast解决办法](#fail-fast解决办法)
-* [Comparable 和 Comparator](#comparable-和-comparator)
- * [Comparable](#comparable)
- * [Comparator](#comparator)
- * [Java8ä¸ä½¿ç”¨lambda实现比较器](#java8ä¸ä½¿ç”¨lambda实现比较器)
- * [总结](#总结)
- * [å�‚è€ƒæ–‡ç« ](#å�‚è€ƒæ–‡ç« )
+ * [Comparable 和 Comparator](#comparable-和-comparator)
+ * [Comparable](#comparable)
+ * [Comparator](#comparator)
+ * [Java8ä¸ä½¿ç”¨lambda实现比较器](#java8ä¸ä½¿ç”¨lambda实现比较器)
+ * [总结](#总结)
+ * [å�‚è€ƒæ–‡ç« ](#å�‚è€ƒæ–‡ç« )
本文�考 cmsblogs.com/p=1185
diff --git "a/docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\243\357\274\232\344\270\200\346\226\207\350\257\273\346\207\202ArrayList,Vector\344\270\216Stack\344\275\277\347\224\250\346\226\271\346\263\225\345\222\214\345\256\236\347\216\260\345\216\237\347\220\206.md" "b/docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\243\357\274\232\344\270\200\346\226\207\350\257\273\346\207\202ArrayList,Vector\344\270\216Stack\344\275\277\347\224\250\346\226\271\346\263\225\345\222\214\345\256\236\347\216\260\345\216\237\347\220\206.md"
index e228969..ed04968 100644
--- "a/docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\243\357\274\232\344\270\200\346\226\207\350\257\273\346\207\202ArrayList,Vector\344\270\216Stack\344\275\277\347\224\250\346\226\271\346\263\225\345\222\214\345\256\236\347\216\260\345\216\237\347\220\206.md"
+++ "b/docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\243\357\274\232\344\270\200\346\226\207\350\257\273\346\207\202ArrayList,Vector\344\270\216Stack\344\275\277\347\224\250\346\226\271\346\263\225\345\222\214\345\256\236\347\216\260\345\216\237\347\220\206.md"
@@ -13,9 +13,8 @@
* [�始容�和扩容](#�始容�和扩容)
* [线程安全](#线程安全-1)
* [Stack](#stack)
-* [Stack](#stack-1)
- * [三个集�类之间的区别](#三个集�类之间的区别)
- * [å�‚è€ƒæ–‡ç« ](#å�‚è€ƒæ–‡ç« )
+ * [三个集�类之间的区别](#三个集�类之间的区别)
+ * [å�‚è€ƒæ–‡ç« ](#å�‚è€ƒæ–‡ç« )
本文å�‚考多篇优质技术å�šå®¢ï¼Œå�‚è€ƒæ–‡ç« è¯·åœ¨æ–‡æœ«æŸ¥çœ‹
@@ -464,11 +463,11 @@ vector大部分方法都使用了synchronized修饰符,所以他是线层安
# Stack
-  如果我们去查jdk的文档,我们会�现stack是在java.util这个包里。它对应的一个大致的类关系图如下:
+ 如果我们去查jdk的文档,我们会�现stack是在java.util这个包里。它对应的一个大致的类关系图如下:

-  通过继承Vector类,Stackç±»å�¯ä»¥å¾ˆå®¹æ˜“çš„å®žçŽ°ä»–æœ¬èº«çš„åŠŸèƒ½ã€‚å› ä¸ºå¤§éƒ¨åˆ†çš„åŠŸèƒ½åœ¨Vector里é�¢å·²ç»�æ��供支æŒ�了。
+ 通过继承Vector类,Stackç±»å�¯ä»¥å¾ˆå®¹æ˜“çš„å®žçŽ°ä»–æœ¬èº«çš„åŠŸèƒ½ã€‚å› ä¸ºå¤§éƒ¨åˆ†çš„åŠŸèƒ½åœ¨Vector里é�¢å·²ç»�æ��供支æŒ�了。
在Javaä¸Stack类表示å�Žè¿›å…ˆå‡ºï¼ˆLIFOï¼‰çš„å¯¹è±¡å †æ ˆã€‚æ ˆæ˜¯ä¸€ç§�é�žå¸¸å¸¸è§�的数æ�®ç»“构,它采用典型的先进å�Žå‡ºçš„æ“�作方å¼�完æˆ�的。
diff --git "a/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232AQS\344\270\255\347\232\204\345\205\254\345\271\263\351\224\201\344\270\216\351\235\236\345\205\254\345\271\263\351\224\201\357\274\214Condtion.md" "b/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232AQS\344\270\255\347\232\204\345\205\254\345\271\263\351\224\201\344\270\216\351\235\236\345\205\254\345\271\263\351\224\201\357\274\214Condtion.md"
index 7cacaae..eb10601 100644
--- "a/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232AQS\344\270\255\347\232\204\345\205\254\345\271\263\351\224\201\344\270\216\351\235\236\345\205\254\345\271\263\351\224\201\357\274\214Condtion.md"
+++ "b/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232AQS\344\270\255\347\232\204\345\205\254\345\271\263\351\224\201\344\270\216\351\235\236\345\205\254\345\271\263\351\224\201\357\274\214Condtion.md"
@@ -8,8 +8,8 @@
* [5\. 唤醒å�Žæ£€æŸ¥ä¸æ–状æ€�](#5-唤醒å�Žæ£€æŸ¥ä¸æ–状æ€�)
* [6\. 获å�–独å� é”�](#6-获å�–独å� é”�)
* [7\. 处ç�†ä¸æ–状æ€�](#7-处ç�†ä¸æ–状æ€�)
- * [* 带超时机制的 await](#-带超时机制的-await)
- * [* �抛出 InterruptedException 的 await](#-�抛出-interruptedexception-的-await)
+ * [带超时机制的 await](#-带超时机制的-await)
+ * [�抛出 InterruptedException 的 await](#-�抛出-interruptedexception-的-await)
* [AbstractQueuedSynchronizer 独å� é”�çš„å�–消排队](#abstractqueuedsynchronizer-独å� é”�çš„å�–消排队)
* [å†�说 java çº¿ç¨‹ä¸æ–å’Œ InterruptedException 异常](#å†�说-java-çº¿ç¨‹ä¸æ–å’Œ-interruptedexception-异常)
* [çº¿ç¨‹ä¸æ–](#çº¿ç¨‹ä¸æ–)
diff --git "a/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232ForkJoin\345\271\266\345\217\221\346\241\206\346\236\266\344\270\216\345\267\245\344\275\234\347\252\203\345\217\226\347\256\227\346\263\225\345\211\226\346\236\220.md" "b/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232ForkJoin\345\271\266\345\217\221\346\241\206\346\236\266\344\270\216\345\267\245\344\275\234\347\252\203\345\217\226\347\256\227\346\263\225\345\211\226\346\236\220.md"
index ca072a2..74fa6a0 100644
--- "a/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232ForkJoin\345\271\266\345\217\221\346\241\206\346\236\266\344\270\216\345\267\245\344\275\234\347\252\203\345\217\226\347\256\227\346\263\225\345\211\226\346\236\220.md"
+++ "b/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232ForkJoin\345\271\266\345\217\221\346\241\206\346\236\266\344\270\216\345\267\245\344\275\234\347\252\203\345\217\226\347\256\227\346\263\225\345\211\226\346\236\220.md"
@@ -27,7 +27,7 @@ Fork/Join框架是Java7�供的一个用于并行执行任务的框架, 是
## 简介
-通常,使用Javaæ�¥å¼€å�‘一个简å�•的并å�‘应用程åº�时,会创建一些**Runnable**对象,然å�Žåˆ›å»ºå¯¹åº”çš„**Thread** 对象æ�¥æŽ§åˆ¶ç¨‹åº�ä¸è¿™äº›çº¿ç¨‹çš„创建ã€�执行以å�Šçº¿ç¨‹çš„状æ€�。自从Java 5开始引入了**Executor**å’Œ**ExecutorService**接å�£ä»¥å�Šå®žçŽ°è¿™ä¸¤ä¸ªæŽ¥å�£çš„类(比如**ThreadPoolExecutor**)之å�Žï¼Œä½¿å¾—Java在并å�‘支æŒ�上得到了进一æ¥çš„æ��å�‡ã€‚
+通常,使用Javaæ�¥å¼€å�‘一个简å�•的并å�‘应用程åº�时,会创建一些**Runnable**对象,然å�Žåˆ›å»ºå¯¹åº”çš„**Thread**对象æ�¥æŽ§åˆ¶ç¨‹åº�ä¸è¿™äº›çº¿ç¨‹çš„创建ã€�执行以å�Šçº¿ç¨‹çš„状æ€�。自从Java 5开始引入了**Executor**å’Œ**ExecutorService**接å�£ä»¥å�Šå®žçŽ°è¿™ä¸¤ä¸ªæŽ¥å�£çš„类(比如**ThreadPoolExecutor**)之å�Žï¼Œä½¿å¾—Java在并å�‘支æŒ�上得到了进一æ¥çš„æ��å�‡ã€‚
**执行器框架(Executor Framework)**将任务的创建和执行进行了分离,通过这个框架,�需�实现**Runnable**接�的对象和使用**Executor**对象,然�将**Runnable**对象��给执行器。执行器�负责�行这些任务所需�的线程,包括线程的创建,线程的管�以�线程的结�。
@@ -37,7 +37,7 @@ Fork/Join框架是Java7�供的一个用于并行执行任务的框架, 是

-没有固定的公å¼�æ�¥å†³å®šé—®é¢˜çš„**å�‚考大å°�(Reference Size)**,从而决定一个任务是需è¦�进行拆分或ä¸�需è¦�拆分,拆分与å�¦ä»�是ä¾�赖于任务本身的特性。å�¯ä»¥ä½¿ç”¨åœ¨ä»»åŠ¡ä¸å°†è¦�处ç�†çš„å…ƒç´ çš„æ•°ç›®å’Œä»»åŠ¡æ‰§è¡Œæ‰€éœ€è¦�的时间æ�¥å†³å®šå�‚考大å°�。测试ä¸�å�Œçš„å�‚考大å°�æ�¥å†³å®šè§£å†³é—®é¢˜æœ€å¥½çš„一个方案,将**ForkJoinPool**类看作一个特殊的 **Executor** 执行器类型。这个框架基于以下两ç§�æ“�作。
+没有固定的公å¼�æ�¥å†³å®šé—®é¢˜çš„**å�‚考大å°�(Reference Size)**,从而决定一个任务是需è¦�进行拆分或ä¸�需è¦�拆分,拆分与å�¦ä»�是ä¾�赖于任务本身的特性。å�¯ä»¥ä½¿ç”¨åœ¨ä»»åŠ¡ä¸å°†è¦�处ç�†çš„å…ƒç´ çš„æ•°ç›®å’Œä»»åŠ¡æ‰§è¡Œæ‰€éœ€è¦�的时间æ�¥å†³å®šå�‚考大å°�。测试ä¸�å�Œçš„å�‚考大å°�æ�¥å†³å®šè§£å†³é—®é¢˜æœ€å¥½çš„一个方案,将**ForkJoinPool**类看作一个特殊的**Executor**执行器类型。这个框架基于以下两ç§�æ“�作。
* **分解(Fork)**æ“�作:当需è¦�将一个任务拆分æˆ�æ›´å°�çš„å¤šä¸ªä»»åŠ¡æ—¶ï¼Œåœ¨æ¡†æž¶ä¸æ‰§è¡Œè¿™äº›ä»»åŠ¡ï¼›
* **å�ˆå¹¶ï¼ˆJoin)**æ“�作:当一个主任务ç‰å¾…其创建的多个å�任务的完æˆ�执行。
@@ -46,7 +46,7 @@ Fork/Join框架是Java7�供的一个用于并行执行任务的框架, 是
ä¸ºäº†è¾¾åˆ°è¿™ä¸ªç›®æ ‡ï¼Œé€šè¿‡**Fork/Join框架**执行的任务有以下é™�制。
-* 任务å�ªèƒ½ä½¿ç”¨**fork()**å’Œ**join()** æ“�作当作å�Œæ¥æœºåˆ¶ã€‚如果使用其他的å�Œæ¥æœºåˆ¶ï¼Œå·¥ä½œè€…线程就ä¸�能执行其他任务,当然这些任务是在å�Œæ¥æ“�作里时。比如,如果在**Fork/Join 框架**ä¸å°†ä¸€ä¸ªä»»åŠ¡ä¼‘çœ ï¼Œæ£åœ¨æ‰§è¡Œè¿™ä¸ªä»»åŠ¡çš„å·¥ä½œè€…çº¿ç¨‹åœ¨ä¼‘çœ æœŸå†…ä¸�能执行å�¦ä¸€ä¸ªä»»åŠ¡ã€‚
+* 任务å�ªèƒ½ä½¿ç”¨**fork()**å’Œ**join()**æ“�作当作å�Œæ¥æœºåˆ¶ã€‚如果使用其他的å�Œæ¥æœºåˆ¶ï¼Œå·¥ä½œè€…线程就ä¸�能执行其他任务,当然这些任务是在å�Œæ¥æ“�作里时。比如,如果在**Fork/Join 框架**ä¸å°†ä¸€ä¸ªä»»åŠ¡ä¼‘çœ ï¼Œæ£åœ¨æ‰§è¡Œè¿™ä¸ªä»»åŠ¡çš„å·¥ä½œè€…çº¿ç¨‹åœ¨ä¼‘çœ æœŸå†…ä¸�能执行å�¦ä¸€ä¸ªä»»åŠ¡ã€‚
* 任务�能执行I/O�作,比如文件数�的读�与写入。
* 任务ä¸�能抛出é�žè¿�行时异常(Checked Exception),必须在代ç �ä¸å¤„ç�†æŽ‰è¿™äº›å¼‚常。
diff --git "a/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232JMM\344\270\255\347\232\204final\345\205\263\351\224\256\345\255\227\350\247\243\346\236\220.md" "b/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232JMM\344\270\255\347\232\204final\345\205\263\351\224\256\345\255\227\350\247\243\346\236\220.md"
index 2d825d4..f7fe31b 100644
--- "a/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232JMM\344\270\255\347\232\204final\345\205\263\351\224\256\345\255\227\350\247\243\346\236\220.md"
+++ "b/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232JMM\344\270\255\347\232\204final\345\205\263\351\224\256\345\255\227\350\247\243\346\236\220.md"
@@ -1,3 +1,12 @@
+# Table of Contents
+
+ * [一�properly constructed / this对象逸出](#一�properly-constructed--this对象逸出)
+ * [二�对象的安全�布](#二�对象的安全�布)
+ * [三ã€� final 关键å—的内å˜è¯ä¹‰](#三ã€�-final-关键å—的内å˜è¯ä¹‰)
+ * [å››ã€�HotSpot VMä¸å¯¹final内å˜è¯ä¹‰çš„实现](#å››ã€�hotspot-vmä¸å¯¹final内å˜è¯ä¹‰çš„实现)
+* [�考文献](#�考文献)
+
+
**本文转载自互è�”ç½‘ï¼Œä¾µåˆ **
æœ¬ç³»åˆ—æ–‡ç« å°†æ•´ç�†åˆ°æˆ‘在GitHub上的《Javaé�¢è¯•指å�—》仓库,更多精彩内容请到我的仓库里查看
@@ -215,4 +224,4 @@ JSR 133 (Java Memory Model) FAQ
Java Concurrency in Practice
The JSR-133 Cookbook for Compiler Writers
-Intel® 64 and IA-32 ArchitecturesvSoftware Developer’s Manual Volume 3A: System Programming Guide, Part 1
\ No newline at end of file
+Intel® 64 and IA-32 ArchitecturesvSoftware Developer’s Manual Volume 3A: System Programming Guide, Part 1
diff --git "a/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232Java\344\270\255\347\232\204HashMap\345\222\214ConcurrentHashMap\345\205\250\350\247\243\346\236\220.md" "b/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232Java\344\270\255\347\232\204HashMap\345\222\214ConcurrentHashMap\345\205\250\350\247\243\346\236\220.md"
index 6314e77..dff6cc3 100644
--- "a/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232Java\344\270\255\347\232\204HashMap\345\222\214ConcurrentHashMap\345\205\250\350\247\243\346\236\220.md"
+++ "b/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232Java\344\270\255\347\232\204HashMap\345\222\214ConcurrentHashMap\345\205\250\350\247\243\346\236\220.md"
@@ -345,7 +345,7 @@ public V put(K key, V value) {
第一层皮很简å�•ï¼Œæ ¹æ�® hash 值很快就能找到相应的 Segment,之å�Žå°±æ˜¯ Segment 内部的 put æ“�作了。
-Segment 内部是由 **数组+链表** 组�的。
+Segment 内部是由**数组+链表**组�的。
```
final V put(K key, int hash, V value, boolean onlyIfAbsent) {
@@ -640,11 +640,11 @@ public V get(Object key) {
## Java8 HashMap
-Java8 对 HashMap 进行了一些修改,最大的ä¸�å�Œå°±æ˜¯åˆ©ç”¨äº†çº¢é»‘æ ‘ï¼Œæ‰€ä»¥å…¶ç”±Â **数组+链表+çº¢é»‘æ ‘** 组æˆ�。
+Java8 对 HashMap 进行了一些修改,最大的ä¸�å�Œå°±æ˜¯åˆ©ç”¨äº†çº¢é»‘æ ‘ï¼Œæ‰€ä»¥å…¶ç”±**数组+链表+çº¢é»‘æ ‘**组æˆ�。
-æ ¹æ�® Java7 HashMap 的介ç»�,我们知é�“ï¼ŒæŸ¥æ‰¾çš„æ—¶å€™ï¼Œæ ¹æ�® hash 值我们能够快速定ä½�åˆ°æ•°ç»„çš„å…·ä½“ä¸‹æ ‡ï¼Œä½†æ˜¯ä¹‹å�Žçš„è¯�,需è¦�顺ç�€é“¾è¡¨ä¸€ä¸ªä¸ªæ¯”较下去æ‰�能找到我们需è¦�的,时间å¤�æ�‚度å�–决于链表的长度,为 **O(n)**。
+æ ¹æ�® Java7 HashMap 的介ç»�,我们知é�“ï¼ŒæŸ¥æ‰¾çš„æ—¶å€™ï¼Œæ ¹æ�® hash 值我们能够快速定ä½�åˆ°æ•°ç»„çš„å…·ä½“ä¸‹æ ‡ï¼Œä½†æ˜¯ä¹‹å�Žçš„è¯�,需è¦�顺ç�€é“¾è¡¨ä¸€ä¸ªä¸ªæ¯”较下去æ‰�能找到我们需è¦�的,时间å¤�æ�‚度å�–决于链表的长度,为**O(n)**。
-为了é™�低这部分的开销,在 Java8 ä¸ï¼Œå½“链表ä¸çš„å…ƒç´ è¾¾åˆ°äº† 8 个时,会将链表转æ�¢ä¸ºçº¢é»‘æ ‘ï¼Œåœ¨è¿™äº›ä½�置进行查找的时候å�¯ä»¥é™�低时间å¤�æ�‚度为 **O(logN)**。
+为了é™�低这部分的开销,在 Java8 ä¸ï¼Œå½“链表ä¸çš„å…ƒç´ è¾¾åˆ°äº† 8 个时,会将链表转æ�¢ä¸ºçº¢é»‘æ ‘ï¼Œåœ¨è¿™äº›ä½�置进行查找的时候å�¯ä»¥é™�低时间å¤�æ�‚度为**O(logN)**。
æ�¥ä¸€å¼ 图简å�•示æ„�一下å�§ï¼š
@@ -654,7 +654,7 @@ Java8 对 HashMap 进行了一些修改,最大的��就是利用了红黑
下é�¢ï¼Œæˆ‘们还是用代ç �æ�¥ä»‹ç»�å�§ï¼Œä¸ªäººæ„Ÿè§‰ï¼ŒJava8 çš„æº�ç �å�¯è¯»æ€§è¦�差一些,ä¸�过精简一些。
-Java7 ä¸ä½¿ç”¨ Entry æ�¥ä»£è¡¨æ¯�个 HashMap ä¸çš„æ•°æ�®èŠ‚ç‚¹ï¼ŒJava8 ä¸ä½¿ç”¨Â **Node**,基本没有区别,都是 key,value,hash å’Œ next 这四个属性,ä¸�过,Node å�ªèƒ½ç”¨äºŽé“¾è¡¨çš„æƒ…å†µï¼Œçº¢é»‘æ ‘çš„æƒ…å†µéœ€è¦�使用 **TreeNode**。
+Java7 ä¸ä½¿ç”¨ Entry æ�¥ä»£è¡¨æ¯�个 HashMap ä¸çš„æ•°æ�®èŠ‚ç‚¹ï¼ŒJava8 ä¸ä½¿ç”¨**Node**,基本没有区别,都是 key,value,hash å’Œ next 这四个属性,ä¸�过,Node å�ªèƒ½ç”¨äºŽé“¾è¡¨çš„æƒ…å†µï¼Œçº¢é»‘æ ‘çš„æƒ…å†µéœ€è¦�使用**TreeNode**。
æˆ‘ä»¬æ ¹æ�®æ•°ç»„å…ƒç´ ä¸ï¼Œç¬¬ä¸€ä¸ªèŠ‚ç‚¹æ•°æ�®ç±»åž‹æ˜¯ Node 还是 TreeNode æ�¥åˆ¤æ–该ä½�ç½®ä¸‹æ˜¯é“¾è¡¨è¿˜æ˜¯çº¢é»‘æ ‘çš„ã€‚
@@ -1145,7 +1145,7 @@ private final void tryPresize(int size) {
è¿™ä¸ªæ–¹æ³•çš„æ ¸å¿ƒåœ¨äºŽ sizeCtl 值的æ“�作,首先将其设置为一个负数,然å�Žæ‰§è¡Œ transfer(tab, null),å†�下一个循环将 sizeCtl åŠ 1,并执行 transfer(tab, nt),之å�Žå�¯èƒ½æ˜¯ç»§ç» sizeCtl åŠ 1,并执行 transfer(tab, nt)。
-所以,å�¯èƒ½çš„æ“�作就是执行 **1 次 transfer(tab, null) + 多次 transfer(tab, nt)**,这里怎么结æ�Ÿå¾ªçŽ¯çš„éœ€è¦�看完 transfer æº�ç �æ‰�清楚。
+所以,å�¯èƒ½çš„æ“�作就是执行**1 次 transfer(tab, null) + 多次 transfer(tab, nt)**,这里怎么结æ�Ÿå¾ªçŽ¯çš„éœ€è¦�看完 transfer æº�ç �æ‰�清楚。
#### 数��移:transfer
diff --git "a/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232Java\350\257\273\345\206\231\351\224\201ReentrantReadWriteLock\346\272\220\347\240\201\345\210\206\346\236\220.md" "b/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232Java\350\257\273\345\206\231\351\224\201ReentrantReadWriteLock\346\272\220\347\240\201\345\210\206\346\236\220.md"
index 50c20d6..a357d88 100644
--- "a/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232Java\350\257\273\345\206\231\351\224\201ReentrantReadWriteLock\346\272\220\347\240\201\345\210\206\346\236\220.md"
+++ "b/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232Java\350\257\273\345\206\231\351\224\201ReentrantReadWriteLock\346\272\220\347\240\201\345\210\206\346\236\220.md"
@@ -91,7 +91,7 @@ ReentrantReadWriteLock 分为读�和写�两个实例,读�是共享�,
很清楚了,ReadLock å’Œ WriteLock ä¸çš„æ–¹æ³•都是通过 Sync 这个类æ�¥å®žçŽ°çš„ã€‚Sync 是 AQS çš„å�类,然å�Žå†�派生了公平模å¼�å’Œä¸�公平模å¼�。
-从它们调用的 Sync 方法,我们å�¯ä»¥çœ‹åˆ°ï¼šÂ **ReadLock 使用了共享模å¼�,WriteLock 使用了独å� 模å¼�**。
+从它们调用的 Sync 方法,我们å�¯ä»¥çœ‹åˆ°ï¼š**ReadLock 使用了共享模å¼�,WriteLock 使用了独å� 模å¼�**。
ç‰ç‰ï¼Œ**å�Œä¸€ä¸ª AQS 实例怎么å�¯ä»¥å�Œæ—¶ä½¿ç”¨å…±äº«æ¨¡å¼�和独å� 模å¼�**???
@@ -99,7 +99,7 @@ ReentrantReadWriteLock 分为读�和写�两个实例,读�是共享�,

-AQS 的精髓在于内部的属性 **state**:
+AQS 的精髓在于内部的属性**state**:
1. 对于独å� 模å¼�æ�¥è¯´ï¼Œé€šå¸¸å°±æ˜¯ 0 代表å�¯èŽ·å�–é”�,1 代表é”�被别人获å�–了,é‡�入例外
2. 而共享模å¼�下,æ¯�个线程都å�¯ä»¥å¯¹ state è¿›è¡ŒåŠ å‡�æ“�作
@@ -168,9 +168,9 @@ abstract static class Sync extends AbstractQueuedSynchronizer {
1. state 的高 16 ä½�代表读é”�的获å�–次数,包括é‡�入次数,获å�–到读é”�ä¸€æ¬¡åŠ 1,释放掉读é”�一次å‡� 1
2. state 的低 16 ä½�代表写é”�的获å�–æ¬¡æ•°ï¼Œå› ä¸ºå†™é”�是独å� é”�,å�Œæ—¶å�ªèƒ½è¢«ä¸€ä¸ªçº¿ç¨‹èŽ·å¾—ï¼Œæ‰€ä»¥å®ƒä»£è¡¨é‡�入次数
-3. æ¯�个线程都需è¦�维护自己的 HoldCounter,记录该线程获å�–的读é”�æ¬¡æ•°ï¼Œè¿™æ ·æ‰�能知é�“到底是ä¸�是读é”�é‡�入,用 ThreadLocal 属性 **readHolds** 维护
-4. **cachedHoldCounter** 有什么用?其实没什么用,但能æ��示性能。将最å�Žä¸€æ¬¡èŽ·å�–读é”�的线程的 HoldCounter 缓å˜åˆ°è¿™é‡Œï¼Œè¿™æ ·æ¯”使用 ThreadLocal 性能è¦�å¥½ä¸€äº›ï¼Œå› ä¸º ThreadLocal 内部是基于 map æ�¥æŸ¥è¯¢çš„。但是 cachedHoldCounter 这一个属性毕竟å�ªèƒ½ç¼“å˜ä¸€ä¸ªçº¿ç¨‹ï¼Œæ‰€ä»¥å®ƒè¦�èµ·æ��å�‡æ€§èƒ½ä½œç”¨çš„ä¾�æ�®å°±æ˜¯ï¼šé€šå¸¸è¯»é”�的获å�–ç´§éš�ç�€å°±æ˜¯è¯¥è¯»é”�的释放。我这里å�¯èƒ½è¡¨è¾¾ä¸�太好,但是大家应该是懂的å�§ã€‚
-5. **firstReader** 和 **firstReaderHoldCount** 有什么用?其实也没什么用,但是它也能æ��示性能。将"第一个"获å�–读é”�的线程记录在 firstReader 属性ä¸ï¼Œè¿™é‡Œçš„**第一个**ä¸�是全局的概念,ç‰è¿™ä¸ª firstReader 当å‰�代表的线程释放掉读é”�以å�Žï¼Œä¼šæœ‰å�Žæ�¥çš„线程å� 用这个属性的。**firstReader å’Œ firstReaderHoldCount 使得在读é”�ä¸�产生竞争的情况下,记录读é”�é‡�入次数é�žå¸¸æ–¹ä¾¿å¿«é€Ÿ**
+3. æ¯�个线程都需è¦�维护自己的 HoldCounter,记录该线程获å�–的读é”�æ¬¡æ•°ï¼Œè¿™æ ·æ‰�能知é�“到底是ä¸�是读é”�é‡�入,用 ThreadLocal 属性**readHolds**维护
+4. **cachedHoldCounter**有什么用?其实没什么用,但能æ��示性能。将最å�Žä¸€æ¬¡èŽ·å�–读é”�的线程的 HoldCounter 缓å˜åˆ°è¿™é‡Œï¼Œè¿™æ ·æ¯”使用 ThreadLocal 性能è¦�å¥½ä¸€äº›ï¼Œå› ä¸º ThreadLocal 内部是基于 map æ�¥æŸ¥è¯¢çš„。但是 cachedHoldCounter 这一个属性毕竟å�ªèƒ½ç¼“å˜ä¸€ä¸ªçº¿ç¨‹ï¼Œæ‰€ä»¥å®ƒè¦�èµ·æ��å�‡æ€§èƒ½ä½œç”¨çš„ä¾�æ�®å°±æ˜¯ï¼šé€šå¸¸è¯»é”�的获å�–ç´§éš�ç�€å°±æ˜¯è¯¥è¯»é”�的释放。我这里å�¯èƒ½è¡¨è¾¾ä¸�太好,但是大家应该是懂的å�§ã€‚
+5. **firstReader**å’Œ**firstReaderHoldCount**有什么用?其实也没什么用,但是它也能æ��示性能。将"第一个"获å�–读é”�的线程记录在 firstReader 属性ä¸ï¼Œè¿™é‡Œçš„**第一个**ä¸�是全局的概念,ç‰è¿™ä¸ª firstReader 当å‰�代表的线程释放掉读é”�以å�Žï¼Œä¼šæœ‰å�Žæ�¥çš„线程å� 用这个属性的。**firstReader å’Œ firstReaderHoldCount 使得在读é”�ä¸�产生竞争的情况下,记录读é”�é‡�入次数é�žå¸¸æ–¹ä¾¿å¿«é€Ÿ**
6. 如果一个线程使用了 firstReader,那么它就ä¸�需è¦�å� 用 cachedHoldCounter
7. 个人认为,读写é”�æº�ç �䏿œ€è®©åˆ�å¦è€…å¤´ç–¼çš„å°±æ˜¯è¿™å‡ ä¸ªç”¨äºŽæ��å�‡æ€§èƒ½çš„属性了,使得大家看得云里雾里的。主è¦�æ˜¯å› ä¸º ThreadLocal 内部是通过一个 ThreadLocalMap æ�¥æ“�ä½œçš„ï¼Œä¼šå¢žåŠ æ£€ç´¢æ—¶é—´ã€‚è€Œå¾ˆå¤šåœºæ™¯ä¸‹ï¼Œæ‰§è¡Œ unlock 的线程往往就是刚刚最å�Žä¸€æ¬¡æ‰§è¡Œ lock 的线程,ä¸é—´å�¯èƒ½æ²¡æœ‰å…¶ä»–线程进行 lock。还有就是很多ä¸�怎么会å�‘生读é”�竞争的场景。
@@ -498,7 +498,7 @@ protected final boolean tryAcquire(int acquires) {
}
```
-下é�¢çœ‹ä¸€çœ¼Â **writerShouldBlock()** 的判定,然å�Žä½ å†�回去看一篇写é”�获å�–过程。
+下é�¢çœ‹ä¸€çœ¼**writerShouldBlock()**的判定,然å�Žä½ å†�回去看一篇写é”�获å�–过程。
```
static final class NonfairSync extends Sync {
diff --git "a/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232\345\271\266\345\217\221\344\270\211\345\244\247\351\227\256\351\242\230\344\270\216volatile\345\205\263\351\224\256\345\255\227\357\274\214CAS\346\223\215\344\275\234.md" "b/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232\345\271\266\345\217\221\344\270\211\345\244\247\351\227\256\351\242\230\344\270\216volatile\345\205\263\351\224\256\345\255\227\357\274\214CAS\346\223\215\344\275\234.md"
index 0abdbe8..60a9c3e 100644
--- "a/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232\345\271\266\345\217\221\344\270\211\345\244\247\351\227\256\351\242\230\344\270\216volatile\345\205\263\351\224\256\345\255\227\357\274\214CAS\346\223\215\344\275\234.md"
+++ "b/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232\345\271\266\345\217\221\344\270\211\345\244\247\351\227\256\351\242\230\344\270\216volatile\345\205\263\351\224\256\345\255\227\357\274\214CAS\346\223\215\344\275\234.md"
@@ -9,7 +9,6 @@
* [volatile写-读的内å˜è¯ä¹‰](#volatile写-读的内å˜è¯ä¹‰)
* [volatile内å˜è¯ä¹‰çš„实现](#volatile内å˜è¯ä¹‰çš„实现)
* [JSR-133为什么è¦�增强volatile的内å˜è¯ä¹‰](#jsr-133为什么è¦�增强volatile的内å˜è¯ä¹‰)
- * [](#)
* [引言](#引言)
* [术è¯å®šä¹‰](#术è¯å®šä¹‰)
* [3 处ç�†å™¨å¦‚何实现原å�æ“�作](#3-处ç�†å™¨å¦‚何实现原å�æ“�作)
diff --git "a/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232\346\267\261\345\205\245\347\220\206\350\247\243Java\345\206\205\345\255\230\346\250\241\345\236\213JMM.md" "b/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232\346\267\261\345\205\245\347\220\206\350\247\243Java\345\206\205\345\255\230\346\250\241\345\236\213JMM.md"
index 0856914..a9aad6e 100644
--- "a/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232\346\267\261\345\205\245\347\220\206\350\247\243Java\345\206\205\345\255\230\346\250\241\345\236\213JMM.md"
+++ "b/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232\346\267\261\345\205\245\347\220\206\350\247\243Java\345\206\205\345\255\230\346\250\241\345\236\213JMM.md"
@@ -176,7 +176,7 @@ Java è¯è¨€åœ¨é�µå¾ªå†…å˜æ¨¡åž‹çš„基础上推出了 JMM 规范,目的是解
我们知é�“,Java程åº�是需è¦�è¿�行在Java虚拟机上é�¢çš„,**Javaå†…å˜æ¨¡åž‹ï¼ˆJava Memory Model ,JMM)就是一ç§�符å�ˆå†…å˜æ¨¡åž‹è§„范的,å±�蔽了å�„ç§�硬件和æ“�作系统的访问差异的,ä¿�è¯�了Java程åº�在å�„ç§�å¹³å�°ä¸‹å¯¹å†…å˜çš„访问都能ä¿�è¯�效果一致的机制å�Šè§„范。**
-æ��到Javaå†…å˜æ¨¡åž‹ï¼Œä¸€èˆ¬æŒ‡çš„æ˜¯JDK 5 å¼€å§‹ä½¿ç”¨çš„æ–°çš„å†…å˜æ¨¡åž‹ï¼Œä¸»è¦�ç”±[JSR-133: JavaTM Memory Model and Thread Specification](http://www.cs.umd.edu/~pugh/java/memoryModel/jsr133.pdf) æ��述。感兴趣的å�¯ä»¥å�‚看下这份PDF文档([http://www.cs.umd.edu/~pugh/java/memoryModel/jsr133.pdf](http://www.cs.umd.edu/~pugh/java/memoryModel/jsr133.pdf))
+æ��到Javaå†…å˜æ¨¡åž‹ï¼Œä¸€èˆ¬æŒ‡çš„æ˜¯JDK 5 å¼€å§‹ä½¿ç”¨çš„æ–°çš„å†…å˜æ¨¡åž‹ï¼Œä¸»è¦�ç”±[JSR-133: JavaTM Memory Model and Thread Specification](http://www.cs.umd.edu/~pugh/java/memoryModel/jsr133.pdf)æ��述。感兴趣的å�¯ä»¥å�‚看下这份PDF文档([http://www.cs.umd.edu/~pugh/java/memoryModel/jsr133.pdf](http://www.cs.umd.edu/~pugh/java/memoryModel/jsr133.pdf))
Javaå†…å˜æ¨¡åž‹è§„定了所有的å�˜é‡�都å˜å‚¨åœ¨ä¸»å†…å˜ä¸ï¼Œæ¯�æ�¡çº¿ç¨‹è¿˜æœ‰è‡ªå·±çš„工作内å˜ï¼Œçº¿ç¨‹çš„工作内å˜ä¸ä¿�å˜äº†è¯¥çº¿ç¨‹ä¸æ˜¯ç”¨åˆ°çš„å�˜é‡�的主内å˜å‰¯æœ¬æ‹·è´�,线程对å�˜é‡�的所有æ“�作都必须在工作内å˜ä¸è¿›è¡Œï¼Œè€Œä¸�能直接读写主内å˜ã€‚ä¸�å�Œçš„çº¿ç¨‹ä¹‹é—´ä¹Ÿæ— æ³•ç›´æŽ¥è®¿é—®å¯¹æ–¹å·¥ä½œå†…å˜ä¸çš„å�˜é‡�,线程间å�˜é‡�çš„ä¼ é€’å�‡éœ€è¦�自己的工作内å˜å’Œä¸»å˜ä¹‹é—´è¿›è¡Œæ•°æ�®å�Œæ¥è¿›è¡Œã€‚
diff --git "a/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232\346\267\261\345\272\246\350\247\243\350\257\273Java\347\272\277\347\250\213\346\261\240\350\256\276\350\256\241\346\200\235\346\203\263\345\217\212\346\272\220\347\240\201\345\256\236\347\216\260.md" "b/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232\346\267\261\345\272\246\350\247\243\350\257\273Java\347\272\277\347\250\213\346\261\240\350\256\276\350\256\241\346\200\235\346\203\263\345\217\212\346\272\220\347\240\201\345\256\236\347\216\260.md"
index b318132..aa025c9 100644
--- "a/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232\346\267\261\345\272\246\350\247\243\350\257\273Java\347\272\277\347\250\213\346\261\240\350\256\276\350\256\241\346\200\235\346\203\263\345\217\212\346\272\220\347\240\201\345\256\236\347\216\260.md"
+++ "b/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232\346\267\261\345\272\246\350\247\243\350\257\273Java\347\272\277\347\250\213\346\261\240\350\256\276\350\256\241\346\200\235\346\203\263\345\217\212\346\272\220\347\240\201\345\256\236\347\216\260.md"
@@ -92,7 +92,7 @@ public interface Executor {
}
```
-我们å�¯ä»¥çœ‹åˆ° Executor 接å�£é�žå¸¸ç®€å�•,就一个 `void execute(Runnable command)` 方法,代表æ��交一个任务。为了让大家ç�†è§£ java çº¿ç¨‹æ± çš„æ•´ä¸ªè®¾è®¡æ–¹æ¡ˆï¼Œæˆ‘ä¼šæŒ‰ç…§ Doug Lea 的设计æ€�è·¯æ�¥å¤šè¯´ä¸€äº›ç›¸å…³çš„东西。
+我们å�¯ä»¥çœ‹åˆ° Executor 接å�£é�žå¸¸ç®€å�•,就一个`void execute(Runnable command)`方法,代表æ��交一个任务。为了让大家ç�†è§£ java çº¿ç¨‹æ± çš„æ•´ä¸ªè®¾è®¡æ–¹æ¡ˆï¼Œæˆ‘ä¼šæŒ‰ç…§ Doug Lea 的设计æ€�è·¯æ�¥å¤šè¯´ä¸€äº›ç›¸å…³çš„东西。
我们ç»�å¸¸è¿™æ ·å�¯åŠ¨ä¸€ä¸ªçº¿ç¨‹ï¼š
@@ -171,7 +171,7 @@ class SerialExecutor implements Executor {
}
```
-当然了,Executor 这个接å�£å�ªæœ‰æ��交任务的功能,太简å�•了,我们想è¦�更丰富的功能,比如我们想知é�“执行结果ã€�我们想知é�“当å‰�çº¿ç¨‹æ± æœ‰å¤šå°‘ä¸ªçº¿ç¨‹æ´»ç�€ã€�å·²ç»�完æˆ�了多少任务ç‰ç‰ï¼Œè¿™äº›éƒ½æ˜¯è¿™ä¸ªæŽ¥å�£çš„ä¸�足的地方。接下æ�¥æˆ‘们è¦�介ç»�的是继承自 `Executor` 接å�£çš„ `ExecutorService` 接å�£ï¼Œè¿™ä¸ªæŽ¥å�£æ��供了比较丰富的功能,也是我们最常使用到的接å�£ã€‚
+当然了,Executor 这个接å�£å�ªæœ‰æ��交任务的功能,太简å�•了,我们想è¦�更丰富的功能,比如我们想知é�“执行结果ã€�我们想知é�“当å‰�çº¿ç¨‹æ± æœ‰å¤šå°‘ä¸ªçº¿ç¨‹æ´»ç�€ã€�å·²ç»�完æˆ�了多少任务ç‰ç‰ï¼Œè¿™äº›éƒ½æ˜¯è¿™ä¸ªæŽ¥å�£çš„ä¸�足的地方。接下æ�¥æˆ‘们è¦�介ç»�的是继承自`Executor`接å�£çš„`ExecutorService`接å�£ï¼Œè¿™ä¸ªæŽ¥å�£æ��供了比较丰富的功能,也是我们最常使用到的接å�£ã€‚
## ExecutorService
@@ -277,13 +277,13 @@ public interface Callable {
在这里,就ä¸�展开说 FutureTask ç±»äº†ï¼Œå› ä¸ºæœ¬æ–‡ç¯‡å¹…æœ¬æ�¥å°±å¤Ÿå¤§äº†ï¼Œè¿™é‡Œæˆ‘们需è¦�知é�“怎么用就行了。
-下�,我们�看看 `ExecutorService` 的抽象实现 `AbstractExecutorService` 。
+下�,我们�看看`ExecutorService`的抽象实现`AbstractExecutorService`。
## AbstractExecutorService
AbstractExecutorService 抽象类派生自 ExecutorService 接å�£ï¼Œç„¶å�Žåœ¨å…¶åŸºç¡€ä¸Šå®žçŽ°äº†å‡ ä¸ªå®žç”¨çš„æ–¹æ³•ï¼Œè¿™äº›æ–¹æ³•æ��供给å�类进行调用。
-这个抽象类实现了 invokeAny 方法和 invokeAll 方法,这里的两个 newTaskFor 方法也比较有用,用于将任务包装æˆ� FutureTask。定义于最上层接å�£ Executorä¸çš„ `void execute(Runnable command)` 由于ä¸�需è¦�获å�–结果,ä¸�会进行 FutureTask 的包装。
+这个抽象类实现了 invokeAny 方法和 invokeAll 方法,这里的两个 newTaskFor 方法也比较有用,用于将任务包装æˆ� FutureTask。定义于最上层接å�£ Executorä¸çš„`void execute(Runnable command)`由于ä¸�需è¦�获å�–结果,ä¸�会进行 FutureTask 的包装。
> 需�获�结果(FutureTask),用 submit 方法,�需�获�结果,�以用 execute 方法。
@@ -600,7 +600,7 @@ public Future submit(Callable task) {
当然,上图没有考虑队列是å�¦æœ‰ç•Œï¼Œæ��交任务时队列满了怎么办?什么情况下会创建新的线程?æ��äº¤ä»»åŠ¡æ—¶çº¿ç¨‹æ± æ»¡äº†æ€Žä¹ˆåŠžï¼Ÿç©ºé—²çº¿ç¨‹æ€Žä¹ˆå…³æŽ‰ï¼Ÿè¿™äº›é—®é¢˜ä¸‹é�¢æˆ‘们会一一解决。
-我们ç»�常会使用 `Executors` 这个工具类æ�¥å¿«é€Ÿæž„é€ ä¸€ä¸ªçº¿ç¨‹æ± ï¼Œå¯¹äºŽåˆ�å¦è€…而言,这ç§�工具类是很有用的,开å�‘者ä¸�需è¦�关注太多的细节,å�ªè¦�知é�“自己需è¦�ä¸€ä¸ªçº¿ç¨‹æ± ï¼Œä»…ä»…æ��供必需的å�‚æ•°å°±å�¯ä»¥äº†ï¼Œå…¶ä»–å�‚数都采用作者æ��供的默认值。
+我们ç»�常会使用`Executors`这个工具类æ�¥å¿«é€Ÿæž„é€ ä¸€ä¸ªçº¿ç¨‹æ± ï¼Œå¯¹äºŽåˆ�å¦è€…而言,这ç§�工具类是很有用的,开å�‘者ä¸�需è¦�关注太多的细节,å�ªè¦�知é�“自己需è¦�ä¸€ä¸ªçº¿ç¨‹æ± ï¼Œä»…ä»…æ��供必需的å�‚æ•°å°±å�¯ä»¥äº†ï¼Œå…¶ä»–å�‚数都采用作者æ��供的默认值。
```
public static ExecutorService newFixedThreadPool(int nThreads) {
@@ -659,7 +659,7 @@ public static ExecutorService newCachedThreadPool() {
* keepAliveTime
- > 空闲线程的ä¿�活时间,如果æŸ�线程的空闲时间超过这个值都没有任务给它å�šï¼Œé‚£ä¹ˆå�¯ä»¥è¢«å…³é—了。注æ„�这个值并ä¸�ä¼šå¯¹æ‰€æœ‰çº¿ç¨‹èµ·ä½œç”¨ï¼Œå¦‚æžœçº¿ç¨‹æ± ä¸çš„线程数少于ç‰äºŽæ ¸å¿ƒçº¿ç¨‹æ•° corePoolSize,那么这些线程ä¸�ä¼šå› ä¸ºç©ºé—²å¤ªé•¿æ—¶é—´è€Œè¢«å…³é—,当然,也å�¯ä»¥é€šè¿‡è°ƒç”¨Â `allowCoreThreadTimeOut(true)`ä½¿æ ¸å¿ƒçº¿ç¨‹æ•°å†…çš„çº¿ç¨‹ä¹Ÿå�¯ä»¥è¢«å›žæ”¶ã€‚
+ > 空闲线程的ä¿�活时间,如果æŸ�线程的空闲时间超过这个值都没有任务给它å�šï¼Œé‚£ä¹ˆå�¯ä»¥è¢«å…³é—了。注æ„�这个值并ä¸�ä¼šå¯¹æ‰€æœ‰çº¿ç¨‹èµ·ä½œç”¨ï¼Œå¦‚æžœçº¿ç¨‹æ± ä¸çš„线程数少于ç‰äºŽæ ¸å¿ƒçº¿ç¨‹æ•° corePoolSize,那么这些线程ä¸�ä¼šå› ä¸ºç©ºé—²å¤ªé•¿æ—¶é—´è€Œè¢«å…³é—,当然,也å�¯ä»¥é€šè¿‡è°ƒç”¨`allowCoreThreadTimeOut(true)`ä½¿æ ¸å¿ƒçº¿ç¨‹æ•°å†…çš„çº¿ç¨‹ä¹Ÿå�¯ä»¥è¢«å›žæ”¶ã€‚
* threadFactory
diff --git "a/docs/java/concurrency/Java\345\271\266\345\217\221\347\274\226\347\250\213\345\255\246\344\271\240\346\200\273\347\273\223.md" "b/docs/java/concurrency/Java\345\271\266\345\217\221\347\274\226\347\250\213\345\255\246\344\271\240\346\200\273\347\273\223.md"
index f5ab376..98f3e38 100644
--- "a/docs/java/concurrency/Java\345\271\266\345\217\221\347\274\226\347\250\213\345\255\246\344\271\240\346\200\273\347\273\223.md"
+++ "b/docs/java/concurrency/Java\345\271\266\345\217\221\347\274\226\347\250\213\345\255\246\344\271\240\346\200\273\347\273\223.md"
@@ -9,7 +9,6 @@
* [Lockç±»](#lockç±»)
* [AQS](#aqs)
* [�Lock和Conditon](#�lock和conditon)
- * [](#)
* [并�工具类](#并�工具类)
* [原å�æ•°æ�®ç±»åž‹](#原å�æ•°æ�®ç±»åž‹)
* [å�Œæ¥å®¹å™¨](#å�Œæ¥å®¹å™¨)
diff --git "a/docs/java/design-parttern/\345\210\235\346\216\242Java\350\256\276\350\256\241\346\250\241\345\274\217\357\274\232JDK\344\270\255\347\232\204\350\256\276\350\256\241\346\250\241\345\274\217.md" "b/docs/java/design-parttern/\345\210\235\346\216\242Java\350\256\276\350\256\241\346\250\241\345\274\217\357\274\232JDK\344\270\255\347\232\204\350\256\276\350\256\241\346\250\241\345\274\217.md"
index dc643c3..61748b1 100644
--- "a/docs/java/design-parttern/\345\210\235\346\216\242Java\350\256\276\350\256\241\346\250\241\345\274\217\357\274\232JDK\344\270\255\347\232\204\350\256\276\350\256\241\346\250\241\345\274\217.md"
+++ "b/docs/java/design-parttern/\345\210\235\346\216\242Java\350\256\276\350\256\241\346\250\241\345\274\217\357\274\232JDK\344\270\255\347\232\204\350\256\276\350\256\241\346\250\241\345\274\217.md"
@@ -1,3 +1,34 @@
+# Table of Contents
+
+ * [**一,结构型模�**](#一,结构型模�)
+ * [**1,适�器模�**](#1,适�器模�)
+ * [**2,桥接模�**](#2,桥接模�)
+ * [**3,组�模�**](#3,组�模�)
+ * [**4,装饰者模�**](#4,装饰者模�)
+ * [**5,门�模�**](#5,门�模�)
+ * [**6,享元模�**](#6,享元模�)
+ * [**7,代�模�**](#7,代�模�)
+ * [**二,创建模�**](#二,创建模�)
+ * [**1,抽象工厂模�**](#1,抽象工厂模�)
+ * [**2ï¼Œå»ºé€ æ¨¡å¼�(Builder)**](#2ï¼Œå»ºé€ æ¨¡å¼�builder)
+ * [**3,工厂方法**](#3,工厂方法)
+ * [**4,原型模�**](#4,原型模�)
+ * [**5,�例模�**](#5,�例模�)
+ * [**三,行为模�**](#三,行为模�)
+ * [**1,责任链模�**](#1,责任链模�)
+ * [**2,命令模�**](#2,命令模�)
+ * [**3,解释器模�**](#3,解释器模�)
+ * [**4,è¿ä»£å™¨æ¨¡å¼�**](#4,è¿ä»£å™¨æ¨¡å¼�)
+ * [**5,ä¸ä»‹è€…模å¼�**](#5,ä¸ä»‹è€…模å¼�)
+ * [**6,备忘录模�**](#6,备忘录模�)
+ * [**7,空对象模�**](#7,空对象模�)
+ * [**8,观察者模�**](#8,观察者模�)
+ * [**9,状�模�**](#9,状�模�)
+ * [**10,ç–略模å¼�**](#10,ç–略模å¼�)
+ * [**11,模�方法模�**](#11,模�方法模�)
+ * [**12,访问者模�**](#12,访问者模�)
+
+
æœ¬ç³»åˆ—æ–‡ç« å°†æ•´ç�†åˆ°æˆ‘在GitHub上的《Javaé�¢è¯•指å�—》仓库,更多精彩内容请到我的仓库里查看
@@ -12,9 +43,9 @@
本文转自https://www.cnblogs.com/LinkinPark/p/5233075.html
-**一,结构型模�**
+## **一,结构型模�**
-**1,适�器模�**
+### **1,适�器模�**
**用�把一个接�转化��一个接�**
@@ -30,7 +61,7 @@
>
> **javax.xml.bind.annotation.adapters.XmlAdapter#unmarshal()**
-**2,桥接模�**
+### **2,桥接模�**
**这个模å¼�将抽象和抽象æ“�ä½œçš„å®žçŽ°è¿›è¡Œäº†è§£è€¦ï¼Œè¿™æ ·ä½¿å¾—æŠ½è±¡å’Œå®žçŽ°å�¯ä»¥ç‹¬ç«‹åœ°å�˜åŒ–**
@@ -38,7 +69,7 @@
>
> **JDBC**
-**3,组�模�**
+### **3,组�模�**
**使得客户端看æ�¥å�•个对象和对象的组å�ˆæ˜¯å�Œç‰çš„。æ�¢å�¥è¯�说,æŸ�个类型的方法å�Œæ—¶ä¹ŸæŽ¥å�—自身类型作为å�‚æ•°**
@@ -52,7 +83,7 @@
>
> **java.util.Set#addAll(Collection)**
-**4,装饰者模�**
+### **4,装饰者模�**
**动æ€�çš„ç»™ä¸€ä¸ªå¯¹è±¡é™„åŠ é¢�外的功能,这也是å�类的一ç§�替代方å¼�。å�¯ä»¥çœ‹åˆ°ï¼Œåœ¨åˆ›å»ºä¸€ä¸ªç±»åž‹çš„æ—¶å€™ï¼Œå�Œæ—¶ä¹Ÿä¼ å…¥å�Œä¸€ç±»åž‹çš„对象。这在JDK里éš�处å�¯è§�ï¼Œä½ ä¼šå�‘çŽ°å®ƒæ— å¤„ä¸�在,所以下é�¢è¿™ä¸ªåˆ—表å�ªæ˜¯ä¸€å°�部分**
@@ -64,9 +95,9 @@
>
> **java.util.zip.ZipOutputStream(OutputStream)**
>
-> **java.util.Collections#checked**
+> **java.util.Collections#checked**
-**5,门�模�**
+### **5,门�模�**
**给一组组件,接å�£ï¼ŒæŠ½è±¡ï¼Œæˆ–者å�系统æ��供一个简å�•的接å�£**
@@ -74,7 +105,7 @@
>
> **javax.faces.webapp.FacesServlet**
-**6,享元模�**
+### **6,享元模�**
**ä½¿ç”¨ç¼“å˜æ�¥åŠ é€Ÿå¤§é‡�å°�对象的访问时间**
@@ -86,7 +117,7 @@
>
> **java.lang.Character#valueOf(char)**
-**7,代�模�**
+### **7,代�模�**
**代�模�是用一个简�的对象�代替一个��的或者创建耗时的对象。**
@@ -94,11 +125,11 @@
>
> **RMI**
-**Â **
+****
-**二,创建模�**
+## **二,创建模�**
-**1,抽象工厂模�**
+### **1,抽象工厂模�**
**抽象工厂模å¼�æ��供了一个å��è®®æ�¥ç”Ÿæˆ�一系列的相关或者独立的对象,而ä¸�用指定具体对象的类型。它使得应用程åº�能够和使用的框架的具体实现进行解耦。这在JDK或者许多框架比如Springä¸éƒ½éš�处å�¯è§�。它们也很容易识别,一个创建新对象的方法,返回的å�´æ˜¯æŽ¥å�£æˆ–者抽象类的,就是抽象工厂模å¼�了**
@@ -118,7 +149,7 @@
>
> **javax.xml.transform.TransformerFactory#newInstance()**
-**2ï¼Œå»ºé€ æ¨¡å¼�(Builder)**
+### **2ï¼Œå»ºé€ æ¨¡å¼�(Builder)**
**定义了一个新的类æ�¥æž„建å�¦ä¸€ä¸ªç±»çš„实例,以简化å¤�æ�‚å¯¹è±¡çš„åˆ›å»ºã€‚å»ºé€ æ¨¡å¼�通常也使用方法链接æ�¥å®žçް**
@@ -130,7 +161,7 @@
>
> **javax.swing.GroupLayout.Group#addComponent()**
-**3,工厂方法**
+### **3,工厂方法**
**就是一个返回具体对象的方法**
@@ -148,7 +179,7 @@
>
> **java.lang.Class#forName()**
-**4,原型模�**
+### **4,原型模�**
**使得类的实例能够生æˆ�自身的拷è´�。如果创建一个对象的实例é�žå¸¸å¤�æ�‚且耗时时,就å�¯ä»¥ä½¿ç”¨è¿™ç§�模å¼�,而ä¸�é‡�æ–°åˆ›å»ºä¸€ä¸ªæ–°çš„å®žä¾‹ï¼Œä½ å�¯ä»¥æ‹·è´�一个对象并直接修改它**
@@ -156,7 +187,7 @@
>
> **java.lang.Cloneable**
-**5,�例模�**
+### **5,�例模�**
**用æ�¥ç¡®ä¿�ç±»å�ªæœ‰ä¸€ä¸ªå®žä¾‹ã€‚Joshua Bloch在Effetive Javaä¸å»ºè®®åˆ°ï¼Œè¿˜æœ‰ä¸€ç§�方法就是使用枚举**
@@ -168,11 +199,11 @@
>
> **java.awt.Desktop#getDesktop()**
-**Â **
+****
-**三,行为模�**
+## **三,行为模�**
-**1,责任链模�**
+### **1,责任链模�**
**é€šè¿‡æŠŠè¯·æ±‚ä»Žä¸€ä¸ªå¯¹è±¡ä¼ é€’åˆ°é“¾æ�¡ä¸ä¸‹ä¸€ä¸ªå¯¹è±¡çš„æ–¹å¼�,直到请求被处ç�†å®Œæ¯•,以实现对象间的解耦**
@@ -180,7 +211,7 @@
>
> **javax.servlet.Filter#doFilter()**
-**2,命令模�**
+### **2,命令模�**
**å°†æ“�作å°�装到对象内,以便å˜å‚¨ï¼Œä¼ 递和返回**
@@ -188,7 +219,7 @@
>
> **javax.swing.Action**
-**3,解释器模�**
+### **3,解释器模�**
**这个模å¼�通常定义了一个è¯è¨€çš„è¯æ³•,然å�Žè§£æž�ç›¸åº”è¯æ³•çš„è¯å�¥**
@@ -198,7 +229,7 @@
>
> **java.text.Format**
-**4,è¿ä»£å™¨æ¨¡å¼�**
+### **4,è¿ä»£å™¨æ¨¡å¼�**
**æ��供一个一致的方法æ�¥é¡ºåº�访问集å�ˆä¸çš„对象,这个方法与底层的集å�ˆçš„å…·ä½“å®žçŽ°æ— å…³**
@@ -206,7 +237,7 @@
>
> **java.util.Enumeration**
-**5,ä¸ä»‹è€…模å¼�**
+### **5,ä¸ä»‹è€…模å¼�**
**通过使用一个ä¸é—´å¯¹è±¡æ�¥è¿›è¡Œæ¶ˆæ�¯åˆ†å�‘以å�Šå‡�少类之间的直接ä¾�èµ–**
@@ -218,7 +249,7 @@
>
> **java.lang.reflect.Method#invoke()**
-**6,备忘录模�**
+### **6,备忘录模�**
**生�对象状�的一个快照,以便对象�以��原始状�而�用暴露自身的内容。Date对象通过自身内部的一个long值�实现备忘录模�**
@@ -226,7 +257,7 @@
>
> **java.io.Serializable**
-**7,空对象模�**
+### **7,空对象模�**
**这个模å¼�é€šè¿‡ä¸€ä¸ªæ— æ„�义的对象æ�¥ä»£æ›¿æ²¡æœ‰å¯¹è±¡è¿™ä¸ªçжæ€�ã€‚å®ƒä½¿å¾—ä½ ä¸�用é¢�外对空对象进行处ç�†**
@@ -236,7 +267,7 @@
>
> **java.util.Collections#emptySet()**
-**8,观察者模�**
+### **8,观察者模�**
**它使得一个对象�以�活的将消���给感兴趣的对象**
@@ -248,7 +279,7 @@
>
> **javax.faces.event.PhaseListener**
-**9,状�模�**
+### **9,状�模�**
**通过改å�˜å¯¹è±¡å†…部的状æ€�ï¼Œä½¿å¾—ä½ å�¯ä»¥åœ¨è¿�行时动æ€�改å�˜ä¸€ä¸ªå¯¹è±¡çš„行为**
@@ -256,7 +287,7 @@
>
> **javax.faces.lifecycle.LifeCycle#execute()**
-**10,ç–略模å¼�**
+### **10,ç–略模å¼�**
**使用这个模å¼�æ�¥å°†ä¸€ç»„算法å°�装æˆ�ä¸€ç³»åˆ—å¯¹è±¡ã€‚é€šè¿‡ä¼ é€’è¿™äº›å¯¹è±¡å�¯ä»¥ç�µæ´»çš„æ”¹å�˜ç¨‹åº�的功能**
@@ -266,7 +297,7 @@
>
> **javax.servlet.Filter#doFilter()**
-**11,模�方法模�**
+### **11,模�方法模�**
**让å�ç±»å�¯ä»¥é‡�写方法的一部分,而ä¸�是整个é‡�å†™ï¼Œä½ å�¯ä»¥æŽ§åˆ¶å�类需è¦�é‡�写那些æ“�作**
@@ -278,7 +309,7 @@
>
> **java.util.AbstractList#indexOf()**
-**12,访问者模�**
+### **12,访问者模�**
**æ��供一个方便的å�¯ç»´æŠ¤çš„æ–¹å¼�æ�¥æ“�ä½œä¸€ç»„å¯¹è±¡ã€‚å®ƒä½¿å¾—ä½ åœ¨ä¸�改å�˜æ“�作的对象å‰�æ��下,å�¯ä»¥ä¿®æ”¹æˆ–者扩展对象的行为**
diff --git "a/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232GC\350\260\203\344\274\230\346\200\235\350\267\257\344\270\216\345\270\270\347\224\250\345\267\245\345\205\267.md" "b/docs/java/jvm/temp/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232GC\350\260\203\344\274\230\346\200\235\350\267\257\344\270\216\345\270\270\347\224\250\345\267\245\345\205\267.md"
similarity index 98%
rename from "docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232GC\350\260\203\344\274\230\346\200\235\350\267\257\344\270\216\345\270\270\347\224\250\345\267\245\345\205\267.md"
rename to "docs/java/jvm/temp/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232GC\350\260\203\344\274\230\346\200\235\350\267\257\344\270\216\345\270\270\347\224\250\345\267\245\345\205\267.md"
index 341f675..30d3350 100644
--- "a/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232GC\350\260\203\344\274\230\346\200\235\350\267\257\344\270\216\345\270\270\347\224\250\345\267\245\345\205\267.md"
+++ "b/docs/java/jvm/temp/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232GC\350\260\203\344\274\230\346\200\235\350\267\257\344\270\216\345\270\270\347\224\250\345\267\245\345\205\267.md"
@@ -1,4 +1,23 @@
-# 目录
+# Table of Contents
+
+* [æ ¸å¿ƒæ¦‚å¿µ(Core Concepts)](#æ ¸å¿ƒæ¦‚å¿µcore-concepts)
+ * [Latency(延迟)](#latency延迟)
+ * [Throughput(���)](#throughput���)
+ * [Capacity(系统容�)](#capacity系统容�)
+* [相关示例](#相关示例)
+ * [Tuning for Latency(è°ƒä¼˜å»¶è¿ŸæŒ‡æ ‡)](#tuning-for-latencyè°ƒä¼˜å»¶è¿ŸæŒ‡æ ‡)
+ * [Tuning for Throughput(���调优)](#tuning-for-throughput���调优)
+ * [Tuning for Capacity(调优系统容�)](#tuning-for-capacity调优系统容�)
+ * [6\. GC 调优(工具篇) - GC�考手册](#6-gc-调优工具篇---gc�考手册)
+ * [JMX API](#jmx-api)
+ * [JVisualVM](#jvisualvm)
+ * [jstat](#jstat)
+ * [GC日志(GC logs)](#gc日志gc-logs)
+ * [GCViewer](#gcviewer)
+ * [分�器(Profilers)](#分�器profilers)
+ * [hprof](#hprof)
+ * [Java VisualVM](#java-visualvm)
+ * [AProf](#aprof)
* [å�‚è€ƒæ–‡ç« ](#å�‚è€ƒæ–‡ç« )
@@ -18,8 +37,6 @@
-## 5\. GC 调优(基础篇) - GC�考手册
-
> **说明**:
>
> **Capacity**: 性能,能力,系统容é‡�; æ–‡ä¸ç¿»è¯‘为â€�**系统容é‡�**“; æ„�为硬件é…�置。
diff --git "a/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232JVM\345\270\270\347\224\250\345\217\202\346\225\260\344\273\245\345\217\212\350\260\203\344\274\230\345\256\236\350\267\265.md" "b/docs/java/jvm/temp/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232JVM\345\270\270\347\224\250\345\217\202\346\225\260\344\273\245\345\217\212\350\260\203\344\274\230\345\256\236\350\267\265.md"
similarity index 98%
rename from "docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232JVM\345\270\270\347\224\250\345\217\202\346\225\260\344\273\245\345\217\212\350\260\203\344\274\230\345\256\236\350\267\265.md"
rename to "docs/java/jvm/temp/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232JVM\345\270\270\347\224\250\345\217\202\346\225\260\344\273\245\345\217\212\350\260\203\344\274\230\345\256\236\350\267\265.md"
index 987466f..5b7c03c 100644
--- "a/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232JVM\345\270\270\347\224\250\345\217\202\346\225\260\344\273\245\345\217\212\350\260\203\344\274\230\345\256\236\350\267\265.md"
+++ "b/docs/java/jvm/temp/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232JVM\345\270\270\347\224\250\345\217\202\346\225\260\344\273\245\345\217\212\350\260\203\344\274\230\345\256\236\350\267\265.md"
@@ -1,24 +1,21 @@
+# Table of Contents
+ * [JVM优化的必�性](#jvm优化的必�性)
+ * [JVM调优原则](#jvm调优原则)
+ * [JVM�行�数设置](#jvm�行�数设置)
+ * [JVM性能调优工具](#jvm性能调优工具)
+ * [常用调优ç–ç•¥](#常用调优ç–ç•¥)
+ * [å…ã€�JVM调优实例](#å…ã€�jvm调优实例)
+ * [七�一个具体的实战案例分�](#七�一个具体的实战案例分�)
+ * [�考资料](#�考资料)
+ * [å�‚è€ƒæ–‡ç« ](#å�‚è€ƒæ–‡ç« )
-
-
-**目录**
-
-一. JVM优化的必�性
-
-二. JVM调优原则
-三. JVM�行�数设置
-四. JVM性能调优工具
-五. 常用调优ç–ç•¥
-
-å…. JVM调优实例
-
-七. 一个具体的实战案例分�
+
-### JVM优化的必�性
+## JVM优化的必�性
**1.1: 项目上线å�Žï¼Œä»€ä¹ˆåŽŸå› ä½¿å¾—æˆ‘ä»¬éœ€è¦�进行jvm调优**
@@ -58,7 +55,7 @@ Jvmå †å†…å˜ä¸�能设置太大,å�¦åˆ™ä¼šå¯¼è‡´å¯»å�€åžƒåœ¾çš„æ—¶é—´è¿‡é•¿ï¼Œ
* 系统���与�应性能�高或下�。
-### JVM调优原则
+## JVM调优原则

@@ -254,13 +251,13 @@ TLAB空间一般ä¸�ä¼šå¤ªå¤§ï¼Œå½“å¤§å¯¹è±¡æ— æ³•åœ¨TLAB分é…�时,则会直接
-### 四.JVM性能调优工具
+## JVM性能调优工具
这个篇幅在这里就�过多介�了,�以�照:
深入ç�†è§£JVM虚拟机——Java虚拟机的监控å�Šè¯Šæ–工具大全
-### 五.常用调优ç–ç•¥
+## 常用调优ç–ç•¥
这里还是��一下,�时确定�进行JVM调优,也��陷入“知�障�,进行分�之�,�现�以通过优化程���性能,�然首选优化程�。
@@ -410,7 +407,7 @@ CPUå¤šæ ¸ï¼Œå…³æ³¨ç”¨æˆ·å�œé¡¿æ—¶é—´ï¼ŒJDK1.8å�Šä»¥ä¸Šï¼ŒJVMå�¯ç”¨å†…å˜6G以上
> XX:MaxDirectMemorySize
-### å…ã€�JVM调优实例
+## å…ã€�JVM调优实例
整�的一些JVM调优实例:
@@ -533,7 +530,7 @@ CPUå¤šæ ¸ï¼Œå…³æ³¨ç”¨æˆ·å�œé¡¿æ—¶é—´ï¼ŒJDK1.8å�Šä»¥ä¸Šï¼ŒJVMå�¯ç”¨å†…å˜6G以上
系统对外æ��ä¾›å�„ç§�è´¦å�·é‰´æ�ƒæœ�务,使用时å�‘现系统ç»�常æœ�务ä¸�å�¯ç”¨ï¼Œé€šè¿‡ Zabbix 的监控平å�°ç›‘控å�‘现系统频ç¹�å�‘生长时间 Full GC,且触å�‘æ—¶è€�å¹´ä»£çš„å †å†…å˜é€šå¸¸å¹¶æ²¡æœ‰å� 满,å�‘现原æ�¥æ˜¯ä¸šåС代ç �ä¸è°ƒç”¨äº†
-### 七�一个具体的实战案例分�
+## 七�一个具体的实战案例分�
**7.1 典型调优�数设置**
diff --git "a/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232JNDI\357\274\214OSGI\357\274\214Tomcat\347\261\273\345\212\240\350\275\275\345\231\250\345\256\236\347\216\260.md" "b/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232JNDI\357\274\214OSGI\357\274\214Tomcat\347\261\273\345\212\240\350\275\275\345\231\250\345\256\236\347\216\260.md"
index b48b79b..6c1b066 100644
--- "a/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232JNDI\357\274\214OSGI\357\274\214Tomcat\347\261\273\345\212\240\350\275\275\345\231\250\345\256\236\347\216\260.md"
+++ "b/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232JNDI\357\274\214OSGI\357\274\214Tomcat\347\261\273\345\212\240\350\275\275\345\231\250\345\256\236\347\216\260.md"
@@ -1,7 +1,7 @@
# 目录
* [æ‰“ç ´å�Œäº²å§”派模型](#æ‰“ç ´å�Œäº²å§”派模型)
* [JNDI](#jndi)
- * [[JNDI 的�解](https://yq.aliyun.com/go/articleRenderRedirect?url=https%3A%2F%2Fwww.cnblogs.com%2Fzhchoutai%2Fp%2F7389089.html)](#[jndi-的�解]httpsyqaliyuncomgoarticlerenderredirecturlhttps3a2f2fwwwcnblogscom2fzhchoutai2fp2f7389089html)
+ * [JNDI 的�解](#[jndi-的�解])
* [OSGI](#osgi)
* [1.如何æ£ç¡®çš„ç�†è§£å’Œè®¤è¯†OSGI技术?](#1如何æ£ç¡®çš„ç�†è§£å’Œè®¤è¯†osgi技术?)
* [Tomcatç±»åŠ è½½å™¨ä»¥å�Šåº”用间class隔离与共享](#tomcatç±»åŠ è½½å™¨ä»¥å�Šåº”用间class隔离与共享)
diff --git "a/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232JVM\345\236\203\345\234\276\345\233\236\346\224\266\345\237\272\346\234\254\345\216\237\347\220\206\345\222\214\347\256\227\346\263\225.md" "b/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232JVM\345\236\203\345\234\276\345\233\236\346\224\266\345\237\272\346\234\254\345\216\237\347\220\206\345\222\214\347\256\227\346\263\225.md"
index 65e4869..8048fb5 100644
--- "a/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232JVM\345\236\203\345\234\276\345\233\236\346\224\266\345\237\272\346\234\254\345\216\237\347\220\206\345\222\214\347\256\227\346\263\225.md"
+++ "b/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232JVM\345\236\203\345\234\276\345\233\236\346\224\266\345\237\272\346\234\254\345\216\237\347\220\206\345\222\214\347\256\227\346\263\225.md"
@@ -14,7 +14,7 @@
* [垃圾回收ä¸å®žä¾‹çš„终结](#垃圾回收ä¸å®žä¾‹çš„终结)
* [对象什么时候符�垃圾回收的�件?](#对象什么时候符�垃圾回收的�件?)
* [GC Scope 示例程�](#gc-scope-示例程�)
- * [[JVM GC算法](https://www.cnblogs.com/wupeixuan/p/8670341.html)](#[jvm-gc算法]httpswwwcnblogscomwupeixuanp8670341html)
+ * [JVM GC算法](#JVM GC算法)
* [JVM垃圾判定算法](#jvm垃圾判定算法)
* [引用计数算法(Reference Counting)](#引用计数算法reference-counting)
* [å�¯è¾¾æ€§åˆ†æž�ç®—æ³•ï¼ˆæ ¹æ�œç´¢ç®—法)](#å�¯è¾¾æ€§åˆ†æž�ç®—æ³•ï¼ˆæ ¹æ�œç´¢ç®—法))
diff --git "a/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232Java\347\232\204\347\274\226\350\257\221\346\234\237\344\274\230\345\214\226\344\270\216\350\277\220\350\241\214\346\234\237\344\274\230\345\214\226.md" "b/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232Java\347\232\204\347\274\226\350\257\221\346\234\237\344\274\230\345\214\226\344\270\216\350\277\220\350\241\214\346\234\237\344\274\230\345\214\226.md"
index 0a1c3ac..58b8166 100644
--- "a/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232Java\347\232\204\347\274\226\350\257\221\346\234\237\344\274\230\345\214\226\344\270\216\350\277\220\350\241\214\346\234\237\344\274\230\345\214\226.md"
+++ "b/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232Java\347\232\204\347\274\226\350\257\221\346\234\237\344\274\230\345\214\226\344\270\216\350\277\220\350\241\214\346\234\237\344\274\230\345\214\226.md"
@@ -1,5 +1,5 @@
# 目录
- * [[java编译期优化](https://www.cnblogs.com/LeonNew/p/6187411.html)](#[java编译期优化]httpswwwcnblogscomleonnewp6187411html)
+ * [java编译期优化](#[java编译期优化])
* [早期(编译期)优化](#早期(编译期)优化)
* [泛型与类型擦除](#泛型与类型擦除)
* [自动装箱�拆箱与�历循环](#自动装箱�拆箱与�历循环)
@@ -41,7 +41,7 @@ javaè¯è¨€çš„编译期其实是一段ä¸�确定的æ“�ä½œè¿‡ç¨‹ï¼Œå› ä¸ºå®ƒå�¯ä»¥
2.å�Žç«¯ç¼–译:把å—节ç �转å�˜ä¸ºæœºå™¨ç �
3.é�™æ€�æ��å‰�编译:直接把*.java文件编译æˆ�本地机器代ç �
从JDK1.3开始,虚拟机设计团队就把对性能的优化集ä¸åˆ°äº†å�Žç«¯çš„å�³æ—¶ç¼–译ä¸ï¼Œè¿™æ ·å�¯ä»¥è®©é‚£äº›ä¸�是由Javac产生的Class文件(如JRubyã€�Groovyç‰è¯è¨€çš„Class文件)也能享å�—到编译期优化所带æ�¥çš„好处
-**Javaä¸å�³æ—¶ç¼–译在è¿�行期的优化过程对于程åº�è¿�行æ�¥è¯´æ›´é‡�è¦�,而å‰�端编译期在编译期的优化过程对于程åº�ç¼–ç �æ�¥è¯´å…³ç³»æ›´åŠ å¯†åˆ‡Â Â Â Â **
+**Javaä¸å�³æ—¶ç¼–译在è¿�行期的优化过程对于程åº�è¿�行æ�¥è¯´æ›´é‡�è¦�,而å‰�端编译期在编译期的优化过程对于程åº�ç¼–ç �æ�¥è¯´å…³ç³»æ›´åŠ å¯†åˆ‡**
### 早期(编译期)优化
@@ -102,7 +102,7 @@ public static void main(String[] args) {
##### 解释器与编译器
-Java程åº�最åˆ�是通过解释器进行解释执行的,当程åº�需è¦�迅速å�¯åŠ¨å’Œæ‰§è¡Œæ—¶ï¼Œè§£é‡Šå™¨å�¯ä»¥é¦–å…ˆå�‘挥作用,çœ�去编译时间,立å�³æ‰§è¡Œï¼›å½“程åº�è¿�行å�Žï¼Œéš�ç�€æ—¶é—´çš„æŽ¨ç§»ï¼Œç¼–译期é€�æ¸�å�‘挥作用,把越æ�¥è¶Šå¤šçš„代ç �编译æˆ�本地代ç �,获得更高的执行效率。**解释执行节约内å˜ï¼Œç¼–译执行æ��å�‡æ•ˆçŽ‡ã€‚** å�Œæ—¶ï¼Œè§£é‡Šå™¨å�¯ä»¥ä½œä¸ºç¼–译器激进优化时的一个“逃生门â€�ï¼Œè®©ç¼–è¯‘å™¨æ ¹æ�®æ¦‚率选择一些大多数时候都能æ��å�‡è¿�行速度的优化手段,当激进优化的å�‡è®¾ä¸�æˆ�立,则通过逆优化退回到解释状æ€�ç»§ç»æ‰§è¡Œã€‚
+Java程åº�最åˆ�是通过解释器进行解释执行的,当程åº�需è¦�迅速å�¯åŠ¨å’Œæ‰§è¡Œæ—¶ï¼Œè§£é‡Šå™¨å�¯ä»¥é¦–å…ˆå�‘挥作用,çœ�去编译时间,立å�³æ‰§è¡Œï¼›å½“程åº�è¿�行å�Žï¼Œéš�ç�€æ—¶é—´çš„æŽ¨ç§»ï¼Œç¼–译期é€�æ¸�å�‘挥作用,把越æ�¥è¶Šå¤šçš„代ç �编译æˆ�本地代ç �,获得更高的执行效率。**解释执行节约内å˜ï¼Œç¼–译执行æ��å�‡æ•ˆçŽ‡ã€‚**å�Œæ—¶ï¼Œè§£é‡Šå™¨å�¯ä»¥ä½œä¸ºç¼–译器激进优化时的一个“逃生门â€�ï¼Œè®©ç¼–è¯‘å™¨æ ¹æ�®æ¦‚率选择一些大多数时候都能æ��å�‡è¿�行速度的优化手段,当激进优化的å�‡è®¾ä¸�æˆ�立,则通过逆优化退回到解释状æ€�ç»§ç»æ‰§è¡Œã€‚
HotSpot虚拟机ä¸å†…置了两个å�³æ—¶ç¼–译器,分别称为Client Compiler(C1编译器)å’ŒServer Compiler(C2编译器),默认采用解释器与其ä¸ä¸€ä¸ªç¼–译器直接é…�å�ˆçš„æ–¹å¼�工作,使用哪个编译器å�–决于虚拟机è¿�行的模å¼�,也å�¯ä»¥è‡ªå·±åŽ»æŒ‡å®šã€‚è‹¥å¼ºåˆ¶è™šæ‹Ÿæœºè¿�行与“解释模å¼�â€�,编译器完全ä¸�介入工作,若强制虚拟机è¿�行于“编译模å¼�â€�,则优先采用编译方å¼�执行程åº�,解释器ä»�ç„¶è¦�åœ¨ç¼–è¯‘æ— æ³•è¿›è¡Œçš„æƒ…å†µä¸‹ä»‹å…¥æ‰§è¡Œè¿‡ç¨‹ã€‚

diff --git "a/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232\345\206\215\350\260\210\345\233\233\347\247\215\345\274\225\347\224\250\345\217\212GC\345\256\236\350\267\265.md" "b/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232\345\206\215\350\260\210\345\233\233\347\247\215\345\274\225\347\224\250\345\217\212GC\345\256\236\350\267\265.md"
index 08cc449..cca62d4 100644
--- "a/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232\345\206\215\350\260\210\345\233\233\347\247\215\345\274\225\347\224\250\345\217\212GC\345\256\236\350\267\265.md"
+++ "b/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232\345\206\215\350\260\210\345\233\233\347\247\215\345\274\225\347\224\250\345\217\212GC\345\256\236\350\267\265.md"
@@ -32,7 +32,7 @@
## 一�背景
-Java的内å˜å›žæ”¶ä¸�需è¦�程åº�员负责,JVM会在必è¦�æ—¶å�¯åЍJava GC完æˆ�垃圾回收。Java以便我们控制对象的生å˜å‘¨æœŸï¼Œæ��供给了我们四ç§�引用方å¼�,引用强度从强到弱分别为:强引用ã€�软引用ã€�弱引用ã€�虚引用。Â
+Java的内å˜å›žæ”¶ä¸�需è¦�程åº�员负责,JVM会在必è¦�æ—¶å�¯åЍJava GC完æˆ�垃圾回收。Java以便我们控制对象的生å˜å‘¨æœŸï¼Œæ��供给了我们四ç§�引用方å¼�,引用强度从强到弱分别为:强引用ã€�软引用ã€�弱引用ã€�虚引用。
## 二�简介
diff --git "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232IO\346\250\241\345\236\213\344\270\216Java\347\275\221\347\273\234\347\274\226\347\250\213\346\250\241\345\236\213.md" "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232IO\346\250\241\345\236\213\344\270\216Java\347\275\221\347\273\234\347\274\226\347\250\213\346\250\241\345\236\213.md"
index 8bdf054..838c7d7 100644
--- "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232IO\346\250\241\345\236\213\344\270\216Java\347\275\221\347\273\234\347\274\226\347\250\213\346\250\241\345\236\213.md"
+++ "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232IO\346\250\241\345\236\213\344\270\216Java\347\275\221\347\273\234\347\274\226\347\250\213\346\250\241\345\236\213.md"
@@ -90,7 +90,7 @@ asynchronous IO
**_当一个read�作�生时,它会�历两个阶段:_**
-* ç‰å¾…æ•°æ�®å‡†å¤‡,比如accept(), recv()ç‰å¾…æ•°æ�®Â `(Waiting for the data to be ready)`
+* ç‰å¾…æ•°æ�®å‡†å¤‡,比如accept(), recv()ç‰å¾…æ•°æ�®`(Waiting for the data to be ready)`
* 将数æ�®ä»Žå†…æ ¸æ‹·è´�到进程ä¸, 比如 accept()接å�—到请求,recv()接收连接å�‘é€�的数æ�®å�Žéœ€è¦�å¤�åˆ¶åˆ°å†…æ ¸,å†�ä»Žå†…æ ¸å¤�制到进程用户空间`(Copying the data from the kernel to the process)`
**_对于socket�而言,数�的���历两个阶段:_**
@@ -206,7 +206,7 @@ linux下的asynchronous IO其实用得很少。先看一下它的�程:
å�Œæ¥IO VS 异æ¥IO:
概念:
-å�Œæ¥ä¸Žå¼‚æ¥å�Œæ¥å’Œå¼‚æ¥å…³æ³¨çš„æ˜¯___消æ�¯é€šä¿¡æœºåˆ¶Â ___(synchronous communication/ asynchronous communication)所谓å�Œæ¥ï¼Œå°±æ˜¯åœ¨å�‘出一个_调用_时,在没有得到结果之å‰�,该_调用_å°±ä¸�返回。但是一旦调用返回,就得到返回值了。æ�¢å�¥è¯�说,就是由_调用者_主动ç‰å¾…这个_调用_的结果。而异æ¥åˆ™æ˜¯ç›¸å��,_调用_在å�‘出之å�Žï¼Œè¿™ä¸ªè°ƒç”¨å°±ç›´æŽ¥è¿”回了,所以没有返回结果。æ�¢å�¥è¯�说,当一个异æ¥è¿‡ç¨‹è°ƒç”¨å�‘出å�Žï¼Œè°ƒç”¨è€…ä¸�会立刻得到结果。而是在_调用_å�‘出å�Žï¼Œ_被调用者_通过状æ€�ã€�通知æ�¥é€šçŸ¥è°ƒç”¨è€…,或通过回调函数处ç�†è¿™ä¸ªè°ƒç”¨ã€‚
+å�Œæ¥ä¸Žå¼‚æ¥å�Œæ¥å’Œå¼‚æ¥å…³æ³¨çš„æ˜¯___消æ�¯é€šä¿¡æœºåˆ¶___(synchronous communication/ asynchronous communication)所谓å�Œæ¥ï¼Œå°±æ˜¯åœ¨å�‘出一个_调用_时,在没有得到结果之å‰�,该_调用_å°±ä¸�返回。但是一旦调用返回,就得到返回值了。æ�¢å�¥è¯�说,就是由_调用者_主动ç‰å¾…这个_调用_的结果。而异æ¥åˆ™æ˜¯ç›¸å��,_调用_在å�‘出之å�Žï¼Œè¿™ä¸ªè°ƒç”¨å°±ç›´æŽ¥è¿”回了,所以没有返回结果。æ�¢å�¥è¯�说,当一个异æ¥è¿‡ç¨‹è°ƒç”¨å�‘出å�Žï¼Œè°ƒç”¨è€…ä¸�会立刻得到结果。而是在_调用_å�‘出å�Žï¼Œ_被调用者_通过状æ€�ã€�通知æ�¥é€šçŸ¥è°ƒç”¨è€…,或通过回调函数处ç�†è¿™ä¸ªè°ƒç”¨ã€‚
典型的异æ¥ç¼–程模型比如Node.js举个通俗的例å�ï¼šä½ æ‰“ç”µè¯�问书店è€�æ�¿æœ‰æ²¡æœ‰ã€Šåˆ†å¸ƒå¼�系统》这本书,如果是å�Œæ¥é€šä¿¡æœºåˆ¶ï¼Œä¹¦åº—è€�æ�¿ä¼šè¯´ï¼Œä½ ç¨�ç‰ï¼Œâ€�我查一下",然å�Žå¼€å§‹æŸ¥å•ŠæŸ¥ï¼Œç‰æŸ¥å¥½äº†ï¼ˆå�¯èƒ½æ˜¯5秒,也å�¯èƒ½æ˜¯ä¸€å¤©ï¼‰å‘Šè¯‰ä½ 结果(返回结果)。而异æ¥é€šä¿¡æœºåˆ¶ï¼Œä¹¦åº—è€�æ�¿ç›´æŽ¥å‘Šè¯‰ä½ 我查一下啊,查好了打电è¯�ç»™ä½ ï¼Œç„¶å�Žç›´æŽ¥æŒ‚电è¯�了(ä¸�返回结果)。然å�ŽæŸ¥å¥½äº†ï¼Œä»–会主动打电è¯�ç»™ä½ ã€‚åœ¨è¿™é‡Œè€�æ�¿é€šè¿‡â€œå›žç”µâ€�è¿™ç§�æ–¹å¼�æ�¥å›žè°ƒã€‚
diff --git "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232Java\351\235\236\351\230\273\345\241\236IO\345\222\214\345\274\202\346\255\245IO.md" "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232Java\351\235\236\351\230\273\345\241\236IO\345\222\214\345\274\202\346\255\245IO.md"
index 4ec65bc..2837b73 100644
--- "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232Java\351\235\236\351\230\273\345\241\236IO\345\222\214\345\274\202\346\255\245IO.md"
+++ "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232Java\351\235\236\351\230\273\345\241\236IO\345\222\214\345\274\202\346\255\245IO.md"
@@ -32,7 +32,7 @@
ä¸Šä¸€ç¯‡æ–‡ç« ä»‹ç»�了 Java NIO ä¸ Bufferã€�Channel å’Œ Selector 的基本æ“�作,主è¦�是一些接å�£æ“�作,比较简å�•。
-本文将介ç»�**é�žé˜»å¡ž IO** 和**å¼‚æ¥ IO**,也就是大家耳熟能详的 NIO å’Œ AIO。很多åˆ�å¦è€…å�¯èƒ½åˆ†ä¸�清楚异æ¥å’Œé�žé˜»å¡žçš„区别,å�ªæ˜¯åœ¨å�„ç§�场å�ˆèƒ½å�¬åˆ°**异æ¥é�žé˜»å¡ž**这个è¯�。
+本文将介ç»�**é�žé˜»å¡ž IO**å’Œ**å¼‚æ¥ IO**,也就是大家耳熟能详的 NIO å’Œ AIO。很多åˆ�å¦è€…å�¯èƒ½åˆ†ä¸�清楚异æ¥å’Œé�žé˜»å¡žçš„区别,å�ªæ˜¯åœ¨å�„ç§�场å�ˆèƒ½å�¬åˆ°**异æ¥é�žé˜»å¡ž**这个è¯�。
本文会先介ç»�并演示阻塞模å¼�,然å�Žå¼•å…¥é�žé˜»å¡žæ¨¡å¼�æ�¥å¯¹é˜»å¡žæ¨¡å¼�进行优化,最å�Žå†�介ç»� JDK7 å¼•å…¥çš„å¼‚æ¥ IOï¼Œç”±äºŽç½‘ä¸Šå…³äºŽå¼‚æ¥ IO 的介ç»�相对较少,所以这部分内容我会介ç»�得具体一些。
@@ -160,7 +160,7 @@ select 和 poll 都有一个共�的问题,那就是**它们都�会告诉
**epoll**:2002 å¹´éš� Linux å†…æ ¸ 2.5.44 å�‘布,epoll 能直接返回具体的准备好的通é�“,时间å¤�æ�‚度 O(1)。
-除了 Linux ä¸çš„ epoll,2000 å¹´ FreeBSD 出现了 **Kqueue**,还有就是,Solaris 䏿œ‰Â **/dev/poll**。
+除了 Linux ä¸çš„ epoll,2000 å¹´ FreeBSD 出现了**Kqueue**,还有就是,Solaris 䏿œ‰**/dev/poll**。
> å‰�é�¢è¯´äº†é‚£ä¹ˆå¤šå®žçŽ°ï¼Œä½†æ˜¯æ²¡æœ‰å‡ºçŽ° Windows,Windows å¹³å�°çš„é�žé˜»å¡ž IO 使用 select,我们也ä¸�必觉得 Windows 很è�½å�Žï¼Œåœ¨ Windows ä¸ IOCP æ��ä¾›çš„å¼‚æ¥ IO 是比较强大的。
@@ -239,13 +239,13 @@ More New IO,或称 NIO.2,éš� JDK 1.7 å�‘å¸ƒï¼ŒåŒ…æ‹¬äº†å¼•å…¥å¼‚æ¥ IO 接
**在 Unix/Linux ç‰ç³»ç»Ÿä¸ï¼ŒJDK 使用了并å�‘包ä¸çš„çº¿ç¨‹æ± æ�¥ç®¡ç�†ä»»åŠ¡**,具体å�¯ä»¥æŸ¥çœ‹ AsynchronousChannelGroup çš„æº�ç �。
-在 Windows æ“�作系统ä¸ï¼Œæ��供了一个å�«å�šÂ [I/O Completion Ports](https://msdn.microsoft.com/en-us/library/windows/desktop/aa365198.aspx) 的方案,通常简称为 **IOCP**,æ“�作系统负责管ç�†çº¿ç¨‹æ± ,其性能é�žå¸¸ä¼˜å¼‚,所以**在 Windows ä¸ JDK 直接采用了 IOCP 的支æŒ�**,使用系统支æŒ�,把更多的æ“�作信æ�¯æš´éœ²ç»™æ“�作系统,也使得æ“�作系统能够对我们的 IO 进行一定程度的优化。
+在 Windows æ“�作系统ä¸ï¼Œæ��供了一个å�«å�š[I/O Completion Ports](https://msdn.microsoft.com/en-us/library/windows/desktop/aa365198.aspx)的方案,通常简称为**IOCP**,æ“�作系统负责管ç�†çº¿ç¨‹æ± ,其性能é�žå¸¸ä¼˜å¼‚,所以**在 Windows ä¸ JDK 直接采用了 IOCP 的支æŒ�**,使用系统支æŒ�,把更多的æ“�作信æ�¯æš´éœ²ç»™æ“�作系统,也使得æ“�作系统能够对我们的 IO 进行一定程度的优化。
> 在 Linux ä¸å…¶å®žä¹Ÿæ˜¯æœ‰å¼‚æ¥ IO 系统实现的,但是é™�制比较多,性能也一般,所以 JDK é‡‡ç”¨äº†è‡ªå»ºçº¿ç¨‹æ± çš„æ–¹å¼�。
本文还是以实用为主,想è¦�了解更多信æ�¯è¯·è‡ªè¡ŒæŸ¥æ‰¾å…¶ä»–资料,下é�¢å¯¹ Java å¼‚æ¥ IO 进行实践性的介ç»�。
-总共有三个类需è¦�我们关注,分别是 **AsynchronousSocketChannel**,**AsynchronousServerSocketChannel** 和 **AsynchronousFileChannel**,å�ªä¸�过是在之å‰�介ç»�çš„ FileChannelã€�SocketChannel å’Œ ServerSocketChannel 的类å��ä¸ŠåŠ äº†ä¸ªå‰�缀 **Asynchronous**。
+总共有三个类需è¦�我们关注,分别是**AsynchronousSocketChannel**,**AsynchronousServerSocketChannel**å’Œ**AsynchronousFileChannel**,å�ªä¸�过是在之å‰�介ç»�çš„ FileChannelã€�SocketChannel å’Œ ServerSocketChannel 的类å��ä¸ŠåŠ äº†ä¸ªå‰�ç¼€**Asynchronous**。
Java å¼‚æ¥ IO æ��供了两ç§�使用方å¼�,分别是返回 Future 实例和使用回调函数。
diff --git "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232\345\237\272\344\272\216NIO\347\232\204\347\275\221\347\273\234\347\274\226\347\250\213\346\241\206\346\236\266Netty.md" "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232\345\237\272\344\272\216NIO\347\232\204\347\275\221\347\273\234\347\274\226\347\250\213\346\241\206\346\236\266Netty.md"
index e21ceef..fd4cdf2 100644
--- "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232\345\237\272\344\272\216NIO\347\232\204\347\275\221\347\273\234\347\274\226\347\250\213\346\241\206\346\236\266Netty.md"
+++ "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232\345\237\272\344\272\216NIO\347\232\204\347\275\221\347\273\234\347\274\226\347\250\213\346\241\206\346\236\266Netty.md"
@@ -169,7 +169,7 @@ Encoderså’ŒDecoders
å› ä¸ºæˆ‘ä»¬åœ¨ç½‘ç»œä¼ è¾“æ—¶å�ªèƒ½ä¼ 输å—节æµ�ï¼Œå› æ¤ï¼Œåœ¨å�‘é€�æ•°æ�®ä¹‹å‰�,我们必须把我们的message型转æ�¢ä¸ºbytes,与之对应,我们在接收数æ�®å�Žï¼Œå¿…须把接收到的byteså†�转æ�¢æˆ�message。我们把bytes to message这个过程称作Decode(è§£ç �æˆ�我们å�¯ä»¥ç�†è§£çš„),把message to bytes这个过程æˆ�为Encode。
-Netty䏿��供了很多现æˆ�的编ç �/è§£ç �器,我们一般从他们的å��å—ä¸ä¾¿å�¯çŸ¥é�“他们的用途,如**ByteToMessageDecoder**ã€�**MessageToByteEncoder**,如专门用æ�¥å¤„ç�†Google Protobufå��议的**ProtobufEncoder**ã€� **ProtobufDecoder**。
+Netty䏿��供了很多现æˆ�的编ç �/è§£ç �器,我们一般从他们的å��å—ä¸ä¾¿å�¯çŸ¥é�“他们的用途,如**ByteToMessageDecoder**ã€�**MessageToByteEncoder**,如专门用æ�¥å¤„ç�†Google Protobufå��议的**ProtobufEncoder**ã€�**ProtobufDecoder**。
我们å‰�é�¢è¯´è¿‡ï¼Œå…·ä½“是哪ç§�Handlerå°±è¦�看它们继承的是InboundAdapter还是OutboundAdapter,对于**Decoders**,很容易便å�¯ä»¥çŸ¥é�“它是继承自**ChannelInboundHandlerAdapter**或 ChannelInboundHandlerï¼Œå› ä¸ºè§£ç �çš„æ„�æ€�是把ChannelPipeline**ä¼ å…¥çš„bytesè§£ç �æˆ�我们å�¯ä»¥ç�†è§£çš„message**(å�³Java Object),而ChannelInboundHandleræ£æ˜¯å¤„ç�†Inbound Event,而Inbound Eventä¸ä¼ å…¥çš„æ£æ˜¯å—节æµ�。Decoder会覆盖其ä¸çš„“ChannelRead()â€�æ–¹æ³•ï¼Œåœ¨è¿™ä¸ªæ–¹æ³•ä¸æ�¥è°ƒç”¨å…·ä½“çš„decode方法解ç �ä¼ é€’è¿‡æ�¥çš„å—节æµ�,然å�Žé€šè¿‡è°ƒç”¨ChannelHandlerContext.fireChannelRead(decodedMessage)方法把编ç �好的Messageä¼ é€’ç»™ä¸‹ä¸€ä¸ªHandler。与之类似,Encoderå°±ä¸�必多少了。
diff --git a/src/main/java/md/mdToc.java b/src/main/java/md/mdToc.java
index f449fef..0cf8f98 100644
--- a/src/main/java/md/mdToc.java
+++ b/src/main/java/md/mdToc.java
@@ -4,7 +4,7 @@
public class mdToc {
public static void main(String[] args) {
- String path = "D:\\idea_project\\JavaTutorial\\docs\\distributed\\practice\\temp";
+ String path = "D:\\idea_project\\JavaTutorial\\docs\\java\\jvm\\temp";
AtxMarkdownToc.newInstance().genTocDir(path);
}
}
From 93ba2f44e6890c207597da394aa5c233deb3486e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=BB=84=E5=B0=8F=E6=96=9C?= <362294931@qq.com>
Date: Sun, 9 Apr 2023 18:03:01 +0800
Subject: [PATCH 07/39] modify mds
---
ReadMe.md | 4 +-
...70\345\277\203\346\265\201\347\250\213.md" | 1 -
...45\350\257\206\346\270\205\345\215\225.md" | 31 --------
...67\346\261\202\350\275\254\345\217\221.md" | 4 -
...4\232SpringMVC\346\246\202\350\277\260.md" | 77 ++++++++++++++++++-
...43\346\236\220\345\216\237\347\220\206.md" | 2 -
...6@ResponseBody\346\263\250\350\247\243.md" | 13 +---
...43\345\274\217\345\274\200\345\217\221.md" | 3 -
...274\232Mybatis\345\205\245\351\227\250.md" | 3 -
...66\346\236\204\345\211\226\346\236\220.md" | 8 +-
...5\273\272\345\267\245\345\205\267Maven.md" | 2 -
...0\257\225\346\241\206\346\236\266Junit.md" | 3 -
...\215\347\275\256\347\232\204SpringBoot.md" | 3 -
...72\346\234\254\345\216\237\347\220\206.md" | 4 -
...56\345\255\227\350\247\243\346\236\220.md" | 2 +-
...76\350\256\241\346\250\241\345\274\217.md" | 2 +-
...70\347\224\250\345\267\245\345\205\267.md" | 2 +-
...03\344\274\230\345\256\236\350\267\265.md" | 2 +-
...344\270\216NIO\346\200\273\347\273\223.md" | 14 ++++
...26\347\250\213\346\250\241\345\236\213.md" | 18 +++++
...32\344\277\241\346\234\272\345\210\266.md" | 10 +++
...67\346\261\202\346\250\241\345\236\213.md" | 12 ++-
...\345\222\214\345\274\202\346\255\245IO.md" | 15 ++++
...37\347\220\206\350\257\246\350\247\243.md" | 11 +++
...346\236\220\357\274\210NIO\357\274\211.md" | 14 ++++
...7\250\213\346\241\206\346\236\266Netty.md" | 20 +++++
...343\200\201Channel\345\222\214Selector.md" | 19 +++++
...46\236\220mmap\345\222\214DirectBuffer.md" | 27 +++++++
...36\347\216\260\345\216\237\347\220\206.md" | 19 +++++
...347\232\204NIO\346\250\241\345\236\213.md" | 13 ++++
src/main/java/md/mdToc.java | 2 +-
31 files changed, 280 insertions(+), 80 deletions(-)
rename "docs/java/jvm/temp/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232GC\350\260\203\344\274\230\346\200\235\350\267\257\344\270\216\345\270\270\347\224\250\345\267\245\345\205\267.md" => "docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232GC\350\260\203\344\274\230\346\200\235\350\267\257\344\270\216\345\270\270\347\224\250\345\267\245\345\205\267.md" (99%)
rename "docs/java/jvm/temp/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232JVM\345\270\270\347\224\250\345\217\202\346\225\260\344\273\245\345\217\212\350\260\203\344\274\230\345\256\236\350\267\265.md" => "docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232JVM\345\270\270\347\224\250\345\217\202\346\225\260\344\273\245\345\217\212\350\260\203\344\274\230\345\256\236\350\267\265.md" (99%)
diff --git a/ReadMe.md b/ReadMe.md
index 1a6c3a5..dc53ae6 100644
--- a/ReadMe.md
+++ b/ReadMe.md
@@ -204,11 +204,11 @@ todo
* [深入ç�†è§£JVM虚拟机:JNDI,OSGI,Tomcatç±»åŠ è½½å™¨å®žçŽ°](docs/java/jvm/深入ç�†è§£JVM虚拟机:JNDI,OSGI,Tomcatç±»åŠ è½½å™¨å®žçŽ°.md)
* [深入了解JVM虚拟机:Java的编译期优化与�行期优化](docs/java/jvm/深入�解JVM虚拟机:Java的编译期优化与�行期优化.md)
* [深入ç�†è§£JVM虚拟机:JVM监控工具与诊æ–实践](docs/java/jvm/深入ç�†è§£JVM虚拟机:JVM监控工具与诊æ–实践.md)
-* [深入�解JVM虚拟机:JVM常用�数以�调优实践](docs/java/jvm/temp/深入�解JVM虚拟机:JVM常用�数以�调优实践.md)
+* [深入�解JVM虚拟机:JVM常用�数以�调优实践](docs/java/jvm/深入�解JVM虚拟机:JVM常用�数以�调优实践.md)
* [深入ç�†è§£JVM虚拟机:Java内å˜å¼‚常原ç�†ä¸Žå®žè·µ](docs/java/jvm/深入ç�†è§£JVM虚拟机:Java内å˜å¼‚常原ç�†ä¸Žå®žè·µ.md)
* [深入�解JVM虚拟机:JVM性能管�神器VisualVM介�与实战](docs/java/jvm/深入�解JVM虚拟机:JVM性能管�神器VisualVM介�与实战.md)
* [深入�解JVM虚拟机:�谈四�引用�GC实践](docs/java/jvm/深入�解JVM虚拟机:�谈四�引用�GC实践.md)
-* [深入�解JVM虚拟机:GC调优�路与常用工具](docs/java/jvm/temp/深入�解JVM虚拟机:GC调优�路与常用工具.md)
+* [深入�解JVM虚拟机:GC调优�路与常用工具](docs/java/jvm/深入�解JVM虚拟机:GC调优�路与常用工具.md)
### Java网络编程
diff --git "a/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232\345\210\235\346\216\242SpringIOC\346\240\270\345\277\203\346\265\201\347\250\213.md" "b/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232\345\210\235\346\216\242SpringIOC\346\240\270\345\277\203\346\265\201\347\250\213.md"
index 2ffdb35..ba4415e 100644
--- "a/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232\345\210\235\346\216\242SpringIOC\346\240\270\345\277\203\346\265\201\347\250\213.md"
+++ "b/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232\345\210\235\346\216\242SpringIOC\346\240\270\345\277\203\346\265\201\347\250\213.md"
@@ -4,7 +4,6 @@
* [读�](#读�)
* [解�](#解�)
* [注册](#注册)
- * [注入�赖](#注入�赖)
本文转载自互è�”网,侵åˆ
diff --git "a/docs/java-web/Spring/\347\273\231\344\275\240\344\270\200\344\273\275SpringBoot\347\237\245\350\257\206\346\270\205\345\215\225.md" "b/docs/java-web/Spring/\347\273\231\344\275\240\344\270\200\344\273\275SpringBoot\347\237\245\350\257\206\346\270\205\345\215\225.md"
index 8564da9..96260af 100644
--- "a/docs/java-web/Spring/\347\273\231\344\275\240\344\270\200\344\273\275SpringBoot\347\237\245\350\257\206\346\270\205\345\215\225.md"
+++ "b/docs/java-web/Spring/\347\273\231\344\275\240\344\270\200\344\273\275SpringBoot\347\237\245\350\257\206\346\270\205\345\215\225.md"
@@ -8,7 +8,6 @@
* [2.3�@Import](#23�import)
* [2.4�@Conditional](#24�conditional)
* [2.5�@ConfigurationProperties与@EnableConfigurationProperties](#25�configurationproperties与enableconfigurationproperties)
- * [](#)
* [三�削�如泥:SpringFactoriesLoader详解](#三�削�如泥:springfactoriesloader详解)
* [å››ã€�å�¦ä¸€ä»¶æ¦å™¨ï¼šSpring容器的事件监å�¬æœºåˆ¶](#å››ã€�å�¦ä¸€ä»¶æ¦å™¨ï¼šspring容器的事件监å�¬æœºåˆ¶)
* [Spring容器内的事件监�机制](#spring容器内的事件监�机制)
@@ -17,9 +16,6 @@
* [6.1 SpringApplication�始化](#61-springapplication�始化)
* [6.2 Spring Boot�动�程](#62-spring-boot�动�程)
* [å�‚è€ƒæ–‡ç« ](#å�‚è€ƒæ–‡ç« )
-* [微信公众�](#微信公众�)
- * [个人公众�:黄�斜](#个人公众�:黄�斜)
- * [技术公众�:Java技术江湖](#技术公众�:java技术江湖)
本文转自互è�”网,侵åˆ
@@ -806,30 +802,3 @@ public void initialize(ConfigurableApplicationContext context) {
[5][spring boot实战:自动�置原�分�](https://link.jianshu.com/?t=http%3A%2F%2Fblog.csdn.net%2Fliaokailin%2Farticle%2Fdetails%2F49559951):[http://blog.csdn.net/liaokailin/article/details/49559951](https://link.jianshu.com/?t=http%3A%2F%2Fblog.csdn.net%2Fliaokailin%2Farticle%2Fdetails%2F49559951)
[6][spring boot实战:Spring boot BeanåŠ è½½æº�ç �分æž�](https://link.jianshu.com/?t=http%3A%2F%2Fblog.csdn.net%2Fliaokailin%2Farticle%2Fdetails%2F49107209):[http://blog.csdn.net/liaokailin/article/details/49107209](https://link.jianshu.com/?t=http%3A%2F%2Fblog.csdn.net%2Fliaokailin%2Farticle%2Fdetails%2F49107209)
-
-
-## 微信公众�
-
-### 个人公众�:黄�斜
-
-黄å°�斜是跨考软件工程的 985 ç¡•å£«ï¼Œè‡ªå¦ Java 两年,拿到了 BAT ç‰è¿‘å��家大厂 offer,从技术å°�白æˆ�长为阿里工程师。
-
-作者专注于 JAVA å�Žç«¯æŠ€æœ¯æ ˆï¼Œçƒè¡·äºŽåˆ†äº«ç¨‹åº�员干货ã€�å¦ä¹ ç»�验ã€�求è�Œå¿ƒå¾—和程åº�人生,目å‰�黄å°�斜的CSDNå�šå®¢æœ‰ç™¾ä¸‡+访问é‡�,知乎粉ä¸�2W+,全网已有10W+读者。
-
-黄å°�斜是一个斜æ� é�’年,å�šæŒ�å¦ä¹ 和写作,相信终身å¦ä¹ 的力é‡�,希望和更多的程åº�员交朋å�‹ï¼Œä¸€èµ·è¿›æ¥å’Œæˆ�é•¿ï¼�
-
-**原创电å�书:**
-关注公众å�·ã€�黄å°�斜】å�Žå›žå¤�ã€�原创电å�书】å�³å�¯é¢†å�–我原创的电å�书《è�œé¸Ÿç¨‹åº�员修炼手册:从技术å°�白到阿里巴巴Java工程师》
-
-**程åº�员3T技术å¦ä¹ 资æº�:** 一些程åº�员å¦ä¹ 技术的资æº�大礼包,关注公众å�·å�Žï¼Œå�Žå�°å›žå¤�å…³é”®å— **“资料â€�** å�³å�¯å…�è´¹æ— å¥—è·¯èŽ·å�–。
-**è€ƒç ”å¤�ä¹ èµ„æ–™ï¼š** è®¡ç®—æœºè€ƒç ”å¤§ç¤¼åŒ…ï¼Œéƒ½æ˜¯æˆ‘è‡ªå·±è€ƒç ”å¤�ä¹ æ—¶ç”¨çš„ä¸€äº›å¤�ä¹ èµ„æ–™,包括公共课和专业的å¤�ä¹ è§†é¢‘ï¼Œè¿™é‡Œä¹ŸæŽ¨è��给大家,关注公众å�·å�Žï¼Œå�Žå�°å›žå¤�å…³é”®å— **â€œè€ƒç ”â€�** å�³å�¯å…�费获å�–。
-
-
-
-### 技术公众�:Java技术江湖
-
-如果大家想è¦�å®žæ—¶å…³æ³¨æˆ‘æ›´æ–°çš„æ–‡ç« ä»¥å�Šåˆ†äº«çš„干货的è¯�,å�¯ä»¥å…³æ³¨æˆ‘的公众å�·ã€�Java技术江湖】一ä½�阿里 Java 工程师的技术å°�站,作者黄å°�斜,专注 Java 相关技术:SSMã€�SpringBootã€�MySQLã€�分布å¼�ã€�ä¸é—´ä»¶ã€�集群ã€�Linuxã€�网络ã€�多线程,å�¶å°”讲点Dockerã€�ELK,å�Œæ—¶ä¹Ÿåˆ†äº«æŠ€æœ¯å¹²è´§å’Œå¦ä¹ ç»�验,致力于Javaå…¨æ ˆå¼€å�‘ï¼�
-
-**Java工程师必备å¦ä¹ 资æº�:** 一些Java工程师常用å¦ä¹ 资æº�,关注公众å�·å�Žï¼Œå�Žå�°å›žå¤�å…³é”®å— **“Javaâ€�** å�³å�¯å…�è´¹æ— å¥—è·¯èŽ·å�–。
-
-
\ No newline at end of file
diff --git "a/docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232DispatcherServlet\347\232\204\345\210\235\345\247\213\345\214\226\344\270\216\350\257\267\346\261\202\350\275\254\345\217\221.md" "b/docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232DispatcherServlet\347\232\204\345\210\235\345\247\213\345\214\226\344\270\216\350\257\267\346\261\202\350\275\254\345\217\221.md"
index 6390f87..1ae0ed4 100644
--- "a/docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232DispatcherServlet\347\232\204\345\210\235\345\247\213\345\214\226\344\270\216\350\257\267\346\261\202\350\275\254\345\217\221.md"
+++ "b/docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232DispatcherServlet\347\232\204\345\210\235\345\247\213\345\214\226\344\270\216\350\257\267\346\261\202\350\275\254\345\217\221.md"
@@ -1,11 +1,7 @@
# 目录
* [�言](#�言)
- * [é…�ç½®å…ƒç´ è¯»å�– ](#init-paramé…�ç½®å…ƒç´ è¯»å�–init-param)
* [容器上下文的建立](#容器上下文的建立)
* [�始化SpringMVC默认实现类](#�始化springmvc默认实现类)
-* [Default implementation classes for DispatcherServlet's strategy interfaces.](#default-implementation-classes-for-dispatcherservlets-strategy-interfaces)
-* [Used as fallback when no matching beans are found in the DispatcherServlet context.](#used-as-fallback-when-no-matching-beans-are-found-in-the-dispatcherservlet-context)
-* [Not meant to be customized by application developers.](#not-meant-to-be-customized-by-application-developers)
* [总结](#总结)
diff --git "a/docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232SpringMVC\346\246\202\350\277\260.md" "b/docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232SpringMVC\346\246\202\350\277\260.md"
index 2345fe8..fb7f88e 100644
--- "a/docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232SpringMVC\346\246\202\350\277\260.md"
+++ "b/docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232SpringMVC\346\246\202\350\277\260.md"
@@ -1,4 +1,77 @@
-[## 一�SpringMVC简介
+# 目录
+
+ * [1.1�SpringMVC引言](#11�springmvc引言)
+ * [1.2�SpringMVC的优势](#12�springmvc的优势)
+ * [二�SpringMVC入门](#二�springmvc入门)
+ * [2.1ã€�环境æ�建](#21ã€�环境æ�建)
+ * [2.1.1�引入�赖](#211�引入�赖)
+ * [2.1.2�编写�置文件](#212�编写�置文件)
+ * [2.1.3��置web.xml](#213��置webxml)
+ * [2.1.4�编写控制器](#214�编写控制器)
+ * [2.2�注解详解](#22�注解详解)
+ * [2.2.1�@Controller](#221�controller)
+ * [2.2.2�@RequestMapping](#222�requestmapping)
+ * [2.3�SpringMVC的跳转方�](#23�springmvc的跳转方�)
+ * [2.3.1�Controller ——>��页�](#231�controller-��页�)
+ * [2.3.1.1�forward](#2311�forward)
+ * [2.3.1.2�redirect](#2312�redirect)
+ * [2.3.1Controller ——>Controller](#231controller-controller)
+ * [2.3.1.1�forward](#2311�forward-1)
+ * [2.3.1.2�redirect](#2312�redirect-1)
+ * [2.4�SpringMVC的�数接收](#24�springmvc的�数接收)
+ * [2.4.1�Servlet接收�数的方�](#241�servlet接收�数的方�)
+ * [2.4.2�SpringMVC的�数接收](#242�springmvc的�数接收)
+ * [2.4.2.1�基本数�类型](#2421�基本数�类型)
+ * [2.4.2.2�对象类型](#2422�对象类型)
+ * [2.4.2.3�数组类型](#2423�数组类型)
+ * [2.4.2.4�集�类型](#2424�集�类型)
+ * [2.5ã€�SpringMVC接收å�‚æ•°ä¸æ–‡ä¹±ç �问题](#25ã€�springmvc接收å�‚æ•°ä¸æ–‡ä¹±ç �问题)
+ * [2.5.1�GET请求](#251�get请求)
+ * [2.5.2�POST请求](#252�post请求)
+ * [2.5.2.1ã€�自定义过滤器解决POSTä¹±ç �请求](#2521ã€�自定义过滤器解决postä¹±ç �请求)
+ * [2.5.2.2ã€�使用CharacterEncodingFilter解决POSTä¹±ç �请求](#2522ã€�使用characterencodingfilter解决postä¹±ç �请求)
+ * [2.6ã€�SpringMVC䏿•°æ�®ä¼ 递机制](#26ã€�springmvc䏿•°æ�®ä¼ 递机制)
+ * [2.6.1ã€�什么事数æ�®ä¼ 递机制](#261ã€�什么事数æ�®ä¼ 递机制)
+ * [2.6.2ã€�Servlet的数æ�®ä¼ 递机制](#262ã€�servlet的数æ�®ä¼ 递机制)
+ * [三��端控制器](#三��端控制器)
+ * [3.1�什么是�端控制器](#31�什么是�端控制器)
+ * [3.2ã€�代ç �实现](#32ã€�代ç �实现)
+ * [3.3�注�](#33�注�)
+ * [3.4ã€�æ˜ å°„è·¯å¾„](#34ã€�æ˜ å°„è·¯å¾„)
+ * [3.4.1ã€�访问é�™æ€�资æº�å’Œ JSP è¢«æ‹¦æˆªçš„åŽŸå› ](#341ã€�访问é�™æ€�资æº�å’Œ-jsp-è¢«æ‹¦æˆªçš„åŽŸå› )
+ * [3.4.2�如何解决](#342�如何解决)
+ * [3.4.2.1�方�一](#3421�方�一)
+ * [3.4.2.2�方�二](#3422�方�二)
+ * [3.5�@ModelAttribute 注解](#35�modelattribute-注解)
+ * [四�处��应](#四�处��应)
+ * [4.1�返回 ModelAndView](#41�返回-modelandview)
+ * [4.2�返回String](#42�返回string)
+ * [4.3�改进](#43�改进)
+ * [五�请求转�和�定�](#五�请求转�和�定�)
+ * [5.1�请求转�和�定�的区别](#51�请求转�和�定�的区别)
+ * [5.2�请求转�](#52�请求转�)
+ * [5.3��定�](#53��定�)
+ * [5.4�请求路径](#54�请求路径)
+ * [å…ã€�å�‚数处ç�†](#å…ã€�å�‚数处ç�†)
+ * [6.1�处�简�类型的请求�数](#61�处�简�类型的请求�数)
+ * [6.1.1�请求�数�和控制器方法�数列表形���](#611�请求�数�和控制器方法�数列表形���)
+ * [6.1.2�请求�数�和控制器方法�数列表形����](#612�请求�数�和控制器方法�数列表形����)
+ * [6.2�处���类型的请求�数](#62�处���类型的请求�数)
+ * [6.2.1�数组类型](#621�数组类型)
+ * [6.2.2�自定义类型](#622�自定义类型)
+ * [6.3�处�日期类型的请求�数](#63�处�日期类型的请求�数)
+ * [6.3.1�日期在请求�数上](#631�日期在请求�数上)
+ * [6.3.2�在�装的对象上](#632�在�装的对象上)
+ * [七ã€�æ–‡ä»¶ä¸Šä¼ ä¸Žä¸‹è½½](#七ã€�æ–‡ä»¶ä¸Šä¼ ä¸Žä¸‹è½½)
+ * [7.1ã€�æ–‡ä»¶ä¸Šä¼ ](#71ã€�æ–‡ä»¶ä¸Šä¼ )
+ * [7.1.1�编写表�](#711�编写表�)
+ * [7.1.2�修改web.xml](#712�修改webxml)
+ * [7.1.3ã€�é…�ç½®ä¸Šä¼ è§£æž�器](#713ã€�é…�ç½®ä¸Šä¼ è§£æž�器)
+ * [7.1.4ã€�é…�ç½®ä¸Šä¼ æŽ§åˆ¶å™¨](#714ã€�é…�ç½®ä¸Šä¼ æŽ§åˆ¶å™¨)
+ * [7.2�文件下载](#72�文件下载)
+ * [7.2.1�开�控制器](#721�开�控制器)
+
+
## 1.1�SpringMVC引言
@@ -942,5 +1015,3 @@ package cn.linstudy.controller;
return null;
}
```
-
-]([]())
\ No newline at end of file
diff --git "a/docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232SpringMVC\347\232\204\350\247\206\345\233\276\350\247\243\346\236\220\345\216\237\347\220\206.md" "b/docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232SpringMVC\347\232\204\350\247\206\345\233\276\350\247\243\346\236\220\345\216\237\347\220\206.md"
index 6a3357f..cb28598 100644
--- "a/docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232SpringMVC\347\232\204\350\247\206\345\233\276\350\247\243\346\236\220\345\216\237\347\220\206.md"
+++ "b/docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232SpringMVC\347\232\204\350\247\206\345\233\276\350\247\243\346\236\220\345\216\237\347\220\206.md"
@@ -4,8 +4,6 @@
* [��接�和类介�](#��接�和类介�)
* [æº�ç �分æž�](#æº�ç �分æž�)
* [ç¼–ç �自定义的ViewResolver](#ç¼–ç �自定义的viewresolver)
- * [This is jsp page](#this-is-jsp-page)
- * [This is freemarker page](#this-is-freemarker-page)
* [总结](#总结)
diff --git "a/docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232\346\266\210\346\201\257\350\275\254\346\215\242\345\231\250HttpMessageConverter\344\270\216@ResponseBody\346\263\250\350\247\243.md" "b/docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232\346\266\210\346\201\257\350\275\254\346\215\242\345\231\250HttpMessageConverter\344\270\216@ResponseBody\346\263\250\350\247\243.md"
index f34de3a..d4cb3bc 100644
--- "a/docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232\346\266\210\346\201\257\350\275\254\346\215\242\345\231\250HttpMessageConverter\344\270\216@ResponseBody\346\263\250\350\247\243.md"
+++ "b/docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232\346\266\210\346\201\257\350\275\254\346\215\242\345\231\250HttpMessageConverter\344\270\216@ResponseBody\346\263\250\350\247\243.md"
@@ -1,5 +1,4 @@
# 目录
-* [目录](#目录)
* [�言](#�言)
* [现象](#现象)
* [æº�ç �分æž�](#æº�ç �分æž�)
@@ -29,17 +28,7 @@
å¦‚æžœå¯¹æœ¬ç³»åˆ—æ–‡ç« æœ‰ä»€ä¹ˆå»ºè®®ï¼Œæˆ–è€…æ˜¯æœ‰ä»€ä¹ˆç–‘é—®çš„è¯�,也å�¯ä»¥å…³æ³¨å…¬ä¼—å�·ã€�Java技术江湖】è�”ç³»ä½œè€…ï¼Œæ¬¢è¿Žä½ å�‚与本系列å�šæ–‡çš„åˆ›ä½œå’Œä¿®è®¢ã€‚
-
-
-## 目录
-
-* [�言](http://www.cnblogs.com/fangjian0423/p/springMVC-xml-json-convert.html#preface)
-* [现象](http://www.cnblogs.com/fangjian0423/p/springMVC-xml-json-convert.html#phenomenon)
-* [æº�ç �分æž�](http://www.cnblogs.com/fangjian0423/p/springMVC-xml-json-convert.html#analysis)
-* [实例讲解](http://www.cnblogs.com/fangjian0423/p/springMVC-xml-json-convert.html#demo)
-* [关于�置](http://www.cnblogs.com/fangjian0423/p/springMVC-xml-json-convert.html#config)
-* [总结](http://www.cnblogs.com/fangjian0423/p/springMVC-xml-json-convert.html#summary)
-* [�考资料](http://www.cnblogs.com/fangjian0423/p/springMVC-xml-json-convert.html#reference)
+
## �言
diff --git "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232Hibernate\345\205\245\351\227\250\347\273\217\345\205\270\344\270\216\346\263\250\350\247\243\345\274\217\345\274\200\345\217\221.md" "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232Hibernate\345\205\245\351\227\250\347\273\217\345\205\270\344\270\216\346\263\250\350\247\243\345\274\217\345\274\200\345\217\221.md"
index e9ff30d..76dfece 100644
--- "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232Hibernate\345\205\245\351\227\250\347\273\217\345\205\270\344\270\216\346\263\250\350\247\243\345\274\217\345\274\200\345\217\221.md"
+++ "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232Hibernate\345\205\245\351\227\250\347\273\217\345\205\270\344\270\216\346\263\250\350\247\243\345\274\217\345\274\200\345\217\221.md"
@@ -5,9 +5,6 @@
* [相关类](#相关类)
* [扩展](#扩展)
* [å�‚è€ƒæ–‡ç« ](#å�‚è€ƒæ–‡ç« )
-* [微信公众�](#微信公众�)
- * [个人公众�:程�员黄�斜](#个人公众�:程�员黄�斜)
- * [技术公众�:Java技术江湖](#技术公众�:java技术江湖)
本文转载自互è�”网,侵åˆ
diff --git "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232Mybatis\345\205\245\351\227\250.md" "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232Mybatis\345\205\245\351\227\250.md"
index fa50a2b..bc23655 100644
--- "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232Mybatis\345\205\245\351\227\250.md"
+++ "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232Mybatis\345\205\245\351\227\250.md"
@@ -18,9 +18,6 @@
* [3.会�工厂与会�](#3会�工厂与会�)
* [4.�行�程](#4�行�程)
* [测试工程æ�建](#测试工程æ�建)
- * [微信公众�](#微信公众�-1)
- * [个人公众�:程�员黄�斜](#个人公众�:程�员黄�斜)
- * [技术公众�:Java技术江湖](#技术公众�:java技术江湖)
本文转载自互è�”网,侵åˆ
diff --git "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232Tomcat5\346\200\273\344\275\223\346\236\266\346\236\204\345\211\226\346\236\220.md" "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232Tomcat5\346\200\273\344\275\223\346\236\266\346\236\204\345\211\226\346\236\220.md"
index fa1490e..5937ec0 100644
--- "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232Tomcat5\346\200\273\344\275\223\346\236\266\346\236\204\345\211\226\346\236\220.md"
+++ "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232Tomcat5\346\200\273\344\275\223\346\236\266\346\236\204\345\211\226\346\236\220.md"
@@ -1,3 +1,9 @@
+# 目录
+
+ * [连接器(Connector)](#连接器(connector))
+ * [容器(Container)](#容器(container))
+
+
本文转载自互è�”网,侵åˆ
æœ¬ç³»åˆ—æ–‡ç« å°†æ•´ç�†åˆ°æˆ‘在GitHub上的《Javaé�¢è¯•指å�—》仓库,更多精彩内容请到我的仓库里查看
@@ -187,4 +193,4 @@ Container[] conHosts = engine.findChildren();
定� Servlet 的�程图:
-
\ No newline at end of file
+
diff --git "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232\344\273\216\346\211\213\345\212\250\347\274\226\350\257\221\346\211\223\345\214\205\345\210\260\351\241\271\347\233\256\346\236\204\345\273\272\345\267\245\345\205\267Maven.md" "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232\344\273\216\346\211\213\345\212\250\347\274\226\350\257\221\346\211\223\345\214\205\345\210\260\351\241\271\347\233\256\346\236\204\345\273\272\345\267\245\345\205\267Maven.md"
index 7f80e4f..d6cfa8c 100644
--- "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232\344\273\216\346\211\213\345\212\250\347\274\226\350\257\221\346\211\223\345\214\205\345\210\260\351\241\271\347\233\256\346\236\204\345\273\272\345\267\245\345\205\267Maven.md"
+++ "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232\344\273\216\346\211\213\345\212\250\347\274\226\350\257\221\346\211\223\345\214\205\345\210\260\351\241\271\347\233\256\346\236\204\345\273\272\345\267\245\345\205\267Maven.md"
@@ -9,8 +9,6 @@
* [maven目录](#maven目录)
* [Maven常用命令说明](#maven常用命令说明)
* [Maven使用](#maven使用)
- * [[](http://tengj.top/2018/01/01/maven/#%E4%BE%9D%E8%B5%96%E7%9A%84%E9%85%8D%E7%BD%AE "�赖的�置")�赖的�置](#[]httptengjtop20180101mavene4be9de8b596e79a84e9858de7bdae-�赖的�置�赖的�置)
- * [[](http://tengj.top/2018/01/01/maven/#%E4%BE%9D%E8%B5%96%E8%8C%83%E5%9B%B4 "�赖范围")�赖范围](#[]httptengjtop20180101mavene4be9de8b596e88c83e59bb4-�赖范围�赖范围)
* [ä¼ é€’æ€§ä¾�èµ–](#ä¼ é€’æ€§ä¾�èµ–)
* [�赖范围](#�赖范围)
* [Maven和Gradle的比较](#maven和gradle的比较)
diff --git "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232\345\215\225\345\205\203\346\265\213\350\257\225\346\241\206\346\236\266Junit.md" "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232\345\215\225\345\205\203\346\265\213\350\257\225\346\241\206\346\236\266Junit.md"
index 0732005..ee6dffc 100644
--- "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232\345\215\225\345\205\203\346\265\213\350\257\225\346\241\206\346\236\266Junit.md"
+++ "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232\345\215\225\345\205\203\346\265\213\350\257\225\346\241\206\346\236\266Junit.md"
@@ -16,9 +16,6 @@
* [5.1 示例一:简�的 JUnit 3.X 测试](#51-示例一:简�的-junit-3x-测试)
* [6 个人建议](#6-个人建议)
* [8 大�元测试框架](#8-大�元测试框架)
-* [微信公众�](#微信公众�)
- * [个人公众�:程�员黄�斜](#个人公众�:程�员黄�斜)
- * [技术公众�:Java技术江湖](#技术公众�:java技术江湖)
diff --git "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232\346\236\201\347\256\200\351\205\215\347\275\256\347\232\204SpringBoot.md" "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232\346\236\201\347\256\200\351\205\215\347\275\256\347\232\204SpringBoot.md"
index adaa923..e98f6e8 100644
--- "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232\346\236\201\347\256\200\351\205\215\347\275\256\347\232\204SpringBoot.md"
+++ "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232\346\236\201\347\256\200\351\205\215\347\275\256\347\232\204SpringBoot.md"
@@ -15,9 +15,6 @@
* [Spring Boot 支� JSP](#spring-boot-支�-jsp)
* [集� MyBatis](#集�-mybatis)
* [springMVC和springboot的区别](#springmvc和springboot的区别)
-* [微信公众�](#微信公众�)
- * [个人公众�:程�员黄�斜](#个人公众�:程�员黄�斜)
- * [技术公众�:Java技术江湖](#技术公众�:java技术江湖)
本文转载自互è�”网,侵åˆ
diff --git "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232\346\267\261\345\205\245\346\265\205\345\207\272Mybatis\345\237\272\346\234\254\345\216\237\347\220\206.md" "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232\346\267\261\345\205\245\346\265\205\345\207\272Mybatis\345\237\272\346\234\254\345\216\237\347\220\206.md"
index 1b37c95..7556dc4 100644
--- "a/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232\346\267\261\345\205\245\346\265\205\345\207\272Mybatis\345\237\272\346\234\254\345\216\237\347\220\206.md"
+++ "b/docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232\346\267\261\345\205\245\346\265\205\345\207\272Mybatis\345\237\272\346\234\254\345\216\237\347\220\206.md"
@@ -1,5 +1,4 @@
# 目录
-
* [引言](#引言)
* [工作原�原型图](#工作原�原型图)
* [工作原�解�](#工作原�解�)
@@ -8,9 +7,6 @@
* [MyBatis的�置](#mybatis的�置)
* [MyBatis的主��员](#mybatis的主��员)
* [å�‚è€ƒæ–‡ç« ](#å�‚è€ƒæ–‡ç« )
-* [微信公众�](#微信公众�)
- * [个人公众�:程�员黄�斜](#个人公众�:程�员黄�斜)
- * [技术公众�:Java技术江湖](#技术公众�:java技术江湖)
æœ¬ç³»åˆ—æ–‡ç« å°†æ•´ç�†åˆ°æˆ‘在GitHub上的《Javaé�¢è¯•指å�—》仓库,更多精彩内容请到我的仓库里查看
diff --git "a/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232JMM\344\270\255\347\232\204final\345\205\263\351\224\256\345\255\227\350\247\243\346\236\220.md" "b/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232JMM\344\270\255\347\232\204final\345\205\263\351\224\256\345\255\227\350\247\243\346\236\220.md"
index f7fe31b..c9a13f8 100644
--- "a/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232JMM\344\270\255\347\232\204final\345\205\263\351\224\256\345\255\227\350\247\243\346\236\220.md"
+++ "b/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232JMM\344\270\255\347\232\204final\345\205\263\351\224\256\345\255\227\350\247\243\346\236\220.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [一�properly constructed / this对象逸出](#一�properly-constructed--this对象逸出)
* [二�对象的安全�布](#二�对象的安全�布)
diff --git "a/docs/java/design-parttern/\345\210\235\346\216\242Java\350\256\276\350\256\241\346\250\241\345\274\217\357\274\232JDK\344\270\255\347\232\204\350\256\276\350\256\241\346\250\241\345\274\217.md" "b/docs/java/design-parttern/\345\210\235\346\216\242Java\350\256\276\350\256\241\346\250\241\345\274\217\357\274\232JDK\344\270\255\347\232\204\350\256\276\350\256\241\346\250\241\345\274\217.md"
index 61748b1..ab7b901 100644
--- "a/docs/java/design-parttern/\345\210\235\346\216\242Java\350\256\276\350\256\241\346\250\241\345\274\217\357\274\232JDK\344\270\255\347\232\204\350\256\276\350\256\241\346\250\241\345\274\217.md"
+++ "b/docs/java/design-parttern/\345\210\235\346\216\242Java\350\256\276\350\256\241\346\250\241\345\274\217\357\274\232JDK\344\270\255\347\232\204\350\256\276\350\256\241\346\250\241\345\274\217.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [**一,结构型模�**](#一,结构型模�)
* [**1,适�器模�**](#1,适�器模�)
diff --git "a/docs/java/jvm/temp/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232GC\350\260\203\344\274\230\346\200\235\350\267\257\344\270\216\345\270\270\347\224\250\345\267\245\345\205\267.md" "b/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232GC\350\260\203\344\274\230\346\200\235\350\267\257\344\270\216\345\270\270\347\224\250\345\267\245\345\205\267.md"
similarity index 99%
rename from "docs/java/jvm/temp/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232GC\350\260\203\344\274\230\346\200\235\350\267\257\344\270\216\345\270\270\347\224\250\345\267\245\345\205\267.md"
rename to "docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232GC\350\260\203\344\274\230\346\200\235\350\267\257\344\270\216\345\270\270\347\224\250\345\267\245\345\205\267.md"
index 30d3350..ceda305 100644
--- "a/docs/java/jvm/temp/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232GC\350\260\203\344\274\230\346\200\235\350\267\257\344\270\216\345\270\270\347\224\250\345\267\245\345\205\267.md"
+++ "b/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232GC\350\260\203\344\274\230\346\200\235\350\267\257\344\270\216\345\270\270\347\224\250\345\267\245\345\205\267.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [æ ¸å¿ƒæ¦‚å¿µ(Core Concepts)](#æ ¸å¿ƒæ¦‚å¿µcore-concepts)
* [Latency(延迟)](#latency延迟)
diff --git "a/docs/java/jvm/temp/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232JVM\345\270\270\347\224\250\345\217\202\346\225\260\344\273\245\345\217\212\350\260\203\344\274\230\345\256\236\350\267\265.md" "b/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232JVM\345\270\270\347\224\250\345\217\202\346\225\260\344\273\245\345\217\212\350\260\203\344\274\230\345\256\236\350\267\265.md"
similarity index 99%
rename from "docs/java/jvm/temp/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232JVM\345\270\270\347\224\250\345\217\202\346\225\260\344\273\245\345\217\212\350\260\203\344\274\230\345\256\236\350\267\265.md"
rename to "docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232JVM\345\270\270\347\224\250\345\217\202\346\225\260\344\273\245\345\217\212\350\260\203\344\274\230\345\256\236\350\267\265.md"
index 5b7c03c..caac027 100644
--- "a/docs/java/jvm/temp/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232JVM\345\270\270\347\224\250\345\217\202\346\225\260\344\273\245\345\217\212\350\260\203\344\274\230\345\256\236\350\267\265.md"
+++ "b/docs/java/jvm/\346\267\261\345\205\245\347\220\206\350\247\243JVM\350\231\232\346\213\237\346\234\272\357\274\232JVM\345\270\270\347\224\250\345\217\202\346\225\260\344\273\245\345\217\212\350\260\203\344\274\230\345\256\236\350\267\265.md"
@@ -1,4 +1,4 @@
-# Table of Contents
+# 目录
* [JVM优化的必�性](#jvm优化的必�性)
* [JVM调优原则](#jvm调优原则)
diff --git "a/docs/java/network-programming/Java\347\275\221\347\273\234\344\270\216NIO\346\200\273\347\273\223.md" "b/docs/java/network-programming/Java\347\275\221\347\273\234\344\270\216NIO\346\200\273\347\273\223.md"
index 634e1c6..15c003a 100644
--- "a/docs/java/network-programming/Java\347\275\221\347\273\234\344\270\216NIO\346\200\273\347\273\223.md"
+++ "b/docs/java/network-programming/Java\347\275\221\347\273\234\344\270\216NIO\346\200\273\347\273\223.md"
@@ -1,3 +1,17 @@
+# 目录
+
+* [目录](#目录)
+ * [Java IO](#java-io)
+ * [Socket编程](#socket编程)
+ * [客户端,�务端的线程模型](#客户端,�务端的线程模型)
+ * [IO模型](#io模型)
+ * [NIO](#nio)
+ * [AIO](#aio)
+ * [Tomcatä¸çš„NIO模型](#tomcatä¸çš„nio模型)
+ * [Tomcat的container](#tomcat的container)
+ * [netty](#netty)
+
+
# 目录
* [Java IO](#java-io)
* [Socket编程](#socket编程)
diff --git "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232IO\346\250\241\345\236\213\344\270\216Java\347\275\221\347\273\234\347\274\226\347\250\213\346\250\241\345\236\213.md" "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232IO\346\250\241\345\236\213\344\270\216Java\347\275\221\347\273\234\347\274\226\347\250\213\346\250\241\345\236\213.md"
index 838c7d7..deca42f 100644
--- "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232IO\346\250\241\345\236\213\344\270\216Java\347\275\221\347\273\234\347\274\226\347\250\213\346\250\241\345\236\213.md"
+++ "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232IO\346\250\241\345\236\213\344\270\216Java\347\275\221\347\273\234\347\274\226\347\250\213\346\250\241\345\236\213.md"
@@ -1,3 +1,21 @@
+# 目录
+
+* [目录](#目录)
+ * [IO模型介�](#io模型介�)
+ * [阻塞 I/O(blocking IO)](#阻塞-io(blocking-io))
+ * [�阻塞 I/O(nonblocking IO)](#�阻塞-io(nonblocking-io))
+ * [I/O 多路�用( IO multiplexing)](#io-多路�用(-io-multiplexing))
+ * [å¼‚æ¥ I/O(asynchronous IO)](#异æ¥-io(asynchronous-io))
+ * [阻塞IO,é�žé˜»å¡žIO 与 å�Œæ¥IO, 异æ¥IO的区别和è�”ç³»](#阻塞ioé�žé˜»å¡žio-与-å�Œæ¥io-异æ¥io的区别和è�”ç³»)
+ * [IO模型的形象举例](#io模型的形象举例)
+ * [Select/Poll/Epoll 轮询机制](#selectpollepoll-轮询机制)
+ * [Java网络编程模型](#java网络编程模型)
+ * [BIO](#bio)
+ * [NIO](#nio)
+ * [AIO](#aio)
+ * [对比](#对比)
+
+
# 目录
* [IO模型介�](#io模型介�)
* [阻塞 I/O(blocking IO)](#阻塞-io(blocking-io))
diff --git "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232JAVA\344\270\255\345\216\237\347\224\237\347\232\204socket\351\200\232\344\277\241\346\234\272\345\210\266.md" "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232JAVA\344\270\255\345\216\237\347\224\237\347\232\204socket\351\200\232\344\277\241\346\234\272\345\210\266.md"
index 32a6684..04f25ab 100644
--- "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232JAVA\344\270\255\345\216\237\347\224\237\347\232\204socket\351\200\232\344\277\241\346\234\272\345\210\266.md"
+++ "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232JAVA\344\270\255\345\216\237\347\224\237\347\232\204socket\351\200\232\344\277\241\346\234\272\345\210\266.md"
@@ -1,3 +1,13 @@
+# 目录
+
+ * [当�环境](#当�环境)
+ * [处� socket 输入输出�](#处�-socket-输入输出�)
+ * [结果展示](#结果展示)
+ * [请求模型优化](#请求模型优化)
+ * [补充1:TCP客户端与�务端](#补充1:tcp客户端与�务端)
+ * [补充2:UDP客户端和�务端](#补充2:udp客户端和�务端)
+
+
本文转自:https://github.com/jasonGeng88/blog
æœ¬ç³»åˆ—æ–‡ç« å°†æ•´ç�†åˆ°æˆ‘在GitHub上的《Javaé�¢è¯•指å�—》仓库,更多精彩内容请到我的仓库里查看
diff --git "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232JavaNIO\344\270\200\346\255\245\346\255\245\346\236\204\345\273\272IO\345\244\232\350\267\257\345\244\215\347\224\250\347\232\204\350\257\267\346\261\202\346\250\241\345\236\213.md" "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232JavaNIO\344\270\200\346\255\245\346\255\245\346\236\204\345\273\272IO\345\244\232\350\267\257\345\244\215\347\224\250\347\232\204\350\257\267\346\261\202\346\250\241\345\236\213.md"
index 65d0917..47e6d17 100644
--- "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232JavaNIO\344\270\200\346\255\245\346\255\245\346\236\204\345\273\272IO\345\244\232\350\267\257\345\244\215\347\224\250\347\232\204\350\257\267\346\261\202\346\250\241\345\236\213.md"
+++ "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232JavaNIO\344\270\200\346\255\245\346\255\245\346\236\204\345\273\272IO\345\244\232\350\267\257\345\244\215\347\224\250\347\232\204\350\257\267\346\261\202\346\250\241\345\236\213.md"
@@ -1,3 +1,13 @@
+# 目录
+
+ * [当�环境](#当�环境)
+ * [代ç �地å�€](#代ç �地å�€)
+ * [知识点](#知识点)
+ * [获� socket 连接](#获�-socket-连接)
+ * [完整示例](#完整示例)
+ * [处�连接就绪事件](#处�连接就绪事件)
+
+
本文转载自:[https://github.com/jasonGeng88/blog](https://github.com/jasonGeng88/blog)
æœ¬ç³»åˆ—æ–‡ç« å°†æ•´ç�†åˆ°æˆ‘在GitHub上的《Javaé�¢è¯•指å�—》仓库,更多精彩内容请到我的仓库里查看
@@ -474,4 +484,4 @@ public class NioNonBlockingHttpClient {
````

-本文从 nio 的阻塞方å¼�讲起,介ç»�了阻塞 I/O 与é�žé˜»å¡ž I/O 的区别,以å�Šåœ¨ nio ä¸‹æ˜¯å¦‚ä½•ä¸€æ¥æ¥æž„建一个 IO 多路å¤�用的模型的客户端。文ä¸éœ€è¦�ç�†è§£çš„内容比较多,如果有ç�†è§£é”™è¯¯çš„地方,欢迎指æ£~
\ No newline at end of file
+本文从 nio 的阻塞方å¼�讲起,介ç»�了阻塞 I/O 与é�žé˜»å¡ž I/O 的区别,以å�Šåœ¨ nio ä¸‹æ˜¯å¦‚ä½•ä¸€æ¥æ¥æž„建一个 IO 多路å¤�用的模型的客户端。文ä¸éœ€è¦�ç�†è§£çš„内容比较多,如果有ç�†è§£é”™è¯¯çš„地方,欢迎指æ£~
diff --git "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232Java\351\235\236\351\230\273\345\241\236IO\345\222\214\345\274\202\346\255\245IO.md" "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232Java\351\235\236\351\230\273\345\241\236IO\345\222\214\345\274\202\346\255\245IO.md"
index 2837b73..35be566 100644
--- "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232Java\351\235\236\351\230\273\345\241\236IO\345\222\214\345\274\202\346\255\245IO.md"
+++ "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232Java\351\235\236\351\230\273\345\241\236IO\345\222\214\345\274\202\346\255\245IO.md"
@@ -1,3 +1,18 @@
+# 目录
+
+* [目录](#目录)
+ * [阻塞模� IO](#阻塞模�-io)
+ * [�阻塞 IO](#�阻塞-io)
+ * [NIO.2 å¼‚æ¥ IO](#nio2-异æ¥-io)
+ * [1�返回 Future 实例](#1�返回-future-实例)
+ * [2��供 CompletionHandler 回调函数](#2��供-completionhandler-回调函数)
+ * [AsynchronousFileChannel](#asynchronousfilechannel)
+ * [AsynchronousServerSocketChannel](#asynchronousserversocketchannel)
+ * [AsynchronousSocketChannel](#asynchronoussocketchannel)
+ * [Asynchronous Channel Groups](#asynchronous-channel-groups)
+ * [�结](#�结)
+
+
# 目录
* [阻塞模� IO](#阻塞模�-io)
* [�阻塞 IO](#�阻塞-io)
diff --git "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232LinuxEpoll\345\256\236\347\216\260\345\216\237\347\220\206\350\257\246\350\247\243.md" "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232LinuxEpoll\345\256\236\347\216\260\345\216\237\347\220\206\350\257\246\350\247\243.md"
index 8a4ec27..41852cd 100644
--- "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232LinuxEpoll\345\256\236\347\216\260\345\216\237\347\220\206\350\257\246\350\247\243.md"
+++ "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232LinuxEpoll\345\256\236\347\216\260\345\216\237\347\220\206\350\257\246\350\247\243.md"
@@ -1,3 +1,14 @@
+# 目录
+
+ * [为什么� I/O 多路�用](#为什么�-io-多路�用)
+ * [select](#select)
+ * [poll](#poll)
+ * [epoll](#epoll)
+ * [epoll_create 用�创建一个 epoll �述符:](#epoll_create-用�创建一个-epoll-�述符:)
+ * [epoll_ctl 用æ�¥å¢ž/åˆ /æ”¹å†…æ ¸ä¸çš„事件表:](#epoll_ctl-用æ�¥å¢žåˆ æ”¹å†…æ ¸ä¸çš„事件表:)
+ * [epoll_wait 用æ�¥ç‰å¾…事件](#epoll_wait-用æ�¥ç‰å¾…事件)
+
+
æœ¬ç³»åˆ—æ–‡ç« å°†æ•´ç�†åˆ°æˆ‘在GitHub上的《Javaé�¢è¯•指å�—》仓库,更多精彩内容请到我的仓库里查看
> https://github.com/h2pl/Java-Tutorial
diff --git "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232Tomcat\344\270\255\347\232\204Connector\346\272\220\347\240\201\345\210\206\346\236\220\357\274\210NIO\357\274\211.md" "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232Tomcat\344\270\255\347\232\204Connector\346\272\220\347\240\201\345\210\206\346\236\220\357\274\210NIO\357\274\211.md"
index 2a3740d..7404a6e 100644
--- "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232Tomcat\344\270\255\347\232\204Connector\346\272\220\347\240\201\345\210\206\346\236\220\357\274\210NIO\357\274\211.md"
+++ "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232Tomcat\344\270\255\347\232\204Connector\346\272\220\347\240\201\345\210\206\346\236\220\357\274\210NIO\357\274\211.md"
@@ -1,3 +1,17 @@
+# 目录
+
+* [目录](#目录)
+ * [�言](#�言)
+ * [æº�ç �环境准备](#æº�ç �环境准备)
+ * [endpoint](#endpoint)
+ * [init 过程分�](#init-过程分�)
+ * [start 过程分�](#start-过程分�)
+ * [Acceptor](#acceptor)
+ * [Poller](#poller)
+ * [processKey](#processkey)
+ * [总结](#总结)
+
+
# 目录
* [�言](#�言)
* [æº�ç �环境准备](#æº�ç �环境准备)
diff --git "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232\345\237\272\344\272\216NIO\347\232\204\347\275\221\347\273\234\347\274\226\347\250\213\346\241\206\346\236\266Netty.md" "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232\345\237\272\344\272\216NIO\347\232\204\347\275\221\347\273\234\347\274\226\347\250\213\346\241\206\346\236\266Netty.md"
index fd4cdf2..f2d39e8 100644
--- "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232\345\237\272\344\272\216NIO\347\232\204\347\275\221\347\273\234\347\274\226\347\250\213\346\241\206\346\236\266Netty.md"
+++ "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232\345\237\272\344\272\216NIO\347\232\204\347\275\221\347\273\234\347\274\226\347\250\213\346\241\206\346\236\266Netty.md"
@@ -1,3 +1,23 @@
+# 目录
+
+* [目录](#目录)
+ * [Netty概述](#netty概述)
+ * [Netty简介](#netty简介)
+ * [Netty都有哪些组件?](#netty都有哪些组件?)
+ * [Netty是如何处�连接请求和业务逻辑的呢?](#netty是如何处�连接请求和业务逻辑的呢?)
+ * [如何�置一个Netty应用?](#如何�置一个netty应用?)
+ * [Netty是如何处�数�的?](#netty是如何处�数�的?)
+ * [如何处�我们的业务逻辑?](#如何处�我们的业务逻辑?)
+ * [ByteBuf](#bytebuf)
+ * [Channel](#channel)
+ * [ChannelHandler](#channelhandler)
+ * [ChannelPipeline](#channelpipeline)
+ * [EventLoop](#eventloop)
+ * [Bootstrap](#bootstrap)
+ * [Echo示例](#echo示例)
+ * [�考文献](#�考文献)
+
+
# 目录
* [Netty概述](#netty概述)
* [etty简介](#etty简介)
diff --git "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232\346\265\205\346\236\220NIO\345\214\205\344\270\255\347\232\204Buffer\343\200\201Channel\345\222\214Selector.md" "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232\346\265\205\346\236\220NIO\345\214\205\344\270\255\347\232\204Buffer\343\200\201Channel\345\222\214Selector.md"
index 020f65f..5d47624 100644
--- "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232\346\265\205\346\236\220NIO\345\214\205\344\270\255\347\232\204Buffer\343\200\201Channel\345\222\214Selector.md"
+++ "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232\346\265\205\346\236\220NIO\345\214\205\344\270\255\347\232\204Buffer\343\200\201Channel\345\222\214Selector.md"
@@ -1,3 +1,22 @@
+# 目录
+
+* [目录](#目录)
+ * [Buffer](#buffer)
+ * [position�limit�capacity](#position�limit�capacity)
+ * [�始化 Buffer](#�始化-buffer)
+ * [å¡«å…… Buffer](#å¡«å……-buffer)
+ * [æ��å�– Buffer ä¸çš„值](#æ��å�–-buffer-ä¸çš„值)
+ * [mark() & reset()](#mark--reset)
+ * [rewind() & clear() & compact()](#rewind--clear--compact)
+ * [Channel](#channel)
+ * [FileChannel](#filechannel)
+ * [SocketChannel](#socketchannel)
+ * [ServerSocketChannel](#serversocketchannel)
+ * [DatagramChannel](#datagramchannel)
+ * [Selector](#selector)
+ * [�结](#�结)
+
+
# 目录
* [Buffer](#buffer)
* [position�limit�capacity](#position�limit�capacity)
diff --git "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232\346\265\205\346\236\220mmap\345\222\214DirectBuffer.md" "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232\346\265\205\346\236\220mmap\345\222\214DirectBuffer.md"
index f50c0df..8256703 100644
--- "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232\346\265\205\346\236\220mmap\345\222\214DirectBuffer.md"
+++ "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232\346\265\205\346\236\220mmap\345\222\214DirectBuffer.md"
@@ -1,3 +1,30 @@
+# 目录
+
+* [目录](#目录)
+* [mmap基础概念](#mmap基础概念)
+* [mmapå†…å˜æ˜ 射原ç�†](#mmapå†…å˜æ˜ 射原ç�†)
+* [mmap和常规文件�作的区别](#mmap和常规文件�作的区别)
+* [mmap优点总结](#mmap优点总结)
+* [mmap使用细节](#mmap使用细节)
+ * [å †å¤–å†…å˜](#å †å¤–å†…å˜)
+ * [在讲解DirectByteBuffer之�,需�先简�了解两个知识点](#在讲解directbytebuffer之�,需�先简�了解两个知识点)
+ * [javaå¼•ç”¨ç±»åž‹ï¼Œå› ä¸ºDirectByteBuffer是通过虚引用(Phantom Reference)æ�¥å®žçŽ°å †å¤–å†…å˜çš„释放的。](#javaå¼•ç”¨ç±»åž‹ï¼Œå› ä¸ºdirectbytebuffer是通过虚引用phantom-referenceæ�¥å®žçŽ°å †å¤–å†…å˜çš„释放的。)
+ * [关于linuxçš„å†…æ ¸æ€�和用户æ€�](#关于linuxçš„å†…æ ¸æ€�和用户æ€�)
+ * [DirectByteBuffer ———— 直接缓冲](#directbytebuffer--直接缓冲)
+ * [DirectByteBufferå †å¤–å†…å˜çš„创建和回收的æº�ç �解读](#directbytebufferå †å¤–å†…å˜çš„创建和回收的æº�ç �解读)
+ * [å †å¤–å†…å˜åˆ†é…�](#å †å¤–å†…å˜åˆ†é…�)
+ * [Bits.reserveMemory(size, cap) 方法](#bitsreservememorysize-cap-方法)
+ * [å †å¤–å†…å˜å›žæ”¶](#å †å¤–å†…å˜å›žæ”¶)
+ * [通过é…�ç½®å�‚数的方å¼�æ�¥å›žæ”¶å †å¤–内å˜](#通过é…�ç½®å�‚数的方å¼�æ�¥å›žæ”¶å †å¤–内å˜)
+ * [å †å¤–å†…å˜é‚£äº›äº‹](#å †å¤–å†…å˜é‚£äº›äº‹)
+ * [ä½¿ç”¨å †å¤–å†…å˜çš„åŽŸå› ](#ä½¿ç”¨å †å¤–å†…å˜çš„åŽŸå› )
+ * [ä»€ä¹ˆæƒ…å†µä¸‹ä½¿ç”¨å †å¤–å†…å˜](#ä»€ä¹ˆæƒ…å†µä¸‹ä½¿ç”¨å †å¤–å†…å˜)
+ * [å †å¤–å†…å˜ VS å†…å˜æ± ](#å †å¤–å†…å˜-vs-å†…å˜æ± )
+ * [å †å¤–å†…å˜çš„特点](#å †å¤–å†…å˜çš„特点)
+ * [å †å¤–å†…å˜çš„一些问题](#å †å¤–å†…å˜çš„一些问题)
+ * [å�‚è€ƒæ–‡ç« ](#å�‚è€ƒæ–‡ç« )
+
+
# 目录
* [mmap基础概念](#mmap基础概念)
* [mmapå†…å˜æ˜ 射原ç�†](#mmapå†…å˜æ˜ 射原ç�†)
diff --git "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232\346\265\205\350\260\210Linux\344\270\255Selector\347\232\204\345\256\236\347\216\260\345\216\237\347\220\206.md" "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232\346\265\205\350\260\210Linux\344\270\255Selector\347\232\204\345\256\236\347\216\260\345\216\237\347\220\206.md"
index 02dc4e4..550f7ab 100644
--- "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232\346\265\205\350\260\210Linux\344\270\255Selector\347\232\204\345\256\236\347\216\260\345\216\237\347\220\206.md"
+++ "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232\346\265\205\350\260\210Linux\344\270\255Selector\347\232\204\345\256\236\347\216\260\345\216\237\347\220\206.md"
@@ -1,3 +1,22 @@
+# 目录
+
+* [目录](#目录)
+ * [概述](#概述)
+ * [Selectorçš„ä¸çš„é‡�è¦�属性](#selectorçš„ä¸çš„é‡�è¦�属性)
+ * [Selector æº�ç �è§£æž�](#selector-æº�ç �è§£æž�)
+ * [1�Selector的构建](#1�selector的构建)
+ * [接下�看下 selector.open():](#接下�看下-selectoropen:)
+ * [EPollSelectorImpl](#epollselectorimpl)
+ * [EPollArrayWrapper](#epollarraywrapper)
+ * [ServerSocketChannel的构建](#serversocketchannel的构建)
+ * [将ServerSocketChannel注册到Selector](#将serversocketchannel注册到selector)
+ * [EPollSelectorImpl. implRegister](#epollselectorimpl-implregister)
+ * [Selection�作](#selection�作)
+ * [epoll原�](#epoll原�)
+ * [�记](#�记)
+ * [å�‚è€ƒæ–‡ç« ](#å�‚è€ƒæ–‡ç« )
+
+
# 目录
* [概述](#概述)
* [Selectorçš„ä¸çš„é‡�è¦�属性](#selectorçš„ä¸çš„é‡�è¦�属性)
diff --git "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232\346\267\261\345\272\246\350\247\243\350\257\273Tomcat\344\270\255\347\232\204NIO\346\250\241\345\236\213.md" "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232\346\267\261\345\272\246\350\247\243\350\257\273Tomcat\344\270\255\347\232\204NIO\346\250\241\345\236\213.md"
index ad909d5..65f5206 100644
--- "a/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232\346\267\261\345\272\246\350\247\243\350\257\273Tomcat\344\270\255\347\232\204NIO\346\250\241\345\236\213.md"
+++ "b/docs/java/network-programming/Java\347\275\221\347\273\234\347\274\226\347\250\213\344\270\216NIO\350\257\246\350\247\243\357\274\232\346\267\261\345\272\246\350\247\243\350\257\273Tomcat\344\270\255\347\232\204NIO\346\250\241\345\236\213.md"
@@ -1,3 +1,16 @@
+# 目录
+
+* [目录](#目录)
+ * [一�I/O�用模型解读](#一�io�用模型解读)
+ * [二�TOMCAT对IO模型的支�](#二�tomcat对io模型的支�)
+ * [三ã€�TOMCATä¸NIOçš„é…�置与使用](#三ã€�tomcatä¸nioçš„é…�置与使用)
+ * [四�NioEndpoint组件关系图解读](#四�nioendpoint组件关系图解读)
+ * [五�NioEndpoint执行�列图](#五�nioendpoint执行�列图)
+ * [å…ã€�NioEndpointæº�ç �解读](#å…ã€�nioendpointæº�ç �解读)
+ * [七�关于性能](#七�关于性能)
+ * [八�总结](#八�总结)
+
+
# 目录
* [一�I/O�用模型解读](#一�io�用模型解读)
* [二�TOMCAT对IO模型的支�](#二�tomcat对io模型的支�)
diff --git a/src/main/java/md/mdToc.java b/src/main/java/md/mdToc.java
index 0cf8f98..2fb42bd 100644
--- a/src/main/java/md/mdToc.java
+++ b/src/main/java/md/mdToc.java
@@ -4,7 +4,7 @@
public class mdToc {
public static void main(String[] args) {
- String path = "D:\\idea_project\\JavaTutorial\\docs\\java\\jvm\\temp";
+ String path = "D:\\idea_project\\JavaTutorial\\docs\\java-web\\temp";
AtxMarkdownToc.newInstance().genTocDir(path);
}
}
From 928058d55cc5f6bb6ed77dc7f6d8504d8c708d75 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=BB=84=E5=B0=8F=E6=96=9C?= <362294931@qq.com>
Date: Sat, 15 Apr 2023 11:48:55 +0800
Subject: [PATCH 08/39] add SpringBoot1
---
ReadMe.md | 32 +--
...15\344\270\226\344\273\212\347\224\237.md" | 246 ++++++++++++++++++
...37\347\220\206\350\257\246\350\247\243.md" | 0
...37\347\220\206\350\257\246\350\247\243.md" | 0
...4\232SpringAOP\346\246\202\350\277\260.md" | 0
...40\350\275\275\350\277\207\347\250\213.md" | 0
...13\345\212\241\346\246\202\350\277\260.md" | 0
...20\347\240\201\345\211\226\346\236\220.md" | 0
...\274\232Spring\346\246\202\350\277\260.md" | 0
...70\345\277\203\346\265\201\347\250\213.md" | 0
...07\347\250\213\345\210\206\346\236\220.md" | 0
...\243\347\241\256\347\232\204Controller.md" | 0
...67\346\261\202\350\275\254\345\217\221.md" | 0
...4\232SpringMVC\346\246\202\350\277\260.md" | 0
...43\346\236\220\345\216\237\347\220\206.md" | 0
...5\277\265\344\270\216DispatcherServlet.md" | 0
...6@ResponseBody\346\263\250\350\247\243.md" | 0
...45\350\257\206\346\270\205\345\215\225.md" | 0
18 files changed, 262 insertions(+), 16 deletions(-)
create mode 100644 "docs/spring/SpringBoot/SpringBoot\347\232\204\345\211\215\344\270\226\344\273\212\347\224\237.md"
rename "docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232AOP\345\256\236\347\216\260\345\216\237\347\220\206\350\257\246\350\247\243.md" => "docs/spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232AOP\345\256\236\347\216\260\345\216\237\347\220\206\350\257\246\350\247\243.md" (100%)
rename "docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232JDK\345\222\214cglib\345\212\250\346\200\201\344\273\243\347\220\206\345\216\237\347\220\206\350\257\246\350\247\243.md" => "docs/spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232JDK\345\222\214cglib\345\212\250\346\200\201\344\273\243\347\220\206\345\216\237\347\220\206\350\257\246\350\247\243.md" (100%)
rename "docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232SpringAOP\346\246\202\350\277\260.md" => "docs/spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232SpringAOP\346\246\202\350\277\260.md" (100%)
rename "docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232SpringIOC\345\256\271\345\231\250\347\232\204\345\212\240\350\275\275\350\277\207\347\250\213.md" => "docs/spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232SpringIOC\345\256\271\345\231\250\347\232\204\345\212\240\350\275\275\350\277\207\347\250\213.md" (100%)
rename "docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232Spring\344\272\213\345\212\241\346\246\202\350\277\260.md" => "docs/spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232Spring\344\272\213\345\212\241\346\246\202\350\277\260.md" (100%)
rename "docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232Spring\344\272\213\345\212\241\346\272\220\347\240\201\345\211\226\346\236\220.md" => "docs/spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232Spring\344\272\213\345\212\241\346\272\220\347\240\201\345\211\226\346\236\220.md" (100%)
rename "docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232Spring\346\246\202\350\277\260.md" => "docs/spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232Spring\346\246\202\350\277\260.md" (100%)
rename "docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232\345\210\235\346\216\242SpringIOC\346\240\270\345\277\203\346\265\201\347\250\213.md" => "docs/spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232\345\210\235\346\216\242SpringIOC\346\240\270\345\277\203\346\265\201\347\250\213.md" (100%)
rename "docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232\346\207\222\345\212\240\350\275\275\347\232\204\345\215\225\344\276\213Bean\350\216\267\345\217\226\350\277\207\347\250\213\345\210\206\346\236\220.md" => "docs/spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232\346\207\222\345\212\240\350\275\275\347\232\204\345\215\225\344\276\213Bean\350\216\267\345\217\226\350\277\207\347\250\213\345\210\206\346\236\220.md" (100%)
rename "docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232DispatcherServlet\345\246\202\344\275\225\346\211\276\345\210\260\346\255\243\347\241\256\347\232\204Controller.md" => "docs/spring/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232DispatcherServlet\345\246\202\344\275\225\346\211\276\345\210\260\346\255\243\347\241\256\347\232\204Controller.md" (100%)
rename "docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232DispatcherServlet\347\232\204\345\210\235\345\247\213\345\214\226\344\270\216\350\257\267\346\261\202\350\275\254\345\217\221.md" => "docs/spring/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232DispatcherServlet\347\232\204\345\210\235\345\247\213\345\214\226\344\270\216\350\257\267\346\261\202\350\275\254\345\217\221.md" (100%)
rename "docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232SpringMVC\346\246\202\350\277\260.md" => "docs/spring/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232SpringMVC\346\246\202\350\277\260.md" (100%)
rename "docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232SpringMVC\347\232\204\350\247\206\345\233\276\350\247\243\346\236\220\345\216\237\347\220\206.md" => "docs/spring/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232SpringMVC\347\232\204\350\247\206\345\233\276\350\247\243\346\236\220\345\216\237\347\220\206.md" (100%)
rename "docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232SpringMVC\350\256\276\350\256\241\347\220\206\345\277\265\344\270\216DispatcherServlet.md" => "docs/spring/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232SpringMVC\350\256\276\350\256\241\347\220\206\345\277\265\344\270\216DispatcherServlet.md" (100%)
rename "docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232\346\266\210\346\201\257\350\275\254\346\215\242\345\231\250HttpMessageConverter\344\270\216@ResponseBody\346\263\250\350\247\243.md" => "docs/spring/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232\346\266\210\346\201\257\350\275\254\346\215\242\345\231\250HttpMessageConverter\344\270\216@ResponseBody\346\263\250\350\247\243.md" (100%)
rename "docs/java-web/Spring/\347\273\231\344\275\240\344\270\200\344\273\275SpringBoot\347\237\245\350\257\206\346\270\205\345\215\225.md" => "docs/spring/\347\273\231\344\275\240\344\270\200\344\273\275SpringBoot\347\237\245\350\257\206\346\270\205\345\215\225.md" (100%)
diff --git a/ReadMe.md b/ReadMe.md
index dc53ae6..c83ee64 100644
--- a/ReadMe.md
+++ b/ReadMe.md
@@ -144,28 +144,28 @@
### Spring
-* [Springæº�ç �剖æž�:Spring概述](docs/java-web/Spring/Springæº�ç �剖æž�:Spring概述.md)
-* [Springæº�ç �剖æž�:åˆ�探SpringIOCæ ¸å¿ƒæµ�程](docs/java-web/Spring/Springæº�ç �剖æž�:åˆ�探SpringIOCæ ¸å¿ƒæµ�程.md)
-* [Springæº�ç �剖æž�:SpringIOCå®¹å™¨çš„åŠ è½½è¿‡ç¨‹ ](docs/java-web/Spring/Springæº�ç �剖æž�:SpringIOCå®¹å™¨çš„åŠ è½½è¿‡ç¨‹.md)
-* [Springæº�ç �剖æž�ï¼šæ‡’åŠ è½½çš„å�•例Bean获å�–过程分æž�](docs/java-web/Spring/Springæº�ç �剖æž�ï¼šæ‡’åŠ è½½çš„å�•例Bean获å�–过程分æž�.md)
-* [Springæº�ç �剖æž�:JDKå’Œcglib动æ€�代ç�†åŽŸç�†è¯¦è§£ ](docs/java-web/Spring/Springæº�ç �剖æž�:JDKå’Œcglib动æ€�代ç�†åŽŸç�†è¯¦è§£.md)
-* [Springæº�ç �剖æž�:SpringAOP概述](docs/java-web/Spring/Springæº�ç �剖æž�:SpringAOP概述.md)
-* [Springæº�ç �剖æž�:AOP实现原ç�†è¯¦è§£ ](docs/java-web/Spring/Springæº�ç �剖æž�:AOP实现原ç�†è¯¦è§£.md)
-* [Springæº�ç �剖æž�:Spring事务概述](docs/java-web/Spring/Springæº�ç �剖æž�:Spring事务概述.md)
-* [Springæº�ç �剖æž�:Spring事务æº�ç �剖æž�](docs/java-web/Spring/Springæº�ç �剖æž�:Spring事务æº�ç �剖æž�.md)
+* [Springæº�ç �剖æž�:Spring概述](docs/spring/Springæº�ç �剖æž�:Spring概述.md)
+* [Springæº�ç �剖æž�:åˆ�探SpringIOCæ ¸å¿ƒæµ�程](docs/spring/Springæº�ç �剖æž�:åˆ�探SpringIOCæ ¸å¿ƒæµ�程.md)
+* [Springæº�ç �剖æž�:SpringIOCå®¹å™¨çš„åŠ è½½è¿‡ç¨‹ ](docs/spring/Springæº�ç �剖æž�:SpringIOCå®¹å™¨çš„åŠ è½½è¿‡ç¨‹.md)
+* [Springæº�ç �剖æž�ï¼šæ‡’åŠ è½½çš„å�•例Bean获å�–过程分æž�](docs/spring/Springæº�ç �剖æž�ï¼šæ‡’åŠ è½½çš„å�•例Bean获å�–过程分æž�.md)
+* [Springæº�ç �剖æž�:JDKå’Œcglib动æ€�代ç�†åŽŸç�†è¯¦è§£ ](docs/spring/Springæº�ç �剖æž�:JDKå’Œcglib动æ€�代ç�†åŽŸç�†è¯¦è§£.md)
+* [Springæº�ç �剖æž�:SpringAOP概述](docs/spring/Springæº�ç �剖æž�:SpringAOP概述.md)
+* [Springæº�ç �剖æž�:AOP实现原ç�†è¯¦è§£ ](docs/spring/Springæº�ç �剖æž�:AOP实现原ç�†è¯¦è§£.md)
+* [Springæº�ç �剖æž�:Spring事务概述](docs/spring/Springæº�ç �剖æž�:Spring事务概述.md)
+* [Springæº�ç �剖æž�:Spring事务æº�ç �剖æž�](docs/spring/Springæº�ç �剖æž�:Spring事务æº�ç �剖æž�.md)
### SpringMVC
-* [SpringMVCæº�ç �分æž�:SpringMVC概述](docs/java-web/SpringMVC/SpringMVCæº�ç �分æž�:SpringMVC概述.md)
-* [SpringMVCæº�ç �分æž�:SpringMVC设计ç�†å¿µä¸ŽDispatcherServlet](docs/java-web/SpringMVC/SpringMVCæº�ç �分æž�:SpringMVC设计ç�†å¿µä¸ŽDispatcherServlet.md)
-* [SpringMVCæº�ç �分æž�:DispatcherServletçš„åˆ�始化与请求转å�‘ ](docs/java-web/SpringMVC/SpringMVCæº�ç �分æž�:DispatcherServletçš„åˆ�始化与请求转å�‘.md)
-* [SpringMVCæº�ç �分æž�:DispatcherServlet如何找到æ£ç¡®çš„Controller ](docs/java-web/SpringMVC/SpringMVCæº�ç �分æž�:DispatcherServlet如何找到æ£ç¡®çš„Controller.md)
-* [SpringMVCæº�ç �剖æž�:消æ�¯è½¬æ�¢å™¨HttpMessageConverter与@ResponseBody注解](docs/java-web/SpringMVC/SpringMVCæº�ç �剖æž�:消æ�¯è½¬æ�¢å™¨HttpMessageConverter与@ResponseBody注解.md)
-* [SpringMVCæº�ç �分æž�:SpringMVC的视图解æž�原ç�† ](docs/java-web/SpringMVC/SpringMVCæº�ç �分æž�:SpringMVC的视图解æž�原ç�†.md)
+* [SpringMVCæº�ç �分æž�:SpringMVC概述](docs/spring/springMVC/SpringMVCæº�ç �分æž�:SpringMVC概述.md)
+* [SpringMVCæº�ç �分æž�:SpringMVC设计ç�†å¿µä¸ŽDispatcherServlet](docs/spring/springMVC/SpringMVCæº�ç �分æž�:SpringMVC设计ç�†å¿µä¸ŽDispatcherServlet.md)
+* [SpringMVCæº�ç �分æž�:DispatcherServletçš„åˆ�始化与请求转å�‘ ](docs/spring/springMVC/SpringMVCæº�ç �分æž�:DispatcherServletçš„åˆ�始化与请求转å�‘.md)
+* [SpringMVCæº�ç �分æž�:DispatcherServlet如何找到æ£ç¡®çš„Controller ](docs/spring/springMVC/SpringMVCæº�ç �分æž�:DispatcherServlet如何找到æ£ç¡®çš„Controller.md)
+* [SpringMVCæº�ç �剖æž�:消æ�¯è½¬æ�¢å™¨HttpMessageConverter与@ResponseBody注解](docs/spring/springMVC/SpringMVCæº�ç �剖æž�:消æ�¯è½¬æ�¢å™¨HttpMessageConverter与@ResponseBody注解.md)
+* [SpringMVCæº�ç �分æž�:SpringMVC的视图解æž�原ç�† ](docs/spring/springMVC/SpringMVCæº�ç �分æž�:SpringMVC的视图解æž�原ç�†.md)
### SpringBoot
-todo
+* [SpringBoot系列:SpringBoot的�世今生](docs/spring/SpringBoot/SpringBoot的�世今生.md)
### SpringCloud
diff --git "a/docs/spring/SpringBoot/SpringBoot\347\232\204\345\211\215\344\270\226\344\273\212\347\224\237.md" "b/docs/spring/SpringBoot/SpringBoot\347\232\204\345\211\215\344\270\226\344\273\212\347\224\237.md"
new file mode 100644
index 0000000..c524bd5
--- /dev/null
+++ "b/docs/spring/SpringBoot/SpringBoot\347\232\204\345\211\215\344\270\226\344\273\212\347\224\237.md"
@@ -0,0 +1,246 @@
+# SpringBootµÄǰÊÀ½ñÉú
+
+Spring Boot 2.0 µÄÍÆ³öÓÖ¼¤ÆðÁËÒ»Õóѧϰ Spring Boot ÈÈ£¬¾Íµ¥´ÓÎÒ¸öÈ˵IJ©¿ÍµÄ·ÃÎÊÁ¿´ó·ùÔö¼Ó¾Í¿ÉÒÔ¸ÐÊܵ½´ó¼Ò¶Ôѧϰ Spring Boot µÄÈÈÇ飬ÄÇôÔÚÕâô¶àÈËÈÈÖÔÓÚѧϰ Spring Boot ֮ʱ£¬ÎÒ×Ô¼ºÒ²ÔÚ˼¿¼£º Spring Boot µ®ÉúµÄ±³¾°ÊÇʲô£¿Spring ÆóÒµÓÖÊÇ»ùÓÚʲôÑùµÄ¿¼ÂÇ´´½¨ Spring Boot? ´«Í³ÆóҵʹÓà Spring Boot »á¸øÎÒÃÇ´øÀ´Ê²Ã´Ñù±ä¸ï?
+
+´ø×ÅÕâЩÎÊÌ⣬ÎÒÃÇÒ»ÆðÀ´Á˽âÏ Spring Boot µ½µ×ÊÇʲô?
+
+## Spring ÀúÊ·
+
+˵Æð Spring Boot ÎÒÃDz»µÃ²»ÏÈÁ˽âһϠSpring Õâ¸öÆóÒµ£¬²»½öÒòΪ Spring Boot À´Ô´ÓÚ Spirng ´ó¼Ò×壬¶øÇÒ Spring Boot µÄµ®ÉúºÍ Sping ¿ò¼ÜµÄ·¢Õ¹Ï¢Ï¢Ïà¹Ø¡£
+
+ʱ¼ä»Øµ½2002Ä꣬µ±Ê±ÕýÊÇ Java EE ºÍ EJB ´óÐÐÆäµÀµÄʱºò£¬ºÜ¶àÖªÃû¹«Ë¾¶¼ÊDzÉÓô˼¼Êõ·½°¸½øÐÐÏîÄ¿¿ª·¢¡£ÕâʱºòÓÐÒ»¸öÃÀ¹úµÄС»ï×ÓÈÏΪ EJB Ì«¹ýÓ·Ö×£¬²¢²»ÊÇËùÓеÄÏîÄ¿¶¼ÐèҪʹÓà EJB ÕâÖÖ´óÐÍ¿ò¼Ü£¬Ó¦¸Ã»áÓÐÒ»ÖÖ¸üºÃµÄ·½°¸À´½â¾öÕâ¸öÎÊÌâ¡£
+
+ΪÁËÖ¤Ã÷ËûµÄÏë·¨ÊÇÕýÈ·µÄ£¬ÓÚ2002Äê10ÔÂÉõÖÁдÁËÒ»±¾Êé¡¶ Expert One-on-One J2EE ¡·£¬½éÉÜÁ˵±Ê± Java ÆóÒµÓ¦ÓóÌÐò¿ª·¢µÄÇé¿ö£¬²¢Ö¸³öÁË Java EE ºÍ EJB ×é¼þ¿ò¼ÜÖдæÔÚµÄһЩÖ÷ҪȱÏÝ¡£ÔÚÕâ±¾ÊéÖУ¬ËûÌá³öÁËÒ»¸ö»ùÓÚÆÕͨ Java ÀàºÍÒÀÀµ×¢ÈëµÄ¸ü¼òµ¥µÄ½â¾ö·½°¸¡£
+
+ÔÚÊéÖУ¬ËûչʾÁËÈçºÎÔÚ²»Ê¹Óà EJB µÄÇé¿öϹ¹½¨¸ßÖÊÁ¿£¬¿ÉÀ©Õ¹µÄÔÚÏß×ùλԤÁôϵͳ¡£ÎªÁ˹¹½¨Ó¦ÓóÌÐò£¬Ëû±àдÁ˳¬¹ý 30,000 ÐеĻù´¡½á¹¹´úÂ룬ÏîÄ¿Öеĸù°üÃüÃûΪ com.interface21£¬ËùÒÔÈËÃÇ×î³õ³ÆÕâÌ׿ªÔ´¿ò¼ÜΪ interface21£¬Ò²¾ÍÊÇ Spring µÄǰÉí¡£
+
+ËûÊÇËÄØ£¬Ëû¾ÍÊÇ´óÃû¶¦¶¦µÄ Rod Johnson £¨ÏÂͼ£©, Rod Johnson ÔÚϤÄá´óѧ²»½ö»ñµÃÁ˼ÆËã»úѧλ£¬Í¬Ê±»¹»ñµÃÁËÒôÀÖѧ룬¸üÁîÈ˳ԾªµÄÊÇÔڻص½Èí¼þ¿ª·¢ÁìÓò֮ǰ£¬Ëû»¹»ñµÃÁËÒôÀÖѧµÄ²©Ê¿Ñ§Î»¡£ÏÖÔÚ Rod Johnson ÒѾÀ뿪ÁË Spring £¬³ÉΪÁËÒ»¸öÌìʹͶ×ÊÈË£¬Í¬Ê±Ò²ÊǶà¸ö¹«Ë¾µÄ¶Ê£¬ÔçÒÑ×ßÉÏÈËÉúáÛ·å¡£
+
+
+
+ÔÚÕâ±¾Êé·¢²¼ºó£¬Ò»¶ÔÒ»µÄ J2EE Éè¼ÆºÍ¿ª·¢Ò»ÅÚ¶øºì¡£Õâ±¾ÊéÃâ·ÑÌṩµÄ´ó²¿·Ö»ù´¡¼Ü¹¹´úÂë¶¼ÊǸ߶ȿÉÖØÓõġ£ 2003 Äê Rod Johnson ºÍͬ°éÔÚ´Ë¿ò¼ÜµÄ»ù´¡ÉÏ¿ª·¢ÁËÒ»¸öȫеĿò¼ÜÃüÃûΪ Spring ,¾Ý Rod Johnson ½éÉÜ Spring ÊÇ´«Í³ J2EE еĿªÊ¼¡£Ëæºó Spring ·¢Õ¹½øÈë¿ì³µµÀ¡£
+
+* 2004 Äê 03 Ô£¬1.0 °æ·¢²¼¡£
+* 2006 Äê 10 Ô£¬2.0 °æ·¢²¼¡£
+* 2007 Äê 11 Ô¸üÃûΪ SpringSource£¬Í¬Ê±·¢²¼ÁË Spring 2.5¡£
+* 2009 Äê 12 Ô£¬Spring 3.0 ·¢²¼¡£
+* 2013 Äê 12 Ô£¬Pivotal Ðû²¼·¢²¼ Spring ¿ò¼Ü 4.0¡£
+* 2017 Äê 09 Ô£¬Spring 5.0 ·¢²¼¡£
+
+## Spring Boot µÄµ®Éú
+
+Ëæ×ÅʹÓà Spring ½øÐпª·¢µÄ¸öÈËºÍÆóÒµÔ½À´Ô½¶à£¬Spring Ò²ÂýÂý´ÓÒ»¸öµ¥Ò»¼ò½àµÄС¿ò¼Ü±ä³ÉÒ»¸ö´ó¶øÈ«µÄ¿ªÔ´Èí¼þ£¬Spring µÄ±ß½ç²»¶ÏµÄ½øÐÐÀ©³ä£¬µ½Á˺óÀ´ Spring ¼¸ºõ¿ÉÒÔ×öÈκÎÊÂÇéÁË£¬ÊÐÃæÉÏÖ÷Á÷µÄ¿ªÔ´Èí¼þ¡¢Öмä¼þ¶¼ÓÐ Spring ¶ÔÓ¦×é¼þÖ§³Ö£¬ÈËÃÇÔÚÏíÓà Spring µÄÕâÖÖ±ãÀûÖ®ºó£¬Ò²Óöµ½ÁËһЩÎÊÌâ¡£
+
+Spring ÿ¼¯³ÉÒ»¸ö¿ªÔ´Èí¼þ£¬¾ÍÐèÒªÔö¼ÓһЩ»ù´¡ÅäÖã¬ÂýÂýµÄËæ×ÅÈËÃÇ¿ª·¢µÄÏîĿԽÀ´Ô½ÅÓ´ó£¬ÍùÍùÐèÒª¼¯³ÉºÜ¶à¿ªÔ´Èí¼þ£¬Òò´ËºóÆÚʹÓà Spirng ¿ª·¢´óÐÍÏîÄ¿ÐèÒªÒýÈëºÜ¶àÅäÖÃÎļþ£¬Ì«¶àµÄÅäÖ÷dz£ÄÑÒÔÀí½â£¬²¢ÈÝÒ×ÅäÖóö´í£¬µ½Á˺óÀ´ÈËÃÇÉõÖÁ³Æ Spring ΪÅäÖõØÓü¡£
+
+Spring ËÆºõÒ²Òâʶµ½ÁËÕâЩÎÊÌ⣬¼±ÐèÓÐÕâôһÌ×Èí¼þ¿ÉÒÔ½â¾öÕâЩÎÊÌ⣬Õâ¸öʱºò΢·þÎñµÄ¸ÅÄîÒ²ÂýÂýÐËÆð£¬¿ìËÙ¿ª·¢Î¢Ð¡¶ÀÁ¢µÄÓ¦ÓñäµÃ¸üΪ¼±ÆÈ£¬Spring ¸ÕºÃ´¦ÔÚÕâôһ¸ö½»²æµãÉÏ£¬ÓÚ 2013 Äê³õ¿ªÊ¼µÄ Spring Boot ÏîÄ¿µÄÑз¢£¬2014Äê4Ô£¬Spring Boot 1.0.0 ·¢²¼¡£
+
+Spring Boot µ®ÉúÖ®³õ£¬¾ÍÊܵ½¿ªÔ´ÉçÇøµÄ³ÖÐø¹Ø×¢£¬Â½ÐøÓÐһЩ¸öÈËºÍÆóÒµ³¢ÊÔ×ÅʹÓÃÁË Spring Boot£¬²¢Ñ¸ËÙϲ»¶ÉÏÁËÕâ¿î¿ªÔ´Èí¼þ¡£Ö±µ½2016Ä꣬ÔÚ¹úÄÚ Spring Boot ²Å±»ÕýÕæÊ¹ÓÃÁËÆðÀ´£¬ÆÚ¼äºÜ¶àÑо¿ Spring Boot µÄ¿ª·¢ÕßÔÚÍøÉÏдÁË´óÁ¿¹ØÓÚ Spring Boot µÄÎÄÕ£¬Í¬Ê±ÓÐһЩ¹«Ë¾ÔÚÆóÒµÄÚ²¿½øÐÐÁËС¹æÄ£µÄʹÓ㬲¢½«Ê¹ÓþÑé·ÖÏíÁ˳öÀ´¡£´Ó2016Äêµ½2018Ä꣬ʹÓà Spring Boot µÄÆóÒµºÍ¸öÈË¿ª·¢ÕßÔ½À´Ô½¶à£¬ÎÒÃÇ´Ó Spring Boot ¹Ø¼ü×ֵİٶÈÖ¸Êý¾Í¿ÉÒÔ¿´³ö¡£
+
+
+
+ÉÏͼΪ2014Äêµ½2018Äê Spring Boot µÄ°Ù¶ÈÖ¸Êý£¬¿ÉÒÔ¿´³ö Spring Boot 2.0 µÄÍÆ³öÒý·¢ÁËËÑË÷¸ß·å¡£
+
+µ±È» Spring Boot ²»ÊÇΪÁËÈ¡´ú Spring ,Spring Boot »ùÓÚ Spring ¿ª·¢£¬ÊÇΪÁËÈÃÈËÃǸüÈÝÒ×µÄʹÓà Spring¡£¿´µ½ Spring Boot µÄÊг¡·´Ó¦£¬Spring ¹Ù·½Ò²·Ç³£ÖØÊÓ Spring Boot µÄºóÐø·¢Õ¹£¬ÒѾ½« Spring Boot ×÷Ϊ¹«Ë¾×î¶¥¼¶µÄÏîÄ¿À´Íƹ㣬·Åµ½Á˹ÙÍøÉϵÚÒ»µÄλÖã¬Òò´ËºóÐø Spring Boot µÄ³ÖÐø·¢Õ¹Ò²±»¿´ºÃ¡£
+
+# »ù±¾½éÉÜ
+
+
+
+ÕâÊÇspring¹ÙÍø¶ÔÓÚspringbootµÄ»ù±¾½éÉÜ
+
+Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can "just run".
+
+We take an opinionated view of the Spring platform and third-party libraries so you can get started with minimum fuss. Most Spring Boot applications need minimal Spring configuration.
+
+¼ò¶øÑÔÖ®£¬¾ÍÊÇÔÚ¸æËßÎÒÃÇ£¬springboot¿ÉÒÔ°ïÖúÎÒÃÇ¿ìËÙ¹¹½¨¶ÀÁ¢²¿ÊðµÄÉú²ú¼¶Ó¦ÓÃ
+
+£¬Ö»ÐèÒªÒ»¸ö´øÓÐ@SpringBootApplication ×¢½âµÄÓ¦ÓÃÈë¿Ú£¬¼´¿É±»Ê¶±ðΪһ¸öspringbootÓ¦ÓÃ
+
+²¢ÇÒ£¬springboot¼Ì³ÐÁË´óÁ¿µÄµÚÈý·½¿â£¬ÎÒÃǽöÐèºÜÉÙÉõÖÁÊÇÍêÈ«²»ÐèÒª¶îÍâµÄÅäÖ㬾ͿÉÒÔ½øÐÐÓ¦Óô£¬ÒòΪspringboot¿ò¼Ü±¾ÉíÒѾ°ïÎÒÃÇÉèÖúÃÁË´óÁ¿µÄĬÈÏÅäÖá£
+
+# »ù±¾ÌØÐÔ
+
+Features
+
+* Create stand-alone Spring applications
+* Embed Tomcat, Jetty or Undertow directly (no need to deploy WAR files)
+* Provide opinionated 'starter' dependencies to simplify your build configuration
+* Automatically configure Spring and 3rd party libraries whenever possible
+* Provide production-ready features such as metrics, health checks, and externalized configuration
+* Absolutely no code generation and no requirement for XML configuration
+
+¹Ù·½¶ÔÓÚspringboot¼¸´óÌØÐÔµÄÃèÊöÈçÉÏ
+
+1¡¢´´½¨Ò»¸ö¶ÀÁ¢²¿ÊðµÄspringÓ¦Óã¬Ëü³£ÓÃÓÚ¶¨Òå΢·þÎñ£¬»òÕßÊÇÒ»¸öwebÓ¦ÓÃ
+
+2¡¢ÄÚÖõÄtomcatÈÝÆ÷£¬ÎÒÃÇÔÙÒ²ÐèÒª°ÑspringÓ¦Óôò°ü³Éwar°ü£¬¶øÊÇÖ»ÐèÒª½«Æä´ò°ü³Éjar°ü½øÐв¿Êð¼´¿É¡£
+
+3¡¢ÌṩstarterÒÀÀµ£¬¸ü¼Ó¼ò»¯ÁËspringbootÉú̬ÖеÄÒÀÀµºÍÅäÖã¬ÀýÈçµ±ÎÒÃÇʹÓÃspringwebÏà¹ØÒÀÀµÊ±£¬ÎÒÃDz»ÐèÒªµ¥¶ÀµØÌí¼Ó¶à¸öspringmvcÏà¹ØµÄmavenÒÀÀµ£¬¶øÊÇÖ±½ÓÒýÓÃspring-boot-starter-web¾Í¿ÉÒÔÁË£¬Õâ¸östarter»á×Ô¶¯ÒýÈëÏà¹ØµÄÒÀÀµ£¬²¢ÇÒ°ïÄã¹ÜÀí°æ±¾ºÅ£¬»á´óÁ¿µØ¼ò»¯ºÍÓÅ»¯ÄãµÄmavenÅäÖÃ
+
+4¡¢×Ô¶¯×°ÅäspringºÍµÚÈý·½¿â£¬ÕâÀïÖ÷ÒªÊÇָͨ¹ý×¢½âºÍÅäÖÃÎļþ½øÐÐ×Ô¶¯×°Å䣬²¢ÇÒ»¹ÓÐһЩÊÇ»ùÓÚÔ¼¶¨µÄ×Ô¶¯×°Åä»úÖÆ£¬Õâ¿ÉÒÔ°ïÎÒÃǽÚÊ¡´óÁ¿µÄ¶îÍâÅäÖã¬Ò²¿ÉÒÔ×Ô¶¯×°ÅäÍⲿjar°üÌṩµÄspringÏà¹ØbeanºÍÅäÖá£
+
+5¡¢ÌṩÁËÉú²ú»·¾³Ïà¹ØµÄÌØÐÔ£¬±ÈÈç¼à¿Ø¡¢Ö¸±ê´òµã¡¢½¡¿µ¼ì²éµÈ¹¦ÄÜ£¬springbootÌṩÁËÇ¿´óµÄÉú̬×é¼þ£¬ÕâÀï²»½ö°üÀ¨springboot×Ô¼ºµÄ×é¼þ£¬Ò²°üÀ¨Ò»Ð©ÍⲿµÄÉú̬×é¼þ¡£
+
+6¡¢²»²»´æÔÚ´úÂëÉú³É£¬Ò²²»ÐèÒªxmlÅäÖÃÎļþ£¬ÕâÖ¤Ã÷ÁËspringbootµÄ¿ò¼ÜÍêÕû¶È£¬ÒÔ¼°¶ÔÓÚÅäÖüò»¯µÄ¼«ÖÂ×·Çó£¬ÎÒÃǽöÐèÒªapplication.properties½øÐлù±¾ÅäÖòÎÊý¹ÜÀí£¬ÄãÒ²²»»áÔÚspringboot±àÒëÆ÷ÕÒµ½¶¯Ì¬Éú³ÉµÄ¶àÓàclassÎļþ¡£
+
+# ºÍSpringµÄ¹ØÏµ
+
+
+
+## SpringFramework½â¾öÁËʲôÎÊÌ⣿
+
+SpringÊÇJavaÆóÒµ°æ£¨Java Enterprise Edition£¬JEE£¬Ò²³ÆJ2EE£©µÄÇáÁ¿¼¶´úÌæÆ·¡£ÎÞÐ迪·¢ÖØÁ¿¼¶µÄEnterpriseJavaBean£¨EJB£©£¬SpringΪÆóÒµ¼¶Java¿ª·¢ÌṩÁËÒ»ÖÖÏà¶Ô¼òµ¥µÄ·½·¨£¬Í¨¹ýÒÀÀµ×¢ÈëºÍÃæÏòÇÐÃæ±à³Ì£¬Óüòµ¥µÄJava¶ÔÏó£¨Plain Old Java Object£¬POJO£©ÊµÏÖÁËEJBµÄ¹¦ÄÜ¡£
+
+1.ʹÓÃSpringµÄIOCÈÝÆ÷,½«¶ÔÏóÖ®¼äµÄÒÀÀµ¹ØÏµ½»¸øSpring,½µµÍ×é¼þÖ®¼äµÄñîºÏÐÔ,ÈÃÎÒÃǸüרעÓÚÓ¦ÓÃÂß¼
+
+2.¿ÉÒÔÌṩÖÚ¶à·þÎñ,ÊÂÎñ¹ÜÀí,WSµÈ¡£
+
+3.ºÜºÃµØÖ§³ÖAOP,·½±ãÃæÏòÇÐÃæ±à³Ì¡£
+
+4.¶ÔÖ÷Á÷µÄ¿ò¼ÜÌṩÁ˺ܺõÉÖ§³Ö,ÈçHibernate,Struts2,JPAµÈ
+
+5.Spring DI»úÖÆ½µµÍÁËÒµÎñ¶ÔÏóÌæ»»µÄ¸´ÔÓÐÔ¡£
+
+6.SpringÊôÓÚµÍÇÖÈë,´úÂëÎÛȾ¼«µÍ¡£
+
+7.SpringµÄ¸ß¶È¿É¿ª·ÅÐÔ,²¢²»Ç¿ÖÆÒÀÀµÓÚSpring,¿ª·¢Õß¿ÉÒÔ×ÔÓÉÑ¡ÔñSpring²¿·Ö»òÈ«²¿
+
+## SpringFrameworkûÓнâ¾öÁËʲôÎÊÌ⣿
+
+ËäÈ»SpringµÄ×é¼þ´úÂëÊÇÇáÁ¿¼¶µÄ£¬µ«ËüµÄÅäÖÃÈ´ÊÇÖØÁ¿¼¶µÄ¡£Ò»¿ªÊ¼£¬SpringÓÃXMLÅäÖ㬶øÇÒÊǺܶàXMLÅäÖá£Spring 2.5ÒýÈëÁË»ùÓÚ×¢½âµÄ×é¼þɨÃ裬ÕâÏû³ýÁË´óÁ¿Õë¶ÔÓ¦ÓóÌÐò×ÔÉí×é¼þµÄÏÔʽXMLÅäÖá£Spring 3.0ÒýÈëÁË»ùÓÚJavaµÄÅäÖã¬ÕâÊÇÒ»ÖÖÀàÐͰ²È«µÄ¿ÉÖØ¹¹ÅäÖ÷½Ê½£¬¿ÉÒÔ´úÌæXML¡£
+
+ËùÓÐÕâЩÅäÖö¼´ú±íÁË¿ª·¢Ê±µÄËðºÄ¡£ÒòΪÔÚ˼¿¼SpringÌØÐÔÅäÖúͽâ¾öÒµÎñÎÊÌâÖ®¼äÐèÒª½øÐÐ˼άÇл»£¬ËùÒÔ±àдÅäÖü·Õ¼Á˱àдӦÓóÌÐòÂß¼µÄʱ¼ä¡£ºÍËùÓпò¼ÜÒ»Ñù£¬SpringʵÓ㬵«Óë´ËͬʱËüÒªÇóµÄ»Ø±¨Ò²²»ÉÙ¡£
+
+³ý´ËÖ®Í⣬ÏîÄ¿µÄÒÀÀµ¹ÜÀíÒ²ÊÇÒ»¼þºÄʱºÄÁ¦µÄÊÂÇé¡£ÔÚ»·¾³´î½¨Ê±£¬ÐèÒª·ÖÎöÒªµ¼ÈëÄÄЩ¿âµÄ×ø±ê£¬¶øÇÒ»¹ÐèÒª·ÖÎöµ¼ÈëÓëÖ®ÓÐÒÀÀµ¹ØÏµµÄÆäËû¿âµÄ×ø±ê£¬Ò»µ©Ñ¡´íÁËÒÀÀµµÄ°æ±¾£¬ËæÖ®¶øÀ´µÄ²»¼æÈÝÎÊÌâ¾Í»áÑÏÖØ×è°ÏîÄ¿µÄ¿ª·¢½ø¶È¡£
+
+## SpringBoot½â¾öÉÏÊöSpringµÄȱµã
+
+SpringBoot¶ÔÉÏÊöSpringµÄȱµã½øÐеĸÄÉÆºÍÓÅ»¯£¬»ùÓÚÔ¼¶¨ÓÅÓÚÅäÖõÄ˼Ï룬¿ÉÒÔÈÿª·¢ÈËÔ±²»±ØÔÚÅäÖÃÓëÂß¼ÒµÎñÖ®¼ä½øÐÐ˼άµÄÇл»£¬È«ÉíÐĵÄͶÈëµ½Âß¼ÒµÎñµÄ´úÂë±àдÖУ¬´Ó¶ø´ó´óÌá¸ßÁË¿ª·¢µÄЧÂÊ£¬Ò»¶¨³Ì¶ÈÉÏËõ¶ÌÁËÏîÄ¿ÖÜÆÚ¡£
+
+ÔÚʹÓÃSpring¿ò¼Ü½øÐпª·¢µÄ¹ý³ÌÖУ¬ÐèÒªÅäÖúܶàSpring¿ò¼Ü°üµÄÒÀÀµ£¬Èçspring-core¡¢spring-bean¡¢spring-contextµÈ£¬¶øÕâЩÅäÖÃͨ³£¶¼ÊÇÖØ¸´Ìí¼ÓµÄ£¬¶øÇÒÐèÒª×öºÜ¶à¿ò¼ÜʹÓü°»·¾³²ÎÊýµÄÖØ¸´ÅäÖã¬È翪Æô×¢½â¡¢ÅäÖÃÈÕÖ¾µÈ¡£Spring BootÖÂÁ¦ÓÚÈõ»¯ÕâЩ²»±ØÒªµÄ²Ù×÷£¬ÌṩĬÈÏÅäÖ㬵±È»ÕâЩĬÈÏÅäÖÃÊÇ¿ÉÒÔ°´ÐèÐ޸ĵģ¬¿ìËٴ¡¢¿ª·¢ºÍÔËÐÐSpringÓ¦ÓÃ
+
+# ºÍSpringMVCµÄ¹ØÏµ
+
+
+
+Spring Boot£ºSpring Bootʹ¿ìËÙÒýµ¼ºÍ¿ªÊ¼¿ª·¢»ùÓÚSpringµÄÓ¦ÓóÌÐò±äµÃÈÝÒס£ Ëü±ÜÃâÁ˺ܶàÑù°å´úÂë¡£ ËüÔÚÄ»ºóÒþ²ØÁ˺ܶิÔÓÐÔ£¬Òò´Ë¿ª·¢ÈËÔ±¿ÉÒÔ¿ìËÙÉÏÊÖ²¢ÇáËÉ¿ª·¢»ùÓÚSpringµÄÓ¦ÓóÌÐò¡£
+
+Spring MVC£ºSpring MVCÊÇÓÃÓÚ¹¹½¨WebÓ¦ÓóÌÐòµÄWeb MVC¿ò¼Ü¡£ Ëü°üº¬Ðí¶àÓÃÓÚ¸÷ÖÖ¹¦ÄܵÄÅäÖÃÎļþ¡£ ÕâÊÇÒ»¸öÃæÏòHTTPµÄWebÓ¦ÓóÌÐò¿ª·¢¿ò¼Ü¡£
+
+
+
+Spring BootºÍSpring MVC³öÓÚ²»Í¬µÄÄ¿µÄ¶ø´æÔÚ¡£ ÏÂÃæÌÖÂÛÁËSpring BootºÍSpring MVCÖ®¼äµÄÖ÷񻂿±ð£º
+
+
+
+| Spring Boot | Spring MVC |
+| --- | --- |
+| Spring BootÓÃÓÚʹÓúÏÀíµÄĬÈÏÖµ´ò°ü»ùÓÚSpringµÄÓ¦ÓóÌÐò¡£ | Spring MVCÊÇSpring¿ò¼ÜÏ»ùÓÚÄ£ÐÍÊÓͼ¿ØÖÆÆ÷µÄWeb¿ò¼Ü¡£ |
+| ËüÌṩÁËĬÈÏÅäÖÃÀ´¹¹½¨SpringÖ§³ÖµÄ¿ò¼Ü¡£ | ËüÌṩÁËÓÃÓÚ¹¹½¨WebÓ¦ÓóÌÐòµÄ¼´ÓÃÐ͹¦ÄÜ¡£ |
+| ÎÞÐèÊÖ¶¯¹¹½¨ÅäÖᣠ| ËüÐèÒªÊÖ¶¯½øÐй¹½¨ÅäÖᣠ|
+| ²»ÐèÒª²¿ÊðÃèÊö·û¡£ | ²¿ÊðÃèÊö·ûÊDZØÐèµÄ¡£ |
+| Ëü±ÜÃâÁËÑù°å´úÂ룬²¢½«ÒÀÀµÏî°ü×°ÔÚÒ»¸öµ¥ÔªÖС£ | Ëü·Ö±ðÖ¸¶¨Ã¿¸öÒÀÀµÏî¡£ |
+| Ëü¼õÉÙÁË¿ª·¢Ê±¼ä²¢Ìá¸ßÁËÉú²úÂÊ¡£ | ʵÏÖÏàͬĿµÄÐèÒª¸ü¶àʱ¼ä¡£ |
+
+# ºÍ΢·þÎñ¡¢SpringCloudµÄ¹ØÏµ
+
+Spring BootÊÇSpring¼Ò×åµÄ³ÉÔ±£¬ËüÊÇÒ»¸öȫеĿò¼Ü£¬ËüµÄÉè¼ÆÄ¿µÄÊǾ¡¿ÉÄܼòµ¥ºÍ¿ìËٵĿª·¢¡¢ÔËÐÐSpringÓ¦ÓóÌÐò£¬¼ò»¯ÅäÖá£ËüΪ¿ª·¢Õß¿ì½ÝµÄʹÓÃSpring¼°Ïà¹Ø¿ª·¢¿ò¼ÜÌṩÁ˱ãÀû£¬µ«ÊÇËü²¢²»ÊÇ΢·þÎñµÄ¿ò¼Ü£¬ËüÖ»ÊÇΪ΢·þÎñ¿ò¼ÜµÄʹÓÃÒ²ÌṩÁ˺ܺõĽÅÊּܡ£
+
+
+
+
+ÉÏÃæÁ½ÕÅͼ±íÃ÷ÁËÁ½ÕߵĻù±¾Çø±ð£¬springbootÓÃÓÚ¹¹½¨µ¥¸ö·þÎñÓ¦Óã¬Ò²¾ÍÊÇÎÒÃdz£ËµµÄ΢·þÎñ
+
+¶øspringcloudÓÃÓÚ·þÎñÖÎÀí£¬Ò²¾ÍÊÇ´®Áª¡¢¹ÜÀíºÍе÷¶à¸ö΢·þÎñ£¨springbootÓ¦ÓóÌÐò£©
+
+springcloudÖаüº¬ÁËÖÚ¶à·þÎñÖÎÀíÏà¹ØµÄ×é¼þ£º·þÎñAPIÍø¹ØSpringcloud Gateway£¬ÅäÖÃÖÐÐÄ×é¼þConfig Serever£¬¶Ï·Æ÷Circuit Breaker¡¢·þÎñ×¢²áÖÐÐÄService Registty£¬¼à¿Ø×é¼þSleuthµÈ
+
+# ʹÓÃSpringbootµÄ8¸öÔÒò
+
+## ¸ü¿ìµÄ¿ª·¢
+
+Spring Boot ÔÚ Spring Éú̬ϵͳÉÏ×ö³öÁ˺ܶà¾ö¶¨ºÍ¹ÌÖ´¼º¼ûµÄĬÈÏÉèÖᣠÕâÖÖÐÔÖÊÓÐÖúÓÚ¿ª·¢ÈËÔ±¿ìËÙÉèÖò¢Í¶È뿪·¢¡£
+
+ÀýÈ磬Spring MVC ¿ÉÒÔͨ¹ý´óÁ¿ XML bean ¶¨ÒåºÍ×Ô¶¨Òå servlet ÀàʵÏÖ¡£ µ«ÊÇʹÓà Spring Boot£¬Ëü¾ÍÏñÌí¼ÓÆô¶¯Æ÷ÒÀÀµÏîÒ»Ñù¼òµ¥¡£ ¾ø¶Ô²»ÐèÒª´úÂëÉú³É XML ÅäÖá£
+
+## Ò»ÇнÔÓÐÏÈ»ú
+
+Spring Boot Starters Êǰüº¬¿âºÍËüÃǵÄһЩ×Ô¶¯ÅäÖÃµÄ Maven ÃèÊö·û¡£ ¶øÇÒ£¬ÕâЩÆô¶¯Æ÷ÓÐÖúÓÚΪ Spring Boot Ó¦ÓóÌÐòÌṩ¹¦ÄÜ¡£ ÏëÒª½¨Á¢Êý¾Ý¿âÁ¬½Ó£¿ ÓÐÒ»¸öÆô¶¯Æ÷ÒÀÀµÏî¡£ ÏëÓëÏûÏ¢¶ÓÁÐͨ»°»ò·¢Ë͵ç×ÓÓʼþ£¿ Spring Boot º¸ÇÁËÕâÒ»ÇС£
+
+¶ÔÓÚ¼¸ºõËùÓÐµÄ Spring Ä£¿é£¬¶¼ÓÐÒ»¸öÆô¶¯Æ÷ÒÀÀµÏî¿ÉÒÔΪÄúÅäÖÃËùÓÐÄÚÈÝ¡£ ÉõÖÁһЩµÚÈý·½¿âҲͨ¹ýËûÃÇµÄÆô¶¯Ä£¿éÌṩ¶Ô Spring µÄÖ§³Ö¡£ Èç¹ûûÓÐÕâЩÆô¶¯Æ÷£¬Äú×÷Ϊ¿ª·¢ÈËÔ±½«²»µÃ²»Î¬»¤ÒÀÀµÏîºÍ XML ÅäÖᣠÕâÊÇÄúÓ¦¸ÃʹÓà Spring Boot µÄÁíÒ»¸öÔÒò¡£
+
+## ǶÈëʽ·þÎñÆ÷
+
+Spring Boot ΪǶÈëʽ Tomcat¡¢Jetty ºÍ Undertow ·þÎñÆ÷Ìṩ¿ªÏä¼´ÓõÄÖ§³Ö¡£ ÕâÑù£¬¿ª·¢ÈËÔ±¾Í²»±Øµ£ÐÄÔÚ´«Í³Ó¦Ó÷þÎñÆ÷Öв¿Êð Web Ó¦ÓóÌÐò¡£ ͨ¹ýÊʵ±µÄÆô¶¯Æ÷ÒÀÀµÏÄúÉõÖÁ¿ÉÒÔ½«Ò»ÖÖ·þÎñÆ÷¼¼ÊõÓëÆäËû·þÎñÆ÷¼¼Êõ½»»»¡£ ËùÒÔÄãʵ¼ÊÉÏ×îÖյõ½ÁËÒ»¸ö¿ÉÒÔÏñÈκΠJAR Ò»ÑùÔËÐÐµÄ JAR Îļþ¡£ ÔÚÆô¶¯Ê±£¬JAR °üº¬×ã¹»µÄ¿âºÍÅäÖÃÒÔ×÷ΪӦÓóÌÐò·þÎñÆ÷Æô¶¯²¢ÕìÌýÇëÇó¡£
+
+Èç¹ûÄú¶ÔǶÈëʽ·þÎñÆ÷²»¸ÐÐËȤ£¬Äú¿ÉÒÔËæÊ±½« Spring Boot Ó¦ÓóÌÐò´Ó JAR ת»»Îª WAR£¬²¢½«ËüÃDz¿Êðµ½´«Í³·þÎñÆ÷¡£
+
+## IDE ¶Ô Spring Boot µÄÖ§³Ö
+
+ËùÓÐÖ÷ÒªµÄ IDE ¶¼Ìṩ¶Ô Spring Boot ´úÂë°ïÖúµÄÖ§³Ö¡£ ÀýÈ磬IntelliJ IDEA Ultimate Ϊ Spring Boot ÏîÄ¿ÌṩÁ˳öÉ«µÄ´úÂëÍê³ÉºÍµ¼º½¹¦ÄÜ¡£³ý´ËÖ®Í⣬VSCode ºÍ Eclipse Ò²¶ÔÆäÌṩÁ˷ḻµÄ¹¦ÄÜÖ§³Ö¡£
+
+## Éú²ú»·¾³³£Óù¦ÄÜ
+
+Spring Boot ÌṩÁËÉú²ú¾ÍÐ÷µÄÌØÐÔ£¬ÀýÈç¼à¿Ø¡¢Ö¸±êºÍ¿ªÏä¼´ÓõÄ×¢Ïú¡£ ÓÐÁËÕâÐ©ÌØÐÔ£¬¿ª·¢ÈËÔ±¿ÉÒÔ±ÜÃâ¶îÍâµÄÅäÖᣠÀýÈ磬½¡¿µÖ´ÐÐÆ÷¶ËµãµÈ¹¦ÄÜʹӦÓóÌÐò״̬¼à¿Ø³ÉΪ¿ÉÄÜ¡£ ÀýÈ磬
+
+Äú¿ÉÒÔÈÃÏñ Prometheus ÕâÑùµÄ¹¤¾ßÊÕ¼¯Ó¦ÓóÌÐòÖ¸±ê
+
+ÔÚÄúµÄ Kubernetes »ò Openshift »·¾³ÖÐʹÓþÍÐ÷ÐԺͻîÔ¾¶È½¡¿µ¶Ëµã¡£
+
+Ö»ÐèÌí¼ÓÆäËûÊôÐÔ»òͨ¹ý /actuator/logging ¶Ëµã¼´¿É¸ü¸ÄÈÕÖ¾¼Ç¼¼¶±ð¡£
+
+´ËÍ⣬¿ª·¢ÈËÔ±¿ÉÒÔʹÓÃ×Ô¼ºµÄ×Ô¶¨Ò彡¿µ¶ËµãÅäÖÃÕâЩִÐÐÆ÷¶Ëµã¡£
+
+## ¿ªÏä¼´ÓÃµÄ JUnit Ö§³Ö
+
+ĬÈÏÇé¿öÏ£¬ËùÓÐ Spring Boot ÏîÄ¿¶¼´øÓÐ JUnit 5¡£ ´ËÍ⣬Spring Boot ÌṩÁË@SpringBootTest ×¢½âÀ´ÔÚÎÒÃÇÐèҪʱ³õʼ»¯²âÊÔÉÏÏÂÎÄ¡£ ËùÒÔ¿ª·¢ÈËÔ±Ö»ÐèÒª±àд²âÊÔÓÃÀý¡£ ËûÃDz»±ØÔÙµ£ÐIJâÊÔÓÃÀýµÄ¸´ÔÓ spring ÉÏÏÂÎÄ¡£
+
+ÀýÈ磬ÏÂÃæ×Ô¶¯Éú³ÉµÄ²âÊÔ½«¼ì²éÉÏÏÂÎÄÊÇ·ñÕýÈ·¼ÓÔØ¡£
+
+````
+@SpringBootTest
+class SpringBootDerbyDatabaseApplicationTests {
+
+ @²âÊÔ
+ void contextLoads() {
+ }
+
+}
+````
+
+## Spring Profiles
+
+Spring Profiles ÊÇ spring Boot µÄÒ»¸öÇ¿´óÌØÐÔ£¬ÓÐÖúÓÚ¸ôÀëÓ¦ÓóÌÐòÖеIJ»Í¬×é¼þ¡£ ʹÓÃÅäÖÃÎļþ£¬Äú¿ÉÒÔÔÚÌØ¶¨»·¾³ÖÐÆôÓûò½ûÓÃ×é¼þ¡£ µ±Äú±ØÐë¸ù¾ÝÌØ¶¨Ìõ¼þʹÓò»Í¬µÄ×é¼þʱ£¬Õâ¿ÉÄÜ»áÅÉÉÏÓó¡¡£
+````
+@Profile(value = {"prod","uat"})
+class RabbitMQConfig {
+
+// ÌýÖÚ
+
+}
+````
+
+ÔÚÉÏÃæµÄ´úÂëÖУ¬ÉÏÏÂÎĽ«ÏÞÖÆÍÃ×ÓÕìÌýÆ÷½öÔÚ¾ßÓÐ prod »ò uat ×÷Ϊ»î¶¯ÅäÖÃÎļþµÄ»·¾³ÖÐÔËÐС£
+
+## ¶àÖÖ´ò°üºÍ²¿ÊðÑ¡Ïî
+
+¸Ã¿ò¼ÜÌṩÁ˶àÖÖ·½Ê½À´´ò°üÄúµÄÓ¦ÓóÌÐò¡£ ÕýÈçÎÒÃÇ֮ǰËù˵£¬Ó¦ÓóÌÐò¿ÉÒÔÊÇ JAR »ò WAR Îļþ¡£ ͨ¹ýһЩ¶îÍâµÄÅäÖúͲÎÊý£¬Äú»¹¿ÉÒÔ´´½¨¿ªÏä¼´ÓõĸßÐÔÄÜ docker ¾µÏñ¡£
+
+Æô¶¯ºÍÍ£Ö¹ Spring Boot Ó¦ÓóÌÐò·Ç³£¼òµ¥¡£ ´ËÍ⣬Äú¿ÉÒÔͨ¹ý¼¸¸ö¶îÍâµÄ²½Ö轫ÕâЩ JAR Îļþ²¿ÊðΪ linux ·þÎñ¡£ JAR Îļþ³ÆÎª FAT jar£¬ËüÃǰüº¬ÓëÓ¦ÓóÌÐòÏà¹ØµÄËùÓÐÒÀÀµÏî¡£ ÕâʹµÃ²¿Êð¹ý³Ì²»ÄÇô¸´ÔÓ¡£ ʵ¼ÊÉÏ£¬ÕâЩ¹¹½¨¿ÉÒÔÔÚÈκÎ×°ÓÐ Java 8 »ò¸ü¸ß°æ±¾µÄ»úÆ÷ÉÏÔËÐС£
+
+# ²Î¿¼ÎÄÕÂ
+
+[https://spring.io/](https://spring.io/)
+
+[https://pdai.tech/md/spring/springboot/springboot-x-overview.html](https://pdai.tech/md/spring/springboot/springboot-x-overview.html)
+
+[https://springhow.com/why-use-spring-boot/](https://springhow.com/why-use-spring-boot/)
+
+[https://dzone.com/articles/why-springboot](https://dzone.com/articles/why-springboot)
+
+[https://scand.com/company/blog/pros-and-cons-of-using-spring-boot/](https://scand.com/company/blog/pros-and-cons-of-using-spring-boot/)
+
+[https://cloud.tencent.com/developer/article/1620255](https://cloud.tencent.com/developer/article/1620255)
+
+[https://www.yiibai.com/spring-boot/spring-vs-spring-boot-vs-spring-mvc.html](https://www.yiibai.com/spring-boot/spring-vs-spring-boot-vs-spring-mvc.html)
\ No newline at end of file
diff --git "a/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232AOP\345\256\236\347\216\260\345\216\237\347\220\206\350\257\246\350\247\243.md" "b/docs/spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232AOP\345\256\236\347\216\260\345\216\237\347\220\206\350\257\246\350\247\243.md"
similarity index 100%
rename from "docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232AOP\345\256\236\347\216\260\345\216\237\347\220\206\350\257\246\350\247\243.md"
rename to "docs/spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232AOP\345\256\236\347\216\260\345\216\237\347\220\206\350\257\246\350\247\243.md"
diff --git "a/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232JDK\345\222\214cglib\345\212\250\346\200\201\344\273\243\347\220\206\345\216\237\347\220\206\350\257\246\350\247\243.md" "b/docs/spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232JDK\345\222\214cglib\345\212\250\346\200\201\344\273\243\347\220\206\345\216\237\347\220\206\350\257\246\350\247\243.md"
similarity index 100%
rename from "docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232JDK\345\222\214cglib\345\212\250\346\200\201\344\273\243\347\220\206\345\216\237\347\220\206\350\257\246\350\247\243.md"
rename to "docs/spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232JDK\345\222\214cglib\345\212\250\346\200\201\344\273\243\347\220\206\345\216\237\347\220\206\350\257\246\350\247\243.md"
diff --git "a/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232SpringAOP\346\246\202\350\277\260.md" "b/docs/spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232SpringAOP\346\246\202\350\277\260.md"
similarity index 100%
rename from "docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232SpringAOP\346\246\202\350\277\260.md"
rename to "docs/spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232SpringAOP\346\246\202\350\277\260.md"
diff --git "a/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232SpringIOC\345\256\271\345\231\250\347\232\204\345\212\240\350\275\275\350\277\207\347\250\213.md" "b/docs/spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232SpringIOC\345\256\271\345\231\250\347\232\204\345\212\240\350\275\275\350\277\207\347\250\213.md"
similarity index 100%
rename from "docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232SpringIOC\345\256\271\345\231\250\347\232\204\345\212\240\350\275\275\350\277\207\347\250\213.md"
rename to "docs/spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232SpringIOC\345\256\271\345\231\250\347\232\204\345\212\240\350\275\275\350\277\207\347\250\213.md"
diff --git "a/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232Spring\344\272\213\345\212\241\346\246\202\350\277\260.md" "b/docs/spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232Spring\344\272\213\345\212\241\346\246\202\350\277\260.md"
similarity index 100%
rename from "docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232Spring\344\272\213\345\212\241\346\246\202\350\277\260.md"
rename to "docs/spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232Spring\344\272\213\345\212\241\346\246\202\350\277\260.md"
diff --git "a/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232Spring\344\272\213\345\212\241\346\272\220\347\240\201\345\211\226\346\236\220.md" "b/docs/spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232Spring\344\272\213\345\212\241\346\272\220\347\240\201\345\211\226\346\236\220.md"
similarity index 100%
rename from "docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232Spring\344\272\213\345\212\241\346\272\220\347\240\201\345\211\226\346\236\220.md"
rename to "docs/spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232Spring\344\272\213\345\212\241\346\272\220\347\240\201\345\211\226\346\236\220.md"
diff --git "a/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232Spring\346\246\202\350\277\260.md" "b/docs/spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232Spring\346\246\202\350\277\260.md"
similarity index 100%
rename from "docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232Spring\346\246\202\350\277\260.md"
rename to "docs/spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232Spring\346\246\202\350\277\260.md"
diff --git "a/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232\345\210\235\346\216\242SpringIOC\346\240\270\345\277\203\346\265\201\347\250\213.md" "b/docs/spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232\345\210\235\346\216\242SpringIOC\346\240\270\345\277\203\346\265\201\347\250\213.md"
similarity index 100%
rename from "docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232\345\210\235\346\216\242SpringIOC\346\240\270\345\277\203\346\265\201\347\250\213.md"
rename to "docs/spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232\345\210\235\346\216\242SpringIOC\346\240\270\345\277\203\346\265\201\347\250\213.md"
diff --git "a/docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232\346\207\222\345\212\240\350\275\275\347\232\204\345\215\225\344\276\213Bean\350\216\267\345\217\226\350\277\207\347\250\213\345\210\206\346\236\220.md" "b/docs/spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232\346\207\222\345\212\240\350\275\275\347\232\204\345\215\225\344\276\213Bean\350\216\267\345\217\226\350\277\207\347\250\213\345\210\206\346\236\220.md"
similarity index 100%
rename from "docs/java-web/Spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232\346\207\222\345\212\240\350\275\275\347\232\204\345\215\225\344\276\213Bean\350\216\267\345\217\226\350\277\207\347\250\213\345\210\206\346\236\220.md"
rename to "docs/spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232\346\207\222\345\212\240\350\275\275\347\232\204\345\215\225\344\276\213Bean\350\216\267\345\217\226\350\277\207\347\250\213\345\210\206\346\236\220.md"
diff --git "a/docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232DispatcherServlet\345\246\202\344\275\225\346\211\276\345\210\260\346\255\243\347\241\256\347\232\204Controller.md" "b/docs/spring/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232DispatcherServlet\345\246\202\344\275\225\346\211\276\345\210\260\346\255\243\347\241\256\347\232\204Controller.md"
similarity index 100%
rename from "docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232DispatcherServlet\345\246\202\344\275\225\346\211\276\345\210\260\346\255\243\347\241\256\347\232\204Controller.md"
rename to "docs/spring/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232DispatcherServlet\345\246\202\344\275\225\346\211\276\345\210\260\346\255\243\347\241\256\347\232\204Controller.md"
diff --git "a/docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232DispatcherServlet\347\232\204\345\210\235\345\247\213\345\214\226\344\270\216\350\257\267\346\261\202\350\275\254\345\217\221.md" "b/docs/spring/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232DispatcherServlet\347\232\204\345\210\235\345\247\213\345\214\226\344\270\216\350\257\267\346\261\202\350\275\254\345\217\221.md"
similarity index 100%
rename from "docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232DispatcherServlet\347\232\204\345\210\235\345\247\213\345\214\226\344\270\216\350\257\267\346\261\202\350\275\254\345\217\221.md"
rename to "docs/spring/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232DispatcherServlet\347\232\204\345\210\235\345\247\213\345\214\226\344\270\216\350\257\267\346\261\202\350\275\254\345\217\221.md"
diff --git "a/docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232SpringMVC\346\246\202\350\277\260.md" "b/docs/spring/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232SpringMVC\346\246\202\350\277\260.md"
similarity index 100%
rename from "docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232SpringMVC\346\246\202\350\277\260.md"
rename to "docs/spring/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232SpringMVC\346\246\202\350\277\260.md"
diff --git "a/docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232SpringMVC\347\232\204\350\247\206\345\233\276\350\247\243\346\236\220\345\216\237\347\220\206.md" "b/docs/spring/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232SpringMVC\347\232\204\350\247\206\345\233\276\350\247\243\346\236\220\345\216\237\347\220\206.md"
similarity index 100%
rename from "docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232SpringMVC\347\232\204\350\247\206\345\233\276\350\247\243\346\236\220\345\216\237\347\220\206.md"
rename to "docs/spring/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232SpringMVC\347\232\204\350\247\206\345\233\276\350\247\243\346\236\220\345\216\237\347\220\206.md"
diff --git "a/docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232SpringMVC\350\256\276\350\256\241\347\220\206\345\277\265\344\270\216DispatcherServlet.md" "b/docs/spring/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232SpringMVC\350\256\276\350\256\241\347\220\206\345\277\265\344\270\216DispatcherServlet.md"
similarity index 100%
rename from "docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232SpringMVC\350\256\276\350\256\241\347\220\206\345\277\265\344\270\216DispatcherServlet.md"
rename to "docs/spring/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232SpringMVC\350\256\276\350\256\241\347\220\206\345\277\265\344\270\216DispatcherServlet.md"
diff --git "a/docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232\346\266\210\346\201\257\350\275\254\346\215\242\345\231\250HttpMessageConverter\344\270\216@ResponseBody\346\263\250\350\247\243.md" "b/docs/spring/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232\346\266\210\346\201\257\350\275\254\346\215\242\345\231\250HttpMessageConverter\344\270\216@ResponseBody\346\263\250\350\247\243.md"
similarity index 100%
rename from "docs/java-web/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232\346\266\210\346\201\257\350\275\254\346\215\242\345\231\250HttpMessageConverter\344\270\216@ResponseBody\346\263\250\350\247\243.md"
rename to "docs/spring/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232\346\266\210\346\201\257\350\275\254\346\215\242\345\231\250HttpMessageConverter\344\270\216@ResponseBody\346\263\250\350\247\243.md"
diff --git "a/docs/java-web/Spring/\347\273\231\344\275\240\344\270\200\344\273\275SpringBoot\347\237\245\350\257\206\346\270\205\345\215\225.md" "b/docs/spring/\347\273\231\344\275\240\344\270\200\344\273\275SpringBoot\347\237\245\350\257\206\346\270\205\345\215\225.md"
similarity index 100%
rename from "docs/java-web/Spring/\347\273\231\344\275\240\344\270\200\344\273\275SpringBoot\347\237\245\350\257\206\346\270\205\345\215\225.md"
rename to "docs/spring/\347\273\231\344\275\240\344\270\200\344\273\275SpringBoot\347\237\245\350\257\206\346\270\205\345\215\225.md"
From 525265639ede5463e64125a6f82ababf1c609ef1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=BB=84=E5=B0=8F=E6=96=9C?= <362294931@qq.com>
Date: Sat, 15 Apr 2023 22:19:42 +0800
Subject: [PATCH 09/39] add spring content
---
ReadMe.md | 4 +
...65\344\270\216\344\275\234\347\224\250.md" | 621 +++++++++
...10\346\240\270\345\277\203\357\274\211.md" | 182 +++
...70\350\247\201\346\263\250\350\247\243.md" | 158 +++
...72\346\234\254\344\275\277\347\224\250.md" | 152 +++
...45\220\253Spring+SpringMVC+SpringBoot).md" | 1112 ++++++++++++++++
...23\347\232\204\350\256\277\351\227\256.md" | 1183 +++++++++++++++++
...75\347\232\204\346\224\257\346\214\201.md" | 715 ++++++++++
...57\345\242\203\345\217\230\351\207\217.md" | 852 ++++++++++++
...04\347\220\206\346\234\272\345\210\266.md" | 270 ++++
...04\346\272\220\347\256\241\347\220\206.md" | 309 +++++
...54\346\225\260\346\215\256\357\274\211.md" | 298 +++++
...72\346\234\254\347\224\250\346\263\225.md" | 430 ++++++
.../spring/Spring\345\220\210\351\233\206.md" | 22 +
...345\256\271\345\231\250\344\270\216IOC.md" | 157 +++
...70\350\247\201\346\263\250\350\247\243.md" | 724 ++++++++++
.../spring/Spring\346\246\202\350\277\260.md" | 145 ++
...70\350\247\201\346\263\250\350\247\243.md" | 232 ++++
...\270\252Spring\345\272\224\347\224\250.md" | 70 +
pom.xml | 28 +
src/main/java/Test.java | 22 +
21 files changed, 7686 insertions(+)
create mode 100644 "docs/spring/SpringAOP\347\232\204\346\246\202\345\277\265\344\270\216\344\275\234\347\224\250.md"
create mode 100644 "docs/spring/SpringBean\347\232\204\345\256\232\344\271\211\344\270\216\347\256\241\347\220\206\357\274\210\346\240\270\345\277\203\357\274\211.md"
create mode 100644 "docs/spring/SpringBoot/SpringBoot\345\270\270\350\247\201\346\263\250\350\247\243.md"
create mode 100644 "docs/spring/SpringBoot/SpringBoot\347\232\204\345\237\272\346\234\254\344\275\277\347\224\250.md"
create mode 100644 "docs/spring/SpringBoot/Spring\345\270\270\350\247\201\346\263\250\350\247\243\344\275\277\347\224\250\346\214\207\345\215\227(\345\214\205\345\220\253Spring+SpringMVC+SpringBoot).md"
create mode 100644 "docs/spring/Spring\344\270\255\345\257\271\344\272\216\346\225\260\346\215\256\345\272\223\347\232\204\350\256\277\351\227\256.md"
create mode 100644 "docs/spring/Spring\344\270\255\345\257\271\344\272\216\346\240\241\351\252\214\345\212\237\350\203\275\347\232\204\346\224\257\346\214\201.md"
create mode 100644 "docs/spring/Spring\344\270\255\347\232\204Environment\347\216\257\345\242\203\345\217\230\351\207\217.md"
create mode 100644 "docs/spring/Spring\344\270\255\347\232\204\344\272\213\344\273\266\345\244\204\347\220\206\346\234\272\345\210\266.md"
create mode 100644 "docs/spring/Spring\344\270\255\347\232\204\350\265\204\346\272\220\347\256\241\347\220\206.md"
create mode 100644 "docs/spring/Spring\344\270\255\347\232\204\351\205\215\347\275\256\345\205\203\346\225\260\346\215\256\357\274\210\347\256\241\347\220\206\351\205\215\347\275\256\347\232\204\345\237\272\346\234\254\346\225\260\346\215\256\357\274\211.md"
create mode 100644 "docs/spring/Spring\344\272\213\345\212\241\345\237\272\346\234\254\347\224\250\346\263\225.md"
create mode 100644 "docs/spring/Spring\345\220\210\351\233\206.md"
create mode 100644 "docs/spring/Spring\345\256\271\345\231\250\344\270\216IOC.md"
create mode 100644 "docs/spring/Spring\345\270\270\350\247\201\346\263\250\350\247\243.md"
create mode 100644 "docs/spring/Spring\346\246\202\350\277\260.md"
create mode 100644 "docs/spring/springMVC/SpringMVC\345\270\270\350\247\201\346\263\250\350\247\243.md"
create mode 100644 "docs/spring/\347\254\254\344\270\200\344\270\252Spring\345\272\224\347\224\250.md"
create mode 100644 src/main/java/Test.java
diff --git a/ReadMe.md b/ReadMe.md
index c83ee64..c8ec78e 100644
--- a/ReadMe.md
+++ b/ReadMe.md
@@ -144,6 +144,10 @@
### Spring
+* [Spring常�注解.md](docs/spring/Spring常�注解.md)
+
+
+
* [Springæº�ç �剖æž�:Spring概述](docs/spring/Springæº�ç �剖æž�:Spring概述.md)
* [Springæº�ç �剖æž�:åˆ�探SpringIOCæ ¸å¿ƒæµ�程](docs/spring/Springæº�ç �剖æž�:åˆ�探SpringIOCæ ¸å¿ƒæµ�程.md)
* [Springæº�ç �剖æž�:SpringIOCå®¹å™¨çš„åŠ è½½è¿‡ç¨‹ ](docs/spring/Springæº�ç �剖æž�:SpringIOCå®¹å™¨çš„åŠ è½½è¿‡ç¨‹.md)
diff --git "a/docs/spring/SpringAOP\347\232\204\346\246\202\345\277\265\344\270\216\344\275\234\347\224\250.md" "b/docs/spring/SpringAOP\347\232\204\346\246\202\345\277\265\344\270\216\344\275\234\347\224\250.md"
new file mode 100644
index 0000000..26e828a
--- /dev/null
+++ "b/docs/spring/SpringAOP\347\232\204\346\246\202\345\277\265\344\270\216\344\275\234\347\224\250.md"
@@ -0,0 +1,621 @@
+# Spring ¿ò¼ÜµÄ AOP
+
+## Spring ¿ò¼ÜµÄ AOP
+
+Spring ¿ò¼ÜµÄÒ»¸ö¹Ø¼ü×é¼þÊÇ**ÃæÏòÇÐÃæµÄ±à³Ì**(AOP)¿ò¼Ü¡£ÃæÏòÇÐÃæµÄ±à³ÌÐèÒª°Ñ³ÌÐòÂß¼·Ö½â³É²»Í¬µÄ²¿·Ö³ÆÎªËùνµÄ¹Ø×¢µã¡£¿çÒ»¸öÓ¦ÓóÌÐòµÄ¶à¸öµãµÄ¹¦Äܱ»³ÆÎª**ºáÇйØ×¢µã**£¬ÕâЩºáÇйØ×¢µãÔÚ¸ÅÄîÉ϶ÀÁ¢ÓÚÓ¦ÓóÌÐòµÄÒµÎñÂß¼¡£ÔÚÈí¼þ¿ª·¢¹ý³ÌÖÐÓи÷ÖÖ¸÷ÑùµÄºÜºÃµÄÇÐÃæµÄÀý×Ó£¬ÈçÈÕÖ¾¼Ç¼¡¢É󼯡¢ÉùÃ÷ʽÊÂÎñ¡¢°²È«ÐԺͻº´æµÈ¡£
+
+ÔÚ OOP ÖУ¬¹Ø¼üµ¥ÔªÄ£¿é¶ÈÊÇÀ࣬¶øÔÚ AOP Öе¥ÔªÄ£¿é¶ÈÊÇÇÐÃæ¡£ÒÀÀµ×¢Èë°ïÖúÄã¶ÔÓ¦ÓóÌÐò¶ÔÏóÏ໥½âñîºÏ£¬AOP ¿ÉÒÔ°ïÖúÄã´ÓËüÃÇËùÓ°ÏìµÄ¶ÔÏóÖжԺáÇйØ×¢µã½âñî¡£AOP ÏñÊDZà³ÌÓïÑԵĴ¥·¢ÎÈç Perl£¬.NET£¬Java »òÕ߯äËûÓïÑÔ¡£
+
+Spring AOP Ä£¿éÌṩÀ¹½ØÆ÷À´À¹½ØÒ»¸öÓ¦ÓóÌÐò£¬ÀýÈ磬µ±Ö´ÐÐÒ»¸ö·½·¨Ê±£¬Äã¿ÉÒÔÔÚ·½·¨Ö´ÐÐ֮ǰ»òÖ®ºóÌí¼Ó¶îÍâµÄ¹¦ÄÜ¡£
+
+## AOP ÊõÓï
+
+ÔÚÎÒÃÇ¿ªÊ¼Ê¹Óà AOP ¹¤×÷֮ǰ£¬ÈÃÎÒÃÇÊìϤһÏ AOP ¸ÅÄîºÍÊõÓï¡£ÕâЩÊõÓï²¢²»Ìض¨ÓÚ Spring£¬¶øÊÇÓë AOP Óйصġ£
+
+| Ïî | ÃèÊö |
+| --- | --- |
+| Aspect | Ò»¸öÄ£¿é¾ßÓÐÒ»×éÌṩºáÇÐÐèÇóµÄ APIs¡£ÀýÈ磬һ¸öÈÕ־ģ¿éΪÁ˼ǼÈÕÖ¾½«±» AOP ·½Ãæµ÷Óá£Ó¦ÓóÌÐò¿ÉÒÔÓµÓÐÈÎÒâÊýÁ¿µÄ·½Ã棬ÕâÈ¡¾öÓÚÐèÇó¡£ |
+| Join point | ÔÚÄãµÄÓ¦ÓóÌÐòÖÐËü´ú±íÒ»¸öµã£¬Äã¿ÉÒÔÔÚ²å¼þ AOP ·½Ãæ¡£ÄãÒ²ÄÜ˵£¬ËüÊÇÔÚʵ¼ÊµÄÓ¦ÓóÌÐòÖУ¬ÆäÖÐÒ»¸ö²Ù×÷½«Ê¹Óà Spring AOP ¿ò¼Ü¡£ |
+| Advice | ÕâÊÇʵ¼ÊÐж¯Ö®Ç°»òÖ®ºóÖ´Ðеķ½·¨¡£ÕâÊÇÔÚ³ÌÐòÖ´ÐÐÆÚ¼äͨ¹ý Spring AOP ¿ò¼Üʵ¼Ê±»µ÷ÓõĴúÂë¡£ |
+| Pointcut | ÕâÊÇÒ»×éÒ»¸ö»ò¶à¸öÁ¬½Óµã£¬Í¨ÖªÓ¦¸Ã±»Ö´ÐС£Äã¿ÉÒÔʹÓñí´ïʽ»òģʽָ¶¨ÇÐÈëµãÕýÈçÎÒÃǽ«ÔÚ AOP µÄÀý×ÓÖп´µ½µÄ¡£ |
+| Introduction | ÒýÓÃÔÊÐíÄãÌí¼Óз½·¨»òÊôÐÔµ½ÏÖÓеÄÀàÖС£ |
+| Target object | ±»Ò»¸ö»òÕß¶à¸ö·½ÃæËù֪ͨµÄ¶ÔÏó£¬Õâ¸ö¶ÔÏóÓÀÔ¶ÊÇÒ»¸ö±»´úÀí¶ÔÏó¡£Ò²³ÆÎª±»Í¨Öª¶ÔÏó¡£ |
+| Weaving | Weaving °Ñ·½ÃæÁ¬½Óµ½ÆäËüµÄÓ¦ÓóÌÐòÀàÐÍ»òÕß¶ÔÏóÉÏ£¬²¢´´½¨Ò»¸ö±»Í¨ÖªµÄ¶ÔÏó¡£ÕâЩ¿ÉÒÔÔÚ±àÒëʱ£¬Àà¼ÓÔØÊ±ºÍÔËÐÐʱÍê³É¡£ |
+
+## ֪ͨµÄÀàÐÍ
+
+Spring ·½Ãæ¿ÉÒÔʹÓÃÏÂÃæÌáµ½µÄÎåÖÖ֪ͨ¹¤×÷£º
+
+| ֪ͨ | ÃèÊö |
+| --- | --- |
+| ǰÖÃ֪ͨ | ÔÚÒ»¸ö·½·¨Ö´ÐÐ֮ǰ£¬Ö´ÐÐ֪ͨ¡£ |
+| ºóÖÃ֪ͨ | ÔÚÒ»¸ö·½·¨Ö´ÐÐÖ®ºó£¬²»¿¼ÂÇÆä½á¹û£¬Ö´ÐÐ֪ͨ¡£ |
+| ·µ»Øºó֪ͨ | ÔÚÒ»¸ö·½·¨Ö´ÐÐÖ®ºó£¬Ö»ÓÐÔÚ·½·¨³É¹¦Íê³Éʱ£¬²ÅÄÜÖ´ÐÐ֪ͨ¡£ |
+| Å׳öÒì³£ºó֪ͨ | ÔÚÒ»¸ö·½·¨Ö´ÐÐÖ®ºó£¬Ö»ÓÐÔÚ·½·¨Í˳öÅ׳öÒ쳣ʱ£¬²ÅÄÜÖ´ÐÐ֪ͨ¡£ |
+| »·ÈÆÍ¨Öª | ÔÚ½¨Òé·½·¨µ÷ÓÃ֮ǰºÍÖ®ºó£¬Ö´ÐÐ֪ͨ¡£ |
+
+## ʵÏÖ×Ô¶¨Òå·½Ãæ
+
+Spring Ö§³Ö **@AspectJ annotation style** µÄ·½·¨ºÍ**»ùÓÚģʽ**µÄ·½·¨À´ÊµÏÖ×Ô¶¨Òå·½Ãæ¡£ÕâÁ½ÖÖ·½·¨ÒѾÔÚÏÂÃæÁ½¸ö×Ó½Ú½øÐÐÁËÏêϸ½âÊÍ¡£
+
+| ·½·¨ | ÃèÊö |
+| --- | --- |
+| [XML Schema based](https://www.w3cschool.cn/wkspring/omps1mm6.html) | ·½ÃæÊÇʹÓ󣹿ÀàÒÔ¼°»ùÓÚÅäÖÃµÄ XML À´ÊµÏֵġ£ |
+| [@AspectJ based](https://www.w3cschool.cn/wkspring/k4q21mm8.html) | @AspectJ ÒýÓÃÒ»ÖÖÉùÃ÷·½ÃæµÄ·ç¸ñ×÷Ϊ´øÓÐ Java 5 ×¢Ê͵ij£¹æ Java Àà×¢ÊÍ¡£ |
+
+
+
+## Spring ÖлùÓÚ AOP µÄ XML¼Ü¹¹
+
+ΪÁËÔÚ±¾½ÚµÄÃèÊöÖÐʹÓà aop ÃüÃû¿Õ¼ä±êÇ©£¬ÄãÐèÒªµ¼Èë spring-aop ¼Ü¹¹£¬ÈçÏÂËùÊö£º
+
+```
+
+
+
+
+
+
+
+```
+
+Ä㻹ÐèÒªÔÚÄãµÄÓ¦ÓóÌÐòµÄ CLASSPATH ÖÐʹÓÃÒÔÏ AspectJ ¿âÎļþ¡£ÕâЩ¿âÎļþÔÚÒ»¸ö AspectJ ×°ÖÃµÄ ¡®lib¡¯ Ŀ¼ÖÐÊÇ¿ÉÓõ쬷ñÔòÄã¿ÉÒÔÔÚ Internet ÖÐÏÂÔØËüÃÇ¡£(×¢£ºaspectjweaver.jar ÒѰüº¬ÆäËû°ü)
+
+* aspectjrt.jar
+
+* aspectjweaver.jar
+
+* aspectj.jar
+
+* aopalliance.jar
+
+## ¡¡ÉùÃ÷Ò»¸ö aspect
+
+Ò»¸ö **aspect** ÊÇʹÓÃ ÔªËØÉùÃ÷µÄ£¬Ö§³ÖµÄ bean ÊÇʹÓà **ref** ÊôÐÔÒýÓõģ¬ÈçÏÂËùʾ£º
+
+```
+
+
+ ...
+
+
+
+...
+
+```
+
+ÕâÀ¡°aBean¡± ½«±»ÅäÖúÍÒÀÀµ×¢È룬¾ÍÏñÇ°ÃæµÄÕ½ÚÖÐÄã¿´µ½µÄÆäËûµÄ Spring bean Ò»Ñù¡£
+
+## ÉùÃ÷Ò»¸öÇÐÈëµã
+
+Ò»¸ö**ÇÐÈëµã**ÓÐÖúÓÚÈ·¶¨Ê¹Óò»Í¬½¨ÒéÖ´ÐеĸÐÐËȤµÄÁ¬½Óµã£¨¼´·½·¨£©¡£ÔÚ´¦Àí»ùÓÚÅäÖÃµÄ XML ¼Ü¹¹Ê±£¬ÇÐÈëµã½«»á°´ÕÕÈçÏÂËùʾ¶¨Ò壺
+
+```
+
+
+
+ ...
+
+
+
+...
+
+```
+
+ÏÂÃæµÄʾÀý¶¨ÒåÁËÒ»¸öÃûΪ ¡°businessService¡± µÄÇÐÈëµã£¬¸ÃÇÐÈëµã½«Óë com.tutorialspoint °üÏ嵀 Student ÀàÖÐµÄ getName() ·½·¨ÏàÆ¥Å䣺
+
+```
+
+
+
+ ...
+
+
+
+...
+
+```
+
+## ÉùÃ÷½¨Òé
+
+Äã¿ÉÒÔÔÚÖÐʹÓÃÔªËØÉùÃ÷ÈÎÒâÎåÖÖÀàÐ͵Ä֪ͨ£¬ÈçÏ£º
+
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ...
+
+
+
+...
+
+```
+
+Äã¿ÉÒÔ¶Ô²»Í¬µÄ½¨ÒéʹÓÃÏàͬµÄ **doRequiredTask** »òÕß²»Í¬µÄ·½·¨¡£ÕâЩ·½·¨½«»á×÷Ϊ aspect Ä£¿éµÄÒ»²¿·ÖÀ´¶¨Òå¡£
+
+## »ùÓÚ AOP µÄ XML ¼Ü¹¹µÄʾÀý
+
+ΪÁËÀí½âÉÏÃæÌáµ½µÄ»ùÓÚ AOP µÄ XML ¼Ü¹¹µÄ¸ÅÄÈÃÎÒÃDZàдһ¸öʾÀý£¬¿ÉÒÔʵÏÖ¼¸¸ö½¨Ò顣ΪÁËÔÚÎÒÃǵÄʾÀýÖÐʹÓü¸¸ö½¨Ò飬ÈÃÎÒÃÇʹ Eclipse IDE ´¦ÓÚ¹¤×÷״̬£¬È»ºó°´ÕÕÈçϲ½Öè´´½¨Ò»¸ö Spring Ó¦ÓóÌÐò£º
+
+| ²½Öè | ÃèÊö |
+| --- | --- |
+| 1 | ´´½¨Ò»¸öÃûΪ _SpringExample_ µÄÏîÄ¿£¬²¢ÇÒÔÚËù´´½¨ÏîÄ¿µÄ **src** Îļþ¼ÐÏ´´½¨Ò»¸öÃûΪ _com.tutorialspoint_ µÄ°ü¡£ |
+| 2 | ʹÓà _Add External JARs_ Ñ¡ÏîÌí¼ÓËùÐèµÄ Spring ¿âÎļþ£¬¾ÍÈçÔÚ _Spring Hello World Example_ Õ½ÚÖнâÊ͵ÄÄÇÑù¡£ |
+| 3 | ÔÚÏîÄ¿ÖÐÌí¼Ó Spring AOP Ö¸¶¨µÄ¿âÎļþ **aspectjrt.jar£¬ aspectjweaver.jar** ºÍ **aspectj.jar**¡£ |
+| 4 | ÔÚ _com.tutorialspoint_ °üÏ´´½¨ Java Àà **Logging**£¬ _Student_ ºÍ _MainApp_¡£ |
+| 5 | ÔÚ **src** Îļþ¼ÐÏ´´½¨ Beans ÅäÖÃÎļþ _Beans.xml_¡£ |
+| 6 | ×îºóÒ»²½ÊÇ´´½¨ËùÓÐ Java ÎļþºÍ Bean ÅäÖÃÎļþµÄÄÚÈÝ£¬²¢ÇÒ°´ÈçϽâÊ͵ÄÄÇÑùÔËÐÐÓ¦ÓóÌÐò¡£ |
+
+ÕâÀïÊÇ **Logging.java** ÎļþµÄÄÚÈÝ¡£Õâʵ¼ÊÉÏÊÇ aspect Ä£¿éµÄÒ»¸öʾÀý£¬Ëü¶¨ÒåÁËÔÚ¸÷¸öµãµ÷Óõķ½·¨¡£
+
+```
+package com.tutorialspoint;
+public class Logging {
+ /**
+ * This is the method which I would like to execute
+ * before a selected method execution.
+ */
+ public void beforeAdvice(){
+ System.out.println("Going to setup student profile.");
+ }
+ /**
+ * This is the method which I would like to execute
+ * after a selected method execution.
+ */
+ public void afterAdvice(){
+ System.out.println("Student profile has been setup.");
+ }
+ /**
+ * This is the method which I would like to execute
+ * when any method returns.
+ */
+ public void afterReturningAdvice(Object retVal){
+ System.out.println("Returning:" + retVal.toString() );
+ }
+ /**
+ * This is the method which I would like to execute
+ * if there is an exception raised.
+ */
+ public void AfterThrowingAdvice(IllegalArgumentException ex){
+ System.out.println("There has been an exception: " + ex.toString());
+ }
+}
+```
+
+ÏÂÃæÊÇ **Student.java** ÎļþµÄÄÚÈÝ£º
+
+```
+package com.tutorialspoint;
+public class Student {
+ private Integer age;
+ private String name;
+ public void setAge(Integer age) {
+ this.age = age;
+ }
+ public Integer getAge() {
+ System.out.println("Age : " + age );
+ return age;
+ }
+ public void setName(String name) {
+ this.name = name;
+ }
+ public String getName() {
+ System.out.println("Name : " + name );
+ return name;
+ }
+ public void printThrowException(){
+ System.out.println("Exception raised");
+ throw new IllegalArgumentException();
+ }
+}
+```
+
+ÏÂÃæÊÇ **MainApp.java** ÎļþµÄÄÚÈÝ£º
+
+```
+package com.tutorialspoint;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+public class MainApp {
+ public static void main(String[] args) {
+ ApplicationContext context =
+ new ClassPathXmlApplicationContext("Beans.xml");
+ Student student = (Student) context.getBean("student");
+ student.getName();
+ student.getAge();
+ student.printThrowException();
+ }
+}
+```
+
+ÏÂÃæÊÇÅäÖÃÎļþ **Beans.xml**£º
+
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+Ò»µ©ÄãÒѾÍê³ÉµÄ´´½¨ÁËÔ´ÎļþºÍ bean ÅäÖÃÎļþ£¬ÈÃÎÒÃÇÔËÐÐÒ»ÏÂÓ¦ÓóÌÐò¡£Èç¹ûÄãµÄÓ¦ÓóÌÐòÒ»Çж¼Õý³£µÄ»°£¬Õ⽫»áÊä³öÒÔÏÂÏûÏ¢£º
+
+```
+Going to setup student profile.
+Name : Zara
+Student profile has been setup.
+Returning:Zara
+Going to setup student profile.
+Age : 11
+Student profile has been setup.
+Returning:11
+Going to setup student profile.
+Exception raised
+Student profile has been setup.
+There has been an exception: java.lang.IllegalArgumentException
+.....
+other exception content
+```
+
+ÈÃÎÒÃÇÀ´½âÊÍÒ»ÏÂÉÏÃæ¶¨ÒåµÄÔÚ com.tutorialspoint ÖÐ Ñ¡ÔñËùÓз½·¨µÄ ¡£ÈÃÎÒÃǼÙÉèһϣ¬ÄãÏëÒªÔÚÒ»¸öÌØÊâµÄ·½·¨Ö®Ç°»òÕßÖ®ºóÖ´ÐÐÄãµÄ½¨Ò飬Äã¿ÉÒÔͨ¹ýÌæ»»Ê¹ÓÃÕæÊµÀàºÍ·½·¨Ãû³ÆµÄÇÐÈëµã¶¨ÒåÖеÄÐǺţ¨*£©À´¶¨ÒåÄãµÄÇÐÈëµãÀ´Ëõ¶ÌÄãµÄÖ´ÐС£
+
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+Èç¹ûÄãÏëÒªÖ´ÐÐͨ¹ýÕâЩ¸ü¸ÄÖ®ºóµÄʾÀýÓ¦ÓóÌÐò£¬Õ⽫»áÊä³öÒÔÏÂÏûÏ¢£º
+
+```
+Going to setup student profile.
+Name : Zara
+Student profile has been setup.
+Age : 11
+Exception raised
+.....
+other exception content
+```
+
+
+
+## Spring ÖлùÓÚ AOP µÄ @AspectJ
+
+@AspectJ ×÷Ϊͨ¹ý Java 5 ×¢ÊÍ×¢ÊÍµÄÆÕͨµÄ Java À࣬ËüÖ¸µÄÊÇÉùÃ÷ aspects µÄÒ»ÖÖ·ç¸ñ¡£Í¨¹ýÔÚÄãµÄ»ùÓڼܹ¹µÄ XML ÅäÖÃÎļþÖаüº¬ÒÔÏÂÔªËØ£¬@AspectJ Ö§³ÖÊÇ¿ÉÓõġ£
+
+```
+
+```
+
+Ä㻹ÐèÒªÔÚÄãµÄÓ¦ÓóÌÐòµÄ CLASSPATH ÖÐʹÓÃÒÔÏ AspectJ ¿âÎļþ¡£ÕâЩ¿âÎļþÔÚÒ»¸ö AspectJ ×°ÖÃµÄ ¡®lib¡¯ Ŀ¼ÖÐÊÇ¿ÉÓõģ¬Èç¹ûûÓУ¬Äã¿ÉÒÔÔÚ Internet ÖÐÏÂÔØËüÃÇ¡£
+
+* aspectjrt.jar
+
+* aspectjweaver.jar
+
+* aspectj.jar
+
+* aopalliance.jar
+
+## ¡¡ÉùÃ÷Ò»¸ö aspect
+
+Aspects ÀàºÍÆäËûÈκÎÕý³£µÄ bean Ò»Ñù£¬³ýÁËËüÃǽ«»áÓà @AspectJ ×¢ÊÍÖ®Í⣬ËüºÍÆäËûÀàÒ»Ñù¿ÉÄÜÓз½·¨ºÍ×ֶΣ¬ÈçÏÂËùʾ£º
+
+```
+package org.xyz;
+import org.aspectj.lang.annotation.Aspect;
+@Aspect
+public class AspectModule {
+}
+```
+
+ËüÃǽ«ÔÚ XML Öа´ÕÕÈçϽøÐÐÅäÖã¬¾ÍºÍÆäËûÈκΠbean Ò»Ñù£º
+
+```
+
+
+
+
+```
+
+## ÉùÃ÷Ò»¸öÇÐÈëµã
+
+Ò»¸ö**ÇÐÈëµã**ÓÐÖúÓÚÈ·¶¨Ê¹Óò»Í¬½¨ÒéÖ´ÐеĸÐÐËȤµÄÁ¬½Óµã£¨¼´·½·¨£©¡£ÔÚ´¦Àí»ùÓÚÅäÖÃµÄ XML ¼Ü¹¹Ê±£¬ÇÐÈëµãµÄÉùÃ÷ÓÐÁ½¸ö²¿·Ö£º
+
+* Ò»¸öÇÐÈëµã±í´ïʽ¾ö¶¨ÁËÎÒÃǸÐÐËȤµÄÄĸö·½·¨»áÕæÕý±»Ö´ÐС£
+
+* Ò»¸öÇÐÈëµã±êÇ©°üº¬Ò»¸öÃû³ÆºÍÈÎÒâÊýÁ¿µÄ²ÎÊý¡£·½·¨µÄÕæÕýÄÚÈÝÊDz»Ïà¸ÉµÄ£¬²¢ÇÒʵ¼ÊÉÏËüÓ¦¸ÃÊǿյġ£
+
+ÏÂÃæµÄʾÀýÖж¨ÒåÁËÒ»¸öÃûΪ ¡®businessService¡¯ µÄÇÐÈëµã£¬¸ÃÇÐÈëµã½«Óë com.xyz.myapp.service °üϵÄÀàÖпÉÓõÄÿһ¸ö·½·¨ÏàÆ¥Å䣺
+
+```
+import org.aspectj.lang.annotation.Pointcut;
+@Pointcut("execution(* com.xyz.myapp.service.*.*(..))") // expression
+private void businessService() {} // signature
+```
+
+ÏÂÃæµÄʾÀýÖж¨ÒåÁËÒ»¸öÃûΪ ¡®getname¡¯ µÄÇÐÈëµã£¬¸ÃÇÐÈëµã½«Óë com.tutorialspoint °üÏ嵀 Student ÀàÖÐµÄ getName() ·½·¨ÏàÆ¥Å䣺
+
+```
+import org.aspectj.lang.annotation.Pointcut;
+@Pointcut("execution(* com.tutorialspoint.Student.getName(..))")
+private void getname() {}
+```
+
+## ÉùÃ÷½¨Òé
+
+Äã¿ÉÒÔʹÓà @{ADVICE-NAME} ×¢ÊÍÉùÃ÷Îå¸ö½¨ÒéÖеÄÈÎÒâÒ»¸ö£¬ÈçÏÂËùʾ¡£Õâ¼ÙÉèÄãÒѾ¶¨ÒåÁËÒ»¸öÇÐÈëµã±êÇ©·½·¨ businessService()£º
+
+```
+@Before("businessService()")
+public void doBeforeTask(){
+ ...
+}
+@After("businessService()")
+public void doAfterTask(){
+ ...
+}
+@AfterReturning(pointcut = "businessService()", returning="retVal")
+public void doAfterReturnningTask(Object retVal){
+ // you can intercept retVal here.
+ ...
+}
+@AfterThrowing(pointcut = "businessService()", throwing="ex")
+public void doAfterThrowingTask(Exception ex){
+ // you can intercept thrown exception here.
+ ...
+}
+@Around("businessService()")
+public void doAroundTask(){
+ ...
+}
+```
+
+Äã¿ÉÒÔΪÈÎÒâÒ»¸ö½¨Ò鶨ÒåÄãµÄÇÐÈëµãÄÚÁª¡£ÏÂÃæÊÇÔÚ½¨Òé֮ǰ¶¨ÒåÄÚÁªÇÐÈëµãµÄÒ»¸öʾÀý£º
+
+```
+@Before("execution(* com.xyz.myapp.service.*.*(..))")
+public doBeforeTask(){
+ ...
+}
+```
+
+## »ùÓÚ AOP µÄ @AspectJ ʾÀý
+
+ΪÁËÀí½âÉÏÃæÌáµ½µÄ¹ØÓÚ»ùÓÚ AOP µÄ @AspectJ µÄ¸ÅÄÈÃÎÒÃDZàдһ¸öʾÀý£¬¿ÉÒÔʵÏÖ¼¸¸ö½¨Ò顣ΪÁËÔÚÎÒÃǵÄʾÀýÖÐʹÓü¸¸ö½¨Ò飬ÈÃÎÒÃÇʹ Eclipse IDE ´¦ÓÚ¹¤×÷״̬£¬È»ºó°´ÕÕÈçϲ½Öè´´½¨Ò»¸ö Spring Ó¦ÓóÌÐò£º
+
+| ²½Öè | ÃèÊö |
+| --- | --- |
+| 1 | ´´½¨Ò»¸öÃûΪ _SpringExample_ µÄÏîÄ¿£¬²¢ÇÒÔÚËù´´½¨ÏîÄ¿µÄ **src** Îļþ¼ÐÏ´´½¨Ò»¸öÃûΪ _com.tutorialspoint_ µÄ°ü¡£ |
+| 2 | ʹÓà _Add External JARs_ Ñ¡ÏîÌí¼ÓËùÐèµÄ Spring ¿âÎļþ£¬¾ÍÈçÔÚ _Spring Hello World Example_ Õ½ÚÖнâÊ͵ÄÄÇÑù¡£ |
+| 3 | ÔÚÏîÄ¿ÖÐÌí¼Ó Spring AOP Ö¸¶¨µÄ¿âÎļþ **aspectjrt.jar£¬ aspectjweaver.jar** ºÍ **aspectj.jar**¡£ |
+| 4 | ÔÚ _com.tutorialspoint_ °üÏ´´½¨ Java Àà **Logging**£¬ _Student_ ºÍ _MainApp_¡£ |
+| 5 | ÔÚ **src** Îļþ¼ÐÏ´´½¨ Beans ÅäÖÃÎļþ _Beans.xml_¡£ |
+| 6 | ×îºóÒ»²½ÊÇ´´½¨ËùÓÐ Java ÎļþºÍ Bean ÅäÖÃÎļþµÄÄÚÈÝ£¬²¢ÇÒ°´ÈçϽâÊ͵ÄÄÇÑùÔËÐÐÓ¦ÓóÌÐò¡£ |
+
+ÕâÀïÊÇ **Logging.java** ÎļþµÄÄÚÈÝ¡£Õâʵ¼ÊÉÏÊÇ aspect Ä£¿éµÄÒ»¸öʾÀý£¬Ëü¶¨ÒåÁËÔÚ¸÷¸öµãµ÷Óõķ½·¨¡£
+
+```
+package com.tutorialspoint;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.aspectj.lang.annotation.Before;
+import org.aspectj.lang.annotation.After;
+import org.aspectj.lang.annotation.AfterThrowing;
+import org.aspectj.lang.annotation.AfterReturning;
+import org.aspectj.lang.annotation.Around;
+@Aspect
+public class Logging {
+ /** Following is the definition for a pointcut to select
+ * all the methods available. So advice will be called
+ * for all the methods.
+ */
+ @Pointcut("execution(* com.tutorialspoint.*.*(..))")
+ private void selectAll(){}
+ /**
+ * This is the method which I would like to execute
+ * before a selected method execution.
+ */
+ @Before("selectAll()")
+ public void beforeAdvice(){
+ System.out.println("Going to setup student profile.");
+ }
+ /**
+ * This is the method which I would like to execute
+ * after a selected method execution.
+ */
+ @After("selectAll()")
+ public void afterAdvice(){
+ System.out.println("Student profile has been setup.");
+ }
+ /**
+ * This is the method which I would like to execute
+ * when any method returns.
+ */
+ @AfterReturning(pointcut = "selectAll()", returning="retVal")
+ public void afterReturningAdvice(Object retVal){
+ System.out.println("Returning:" + retVal.toString() );
+ }
+ /**
+ * This is the method which I would like to execute
+ * if there is an exception raised by any method.
+ */
+ @AfterThrowing(pointcut = "selectAll()", throwing = "ex")
+ public void AfterThrowingAdvice(IllegalArgumentException ex){
+ System.out.println("There has been an exception: " + ex.toString());
+ }
+}
+```
+
+ÏÂÃæÊÇ **Student.java** ÎļþµÄÄÚÈÝ£º
+
+```
+package com.tutorialspoint;
+public class Student {
+ private Integer age;
+ private String name;
+ public void setAge(Integer age) {
+ this.age = age;
+ }
+ public Integer getAge() {
+ System.out.println("Age : " + age );
+ return age;
+ }
+ public void setName(String name) {
+ this.name = name;
+ }
+ public String getName() {
+ System.out.println("Name : " + name );
+ return name;
+ }
+ public void printThrowException(){
+ System.out.println("Exception raised");
+ throw new IllegalArgumentException();
+ }
+}
+```
+
+ÏÂÃæÊÇ **MainApp.java** ÎļþµÄÄÚÈÝ£º
+
+```
+package com.tutorialspoint;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+public class MainApp {
+ public static void main(String[] args) {
+ ApplicationContext context =
+ new ClassPathXmlApplicationContext("Beans.xml");
+ Student student = (Student) context.getBean("student");
+ student.getName();
+ student.getAge();
+ student.printThrowException();
+ }
+}
+```
+
+ÏÂÃæÊÇÅäÖÃÎļþ **Beans.xml**£º
+
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+Ò»µ©ÄãÒѾÍê³ÉµÄ´´½¨ÁËÔ´ÎļþºÍ bean ÅäÖÃÎļþ£¬ÈÃÎÒÃÇÔËÐÐÒ»ÏÂÓ¦ÓóÌÐò¡£Èç¹ûÄãµÄÓ¦ÓóÌÐòÒ»Çж¼Õý³£µÄ»°£¬Õ⽫»áÊä³öÒÔÏÂÏûÏ¢£º
+
+```
+Going to setup student profile.
+Name : Zara
+Student profile has been setup.
+Returning:Zara
+Going to setup student profile.
+Age : 11
+Student profile has been setup.
+Returning:11
+Going to setup student profile.
+Exception raised
+Student profile has been setup.
+There has been an exception: java.lang.IllegalArgumentException
+.....
+other exception content
+```
+
+
+
+
+
+# ²Î¿¼ÎÄÕÂ
+https://www.w3cschool.cn/wkspring
+https://www.runoob.com/w3cnote/basic-knowledge-summary-of-spring.html
+http://codepub.cn/2015/06/21/Basic-knowledge-summary-of-Spring
+https://dunwu.github.io/spring-tutorial
+https://mszlu.com/java/spring
+http://c.biancheng.net/spring/aop-module.html
\ No newline at end of file
diff --git "a/docs/spring/SpringBean\347\232\204\345\256\232\344\271\211\344\270\216\347\256\241\347\220\206\357\274\210\346\240\270\345\277\203\357\274\211.md" "b/docs/spring/SpringBean\347\232\204\345\256\232\344\271\211\344\270\216\347\256\241\347\220\206\357\274\210\346\240\270\345\277\203\357\274\211.md"
new file mode 100644
index 0000000..a684554
--- /dev/null
+++ "b/docs/spring/SpringBean\347\232\204\345\256\232\344\271\211\344\270\216\347\256\241\347\220\206\357\274\210\346\240\270\345\277\203\357\274\211.md"
@@ -0,0 +1,182 @@
+### ÒÀÀµ×¢Èë
+
+Spring¿ò¼ÜµÄºËÐŦÄÜÓÐÁ½¸ö£º
+
+* SpringÈÝÆ÷×÷Ϊ³¬¼¶´ó¹¤³§£¬¸ºÔð´´½¨¡¢¹ÜÀíËùÓеÄJava¶ÔÏó£¬ÕâЩJava¶ÔÏó±»³ÆÎªBean¡£
+* SpringÈÝÆ÷¹ÜÀíÈÝÆ÷ÖÐBeanÖ®¼äµÄÒÀÀµ¹ØÏµ£¬SpringʹÓÃÒ»ÖÖ±»³ÆÎª"ÒÀÀµ×¢Èë"µÄ·½Ê½À´¹ÜÀíBeanÖ®¼äµÄÒÀÀµ¹ØÏµ¡£
+
+ʹÓÃÒÀÀµ×¢È룬²»½ö¿ÉÒÔΪBean×¢ÈëÆÕͨµÄÊôÐÔÖµ£¬»¹¿ÉÒÔ×¢ÈëÆäËûBeanµÄÒýÓá£ÒÀÀµ×¢ÈëÊÇÒ»ÖÖÓÅÐãµÄ½âñʽ£¬Æä¿ÉÒÔÈÃBeanÒÔÅäÖÃÎļþ×éÖ¯ÔÚÒ»Æð£¬¶ø²»ÊÇÒÔÓ²±àÂëµÄ·½Ê½ñîºÏÔÚÒ»Æð¡£
+
+#### Àí½âÒÀÀµ×¢Èë
+
+Rod JohnsonÊǵÚÒ»¸ö¸ß¶ÈÖØÊÓÒÔÅäÖÃÎļþÀ´¹ÜÀíJavaʵÀýµÄÐ×÷¹ØÏµµÄÈË£¬Ëû¸øÕâÖÖ·½Ê½ÆðÁËÒ»¸öÃû×Ö£º¿ØÖÆ·´×ª£¨Inverse of Control£¬IoC£©¡£ºóÀ´Martine FowlerΪÕâÖÖ·½Ê½ÆðÁËÁíÒ»¸öÃû³Æ£ºÒÀÀµ×¢È루Dependency Injection£©£¬Òò´Ë²»¹ÜÊÇÒÀÀµ×¢È룬»¹ÊÇ¿ØÖÆ·´×ª£¬Æäº¬ÒåÍêÈ«Ïàͬ¡£µ±Ä³¸öJava¶ÔÏ󣨵÷ÓÃÕߣ©ÐèÒªµ÷ÓÃÁíÒ»¸öJava¶ÔÏ󣨱»ÒÀÀµ¶ÔÏ󣩵ķ½·¨Ê±£¬ÔÚ´«Í³Ä£Ê½ÏÂͨ³£ÓÐÁ½ÖÖ×ö·¨£º
+
+1. Ôʼ×ö·¨: µ÷ÓÃÕß**Ö÷¶¯**´´½¨±»ÒÀÀµ¶ÔÏó£¬È»ºóÔÙµ÷Óñ»ÒÀÀµ¶ÔÏóµÄ·½·¨¡£
+2. ¼òµ¥¹¤³§Ä£Ê½: µ÷ÓÃÕßÏÈÕÒµ½±»ÒÀÀµ¶ÔÏóµÄ¹¤³§£¬È»ºó**Ö÷¶¯**ͨ¹ý¹¤³§È¥»ñÈ¡±»ÒÀÀµ¶ÔÏó£¬×îºóÔÙµ÷Óñ»ÒÀÀµ¶ÔÏóµÄ·½·¨¡£
+
+×¢ÒâÉÏÃæµÄ**Ö÷¶¯**¶þ×Ö£¬Õâ±ØÈ»»áµ¼Öµ÷ÓÃÕßÓë±»ÒÀÀµ¶ÔÏóʵÏÖÀàµÄÓ²±àÂëñîºÏ£¬·Ç³£²»ÀûÓÚÏîÄ¿Éý¼¶µÄά»¤¡£Ê¹ÓÃSpring¿ò¼ÜÖ®ºó£¬µ÷ÓÃÕßÎÞÐè**Ö÷¶¯**»ñÈ¡±»ÒÀÀµ¶ÔÏ󣬵÷ÓÃÕßÖ»Òª**±»¶¯**½ÓÊÜSpringÈÝÆ÷Ϊµ÷ÓÃÕߵijÉÔ±±äÁ¿¸³Öµ¼´¿É£¬Óɴ˿ɼû£¬Ê¹ÓÃSpringºó£¬µ÷ÓÃÕß»ñÈ¡±»ÒÀÀµ¶ÔÏóµÄ·½Ê½ÓÉÔÀ´µÄÖ÷¶¯»ñÈ¡£¬±ä³ÉÁ˱»¶¯½ÓÊÜ¡ª¡ªËùÒÔRod Johnson³ÆÖ®Îª¿ØÖÆ·´×ª¡£
+
+ÁíÍâ´ÓSpringÈÝÆ÷µÄ½Ç¶ÈÀ´¿´£¬SpringÈÝÆ÷¸ºÔ𽫱»ÒÀÀµ¶ÔÏó¸³Öµ¸øµ÷ÓÃÕߵijÉÔ±±äÁ¿¡ª¡ªÏ൱ÓÚΪµ÷ÓÃÕß×¢ÈëËüÒÀÀµµÄʵÀý£¬Òò´ËMartine Fowler³ÆÖ®ÎªÒÀÀµ×¢Èë¡£
+
+#### ÉèÖµ×¢Èë
+
+ÉèÖµ×¢ÈëÊÇÖ¸IoCÈÝÆ÷ͨ¹ý³ÉÔ±±äÁ¿µÄsetter·½·¨À´×¢Èë±»ÒÀÀµ¶ÔÏó¡£ÕâÖÖ×¢È뷽ʽ¼òµ¥¡¢Ö±¹Û£¬Òò¶øÔÚSpringµÄÒÀÀµ×¢ÈëÀï´óÁ¿Ê¹Óá£
+
+#### ¹¹Ôì×¢Èë
+
+ÀûÓù¹ÔìÆ÷À´ÉèÖÃÒÀÀµ¹ØÏµµÄ·½Ê½£¬±»³ÆÎª¹¹Ôì×¢È롣ͨË×À´Ëµ£¬¾ÍÊÇÇý¶¯SpringÔڵײãÒÔ·´É䷽ʽִÐдøÖ¸¶¨²ÎÊýµÄ¹¹ÔìÆ÷£¬µ±Ö´Ðдø²ÎÊýµÄ¹¹ÔìÆ÷ʱ£¬¾Í¿ÉÀûÓù¹ÔìÆ÷²ÎÊý¶Ô³ÉÔ±±äÁ¿Ö´Ðгõʼ»¯¡ª¡ªÕâ¾ÍÊǹ¹Ôì×¢ÈëµÄ±¾ÖÊ¡£
+
+#### Á½ÖÖ×¢È뷽ʽµÄ¶Ô±È
+
+ÉèÖµ×¢ÈëÓÐÈçÏÂÓŵ㣺
+
+* Ó봫ͳµÄJavaBeanµÄд·¨¸üÏàËÆ£¬³ÌÐò¿ª·¢ÈËÔ±¸üÈÝÒ×Àí½â¡¢½ÓÊÜ¡£Í¨¹ýsetter·½·¨É趨ÒÀÀµ¹ØÏµÏԵøü¼ÓÖ±¹Û¡¢×ÔÈ»¡£
+* ¶ÔÓÚ¸´ÔÓµÄÒÀÀµ¹ØÏµ£¬Èç¹û²ÉÓù¹Ôì×¢È룬»áµ¼Ö¹¹ÔìÆ÷¹ýÓÚÓ·Ö×£¬ÄÑÒÔÔĶÁ¡£SpringÔÚ´´½¨BeanʵÀýʱ£¬ÐèҪͬʱʵÀý»¯ÆäÒÀÀµµÄÈ«²¿ÊµÀý£¬Òò¶øµ¼ÖÂÐÔÄÜϽµ¡£¶øÊ¹ÓÃÉèÖµ×¢È룬ÔòÄܱÜÃâÕâЩÎÊÌâ¡£
+* ÓÈÆäÔÚijЩ³ÉÔ±±äÁ¿¿ÉÑ¡µÄÇé¿öÏ£¬¶à²ÎÊýµÄ¹¹ÔìÆ÷¸ü¼Ó±¿ÖØ¡£
+
+¹¹Ôì×¢ÈëÓÅÊÆÈçÏ£º
+
+* ¹¹Ôì×¢Èë¿ÉÒÔÔÚ¹¹ÔìÆ÷Öоö¶¨ÒÀÀµ¹ØÏµµÄ×¢Èë˳Ðò£¬ÓÅÏÈÒÀÀµµÄÓÅÏÈ×¢Èë¡£
+* ¶ÔÓÚÒÀÀµ¹ØÏµÎÞÐè±ä»¯µÄBean£¬¹¹Ôì×¢Èë¸üÓÐÓô¦¡£ÒòΪûÓÐsetter·½·¨£¬ËùÓеÄÒÀÀµ¹ØÏµÈ«²¿ÔÚ¹¹ÔìÆ÷ÄÚÉ趨£¬ÎÞÐëµ£ÐĺóÐøµÄ´úÂë¶ÔÒÀÀµ¹ØÏµ²úÉúÆÆ»µ¡£
+* ÒÀÀµ¹ØÏµÖ»ÄÜÔÚ¹¹ÔìÆ÷ÖÐÉ趨£¬ÔòÖ»ÓÐ×é¼þµÄ´´½¨Õß²ÅÄܸıä×é¼þµÄÒÀÀµ¹ØÏµ£¬¶Ô×é¼þµÄµ÷ÓÃÕß¶øÑÔ£¬×é¼þÄÚ²¿µÄÒÀÀµ¹ØÏµÍêȫ͸Ã÷£¬¸ü·ûºÏ¸ßÄÚ¾ÛµÄÔÔò¡£
+
+**_×¢Ò⣺_**
+½¨Òé²ÉÓÃÉèÖµ×¢ÈëΪÖ÷£¬¹¹Ôì×¢ÈëΪ¸¨µÄ×¢Èë²ßÂÔ¡£¶ÔÓÚÒÀÀµ¹ØÏµÎÞÐë±ä»¯µÄ×¢È룬¾¡Á¿²ÉÓù¹Ôì×¢È룻¶øÆäËûÒÀÀµ¹ØÏµµÄ×¢È룬Ôò¿¼ÂDzÉÓÃÉèÖµ×¢Èë¡£
+
+### SpringÈÝÆ÷ÖеÄBean
+
+¶ÔÓÚ¿ª·¢ÕßÀ´Ëµ£¬¿ª·¢ÕßʹÓÃSpring¿ò¼ÜÖ÷ÒªÊÇ×öÁ½¼þÊ£º¢Ù¿ª·¢Bean£»¢ÚÅäÖÃBean¡£¶ÔÓÚSpring¿ò¼ÜÀ´Ëµ£¬ËüÒª×öµÄ¾ÍÊǸù¾ÝÅäÖÃÎļþÀ´´´½¨BeanʵÀý£¬²¢µ÷ÓÃBeanʵÀýµÄ·½·¨Íê³É"ÒÀÀµ×¢Èë"¡ª¡ªÕâ¾ÍÊÇËùνIoCµÄ±¾ÖÊ¡£
+
+#### ÈÝÆ÷ÖÐBeanµÄ×÷ÓÃÓò
+
+µ±Í¨¹ýSpringÈÝÆ÷´´½¨Ò»¸öBeanʵÀýʱ£¬²»½ö¿ÉÒÔÍê³ÉBeanʵÀýµÄʵÀý»¯£¬»¹¿ÉÒÔΪBeanÖ¸¶¨Ìض¨µÄ×÷ÓÃÓò¡£SpringÖ§³ÖÈçÏÂÎåÖÖ×÷ÓÃÓò£º
+
+1. singleton: µ¥Àýģʽ£¬ÔÚÕû¸öSpring IoCÈÝÆ÷ÖУ¬singleton×÷ÓÃÓòµÄBean½«Ö»Éú³ÉÒ»¸öʵÀý¡£
+2. prototype: ÿ´Îͨ¹ýÈÝÆ÷µÄgetBean()·½·¨»ñÈ¡prototype×÷ÓÃÓòµÄBeanʱ£¬¶¼½«²úÉúÒ»¸öеÄBeanʵÀý¡£
+3. request: ¶ÔÓÚÒ»´ÎHTTPÇëÇó£¬request×÷ÓÃÓòµÄBean½«Ö»Éú³ÉÒ»¸öʵÀý£¬ÕâÒâζ×Å£¬ÔÚͬһ´ÎHTTPÇëÇóÄÚ£¬³ÌÐòÿ´ÎÇëÇó¸ÃBean£¬µÃµ½µÄ×ÜÊÇͬһ¸öʵÀý¡£Ö»ÓÐÔÚWebÓ¦ÓÃÖÐʹÓÃSpringʱ£¬¸Ã×÷ÓÃÓò²ÅÕæÕýÓÐЧ¡£
+4. session£º¸Ã×÷ÓÃÓò½« bean µÄ¶¨ÒåÏÞÖÆÎª HTTP »á»°¡£ Ö»ÔÚweb-aware Spring ApplicationContextµÄÉÏÏÂÎÄÖÐÓÐЧ¡£
+5. global session: ÿ¸öÈ«¾ÖµÄHTTP Session¶ÔÓ¦Ò»¸öBeanʵÀý¡£ÔÚµäÐ͵ÄÇé¿öÏ£¬½öÔÚʹÓÃportlet contextµÄʱºòÓÐЧ£¬Í¬ÑùÖ»ÔÚWebÓ¦ÓÃÖÐÓÐЧ¡£
+
+Èç¹û²»Ö¸¶¨BeanµÄ×÷ÓÃÓò£¬SpringĬÈÏʹÓÃsingleton×÷ÓÃÓò¡£prototype×÷ÓÃÓòµÄBeanµÄ´´½¨¡¢Ïú»Ù´ú¼Û±È½Ï´ó¡£¶øsingleton×÷ÓÃÓòµÄBeanʵÀýÒ»µ©´´½¨³É¹û£¬¾Í¿ÉÒÔÖØ¸´Ê¹Óá£Òò´Ë£¬Ó¦¸Ã¾¡Á¿±ÜÃ⽫BeanÉèÖóÉprototype×÷ÓÃÓò¡£
+
+### ʹÓÃ×Ô¶¯×°Åä×¢ÈëºÏ×÷ÕßBean
+
+SpringÄÜ×Ô¶¯×°ÅäBeanÓëBeanÖ®¼äµÄÒÀÀµ¹ØÏµ£¬¼´ÎÞÐëʹÓÃrefÏÔʽָ¶¨ÒÀÀµBean£¬¶øÊÇÓÉSpringÈÝÆ÷¼ì²éXMLÅäÖÃÎļþÄÚÈÝ£¬¸ù¾ÝijÖÖ¹æÔò£¬Îªµ÷ÓÃÕßBean×¢Èë±»ÒÀÀµµÄBean¡£
+Spring×Ô¶¯×°Åä¿Éͨ¹ý` `ÔªËØµÄ`default-autowire`ÊôÐÔÖ¸¶¨£¬¸ÃÊôÐÔ¶ÔÅäÖÃÎļþÖÐËùÓеÄBeanÆð×÷Óã»Ò²¿Éͨ¹ý¶Ô` `ÔªËØµÄ`autowire`ÊôÐÔÖ¸¶¨£¬¸ÃÊôÐÔÖ»¶Ô¸ÃBeanÆð×÷Óá£
+
+`autowire`ºÍ`default-autowire`¿ÉÒÔ½ÓÊÜÈçÏÂÖµ£º
+
+* `no`: ²»Ê¹ÓÃ×Ô¶¯×°Åä¡£BeanÒÀÀµ±ØÐëͨ¹ýrefÔªËØ¶¨Òå¡£ÕâÊÇĬÈÏÅäÖã¬ÔڽϴóµÄ²¿Êð»·¾³Öв»¹ÄÀø¸Ä±äÕâ¸öÅäÖã¬ÏÔʽÅäÖúÏ×÷ÕßÄܹ»µÃµ½¸üÇåÎúµÄÒÀÀµ¹ØÏµ¡£
+* `byName`: ¸ù¾Ýsetter·½·¨Ãû½øÐÐ×Ô¶¯×°Åä¡£SpringÈÝÆ÷²éÕÒÈÝÆ÷ÖÐÈ«²¿Bean£¬ÕÒ³öÆäidÓësetter·½·¨ÃûÈ¥µôsetǰ׺£¬²¢Ð¡Ð´Ê××ÖĸºóͬÃûµÄBeanÀ´Íê³É×¢Èë¡£Èç¹ûûÓÐÕÒµ½Æ¥ÅäµÄBeanʵÀý£¬ÔòSpring²»»á½øÐÐÈκÎ×¢Èë¡£
+* `byType`: ¸ù¾Ýsetter·½·¨µÄÐβÎÀàÐÍÀ´×Ô¶¯×°Åä¡£SpringÈÝÆ÷²éÕÒÈÝÆ÷ÖеÄÈ«²¿Bean£¬Èç¹ûÕýºÃÓÐÒ»¸öBeanÀàÐÍÓësetter·½·¨µÄÐβÎÀàÐÍÆ¥Å䣬¾Í×Ô¶¯×¢ÈëÕâ¸öBean£»Èç¹ûÕÒµ½¶à¸öÕâÑùµÄBean£¬¾ÍÅ׳öÒ»¸öÒì³££»Èç¹ûûÓÐÕÒµ½ÕâÑùµÄBean£¬Ôòʲô¶¼²»»á·¢Éú£¬setter·½·¨²»»á±»µ÷Óá£
+* `constructor`: ÓëbyTypeÀàËÆ£¬Çø±ðÊÇÓÃÓÚ×Ô¶¯Æ¥Åä¹¹ÔìÆ÷µÄ²ÎÊý¡£Èç¹ûÈÝÆ÷²»ÄÜÇ¡ºÃÕÒµ½Ò»¸öÓë¹¹ÔìÆ÷²ÎÊýÀàÐÍÆ¥ÅäµÄBean£¬Ôò»áÅ׳öÒ»¸öÒì³£¡£
+* `autodetect`: SpringÈÝÆ÷¸ù¾ÝBeanÄÚ²¿½á¹¹£¬×ÔÐоö¶¨Ê¹ÓÃconstructor»òbyType²ßÂÔ¡£Èç¹ûÕÒµ½Ò»¸öĬÈϵĹ¹Ô캯Êý£¬ÄÇô¾Í»áÓ¦ÓÃbyType²ßÂÔ¡£
+
+**µ±Ò»¸öBean¼ÈʹÓÃ×Ô¶¯×°ÅäÒÀÀµ£¬ÓÖʹÓÃrefÏÔʽָ¶¨ÒÀÀµÊ±£¬ÔòÏÔʽָ¶¨µÄÒÀÀµ¸²¸Ç×Ô¶¯×°ÅäÒÀÀµ£»¶ÔÓÚ´óÐ͵ÄÓ¦Ó㬲»¹ÄÀøÊ¹ÓÃ×Ô¶¯×°Åä¡£ËäȻʹÓÃ×Ô¶¯×°Åä¿É¼õÉÙÅäÖÃÎļþµÄ¹¤×÷Á¿£¬µ«´ó´ó½«ËÀÁËÒÀÀµ¹ØÏµµÄÇåÎúÐÔºÍ͸Ã÷ÐÔ¡£ÒÀÀµ¹ØÏµµÄ×°ÅäÒÀÀµÓÚÔ´ÎļþµÄÊôÐÔÃûºÍÊôÐÔÀàÐÍ£¬µ¼ÖÂBeanÓëBeanÖ®¼äµÄñîºÏ½µµÍµ½´úÂë²ã´Î£¬²»ÀûÓڸ߲ã´Î½âñî¡£**
+
+
+
+## ´´½¨BeanµÄ3ÖÖ·½Ê½
+
+### ʹÓù¹ÔìÆ÷´´½¨BeanʵÀý
+
+ʹÓù¹ÔìÆ÷À´´´½¨BeanʵÀýÊÇ×î³£¼ûµÄÇé¿ö£¬Èç¹û²»²ÉÓù¹Ôì×¢È룬Springµ×²ã»áµ÷ÓÃBeanÀàµÄÎÞ²ÎÊý¹¹ÔìÆ÷À´´´½¨ÊµÀý£¬Òò´ËÒªÇó¸ÃBeanÀàÌṩÎÞ²ÎÊýµÄ¹¹ÔìÆ÷¡£
+
+²ÉÓÃĬÈϵĹ¹ÔìÆ÷´´½¨BeanʵÀý£¬Spring¶ÔBeanʵÀýµÄËùÓÐÊôÐÔÖ´ÐÐĬÈϳõʼ»¯£¬¼´ËùÓеĻù±¾ÀàÐ͵ÄÖµ³õʼ»¯Îª0»òfalse£»ËùÓеÄÒýÓÃÀàÐ͵ÄÖµ³õʼ»¯Îªnull¡£
+
+### ʹÓþ²Ì¬¹¤³§·½·¨´´½¨Bean
+
+ʹÓþ²Ì¬¹¤³§·½·¨´´½¨BeanʵÀýʱ£¬classÊôÐÔÒ²±ØÐëÖ¸¶¨£¬µ«´ËʱclassÊôÐÔ²¢²»ÊÇÖ¸¶¨BeanʵÀýµÄʵÏÖÀ࣬¶øÊǾ²Ì¬¹¤³§À࣬Springͨ¹ý¸ÃÊôÐÔÖªµÀÓÉÄĸö¹¤³§ÀàÀ´´´½¨BeanʵÀý¡£
+
+³ý´ËÖ®Í⣬»¹ÐèҪʹÓÃfactory-methodÊôÐÔÀ´Ö¸¶¨¾²Ì¬¹¤³§·½·¨£¬Spring½«µ÷Óþ²Ì¬¹¤³§·½·¨·µ»ØÒ»¸öBeanʵÀý£¬Ò»µ©»ñµÃÁËÖ¸¶¨BeanʵÀý£¬SpringºóÃæµÄ´¦Àí²½ÖèÓë²ÉÓÃÆÕͨ·½·¨´´½¨BeanʵÀýÍêȫһÑù¡£Èç¹û¾²Ì¬¹¤³§·½·¨ÐèÒª²ÎÊý£¬ÔòʹÓÃ` `ÔªËØÖ¸¶¨¾²Ì¬¹¤³§·½·¨µÄ²ÎÊý¡£
+
+### µ÷ÓÃʵÀý¹¤³§·½·¨´´½¨Bean
+
+ʵÀý¹¤³§·½·¨Ó뾲̬¹¤³§·½·¨Ö»ÓÐÒ»¸ö²»Í¬£ºµ÷Óþ²Ì¬¹¤³§·½·¨Ö»ÐèʹÓù¤³§À༴¿É£¬¶øµ÷ÓÃʵÀý¹¤³§·½·¨ÔòÐèÒª¹¤³§ÊµÀý¡£Ê¹ÓÃʵÀý¹¤³§·½·¨Ê±£¬ÅäÖÃBeanʵÀýµÄ` `ÔªËØÎÞÐëclassÊôÐÔ£¬ÅäÖÃʵÀý¹¤³§·½·¨Ê¹ÓÃ`factory-bean`Ö¸¶¨¹¤³§ÊµÀý¡£
+²ÉÓÃʵÀý¹¤³§·½·¨´´½¨BeanµÄ` `ÔªËØÊ±ÐèÒªÖ¸¶¨ÈçÏÂÁ½¸öÊôÐÔ£º
+
+* factory-bean: ¸ÃÊôÐÔµÄֵΪ¹¤³§BeanµÄid¡£
+* factory-method: ¸ÃÊôÐÔÖ¸¶¨ÊµÀý¹¤³§µÄ¹¤³§·½·¨¡£
+
+Èôµ÷ÓÃʵÀý¹¤³§·½·¨Ê±ÐèÒª´«Èë²ÎÊý£¬ÔòʹÓÃ` `ÔªËØÈ·¶¨²ÎÊýÖµ¡£
+
+## е÷×÷ÓÃÓò²»Í¬²½µÄBean
+
+µ±singleton×÷ÓÃÓòµÄBeanÒÀÀµÓÚprototype×÷ÓÃÓòµÄBeanʱ£¬»á²úÉú²»Í¬²½µÄÏÖÏó£¬ÔÒòÊÇÒòΪµ±SpringÈÝÆ÷³õʼ»¯Ê±£¬ÈÝÆ÷»áÔ¤³õʼ»¯ÈÝÆ÷ÖÐËùÓеÄ`singleton Bean`£¬ÓÉÓÚ`singleton Bean`ÒÀÀµÓÚ`prototype Bean`£¬Òò´ËSpringÔÚ³õʼ»¯`singleton Bean`֮ǰ£¬»áÏÈ´´½¨`prototypeBean`¡ª¡ªÈ»ºó²Å´´½¨`singleton Bean`£¬½ÓÏÂÀォ`prototype Bean`×¢Èë`singleton Bean`¡£
+½â¾ö²»Í¬²½µÄ·½·¨ÓÐÁ½ÖÖ£º
+
+* ·ÅÆúÒÀÀµ×¢Èë: singleton×÷ÓÃÓòµÄBeanÿ´ÎÐèÒªprototype×÷ÓÃÓòµÄBeanʱ£¬Ö÷¶¯ÏòÈÝÆ÷ÇëÇóеÄBeanʵÀý£¬¼´¿É±£Ö¤Ã¿´Î×¢ÈëµÄ`prototype Bean`ʵÀý¶¼ÊÇ×îеÄʵÀý¡£
+* ÀûÓ÷½·¨×¢Èë: ·½·¨×¢Èëͨ³£Ê¹ÓÃlookup·½·¨×¢È룬ʹÓÃlookup·½·¨×¢Èë¿ÉÒÔÈÃSpringÈÝÆ÷ÖØÐ´ÈÝÆ÷ÖÐBeanµÄ³éÏó»ò¾ßÌå·½·¨£¬·µ»Ø²éÕÒÈÝÆ÷ÖÐÆäËûBeanµÄ½á¹û£¬±»²éÕÒµÄBeanͨ³£ÊÇÒ»¸ö`non-singleton Bean`¡£Springͨ¹ýʹÓÃJDK¶¯Ì¬´úÀí»òcglib¿âÐ޸Ŀͻ§¶ËµÄ¶þ½øÖÆÂ룬´Ó¶øÊµÏÖÉÏÊöÒªÇó¡£
+
+½¨Òé²ÉÓõڶþÖÖ·½·¨£¬Ê¹Ó÷½·¨×¢È롣ΪÁËʹÓÃlookup·½·¨×¢È룬´óÖÂÐèÒªÈçÏÂÁ½²½£º
+
+1. ½«µ÷ÓÃÕßBeanµÄʵÏÖÀඨÒåΪ³éÏóÀ࣬²¢¶¨ÒåÒ»¸ö³éÏó·½·¨À´»ñÈ¡±»ÒÀÀµµÄBean¡£
+2. ÔÚ` `ÔªËØÖÐÌí¼Ó` `×ÓÔªËØÈÃSpringΪµ÷ÓÃÕßBeanµÄʵÏÖÀàʵÏÖÖ¸¶¨µÄ³éÏó·½·¨¡£
+
+**_×¢Ò⣺_**
+
+> Spring»á²ÉÓÃÔËÐÐʱ¶¯Ì¬ÔöÇ¿µÄ·½Ê½À´ÊµÏÖ` `ÔªËØËùÖ¸¶¨µÄ³éÏó·½·¨£¬Èç¹ûÄ¿±ê³éÏóÀàʵÏÖ¹ý½Ó¿Ú£¬Spring»á²ÉÓÃJDK¶¯Ì¬´úÀíÀ´ÊµÏָóéÏóÀ࣬²¢ÎªÖ®ÊµÏÖ³éÏó·½·¨£»Èç¹ûÄ¿±ê³éÏóÀàûÓÐʵÏÖ¹ý½Ó¿Ú£¬Spring»á²ÉÓÃcglibʵÏָóéÏóÀ࣬²¢ÎªÖ®ÊµÏÖ³éÏó·½·¨¡£Spring4.0µÄspring-core-xxx.jar°üÖÐÒѾ¼¯³ÉÁËcglibÀà¿â¡£
+
+## Á½ÖÖºó´¦ÀíÆ÷
+
+SpringÌṩÁËÁ½ÖÖ³£Óõĺó´¦ÀíÆ÷£º
+
+* Beanºó´¦ÀíÆ÷: ÕâÖÖºó´¦ÀíÆ÷»á¶ÔÈÝÆ÷ÖÐBean½øÐкó´¦Àí£¬¶ÔBean½øÐжîÍâ¼ÓÇ¿¡£
+* ÈÝÆ÷ºó´¦ÀíÆ÷: ÕâÖÖºó´¦ÀíÆ÷»á¶ÔIoCÈÝÆ÷½øÐкó´¦Àí£¬ÓÃÓÚÔöÇ¿ÈÝÆ÷¹¦ÄÜ¡£
+
+### Beanºó´¦ÀíÆ÷
+
+Beanºó´¦ÀíÆ÷ÊÇÒ»ÖÖÌØÊâµÄBean£¬ÕâÖÖÌØÊâµÄBean²¢²»¶ÔÍâÌṩ·þÎñ£¬ËüÉõÖÁ¿ÉÒÔÎÞÐëidÊôÐÔ£¬ËüÖ÷Òª¸ºÔð¶ÔÈÝÆ÷ÖÐµÄÆäËûBeanÖ´Ðкó´¦Àí£¬ÀýÈçΪÈÝÆ÷ÖеÄÄ¿±êBeanÉú³É´úÀíµÈ£¬ÕâÖÖBean³ÆÎªBeanºó´¦ÀíÆ÷¡£Beanºó´¦ÀíÆ÷»áÔÚBeanʵÀý´´½¨³É¹¦Ö®ºó£¬¶ÔBeanʵÀý½øÐнøÒ»²½µÄÔöÇ¿´¦Àí¡£Beanºó´¦ÀíÆ÷±ØÐëʵÏÖ`BeanPostProcessor`½Ó¿Ú£¬Í¬Ê±±ØÐëʵÏָýӿڵÄÁ½¸ö·½·¨¡£
+
+1. `Object postProcessBeforeInitialization(Object bean, String name) throws BeansException`: ¸Ã·½·¨µÄµÚÒ»¸ö²ÎÊýÊÇϵͳ¼´½«½øÐкó´¦ÀíµÄBeanʵÀý£¬µÚ¶þ¸ö²ÎÊýÊǸÃBeanµÄÅäÖÃid
+2. `Object postProcessAfterinitialization(Object bean, String name) throws BeansException`: ¸Ã·½·¨µÄµÚÒ»¸ö²ÎÊýÊÇϵͳ¼´½«½øÐкó´¦ÀíµÄBeanʵÀý£¬µÚ¶þ¸ö²ÎÊýÊǸÃBeanµÄÅäÖÃid
+
+ÈÝÆ÷ÖÐÒ»µ©×¢²áÁËBeanºó´¦ÀíÆ÷£¬Beanºó´¦ÀíÆ÷¾Í»á×Ô¶¯Æô¶¯£¬ÔÚÈÝÆ÷ÖÐÿ¸öBean´´½¨Ê±×Ô¶¯¹¤×÷£¬Beanºó´¦ÀíÆ÷Á½¸ö·½·¨µÄ»Øµ÷ʱ»úÈçÏÂͼ£º
+
+
+
+×¢ÒâÒ»µã£¬Èç¹ûʹÓÃ`BeanFactory`×÷ΪSpringÈÝÆ÷£¬Ôò±ØÐëÊÖ¶¯×¢²áBeanºó´¦ÀíÆ÷£¬³ÌÐò±ØÐë»ñÈ¡Beanºó´¦ÀíÆ÷ʵÀý£¬È»ºóÊÖ¶¯×¢²á¡£
+
+ BeanPostProcessor bp = (BeanPostProcessor)beanFactory.getBean("bp"); beanFactory.addBeanPostProcessor(bp); Person p = (Person)beanFactory.getBean("person");
+
+### ÈÝÆ÷ºó´¦ÀíÆ÷
+
+Beanºó´¦ÀíÆ÷¸ºÔð´¦ÀíÈÝÆ÷ÖеÄËùÓÐBeanʵÀý£¬¶øÈÝÆ÷ºó´¦ÀíÆ÷Ôò¸ºÔð´¦ÀíÈÝÆ÷±¾Éí¡£ÈÝÆ÷ºó´¦ÀíÆ÷±ØÐëʵÏÖ`BeanFactoryPostProcessor`½Ó¿Ú£¬²¢ÊµÏָýӿڵÄÒ»¸ö·½·¨`postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)`ʵÏָ÷½·¨µÄ·½·¨Ìå¾ÍÊǶÔSpringÈÝÆ÷½øÐеĴ¦Àí£¬ÕâÖÖ´¦Àí¿ÉÒÔ¶ÔSpringÈÝÆ÷½øÐÐ×Ô¶¨ÒåÀ©Õ¹£¬µ±È»Ò²¿ÉÒÔ¶ÔSpringÈÝÆ÷²»½øÐÐÈκδ¦Àí¡£
+
+ÀàËÆÓÚ`BeanPostProcessor`£¬`ApplicationContext`¿É×Ô¶¯¼ì²âµ½ÈÝÆ÷ÖеÄÈÝÆ÷ºó´¦ÀíÆ÷£¬²¢ÇÒ×Ô¶¯×¢²áÈÝÆ÷ºó´¦ÀíÆ÷¡£µ«ÈôʹÓÃ`BeanFactory`×÷ΪSpringÈÝÆ÷£¬Ôò±ØÐëÊÖ¶¯µ÷ÓøÃÈÝÆ÷ºó´¦ÀíÆ÷À´´¦Àí`BeanFactory`ÈÝÆ÷¡£
+
+## SpringµÄ"ÁãÅäÖÃ"Ö§³Ö
+
+### ËÑË÷BeanÀà
+
+SpringÌṩÈçϼ¸¸öAnnotationÀ´±ê×¢Spring Bean£º
+
+* `@Component`: ±ê×¢Ò»¸öÆÕͨµÄSpring BeanÀà
+* `@Controller`: ±ê×¢Ò»¸ö¿ØÖÆÆ÷×é¼þÀà
+* `@Service`: ±ê×¢Ò»¸öÒµÎñÂß¼×é¼þÀà
+* `@Repository`: ±ê×¢Ò»¸öDAO×é¼þÀà
+
+ÔÚSpringÅäÖÃÎļþÖÐ×öÈçÏÂÅäÖã¬Ö¸¶¨×Ô¶¯É¨ÃèµÄ°ü£º
+
+
+
+### ʹÓÃ@ResourceÅäÖÃÒÀÀµ
+
+`@Resource`λÓÚ`javax.annotation`°üÏ£¬ÊÇÀ´×ÔJavaEE¹æ·¶µÄÒ»¸ö`Annotation`£¬SpringÖ±½Ó½è¼øÁ˸Ã`Annotation`£¬Í¨¹ýʹÓøÃ`Annotation`ΪĿ±êBeanÖ¸¶¨Ð×÷ÕßBean¡£Ê¹ÓÃ`@Resource`Óë` `ÔªËØµÄrefÊôÐÔÓÐÏàͬµÄЧ¹û¡£
+`@Resource`²»½ö¿ÉÒÔÐÞÊÎsetter·½·¨£¬Ò²¿ÉÒÔÖ±½ÓÐÞÊÎʵÀý±äÁ¿£¬Èç¹ûʹÓÃ`@Resource`ÐÞÊÎʵÀý±äÁ¿½«»á¸ü¼Ó¼òµ¥£¬´ËʱSpring½«»áÖ±½ÓʹÓÃJavaEE¹æ·¶µÄField×¢È룬´ËʱÁ¬setter·½·¨¶¼¿ÉÒÔ²»Òª¡£
+
+### ʹÓÃ@PostConstructºÍ@PreDestroy¶¨ÖÆÉúÃüÖÜÆÚÐÐΪ
+
+`@PostConstruct`ºÍ`@PreDestroy`ͬÑùλÓÚjavax.annotation°üÏ£¬Ò²ÊÇÀ´×ÔJavaEE¹æ·¶µÄÁ½¸öAnnotation£¬SpringÖ±½Ó½è¼øÁËËüÃÇ£¬ÓÃÓÚ¶¨ÖÆSpringÈÝÆ÷ÖÐBeanµÄÉúÃüÖÜÆÚÐÐΪ¡£ËüÃǶ¼ÓÃÓÚÐÞÊη½·¨£¬ÎÞÐëÈκÎÊôÐÔ¡£ÆäÖÐǰÕßÐÞÊεķ½·¨Ê±BeanµÄ³õʼ»¯·½·¨£»¶øºóÕßÐÞÊεķ½·¨Ê±BeanÏú»Ù֮ǰµÄ·½·¨¡£
+
+### Spring4.0ÔöÇ¿µÄ×Ô¶¯×°ÅäºÍ¾«È·×°Åä
+
+SpringÌṩÁË`@Autowired`×¢½âÀ´Ö¸¶¨×Ô¶¯×°Å䣬`@Autowired`¿ÉÒÔÐÞÊÎsetter·½·¨¡¢ÆÕͨ·½·¨¡¢ÊµÀý±äÁ¿ºÍ¹¹ÔìÆ÷µÈ¡£µ±Ê¹ÓÃ`@Autowired`±ê×¢setter·½·¨Ê±£¬Ä¬ÈϲÉÓÃbyType×Ô¶¯×°Åä²ßÂÔ¡£ÔÚÕâÖÖ²ßÂÔÏ£¬·ûºÏ×Ô¶¯×°ÅäÀàÐ͵ĺòÑ¡BeanʵÀý³£³£Óжà¸ö£¬Õâ¸öʱºò¾Í¿ÉÄÜÒýÆðÒì³££¬ÎªÁËʵÏÖ¾«È·µÄ×Ô¶¯×°Å䣬SpringÌṩÁË`@Qualifier`×¢½â£¬Í¨¹ýʹÓÃ`@Qualifier`£¬ÔÊÐí¸ù¾ÝBeanµÄidÀ´Ö´ÐÐ×Ô¶¯×°Åä¡£
+
+# ²Î¿¼ÎÄÕÂ
+https://www.w3cschool.cn/wkspring
+https://www.runoob.com/w3cnote/basic-knowledge-summary-of-spring.html
+http://codepub.cn/2015/06/21/Basic-knowledge-summary-of-Spring
+https://dunwu.github.io/spring-tutorial
+https://mszlu.com/java/spring
+http://c.biancheng.net/spring/aop-module.html
\ No newline at end of file
diff --git "a/docs/spring/SpringBoot/SpringBoot\345\270\270\350\247\201\346\263\250\350\247\243.md" "b/docs/spring/SpringBoot/SpringBoot\345\270\270\350\247\201\346\263\250\350\247\243.md"
new file mode 100644
index 0000000..c699974
--- /dev/null
+++ "b/docs/spring/SpringBoot/SpringBoot\345\270\270\350\247\201\346\263\250\350\247\243.md"
@@ -0,0 +1,158 @@
+## 1 ¸ÅÊö
+Spring Boot ͨ¹ýÆä×Ô¶¯ÅäÖù¦ÄÜʹÅäÖà Spring ±äµÃ¸ü¼ÓÈÝÒס£
+
+ÔÚ±¾¿ìËٽ̳ÌÖУ¬ÎÒÃǽ«Ì½Ë÷ org.springframework.boot.autoconfigure ºÍ org.springframework.boot.autoconfigure.condition °üÖеÄ×¢½â¡£
+
+## 2 @SpringBootApplication
+ÎÒÃÇʹÓÃÕâ¸ö×¢½âÀ´±ê¼Ç Spring Boot Ó¦ÓóÌÐòµÄÖ÷Àࣺ
+
+@SpringBootApplication
+ÎÒÃÇʹÓÃÕâ¸ö×¢½âÀ´±ê¼Ç Spring Boot Ó¦ÓóÌÐòµÄÖ÷Àࣺ
+````
+@SpringBootApplication
+class VehicleFactoryApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(VehicleFactoryApplication.class, args);
+ }
+}
+````
+@SpringBootApplication ·â×°ÁË@Configuration¡¢@EnableAutoConfiguration ºÍ@ComponentScan ×¢½â¼°ÆäĬÈÏÊôÐÔ¡£
+
+## 3 @EnableAutoConfiguration
+
+@EnableAutoConfiguration£¬¹ËÃû˼Ò壬ÆôÓÃ×Ô¶¯ÅäÖᣠÕâÒâζ×Å Spring Boot ÔÚÆäÀà·¾¶ÖвéÕÒ×Ô¶¯ÅäÖà bean ²¢×Ô¶¯Ó¦ÓÃËüÃÇ¡£
+
+Çë×¢Ò⣬ÎÒÃDZØÐ뽫´Ë×¢ÊÍÓë@Configuration Ò»ÆðʹÓãº
+
+````
+@Configuration
+@EnableAutoConfiguration
+class VehicleFactoryConfig {}
+````
+
+## 4 @ConfigurationÒÔ¼°Ïà¹ØÀà
+
+@ConfigurationµÄ×÷Ó㺱ê×¢ÔÚÀàÉÏ£¬ÅäÖÃspringÈÝÆ÷(Ó¦ÓÃÉÏÏÂÎÄ)¡£
+
+ÒÔÍùÎÒÃÇÔÚspringÖÐÅäÖÃbean»áʹÓõ½xmlÅäÖÃÎļþ£¬¶¨ÒåÒ»¸ö¸öbean£¬ÔÚspringbootÖУ¬ÎªÁË×öµ½ÁãÅäÖã¬spring¿ò¼ÜÌṩÁË@ConfigurationÕâÒ»×¢½â
+
+Ï൱ÓڰѸÃÀà×÷ΪspringµÄxmlÅäÖÃÎļþÖеÄ
+
+@Configuration×¢½âµÄÀàÖУ¬Ê¹ÓÃ@Bean×¢½â±ê×¢µÄ·½·¨£¬·µ»ØµÄÀàÐͶ¼»áÖ±½Ó×¢²áΪbean¡£
+
+@Configure×¢½âµÄ¶¨ÒåÈçÏ£º
+````
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Component
+public @interface Configuration {
+String value() default "";
+}
+````
+´Ó¶¨ÒåÀ´¿´£¬µ×²ãÊǺ¬ÓÐ@Component £¬ËùÒÔ@Configuration ¾ßÓÐºÍ @Component µÄ×÷Óá£Òò´Ëcontext:component-scan/»òÕß@ComponentScan¶¼ÄÜ´¦Àí@Configuration×¢½âµÄÀà¡£
+
+ͨ³££¬µ±ÎÒÃDZàд×Ô¶¨Òå×Ô¶¯ÅäÖÃʱ£¬ÎÒÃÇÏ£Íû Spring ÓÐÌõ¼þµØÊ¹ÓÃËüÃÇ¡£ ÎÒÃÇ¿ÉÒÔͨ¹ý±¾½ÚÖеÄ×¢ÊÍÀ´ÊµÏÖÕâÒ»µã¡£
+
+ÎÒÃÇ¿ÉÒÔ½«´Ë²¿·ÖÖеÄ×¢ÊÍ·ÅÔÚ@Configuration Àà»ò@Bean ·½·¨ÉÏ¡£
+
+ÔÚ½ÓÏÂÀ´µÄ²¿·ÖÖУ¬ÎÒÃǽ«Ö»½éÉÜÿ¸öÌõ¼þ±³ºóµÄ»ù±¾¸ÅÄî¡£ ÓûÁ˽â¸ü¶àÐÅÏ¢£¬Çë·ÃÎÊÕâÆªÎÄÕ¡£
+
+### 4.1 @ConditionalOnClass and @ConditionalOnMissingClass
+ºÜÃ÷ÏÔÕâÊÇÒ»¸ö´øÓÐÌõ¼þÅжϵÄÅäÖÃ×¢½â£¬ÒªÖªµÀ£¬ºÜ¶àʱºòÎÒÃǰ´Ðè¼ÓÔØbeanµÄ£¬ÉõÖÁÊǸù¾ÝÍⲿjar°üÊÇ·ñ´æÔÚÀ´½øÐмÓÔØºÍÅжϵġ£
+
+ÕâÖÖʱºò£¬¾ÍÒª¸ù¾ÝÍⲿÀàÊÇ·ñ´æÔÚÀ´¾ö¶¨ÊÇ·ñÊÇ·ñ¼ÓÔØ¸Ãbean
+
+ʹÓÃÕâЩÌõ¼þ£¬Èç¹û×¢ÊͲÎÊýÖеÄÀà´æÔÚ/²»´æÔÚ£¬Spring ½«½öʹÓñê¼ÇµÄ×Ô¶¯ÅäÖà bean£º
+
+````
+@Configuration
+@ConditionalOnClass(DataSource.class)
+class MySQLAutoconfiguration {
+//...
+}
+````
+
+### 4.2 @ConditionalOnBean and @ConditionalOnMissingBean
+
+µ±ÎÒÃÇÏëÒª¸ù¾ÝÌØ¶¨ bean µÄ´æÔÚ»ò²»´æÔÚÀ´¶¨ÒåÌõ¼þʱ£¬ÎÒÃÇ¿ÉÒÔʹÓÃÕâЩעÊÍ£º
+
+ºÍÉÏÃæÒ»¸ö×¢½âÉÔÓÐЩ²»Í¬£¬ÒòΪÎÒÃǵÄÅжÏÌõ¼þ±ä³ÉÁËbean
+
+````
+@Bean
+@ConditionalOnBean(name = "dataSource")
+LocalContainerEntityManagerFactoryBean entityManagerFactory() {
+// ...
+}
+````
+### 4.3 @ConditionalOnProperty
+ͨ¹ýÕâ¸ö×¢½â£¬ÎÒÃÇ¿ÉÒÔ¶ÔÊôÐÔµÄÖµÉèÖÃÌõ¼þ
+
+ҪעÒ⣬ÕâÀïµÄÊôÐÔÖµÀ´Ô´ÓÚapplication.propertiesÎļþÖеÄÅäÖÃ
+
+````
+@Bean
+@ConditionalOnProperty(
+name = "usemysql",
+havingValue = "local"
+)
+DataSource dataSource() {
+// ...
+}
+````
+
+### 4.4 @ConditionalOnResource
+
+ÎÒÃÇ¿ÉÒÔÈà Spring ½öÔÚ´æÔÚÌØ¶¨×ÊԴʱʹÓö¨Ò壺
+¹ËÃû˼Ò壬ҪÇóclasspath´æÔÚÕâ¸ö×ÊÔ´Îļþʱ²Å½øÐмÓÔØ£¬ÕâÒ²ÊǺܳ£ÓõÄÒ»¸ö×¢½â¡£
+
+````
+
+@ConditionalOnResource(resources = "classpath:mysql.properties")
+Properties ditionalProperties() {
+// ...
+}
+````
+
+### 4.5 @ConditionalOnWebApplication and @ConditionalOnNotWebApplication
+Õâ¸ö×¢½âͨ³£ÓÃÓÚºÍwebÓÐÇ¿¹ØÁª£¬»òÕßÍêÈ«ÎÞ¹ØÁªµÄÅäÖÃÉÏ
+
+ʹÓÃÕâЩעÊÍ£¬ÎÒÃÇ¿ÉÒÔ¸ù¾Ýµ±Ç°Ó¦ÓóÌÐòÊÇ·ñÊÇ Web Ó¦ÓóÌÐòÀ´´´½¨Ìõ¼þ£º
+````
+
+@ConditionalOnWebApplication
+HealthCheckController healthCheckController() {
+// ...
+}
+````
+
+### 4.6 @ConditionalExpression
+springbootÕæµÄΪÎÒÃÇÏëµ½ÁËËùÓÐÇé¿ö£¬Èç¹ûÉÏÃæµÄ×¢½â»¹²»ÄÜÂú×ãÄãµÄÒªÇó£¬ÄÇô¸É´à¾ÍÈÃÄã×Ô¼ºÐ´£¬ÕâÏÂÓ¦¸ÃûÓÐÎÊÌâ°É£¿
+
+ÎÒÃÇ¿ÉÒÔÔÚ¸ü¸´ÔÓµÄÇé¿öÏÂʹÓÃÕâ¸ö×¢½â¡£ µ± SpEL ±í´ïʽ±»ÆÀ¹ÀÎªÕæÊ±£¬Spring ½«Ê¹Óñê¼ÇµÄ¶¨Ò壺
+
+````
+@Bean
+@ConditionalOnExpression("${usemysql} && ${mysqlserver == 'local'}")
+DataSource dataSource() {
+// ...
+}
+````
+
+### 4.7 @Conditional
+ʲô£¬»¹ÓÐÎÊÌ⣿
+ÄÇspringbootÒ²²»ÔÙÌṩʲô±í´ïʽ¸øÄãÁË£¬Ö±½ÓÈÃÓû§Ð´Ò»¸öÅжÏÌõ¼þ£¬¸æËßÎÒtrue»òÕßfalse¾ÍÐÐÁË
+
+¶ÔÓÚ¸ü¸´ÔÓµÄÌõ¼þ£¬ÎÒÃÇ¿ÉÒÔ´´½¨Ò»¸öÆÀ¹À×Ô¶¨ÒåÌõ¼þµÄÀà¡£ ÎÒÃǸæËß Spring ½«Õâ¸ö×Ô¶¨ÒåÌõ¼þÓë @Conditional Ò»ÆðʹÓãº
+
+````
+@Conditional(HibernateCondition.class)
+Properties ditionalProperties() {
+//...
+}
+````
+
+## 5 ×ܽá
+ÔÚ±¾ÎÄÖУ¬ÎÒÃǸÅÊöÁËÈçºÎ΢µ÷×Ô¶¯ÅäÖùý³Ì²¢Îª×Ô¶¨Òå×Ô¶¯ÅäÖà bean ÌṩÌõ¼þ¡£
\ No newline at end of file
diff --git "a/docs/spring/SpringBoot/SpringBoot\347\232\204\345\237\272\346\234\254\344\275\277\347\224\250.md" "b/docs/spring/SpringBoot/SpringBoot\347\232\204\345\237\272\346\234\254\344\275\277\347\224\250.md"
new file mode 100644
index 0000000..36a2500
--- /dev/null
+++ "b/docs/spring/SpringBoot/SpringBoot\347\232\204\345\237\272\346\234\254\344\275\277\347\224\250.md"
@@ -0,0 +1,152 @@
+# ¿ìËÙ¹¹½¨SpringBootÓ¦ÓÃ
+
+Õâ¸ö½Ì³ÌÀ´×ÔÓÚspringboot¹ÙÍø£¬×㹻ȨÍþ£¬Ò²×ã¹»¼òµ¥¡£
+
+## µÚÒ»¸ö hello world ³ÌÐò
+
+Äú½«¹¹½¨Ò»¸ö¾µäµÄ¡°Hello World£¡¡±ÈκÎä¯ÀÀÆ÷¶¼¿ÉÒÔÁ¬½Óµ½µÄ¶Ëµã¡£ÄãÉõÖÁ¿ÉÒÔ¸æËßËüÄãµÄÃû×Ö£¬Ëü»áÒÔ¸üÓѺõķ½Ê½»ØÓ¦¡£
+
+## »ù±¾»·¾³ÒªÇó
+
+1¡¢Ê×ÏÈÄã×îºÃÓÐÒ»¸ö³ÃÊÖµÄIDE,ÈÈÃÅÑ¡Ôñ°üÀ¨ IntelliJ IDEA¡¢Spring Tools¡¢Visual Studio Code »ò Eclipse µÈµÈ¡£
+
+2¡¢JDK£¬ÖÁÓÚ°æ±¾µÄ»°£¬8-17¶¼ÊDz»´íµÄÑ¡Ôñ
+
+3¡¢µ±È»ÕâÀﻹÐèÒªµ¼ÈëmavenµÄpomÒÀÀµ£¬ËùÒÔÎÒÃÇÒ²ÐèÒªmaven£¬maven²å¼þÔÚidea×Ô´øÁË¡£ÎÒÃÇ»áÔÚ½ÓÏÂÀ´µÄ²¿·Ö½øÐнéÉÜ£¬ÐèÒªÒýÈëÄÄЩÒÀÀµ
+
+## µÚÒ»²½£ºÆô¶¯Ò»¸öеÄSpring BootÏîÄ¿
+
+ʹÓÃ[start.spring.io](http://start.spring.io/)´´½¨Ò»¸ö¡°web¡±ÏîÄ¿¡£ÔÚ¡°dependencies¡±¶Ô»°¿òÖÐËÑË÷²¢Ìí¼Ó¡°web¡±ÒÀÀµÏÈçÆÁÄ»½ØÍ¼Ëùʾ¡£
+
+µã»÷¡°Éú³É¡±°´Å¥£¬ÏÂÔØ zip Îļþ£¬²¢½«Æä½âѹµ½Äú¼ÆËã»úÉϵÄÒ»¸öÎļþ¼ÐÖС£
+
+
+
+[start.spring.io](http://start.spring.io/)´´½¨µÄÏîÄ¿°üº¬[Spring Boot](https://spring.io/projects/spring-boot)£¬Ò»¸öÈÃSpring×¼±¸ºÃÔÚÄúµÄÓ¦ÓóÌÐòÄÚ²¿¹¤×÷£¬µ«²»ÐèҪ̫¶à´úÂë»òÅäÖᣠSpring Boot ÊÇÆô¶¯ Spring ÏîÄ¿µÄ×î¿ìºÍ×îÁ÷Ðеķ½Ê½¡£
+
+ÕâÀïÎÒÃÇÑ¡ÔñʹÓÃmaven×÷Ϊ°ü¹ÜÀí¹¤¾ß£¬ÏÂÔØÏÂÀ´µÄÏîÄ¿Àï»á°üº¬pomÎļþ£¬pomÎļþÀï°üº¬ÁËÄãµÄÌí¼ÓµÄÒÀÀµ¡£
+
+````
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.0.5
+
+
+ com.example
+ demo
+ 0.0.1-SNAPSHOT
+ demo
+ Demo project for Spring Boot
+
+ 17
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+````
+
+
+## µÚ¶þ²½£ºÌí¼ÓÄãµÄ´úÂë
+
+ÔÚÄúµÄ IDE Öдò¿ªÏîÄ¿²¢ÔÚ `src/main/java/com/example/demo` Îļþ¼ÐÖÐÕÒµ½ `DemoApplication.java` Îļþ¡£
+
+ÏÖÔÚͨ¹ýÌí¼ÓÏÂÃæ´úÂëÖÐÏÔʾµÄ¶îÍâ·½·¨ºÍ×¢ÊÍÀ´¸ü¸ÄÎļþµÄÄÚÈÝ¡£Äú¿ÉÒÔ¸´ÖƲ¢Õ³Ìù´úÂë»òÖ±½Ó¼üÈë´úÂë¡£
+```
+package com.example.demo;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+@SpringBootApplication
+@RestController
+public class DemoApplication {
+ public static void main(String[] args) {
+ SpringApplication.run(DemoApplication.class, args);
+ }
+ @GetMapping("/hello")
+ public String hello(@RequestParam(value = "name", defaultValue = "World") String name) {
+ return String.format("Hello %s!", name);
+ }
+}
+
+```
+
+ÕâÊÇÔÚ Spring Boot Öд´½¨Ò»¸ö¼òµ¥µÄ¡°Hello World¡± Web ·þÎñËùÐèµÄËùÓдúÂë¡£
+
+ÎÒÃÇÌí¼ÓµÄ`hello()`·½·¨Ö¼ÔÚ»ñȡһ¸öÃûΪnameµÄString²ÎÊý£¬È»ºó½«´Ë²ÎÊýÓë´úÂëÖеĵ¥´Ê`"Hello"`½áºÏÆðÀ´¡£
+
+ÕâÒâζ×ÅÈç¹ûÄúÔÚÇëÇóÖн«ÄúµÄÃû×ÖÉèÖÃΪ¡°Amy¡±£¬ÔòÏìÓ¦½«ÊÇ¡°Hello Amy¡±¡£
+
+`@RestController` ×¢Ê͸æËß Spring£¬´Ë´úÂëÃèÊöÁËÒ»¸ö¶Ëµã£¬¸Ã¶ËµãÓ¦ÔÚ Web ÉÏ¿ÉÓá£
+
+@GetMapping(¡°/hello¡±) ¸æËß Spring ʹÓÃÎÒÃÇµÄ hello() ·½·¨À´ÏìÓ¦·¢Ë͵½ http://localhost:8080/hello µØÖ·µÄÇëÇó¡£
+
+×îºó£¬@RequestParam ¸æËß Spring ÔÚÇëÇóÖÐÆÚÍûÒ»¸öÃû³ÆÖµ£¬µ«Èç¹û²»´æÔÚ£¬Ëü½«Ä¬ÈÏʹÓõ¥´Ê¡°World¡±¡£
+
+## µÚÈý²½£ºÆô¶¯
+
+ÈÃÎÒÃǹ¹½¨²¢ÔËÐгÌÐò¡£´ò¿ªÃüÁîÐУ¨»òÖÕ¶Ë£©²¢µ¼º½µ½ÄúÓµÓÐÏîÄ¿ÎļþµÄÎļþ¼Ð¡£
+
+ÎÒÃÇ¿ÉÒÔͨ¹ý·¢³öÒÔÏÂÃüÁîÀ´¹¹½¨ºÍÔËÐÐÓ¦ÓóÌÐò£º
+
+**MacOS/Linux:**
+
+```
+COPY./gradlew bootRun
+
+```
+
+**Windows:**
+
+```
+COPY.\gradlew.bat bootRun
+
+```
+
+ÄúÓ¦¸Ã»á¿´µ½Ò»Ð©Óë´Ë·Ç³£ÏàËÆµÄÊä³ö£º
+
+
+ÕâÀïµÄ×îºó¼¸ÐиæËßÎÒÃÇ£¬SpringÓ¦ÓÃÒѾ¿ªÊ¼ÔËÐÐÁË¡£
+Spring Boot µÄǶÈëʽ Apache Tomcat ·þÎñÆ÷³äµ±ÍøÂç·þÎñÆ÷£¬²¢ÕýÔÚ¼àÌý¡°localhost¡±¶Ë¿Ú¡°8080¡±ÉϵÄÇëÇó¡£
+
+´ò¿ªä¯ÀÀÆ÷£¬ÔÚ¶¥²¿µÄµØÖ·À¸ÖÐÊäÈë`http://localhost:8080/hello`¡£
+
+ÄãÓ¦¸ÃµÃµ½ÕâÑùÒ»¸öÓѺõĻØÓ¦£º
+
+
+# ×ܽá
+¾ÍÊÇÈç´Ë¼òµ¥£¬µÚÒ»¸öSpringBootÓ¦ÓþÍÕâô¹¹½¨Íê³ÉÁË£¬Äã²»ÐèÒª¶îÍâµÄÅäÖÃÎļþ£¬¶îÍâµÄÒÀÀµ£¬ÉõÖÁÊǶîÍâµÄ·þÎñÆ÷¡£
+Ö»ÐèÒªÒ»¸öÆô¶¯À࣬¾Í¿ÉÒÔʵÏÖÒ»¸ö×î»ù±¾µÄSpringBootµÄÓ¦Óá£
+
+ÕâÒ²ÊÇΪʲôspringboot¿ÉÒÔÓÃÀ´¿ìËÙ¹¹½¨Ò»¸ö΢·þÎñ£¬ÒòΪËüʵÔÚÊÇÌ«·½±ãÁË¡£
+µ±È»£¬Êµ¼Ê¿ª·¢ÖÐÎÒÃÇÐèÒªÓõ½¸ü¶àspringbootµÄ¹¦ÄܺÍÌØÐÔ£¬ÎÒÃǽ«»áÔÚ½ÓÏÂÀ´µÄÕ½ÚÖÐÖð½¥Õ¹¿ª½éÉÜ¡£
+
+# ²Î¿¼ÎÄÕÂ
+https://spring.io/quickstart
\ No newline at end of file
diff --git "a/docs/spring/SpringBoot/Spring\345\270\270\350\247\201\346\263\250\350\247\243\344\275\277\347\224\250\346\214\207\345\215\227(\345\214\205\345\220\253Spring+SpringMVC+SpringBoot).md" "b/docs/spring/SpringBoot/Spring\345\270\270\350\247\201\346\263\250\350\247\243\344\275\277\347\224\250\346\214\207\345\215\227(\345\214\205\345\220\253Spring+SpringMVC+SpringBoot).md"
new file mode 100644
index 0000000..813fabe
--- /dev/null
+++ "b/docs/spring/SpringBoot/Spring\345\270\270\350\247\201\346\263\250\350\247\243\344\275\277\347\224\250\346\214\207\345\215\227(\345\214\205\345\220\253Spring+SpringMVC+SpringBoot).md"
@@ -0,0 +1,1112 @@
+# Spring×¢½â
+## 1 ¸ÅÊö
+
+ÎÒÃǶ¼ÖªµÀSpring×îºËÐĵÄÌØÐÔ¾ÍÊÇIOC+AOP£¬IOCµÄÔÀí¾ÍÊÇʵÏÖÁËÒ»¸öSpringÈÝÆ÷£¬ÓÃÀ´¹ÜÀíËùÓÐSpring BeanʵÀý
+DI£¬Ò²¾ÍÊÇÒÀÀµ×¢È룬ÊÇÎÒÃÇ×÷Ϊ¿ª·¢ÕßÐèÒª¹ØÐĵĺËÐÄ»°Ì⣬ÈçºÎ×¢ÈëÒÀÀµ£¬×¢ÈëÄĸöÒÀÀµ£¬ÊÇÎÒÃÇÐèÒªÃ÷È·ÖªµÀµÄ¡£
+ÔÚÒÔǰ£¬ÎÒÃÇϰ¹ßÓÚÓÃxmlÅäÖÃÎļþÀ´ÉùÃ÷Ò»¸öbean£¬µ«ÏÖÔÚ£¬ÎÒÃǸü¶àµØÊ¹ÓÃ×¢½âºÍ´úÂëÀ´Íê³ÉDIµÄ¹ý³Ì
+
+
+ÎÒÃÇ¿ÉÒÔʹÓà org.springframework.beans.factory.annotation ºÍ org.springframework.context.annotation °üÖеÄ×¢ÊÍÀ´ÆôÓà Spring DI ÒýÇæµÄ¹¦ÄÜ¡£
+
+ÎÒÃÇͨ³£½«ÕâЩ³ÆÎª¡°Spring ºËÐÄ×¢ÊÍ¡±£¬ÎÒÃǽ«ÔÚ±¾½Ì³ÌÖÐ¶ÔÆä½øÐлعˡ£
+
+
+## 2 DIÏà¹Ø×¢½â
+
+### 2.1 @Autowired
+
+ÎÒÃÇ¿ÉÒÔʹÓà @Autowired À´±ê¼Ç Spring ½«Òª½âÎöºÍ×¢ÈëµÄÒÀÀµÏî¡£
+ÎÒÃÇ¿ÉÒÔ½«´Ë×¢ÊÍÓë¹¹Ô캯Êý¡¢setter »ò×Ö¶Î×¢ÈëÒ»ÆðʹÓá£
+Constructor injection:
+
+**¹¹ÔìÆ÷×¢Èë**
+
+````
+class Car {
+ Engine engine;
+
+ @Autowired
+ Car(Engine engine) {
+ this.engine = engine;
+ }
+}
+````
+
+**Setter×¢Èë**
+````
+class Car {
+ Engine engine;
+
+ @Autowired
+ void setEngine(Engine engine) {
+ this.engine = engine;
+ }
+}
+````
+**±äÁ¿×¢Èë**
+````
+class Car {
+ @Autowired
+ Engine engine;
+}
+````
+
+@Autowired ÓÐÒ»¸öÃûΪ required µÄ²¼¶û²ÎÊý£¬Ä¬ÈÏֵΪ true¡£
+
+µ±ËüÕÒ²»µ½ºÏÊ浀 bean À´Á¬½Óʱ£¬Ëü»áµ÷Õû Spring µÄÐÐΪ¡£ µ±Îª true ʱ£¬½«Å׳öÒì³££¬·ñÔò²»Á¬½ÓÈκÎÄÚÈÝ¡£
+
+Çë×¢Ò⣬Èç¹ûÎÒÃÇʹÓù¹Ô캯Êý×¢È룬ÔòËùÓй¹Ô캯Êý²ÎÊý¶¼ÊÇÇ¿ÖÆÐԵġ£
+
+´Ó 4.3 °æ±¾¿ªÊ¼£¬ÎÒÃDz»ÐèÒªÏÔʽµØÊ¹Óà @Autowired ×¢½â¹¹Ô캯Êý£¬³ý·ÇÎÒÃÇÉùÃ÷ÖÁÉÙÁ½¸ö¹¹Ô캯Êý¡£
+
+### 2.2 @Bean
+
+@Bean ±ê¼ÇʵÀý»¯ Spring bean µÄ¹¤³§·½·¨£º
+
+```
+@Bean
+Engine engine() {
+ return new Engine();
+}
+````
+
+µ±ÐèÒª·µ»ØÀàÐ͵ÄÐÂʵÀýʱ£¬Spring »áµ÷ÓÃÕâЩ·½·¨¡£
+
+Éú³ÉµÄ bean Ó빤³§·½·¨Í¬Ãû¡£ Èç¹ûÎÒÃÇÏëÒÔ²»Í¬µÄ·½Ê½ÃüÃû£¬ÎÒÃÇ¿ÉÒÔʹÓôË×¢Ê͵ÄÃû³Æ»òÖµ²ÎÊý£¨²ÎÊýÖµÊDzÎÊýÃû³ÆµÄ±ðÃû£©£º
+
+````
+@Bean("engine")
+Engine getEngine() {
+ return new Engine();
+}
+````
+ÕâÊÇÒ»Öַdz£³£¼ûµÄbeanÉùÃ÷·½Ê½£¬ÒòΪºÜ¶àµÄbean²¢²»ÊÇÎÒÃÇÒ»¿ªÊ¼¾ÍÔÚ´úÂëÀﶨÒåºÃµÄ£¬Ëü¿ÉÄÜÐèÒª»ùÓÚÔËÐÐʱ»·¾³À´½øÐа´Ðè¹¹½¨¡£
+
+ÎÒÃÇ¿ÉÒÔ×ÔÓɵØÉùÃ÷ºÍ¶¨ÒåBean£¬²¢ÇÒÒ²¿ÉÒÔ¸³ÓèËü×Ô¶¨ÒåµÄbeanÃû³Æ¡£
+
+×¢Ò⣬ËùÓÐÓÃ@Bean ×¢Ê͵ķ½·¨¶¼±ØÐëÔÚ@Configuration ÀàÖС£
+
+### 2.3 @Qualifier
+
+ÎÒÃÇʹÓÃ@Qualifier ºÍ@Autowired À´ÌṩÎÒÃÇÏëÒªÔÚ²»Ã÷È·Çé¿öÏÂʹÓõÄbean id »òbean Ãû³Æ¡£
+
+ÀýÈ磬ÒÔÏÂÁ½¸ö bean ʵÏÖÏàͬµÄ½Ó¿Ú£º
+````
+class Bike implements Vehicle {}
+
+class Car implements Vehicle {}
+
+````
+
+Èç¹û Spring ÐèҪעÈëÒ»¸ö Vehicle bean£¬Ëü»áÒÔ¶à¸öÆ¥Å䶨Òå½áÊø¡£ ÔÚÕâÖÖÇé¿öÏ£¬ÎÒÃÇ¿ÉÒÔʹÓà @Qualifier ×¢ÊÍÏÔʽÌṩ bean µÄÃû³Æ¡£
+
+**¹¹ÔìÆ÷×¢Èë**
+````
+@Autowired
+Biker(@Qualifier("bike") Vehicle vehicle) {
+this.vehicle = vehicle;
+}
+````
+
+**Setter×¢Èë**
+
+````
+@Autowired
+void setVehicle(@Qualifier("bike") Vehicle vehicle) {
+this.vehicle = vehicle;
+}
+````
+»òÕß:
+
+````
+@Autowired
+@Qualifier("bike")
+void setVehicle(Vehicle vehicle) {
+this.vehicle = vehicle;
+````
+**±äÁ¿×¢Èë**
+
+````
+@Autowired
+@Qualifier("bike")
+Vehicle vehicle;
+````
+Õâ¸ö×¢½âÎÒÃÇ¿ÉÄÜÆ½³£ÓõIJ»¶à£¬µ«Êǵ±Ò»¸ö½Ó¿ÚÓжà¸öʵÏÖÀàʱ£¬Ëü¾Í»á¾³£ÅÉÉÏÓ󡣡
+
+### 2.4 @Required
+
+@Required ÔÚ setter ·½·¨Éϱê¼ÇÎÒÃÇÏëҪͨ¹ý XML Ìî³äµÄÒÀÀµÏ
+````
+@Required
+void setColor(String color) {
+this.color = color;
+}
+````
+xml
+````
+
+
+
+````
+·ñÔò£¬½«Å׳ö BeanInitializationException¡£
+·Ç³£ÉÙ¼ûµÄÓ÷¨£¬ÖªµÀһϾÍÐÐÁË
+
+### 2.5 @Value
+ÎÒÃÇ¿ÉÒÔʹÓà @Value ½«ÊôÐÔÖµ×¢Èë bean¡£ ËüÓë¹¹Ô캯Êý¡¢setter ºÍ×Ö¶Î×¢Èë¼æÈÝ¡£
+
+ÕâÒ²ÊǷdz£³£ÓõÄÒ»¸ö×¢½â£¬ÒòΪÎÒÃǺܶàʱºò¶¼ÐèÒª´Óapplication.properties»òÕ߯äËûÅäÖÃÎļþÖÐÀ´¶ÁÈ¡ÅäÖÃÊôÐÔÖµ¡£
+
+**¹¹ÔìÆ÷×¢Èë**
+````
+Engine(@Value("8") int cylinderCount) {
+this.cylinderCount = cylinderCount;
+}
+````
+
+**setter×¢Èë**
+
+````
+@Autowired
+void setCylinderCount(@Value("8") int cylinderCount) {
+this.cylinderCount = cylinderCount;
+}
+````
+
+»òÕß:
+````
+
+@Value("8")
+void setCylinderCount(int cylinderCount) {
+this.cylinderCount = cylinderCount;
+}
+````
+
+**±äÁ¿×¢Èë**
+````
+@Value("8")
+int cylinderCount;
+````
+
+µ±È»£¬×¢È뾲ֵ̬ÊÇûÓÐÓõġ£ Òò´Ë£¬ÎÒÃÇ¿ÉÒÔÔÚ @Value ÖÐʹÓÃռλ·û×Ö·û´®À´Á¬½ÓÔÚÍⲿԴÖж¨ÒåµÄÖµ£¬ÀýÈçÔÚ .properties »ò .yaml ÎļþÖС£
+````
+
+engine.fuelType=petrol
+````
+
+ÎÒÃÇ¿ÉÒÔͨ¹ýÒÔÏ·½Ê½×¢Èë engine.fuelType µÄÖµ£º
+
+````
+@Value("${engine.fuelType}")
+String fuelType;
+````
+
+ÎÒÃÇÉõÖÁ¿ÉÒÔʹÓà SpEL À´Ê¹ÓÃ@Value¡£ ¸ü¶à¸ß¼¶Ê¾Àý¿ÉÒÔÔÚÎÒÃǹØÓÚ@Value µÄÎÄÕÂÖÐÕÒµ½¡£
+
+### 2.6 @DependsOn
+ÎÒÃÇ¿ÉÒÔʹÓôË×¢½âÈà Spring ÔÚ×¢½âµÄ bean ֮ǰ³õʼ»¯ÆäËû bean¡£ ͨ³££¬´ËÐÐΪÊÇ×Ô¶¯µÄ£¬»ùÓÚ bean Ö®¼äµÄÏÔʽÒÀÀµ¹ØÏµ¡£
+
+ÎÒÃÇÖ»ÓÐÔÚÒÀÀµÊÇÒþʽµÄʱºò²ÅÐèÒªÕâ¸ö×¢½â£¬±ÈÈçJDBCÇý¶¯¼ÓÔØ»òÕß¾²Ì¬±äÁ¿³õʼ»¯¡£
+
+ÎÒÃÇ¿ÉÒÔÔÚÖ¸¶¨ÒÀÀµ bean Ãû³ÆµÄÒÀÀµÀàÉÏʹÓà @DependsOn¡£ ×¢Ê͵ÄÖµ²ÎÊýÐèÒªÒ»¸ö°üº¬ÒÀÀµ bean Ãû³ÆµÄÊý×飺
+
+````
+@DependsOn("engine")
+class Car implements Vehicle {}
+````
+Alternatively, if we define a bean with the @Bean annotation, the factory method should be annotated with @DependsOn:
+````
+@Bean
+@DependsOn("fuel")
+Engine engine() {
+return new Engine();
+}
+````
+### 2.7 @Lazy
+µ±ÎÒÃÇÏëÀÁ¶èµØ³õʼ»¯ÎÒÃÇµÄ bean ʱ£¬ÎÒÃÇʹÓà @Lazy¡£ ĬÈÏÇé¿öÏ£¬Spring ÔÚÓ¦ÓóÌÐòÉÏÏÂÎĵįô¶¯/Òýµ¼Ê±¼±Çеش´½¨ËùÓе¥Àý bean¡£
+
+µ«ÊÇ£¬ÓÐЩÇé¿öÏÂÎÒÃÇÐèÒªÔÚÇëÇóʱ´´½¨ bean£¬¶ø²»ÊÇÔÚÓ¦ÓóÌÐòÆô¶¯Ê±´´½¨¡£
+
+Õâ¸ö×¢½âµÄÐÐΪ»á¸ù¾ÝÎÒÃÇ·ÅÖÃËüµÄÈ·ÇÐλÖöøÓÐËù²»Í¬¡£ ÎÒÃÇ¿ÉÒÔ°ÑËü·ÅÔÚ£º
+
+Ò»¸ö @Bean ×¢Ê굀 bean ¹¤³§·½·¨£¬ÒÔÑÓ³Ù·½·¨µ÷Óã¨Òò´Ë´´½¨ bean£©
+@Configuration ÀàºÍËùÓаüº¬µÄ@Bean ·½·¨¶¼»áÊܵ½Ó°Ïì
+
+Ò»¸ö @Component À࣬Ëü²»ÊÇ @Configuration À࣬Õâ¸ö bean ½«±»ÑÓ³Ù³õʼ»¯
+
+@Autowired ¹¹Ô캯Êý¡¢setter »ò×ֶΣ¬ÓÃÓÚÑÓ³Ù¼ÓÔØÒÀÀµÏî±¾Éí£¨Í¨¹ý´úÀí£©
+
+````
+@Configuration
+@Lazy
+class VehicleFactoryConfig {
+
+ @Bean
+ @Lazy(false)
+ Engine engine() {
+ return new Engine();
+ }
+}
+````
+ÕâͬÑù²»ÊÇÒ»¸ö³£ÓõÄ×¢½â¡£
+
+µ±ÎÒÃÇά»¤Ò»¸öÓдóÁ¿beanµÄÏîĿʱ£¬»á·¢ÏÖÓкܶàbean¿ÉÄܶ¼Êǰ´ÐèʹÓõ쬲»Ò»¶¨ÐèÒªÔÚÈÝÆ÷³õʼ»¯Ê±¾Í½øÐгõʼ»¯£¬Õâ¿ÉÒÔ°ïÎÒÃǽÚÊ¡ºÜ¶àʱ¼äºÍÐÔÄÜ¡£
+
+
+### 2.8 @Lookup
+ͬÑùÊÇÒ»¸ö±È½ÏÉÙÓõ½µÄ×¢½â
+
+@Lookup »á¸æËß Spring ÔÚÎÒÃǵ÷ÓÃËüʱ·µ»Ø·½·¨·µ»ØÀàÐ͵ÄʵÀý¡£
+
+±¾ÖÊÉÏ£¬Spring ½«¸²¸ÇÎÒÃÇ´ø×¢Ê͵ķ½·¨²¢Ê¹ÓÃÎÒÃÇ·½·¨µÄ·µ»ØÀàÐͺͲÎÊý×÷Ϊ BeanFactory#getBean µÄ²ÎÊý¡£
+
+@Lookup ÊÊÓÃÓÚ£º
+
+½«ÔÐÍ bean ×¢ÈëÎÒÃÇ×Ô¼ºµÄbean£¨ÀàËÆÓÚ Provider£©
+
+Èç¹ûÎÒÃÇÅöÇɾö¶¨ÓµÓÐÒ»¸öÔÐÍ Spring bean£¬ÄÇôÎÒÃǼ¸ºõ»áÁ¢¼´ÃæÁÙÕâÑùµÄÎÊÌ⣺
+
+ÎÒÃǵĵ¥Àý Spring bean ½«ÈçºÎ·ÃÎÊÕâЩÔÐÍ Spring bean£¿
+
+ÏÖÔÚ£¬Provider ¿Ï¶¨ÊÇÒ»ÖÖ·½Ê½£¬¾¡¹Ü @Lookup ÔÚijЩ·½Ãæ¸ü¼ÓͨÓá£
+
+ҪעÒâµÄÊÇ£¬springĬÈÏʹÓõĵ¥Àýbean£¬ËùÒÔÈç¹ûÎÒÃÇҪעÈëÔÐÍbean£¬ÎÒÃDzÅÐèÒª×öÕâÑùµÄ¶îÍ⹤×÷
+
+Ê×ÏÈ£¬ÈÃÎÒÃÇ´´½¨Ò»¸öÔÐÍ bean£¬ÉÔºóÎÒÃǽ«Æä×¢Èëµ½µ¥Àý bean ÖУº
+````
+@Component
+@Scope("prototype")
+public class SchoolNotification {
+// ... prototype-scoped state
+}
+````
+ʹÓÃ@Lookup£¬ÎÒÃÇ¿ÉÒÔͨ¹ýµ¥Àý bean »ñÈ¡ SchoolNotification µÄʵÀý£º
+
+````
+@Component
+public class StudentServices {
+
+ // ... member variables, etc.
+
+ @Lookup
+ public SchoolNotification getNotification() {
+ return null;
+ }
+
+ // ... getters and setters
+}
+````
+Using @Lookup, we can get an instance of SchoolNotification through our singleton bean:
+````
+@Test
+public void whenLookupMethodCalled_thenNewInstanceReturned() {
+// ... initialize context
+StudentServices first = this.context.getBean(StudentServices.class);
+StudentServices second = this.context.getBean(StudentServices.class);
+
+ assertEquals(first, second);
+ assertNotEquals(first.getNotification(), second.getNotification());
+}
+````
+Çë×¢Ò⣬ÔÚ StudentServices ÖУ¬ÎÒÃǽ« getNotification ·½·¨±£ÁôΪ´æ¸ù¡£
+
+ÕâÊÇÒòΪ Spring ͨ¹ýµ÷Óà beanFactory.getBean(StudentNotification.class) ¸²¸ÇÁ˸÷½·¨£¬Òò´ËÎÒÃÇ¿ÉÒÔ½«ÆäÁô¿Õ¡£
+
+
+### 2.9 @Primary
+ÓÐʱÎÒÃÇÐèÒª¶¨Òå¶à¸öÏàͬÀàÐ͵Äbean¡£ ÔÚÕâЩÇé¿öÏ£¬×¢È뽫²»³É¹¦£¬ÒòΪ Spring ²»ÖªµÀÎÒÃÇÐèÒªÄĸö bean¡£
+
+ÎÒÃÇÒѾ¿´µ½ÁË´¦ÀíÕâÖÖÇé¿öµÄÑ¡ÏÓÃ@Qualifier ±ê¼ÇËùÓнÓÏߵ㲢ָ¶¨ËùÐè bean µÄÃû³Æ¡£
+
+È»¶ø£¬´ó¶àÊýʱºòÎÒÃÇÐèÒªÒ»¸öÌØ¶¨µÄ bean£¬ºÜÉÙÐèÒªÆäËû bean¡£
+
+ÎÒÃÇ¿ÉÒÔʹÓÃ@Primary À´¼ò»¯ÕâÖÖÇé¿ö£ºÈç¹ûÎÒÃÇÓÃ@Primary ±ê¼Ç×î³£ÓõÄbean£¬Ëü½«ÔÚunqualifiedµÄ×¢ÈëµãÉϱ»Ñ¡Ôñ£º
+
+````
+@Component
+@Primary
+class Car implements Vehicle {}
+
+@Component
+class Bike implements Vehicle {}
+
+@Component
+class Driver {
+@Autowired
+Vehicle vehicle;
+}
+
+@Component
+class Biker {
+@Autowired
+@Qualifier("bike")
+Vehicle vehicle;
+}
+````
+ÔÚÇ°ÃæµÄʾÀýÖУ¬Æû³µÊÇÖ÷Òª³µÁ¾¡£ Òò´Ë£¬ÔÚ Driver ÀàÖУ¬Spring ×¢ÈëÁËÒ»¸ö Car bean¡£ µ±È»£¬ÔÚ Biker bean ÖУ¬×Ö¶Î vehicle µÄÖµ½«ÊÇÒ»¸ö Bike ¶ÔÏó£¬ÒòΪËüÊÇqualifiedµÄ¡£
+
+### 2.10 @Scope
+
+¶ÔÓÚͨ³£µÄÓ¦ÓÃÀ´Ëµ£¬ÎÒÃÇbeanµÄscopeĬÈ϶¼Êǵ¥ÀýµÄ£¬µ«Êµ¼ÊÉÏspring bean¿ÉÒÔÖ§³Ö¶àÖÖ¶àÑùµÄ×÷Ó÷¶Î§£¬ËüÃÇÓÐ×Ų»Í¬µÄÉúÃüÖÜÆÚ¡£
+
+ÎÒÃÇʹÓÃ@Scope À´¶¨Òå@Component Àà»ò@Bean ¶¨ÒåµÄ·¶Î§¡£ Ëü¿ÉÒÔÊǵ¥Àý¡¢ÔÐÍ¡¢ÇëÇ󡢻Ự¡¢globalSession »òһЩ×Ô¶¨Ò巶Χ¡£
+
+¶ÔÓ¦µÄö¾ÙֵΪ
+````
+singleton
+prototype
+request
+session
+application
+websocket
+````
+
+Àý×Ó
+````
+@Component
+@Scope("prototype")
+class Engine {}
+````
+ÎÒÃÇ¿ÉÒÔÏëÏóһЩ³¡¾°£¬±ÈÈçrequest¡¢session¡¢websocketÕâÀà×÷ÓÃÓòµÄbean£¬Í¨³£Ó¦¸ÃÊǺÍÍøÂçÇëÇóÏà¹ØµÄ£¬±ÈÈçÓô洢Óû§ÐÅÏ¢¡¢sessionÖ®ÀàµÄbean¡£
+
+¾ßÌåÔõôʹÓ㬾ÍÒª¸ù¾ÝÄãµÄ¾ßÌ峡¾°À´Ñ¡ÔñÁË£¬Õâ»áÊÇÒ»¸öºÜ´óµÄ»°Ì⣬ÕâÀï¾ÍÏȲ»Õ¹¿ªÁË£¬ÒÔºó¿ÉÒÔÔÚµ¥¶ÀµÄÎÄÕÂÀï¼ÌÐø½éÉÜ¡£
+
+## 3 ÉÏÏÂÎÄÅäÖÃ×¢½â
+ÎÒÃÇ¿ÉÒÔʹÓñ¾½ÚÖÐÃèÊöµÄ×¢ÊÍÀ´ÅäÖÃÓ¦ÓóÌÐòÉÏÏÂÎÄ¡£
+
+
+### 3.1 @Profile
+
+Èç¹ûÎÒÃÇÏ£Íû Spring ½öÔÚÌØ¶¨ÅäÖÃÎļþ´¦Óڻ״̬ʱʹÓÃ@Component Àà»ò@Bean ·½·¨£¬ÎÒÃÇ¿ÉÒÔʹÓÃ@Profile ¶ÔÆä½øÐбê¼Ç¡£
+
+ÎÒÃÇ¿ÉÒÔʹÓÃ×¢Ê͵ÄÖµ²ÎÊýÅäÖÃÅäÖÃÎļþµÄÃû³Æ£º
+
+ÎÒÃÇͨ³£Õâ¸ö×¢½âÀ´ÅäÖò»Í¬»·¾³µÄÅäÖá£
+±ÈÈçÏÂÃæÕâ¸öÀý×Ó
+
+````
+public interface DatasourceConfig {
+public void setup();
+}
+````
+
+ÏÂÃæÊÇ¿ª·¢»·¾³µÄÅäÖãº
+
+````
+@Component
+@Profile("dev")
+public class DevDatasourceConfig implements DatasourceConfig {
+@Override
+public void setup() {
+System.out.println("Setting up datasource for DEV environment. ");
+}
+}
+````
+ÏÂÃæÊÇÉú²ú»·¾³µÄÅäÖãº
+
+````
+@Component
+@Profile("production")
+public class ProductionDatasourceConfig implements DatasourceConfig {
+@Override
+public void setup() {
+System.out.println("Setting up datasource for PRODUCTION environment. ");
+}
+}
+````
+µ±È»ÎÒÃÇÒ²¿ÉÒÔʹÓÃxml»òÕ߯äËûÀàÐ͵ÄÅäÖÃÎļþÀ´ÃèÊöÕâ¸öÅäÖÃbean
+
+xml
+````
+
+
+
+````
+### 3.2 @Import
+
+ÎÒÃÇ¿ÉÒÔʹÓÃÌØ¶¨µÄ @Configuration À࣬¶øÎÞÐèʹÓôË×¢½â½øÐÐ×é¼þɨÃè¡£ ÎÒÃÇ¿ÉÒÔΪÕâЩÀàÌṩ@Import µÄÖµ²ÎÊý
+
+Õý³£À´Ëµ£¬Èç¹ûÒªÓõ½@Configuration×¢½âµÄbean£¬ÄÇôspringÓ¦ÓñØÐëҪɨÃèµ½¸ÃĿ¼£¬Èç¹ûÇ¡ºÃûÓжԸ÷¾¶½øÐÐɨÃ裬»òÕßÎÒÃÇÖ»ÊÇÏëʹÓ÷¾¶Ïµĵ¥¸öÅäÖÃÀ࣬ÄÇôÎÒÃǾͿÉÒÔʹÓÃ@ImportÀ´µ¼ÈëÕâ¸öÅäÖÃÀàÁË¡£
+
+Õâ¸ö×¢½â»¹ÊǷdz£³£Óõģ¬¿´Ò»ÏÂÏÂÃæÕâ¸öÀý×Ó
+
+````
+@Import(VehiclePartSupplier.class)
+class VehicleFactoryConfig {}
+
+@Configuration
+class VehiclePartSupplier{
+}
+````
+
+### 3.3 @ImportResource
+
+±ÈÈç˵£ºÏÖÔÚÓÐÒ»¸ö bean.xml µÄÅäÖÃÎļþ£¬ÐèÒª½«¸Ã beans.xml Öж¨ÒåµÄ bean¶ÔÏó ¶¼µ¼Èëµ½ Spring Boot »·¾³µÄÈÝÆ÷ÖУ¬¸ÃÈçºÎ²Ù×÷ÄØ£¿
+
+1.Spring ·½Ê½µÄÅäÖÃÎļþ bean.xml ´Ë´¦Ëæ±ã¾Ù¸öʾÀý£¬±ÈÈç˵ xml ÖÐÅäÖÃÁËÒ»¸ö helloService£¬ÈçÏÂËùʾ
+````
+
+
+
+
+
+
+````
+2.ʹÓÃ@ImportResource×¢½â£¬ÒýÈë xml ÅäÖÃ
+````
+/**
+ * Spring BootÀïÃæÃ»ÓÐSpringµÄÅäÖÃÎļþ£¬ÎÒÃÇ×Ô¼º±àдµÄÅäÖÃÎļþ£¬Ò²²»ÄÜ×Ô¶¯Ê¶±ð£»
+ * Èç¹ûÏëÈÃSpringµÄÅäÖÃÎļþÉúЧ£¬¼ÓÔØµ½Spring ÈÝÆ÷ÖÐÀ´£»
+ * ʹÓÃ@ImportResource×¢½â£¬½«Æä±ê×¢ÔÚÒ»¸öÅäÖÃÀàÉÏ(´Ë´¦ÅäÖÃÔÚÆô¶¯Àà)
+ */
+@SpringBootApplication
+@ImportResource(locations = {"classpath:beans.xml"})
+public class BootApplication {
+
+ public static void main(String[] args) {
+ // SpringÓ¦ÓÃÆô¶¯ÆðÀ´
+ SpringApplication.run(BootApplication.class,args);
+
+ }
+}
+
+````
+### 3.4 @PropertySource
+ͨ¹ýÕâ¸ö×¢½â£¬ÎÒÃÇ¿ÉÒÔΪӦÓóÌÐòÉèÖö¨ÒåÊôÐÔÎļþ£º
+
+@PropertySource ×¢½âÌṩÁËÒ»ÖÖ·½±ãµÄÉùÃ÷ÐÔ»úÖÆ£¬ÓÃÓÚ½« PropertySource Ìí¼Óµ½ Spring µÄ Environment ÖУ¬Óë @Configuration ÀàÒ»ÆðʹÓá£
+
+Äã¿ÉÒÔʹÓà @Value È¥ÒýÓö¨ÒåµÄÊôÐÔ£¬ÀýÈ磺@Value("testbean.name")£»Ò²¿ÉÒÔÖ¸¶¨Ä¬ÈÏÖµ£¬È磺@Value("testbean.name:defaultValue")¡£
+
+Ó÷¨Ê¾Àý
+
+¸ø¶¨Ò»¸öÅäÖÃÎļþapp.properties
+````
+testbean.name=myTestBean
+````
+ÒÔÏ @Configuration ÀàʹÓà @PropertySource ½« app.properties ÉèÖøø Environment µÄ PropertySources ¼¯ºÏ¡£
+````
+@Configuration
+@PropertySource("classpath:/com/myco/app.properties")
+public class AppConfig {
+
+ @Autowired
+ Environment env;
+
+ @Bean
+ public TestBean testBean() {
+ TestBean testBean = new TestBean();
+ testBean.setName(env.getProperty("testbean.name"));
+ return testBean;
+ }
+}
+````
+
+×¢Ò⣺ʹÓà @Autowired ½« Environment ¶ÔÏó×¢Èëµ½ÅäÖÃÀàÖУ¬È»ºóÔÚ testBean() ·½·¨ÖÐʹÓá£
+ÒÔÉÏÅäÖÃÖУ¬µ÷Óà testBean.getName() ·½·¨½«·µ»Ø¡°myTestBean¡±×Ö·û´®¡£
+
+@PropertySource ÀûÓÃÁË Java 8 µÄÖØ¸´×¢½âÌØÐÔ£¬ÕâÒâζ×ÅÎÒÃÇ¿ÉÒÔÓÃËü¶à´Î±ê¼ÇÒ»¸öÀࣺ
+
+````
+@Configuration
+@PropertySource("classpath:/annotations.properties")
+@PropertySource("classpath:/vehicle-factory.properties")
+class VehicleFactoryConfig {}
+````
+
+### 3.5 @PropertySources
+Ó÷¨Í¬ÉÏ£¬Ö»²»¹ý£¬ÕâÒ»´ÎÎÒÃÇ¿ÉÒÔʹÓÃÕâ¸ö×¢½âÖ¸¶¨¶à¸ö@PropertySource ÅäÖãº
+````
+@Configuration
+@PropertySources({
+@PropertySource("classpath:/annotations.properties"),
+@PropertySource("classpath:/vehicle-factory.properties")
+})
+class VehicleFactoryConfig {}
+````
+Çë×¢Ò⣬×Ô Java 8 ÒÔÀ´£¬ÎÒÃÇ¿ÉÒÔͨ¹ýÉÏÊöÖØ¸´×¢Ê͹¦ÄÜʵÏÖÏàͬµÄ¹¦ÄÜ¡£
+
+## 4.½áÂÛ
+
+ÔÚ±¾ÎÄÖУ¬ÎÒÃÇ¿´µ½ÁË×î³£¼ûµÄ Spring ºËÐÄ×¢Ê͵ĸÅÊö¡£ ÎÒÃÇ¿´µ½ÁËÈçºÎÅäÖà bean Á¬½ÓºÍÓ¦ÓÃÉÏÏÂÎÄ£¬ÒÔ¼°ÈçºÎΪ×é¼þɨÃè±ê¼ÇÀà¡£
+
+springÌåϵÖеij£¼û×¢½â»¹Óкܶ࣬һƪÎÄÕ²»¿ÉÄÜÈ«²¿¸²¸Ç£¬ÈçÓÐÒÅ©£¬»¶Ó²¹³ä¡£
+
+# Spring Bean×¢½â
+
+## 1 ¸ÅÊö
+ÔÚ±¾½Ì³ÌÖУ¬ÎÒÃǽ«ÌÖÂÛÓÃÓÚ¶¨Ò岻ͬÀàÐÍ bean µÄ×î³£¼ûµÄ Spring bean ×¢ÊÍ¡£
+
+Óм¸ÖÖ·½·¨¿ÉÒÔÔÚ Spring ÈÝÆ÷ÖÐÅäÖà bean¡£ Ê×ÏÈ£¬ÎÒÃÇ¿ÉÒÔʹÓà XML ÅäÖÃÉùÃ÷ËüÃÇ¡£ ÎÒÃÇ»¹¿ÉÒÔÔÚÅäÖÃÀàÖÐʹÓÃ@Bean ×¢½âÀ´ÉùÃ÷ bean¡£
+
+×îºó£¬ÎÒÃÇ¿ÉÒÔʹÓà org.springframework.stereotype °üÖеÄ×¢ÊÍÖ®Ò»À´±ê¼Ç¸ÃÀ࣬²¢½«ÆäÓಿ·ÖÁô¸ø×é¼þɨÃè¡£
+
+## 2 @ComponentScan
+ÕâÊÇÎÒÃǾ³£»áʹÓõÄÒ»¸ö×¢½â£¬ÔÚÎÒÃǵÄÓ¦ÓÃÖУ¬ÓÐʱºò²»Ò»¶¨»áɨÃèËùÓеİü£¬ÌرðÊǵ±ÎÒÃÇҪɨÃèÍⲿjar°üÖеÄbeanʱ£¬Ëü·Ç³£ÓÐÓá£
+
+Ëü¿ÉÒÔ¼ÓÔÚSpringBootApplicationÉÏ£¬Ò²¿ÉÒÔ¼ÓÔÚ@configuration×¢½âÉϵÄÅäÖÃÀàÉÏ
+
+Èç¹ûÆôÓÃÁË×é¼þɨÃ裬Spring ¿ÉÒÔ×Ô¶¯É¨Ãè°üÖÐµÄ bean¡£
+
+@ComponentScan ÅäÖÃʹÓÃ×¢½âÅäÖÃɨÃèÄÄЩ°üµÄÀà¡£
+
+ÎÒÃÇ¿ÉÒÔÖ±½ÓʹÓà basePackages »ò value ²ÎÊýÖ®Ò»Ö¸¶¨»ù±¾°üÃû³Æ£¨value ÊÇ basePackages µÄ±ðÃû£©
+
+````
+@Configuration
+@ComponentScan(basePackages = "com.baeldung.annotations")
+class VehicleFactoryConfig {}
+````
+´ËÍ⣬ÎÒÃÇ¿ÉÒÔʹÓà basePackageClasses ²ÎÊýÖ¸Ïò»ù´¡°üÖеÄÀࣺ
+
+````
+@Configuration
+@ComponentScan(basePackageClasses = VehicleFactoryConfig.class)
+class VehicleFactoryConfig {}
+````
+
+ÕâÁ½¸ö²ÎÊý¶¼ÊÇÊý×飬Òò´ËÎÒÃÇ¿ÉÒÔΪÿ¸ö²ÎÊýÌṩ¶à¸ö°ü¡£
+
+Èç¹ûδָ¶¨²ÎÊý£¬ÔòɨÃè·¢ÉúÔÚ´æÔÚ @ComponentScan ×¢ÊÍÀàµÄͬһ°üÖС£
+
+@ComponentScan ÀûÓÃÁË Java 8 µÄÖØ¸´×¢½âÌØÐÔ£¬ÕâÒâζ×ÅÎÒÃÇ¿ÉÒÔÓÃËü¶à´Î±ê¼ÇÒ»¸öÀࣺ
+
+````
+@Configuration
+@ComponentScan(basePackages = "com.baeldung.annotations")
+@ComponentScan(basePackageClasses = VehicleFactoryConfig.class)
+class VehicleFactoryConfig {}
+````
+
+»òÕߣ¬ÎÒÃÇ¿ÉÒÔʹÓà @ComponentScans Ö¸¶¨¶à¸ö @ComponentScan ÅäÖãº
+
+````
+@Configuration
+@ComponentScans({
+@ComponentScan(basePackages = "com.baeldung.annotations"),
+@ComponentScan(basePackageClasses = VehicleFactoryConfig.class)
+})
+````
+````
+class VehicleFactoryConfig {
+}
+````
+ʹÓà XML ÅäÖÃʱ£¬ÅäÖÃ×é¼þɨÃèͬÑù¼òµ¥£º
+
+````
+
+````
+
+### 3 @Component
+
+@Component ÊÇÀ༶±ðµÄ×¢½â¡£ ÔÚ×é¼þɨÃèÆÚ¼ä£¬Spring Framework »á×Ô¶¯¼ì²âʹÓÃ@Component ×¢½âµÄÀࣺ
+````
+@Component
+class CarUtility {
+// ...
+}
+````
+
+ĬÈÏÇé¿öÏ£¬´ËÀàµÄ bean ʵÀýÓëÀàÃûͬÃû£¬Ê××ÖĸСд¡£ ´ËÍ⣬ÎÒÃÇ¿ÉÒÔʹÓôË×¢Ê͵ĿÉѡֵ²ÎÊýÖ¸¶¨²»Í¬µÄÃû³Æ¡£
+
+ÓÉÓÚ@Repository¡¢@Service¡¢@Configuration ºÍ@Controller ¶¼ÊÇ´øÓÐ@Component µÄ×¢½â£¬ËüÃǹ²ÏíÏàͬµÄbean ÃüÃûÐÐΪ¡£
+
+Spring »¹»áÔÚ×é¼þɨÃè¹ý³ÌÖÐ×Ô¶¯¼ì²âËüÃÇ¡£
+
+ͨ³£À´Ëµ£¬ÎÒÃÇ»áÔÚmvcÓ¦ÓÃÖÐÎÒÃÇ»áÓõ½ÉÏÊö¼¸ÖÖ×¢½â£¬¶øÎÒÃÇÔÚ·ÇwebÓ¦ÓÃÖиü¶àµØ¿ÉÒÔʹÓÃ@componentÀ´×¢½âbean
+
+### 4 @Repository
+
+DAO or Repository classes usually represent the database access layer in an application, and should be annotated with @Repository:
+````
+@Repository
+class VehicleRepository {
+// ...
+}
+````
+ʹÓôË×¢Ê͵ÄÒ»¸öÓŵãÊÇËüÆôÓÃÁË×Ô¶¯³Ö¾ÃÐÔÒ쳣ת»»¡£ µ±Ê¹Óó־ÃÐÔ¿ò¼Ü£¨Èç Hibernate£©Ê±£¬ÔÚʹÓà @Repository ×¢Ê͵ÄÀàÖÐÅ׳öµÄ±¾»úÒì³£½«×Ô¶¯×ª»»Îª Spring µÄ DataAccessExeption µÄ×ÓÀà¡£
+
+ÒªÆôÓÃÒ쳣ת»»£¬ÎÒÃÇÐèÒªÉùÃ÷ÎÒÃÇ×Ô¼ºµÄ PersistenceExceptionTranslationPostProcessor bean£º
+````
+@Bean
+public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
+return new PersistenceExceptionTranslationPostProcessor();
+}
+````
+Çë×¢Ò⣬ÔÚ´ó¶àÊýÇé¿öÏ£¬Spring »á×Ô¶¯Ö´ÐÐÉÏÊö²½Öè¡£
+
+»òÕßͨ¹ý XML ÅäÖãº
+````
+
+````
+
+### 5 @Service
+Ó¦ÓóÌÐòµÄÒµÎñÂ߼ͨ³£×¤ÁôÔÚ·þÎñ²ãÖУ¬Òò´ËÎÒÃǽ«Ê¹ÓÃ@Service ×¢ÊÍÀ´Ö¸Ê¾Ò»¸öÀàÊôÓڸò㣺
+
+````
+@Service
+public class VehicleService {
+// ...
+}
+````
+### 6 @Controller
+@Controller ÊÇÒ»¸öÀ༶±ðµÄ×¢½â£¬Ëü¸æËß Spring Framework Õâ¸öÀà×÷Ϊ Spring MVC ÖеĿØÖÆÆ÷£º
+
+spring»á¶Ô@Controller ×¢½âµÄbean×öºÜ¶àÊÂÇ飬¾ßÌåÄÚÈÝÎÒÃÇ»áÔÚSpringMVCÏà¹ØµÄÄÚÈÝÀ´½²Êö
+
+````
+@Controller
+public class VehicleController {
+// ...
+}
+
+````
+## 7 @Configuration
+
+ÅäÖÃÀà¿ÉÒÔ°üº¬ÓÃ@Bean ×¢Ê굀 bean ¶¨Òå·½·¨£º
+````
+@Configuration
+class VehicleFactoryConfig {
+
+ @Bean
+ Engine engine() {
+ return new Engine();
+ }
+
+}
+````
+## 8 AOP×¢½â
+µ±ÎÒÃÇʹÓà Spring ¹¹ÔìÐÍ×¢ÊÍʱ£¬ºÜÈÝÒ×´´½¨Ò»¸öÇÐÈëµã£¬¸ÃÇÐÈëµãÒÔËùÓоßÓÐÌØ¶¨¹¹ÔìÐ͵ÄÀàΪĿ±ê¡£
+
+ÀýÈ磬¼ÙÉèÎÒÃÇÏë²âÁ¿ DAO ²ã·½·¨µÄÖ´ÐÐʱ¼ä¡£ ÎÒÃǽ«´´½¨ÒÔÏ·½Ã棨ʹÓà AspectJ ×¢ÊÍ£©£¬ÀûÓà @Repository ¹¹ÔìÐÍ£º
+
+```
+@Aspect
+@Component
+public class PerformanceAspect {
+@Pointcut("within(@org.springframework.stereotype.Repository *)")
+public void repositoryClassMethods() {};
+
+ @Around("repositoryClassMethods()")
+ public Object measureMethodExecutionTime(ProceedingJoinPoint joinPoint)
+ throws Throwable {
+ long start = System.nanoTime();
+ Object returnValue = joinPoint.proceed();
+ long end = System.nanoTime();
+ String methodName = joinPoint.getSignature().getName();
+ System.out.println(
+ "Execution of " + methodName + " took " +
+ TimeUnit.NANOSECONDS.toMillis(end - start) + " ms");
+ return returnValue;
+ }
+}
+````
+
+ÔÚ´ËʾÀýÖУ¬ÎÒÃÇ´´½¨ÁËÒ»¸öÇÐÈëµã£¬¸ÃÇÐÈëµãÆ¥ÅäʹÓÃ@Repository ×¢Ê͵ÄÀàÖеÄËùÓз½·¨¡£ È»ºóÎÒÃÇʹÓÃ@Around ֪ͨÀ´¶¨Î»ÄǸöÇÐÈëµã£¬²¢È·¶¨À¹½Ø·½·¨µ÷ÓõÄÖ´ÐÐʱ¼ä¡£
+
+´ËÍ⣬ʹÓÃÕâÖÖ·½·¨£¬ÎÒÃÇ¿ÉÒÔΪÿ¸öÓ¦ÓóÌÐò²ãÌí¼ÓÈÕÖ¾¼Ç¼¡¢ÐÔÄܹÜÀí¡¢Éó¼ÆºÍÆäËûÐÐΪ¡£
+
+µ±È»ÁË£¬aspectJµÄÏà¹Ø×¢½â»¹ºÜ¶à£¬¿ÉÒÔÓÃÀ´ÉùÃ÷ÇÐÃæ£¬Î´À´ÎÒÃÇÒ²»áµ¥¶ÀдÎĽéÉÜ¡£
+
+## 9 ½áÂÛ
+
+ÔÚ±¾ÎÄÖУ¬ÎÒÃǼì²éÁË Spring ¹¹ÔìÐÍ×¢ÊͲ¢ÌÖÂÛÁËËüÃǸ÷×Ô´ú±íµÄÓïÒåÀàÐÍ¡£
+
+ÎÒÃÇ»¹Ñ§Ï°ÁËÈçºÎʹÓÃ×é¼þɨÃèÀ´¸æËßÈÝÆ÷ÔÚÄÄÀï¿ÉÒÔÕÒµ½´ø×¢Ê͵ÄÀà¡£
+
+×îºó£¬ÎÒÃÇÁ˽âÁËÕâЩעÊÍÈçºÎµ¼Ö¸ɾ»¡¢·Ö²ãµÄÉè¼ÆÒÔ¼°Ó¦ÓóÌÐò¹Ø×¢µãÖ®¼äµÄ·ÖÀë¡£ ËüÃÇ»¹Ê¹ÅäÖøüС£¬ÒòΪÎÒÃDz»ÔÙÐèÒªÊÖ¶¯ÏÔʽ¶¨Òå bean¡£
+# SpringMVC×¢½â
+## 1. ¸ÅÊö
+ÔÚ±¾½Ì³ÌÖУ¬ÎÒÃǽ«Ì½Ë÷ org.springframework.web.bind.annotation °üÖÐµÄ Spring Web ×¢ÊÍ¡£
+
+## 2. @RequestMapping
+
+¼òµ¥µØËµ£¬@RequestMapping ±ê¼Ç@Controller ÀàÄÚ²¿µÄÇëÇó´¦Àí³ÌÐò·½·¨£» Ëü¿ÉÒÔʹÓÃÅäÖãº
+
+·¾¶£¬»òÆä±ðÃû¡¢Ãû³ÆºÍÖµ£º·½·¨Ó³Éäµ½Äĸö URL
+·½·¨£º¼æÈÝµÄ HTTP ·½·¨
+params£º¸ù¾Ý HTTP ²ÎÊýµÄ´æÔÚ¡¢²»´æÔÚ»òÖµ¹ýÂËÇëÇó
+headers£º¸ù¾Ý HTTP ±êÍ·µÄ´æÔÚ¡¢²»´æÔÚ»òÖµ¹ýÂËÇëÇó
+ÏûºÄ£º¸Ã·½·¨¿ÉÒÔÔÚ HTTP ÇëÇóÕýÎÄÖÐÏûºÄÄÄЩýÌåÀàÐÍ
+produces£º¸Ã·½·¨¿ÉÒÔÔÚ HTTP ÏìÓ¦ÕýÎÄÖÐÉú³ÉÄÄЩýÌåÀàÐÍ
+ÕâÊÇÒ»¸ö¼òµ¥µÄʾÀý£º
+
+````
+@Controller
+class VehicleController {
+
+ @RequestMapping(value = "/vehicles/home", method = RequestMethod.GET)
+ String home() {
+ return "home";
+ }
+}
+````
+Èç¹ûÎÒÃÇÔÚÀ༶±ðÓ¦ÓôË×¢ÊÍ£¬ÎÒÃÇ¿ÉÒÔΪ @Controller ÀàÖеÄËùÓд¦Àí³ÌÐò·½·¨ÌṩĬÈÏÉèÖᣠΨһµÄÀýÍâÊÇ Spring ²»»áʹÓ÷½·¨¼¶±ðÉèÖø²¸Çµ«»á¸½¼ÓÁ½¸ö·¾¶²¿·ÖµÄ URL¡£
+
+ÀýÈ磬ÏÂÃæµÄÅäÖúÍÉÏÃæµÄЧ¹ûÊÇÒ»ÑùµÄ£º
+
+````
+@Controller
+@RequestMapping(value = "/vehicles", method = RequestMethod.GET)
+class VehicleController {
+
+ @RequestMapping("/home")
+ String home() {
+ return "home";
+ }
+}
+````
+
+´ËÍ⣬@GetMapping¡¢@PostMapping¡¢@PutMapping¡¢@DeleteMapping ºÍ@PatchMapping ÊÇ@RequestMapping µÄ²»Í¬±äÌ壬ÆäHTTP ·½·¨ÒÑ·Ö±ðÉèÖÃΪGET¡¢POST¡¢PUT¡¢DELETE ºÍPATCH¡£
+
+ÕâЩ´Ó Spring 4.3 °æ±¾¿ªÊ¼¿ÉÓá£
+
+## 3 @RequestBody
+
+ÈÃÎÒÃǼÌÐø@RequestBody¡ª¡ªËü½« HTTP ÇëÇóµÄÖ÷ÌåÓ³Éäµ½Ò»¸ö¶ÔÏó£º
+
+````
+@PostMapping("/save")
+void saveVehicle(@RequestBody Vehicle vehicle) {
+// ...
+}
+````
+·´ÐòÁл¯ÊÇ×Ô¶¯µÄ£¬È¡¾öÓÚÇëÇóµÄÄÚÈÝÀàÐÍ¡£
+
+## 4 @PathVariable
+½ÓÏÂÀ´ËµËµ@PathVariable¡£
+
+´Ë×¢ÊÍָʾ·½·¨²ÎÊý°ó¶¨µ½ URI Ä£°å±äÁ¿¡£ ÎÒÃÇ¿ÉÒÔʹÓà @RequestMapping ×¢ÊÍÖ¸¶¨ URI Ä£°å£¬²¢Ê¹Óà @PathVariable ½«·½·¨²ÎÊý°ó¶¨µ½Ä£°å²¿·ÖÖ®Ò»¡£
+
+ÎÒÃÇ¿ÉÒÔʹÓÃÃû³Æ»òÆä±ðÃû£¬¼´Öµ²ÎÊýÀ´ÊµÏÖÕâÒ»µã£º
+
+````
+@RequestMapping("/{id}")
+Vehicle getVehicle(@PathVariable("id") long id) {
+// ...
+}
+````
+Èç¹ûÄ£°åÖв¿·ÖµÄÃû³ÆÓë·½·¨²ÎÊýµÄÃû³ÆÏàÆ¥Å䣬ÎÒÃǾͲ»±ØÔÚ×¢ÊÍÖÐÖ¸¶¨Ëü£º
+
+````
+@RequestMapping("/{id}")
+Vehicle getVehicle(@PathVariable long id) {
+// ...
+}
+````
+´ËÍ⣬ÎÒÃÇ¿ÉÒÔͨ¹ý½«ËùÐèµÄ²ÎÊýÉèÖÃΪ false À´½«Â·¾¶±äÁ¿±ê¼ÇΪ¿ÉÑ¡£º
+
+````
+@RequestMapping("/{id}")
+Vehicle getVehicle(@PathVariable(required = false) long id) {
+// ...
+}
+````
+## 5. @RequestParam
+We use @RequestParam for accessing HTTP request parameters:
+````
+@RequestMapping
+Vehicle getVehicleByParam(@RequestParam("id") long id) {
+// ...
+}
+````
+Ëü¾ßÓÐÓë @PathVariable ×¢ÊÍÏàͬµÄÅäÖÃÑ¡Ïî¡£
+
+³ýÁËÕâЩÉèÖÃÖ®Í⣬µ± Spring ÔÚÇëÇóÖз¢ÏÖûÓÐÖµ»òΪ¿Õֵʱ£¬ÎÒÃÇ¿ÉÒÔʹÓà @RequestParam Ö¸¶¨×¢ÈëÖµ¡£ Ϊ´Ë£¬ÎÒÃDZØÐëÉèÖà defaultValue ²ÎÊý¡£
+
+ÌṩĬÈÏÖµÒþʽÉèÖà required Ϊ false£º
+````
+@RequestMapping("/buy")
+Car buyCar(@RequestParam(defaultValue = "5") int seatCount) {
+// ...
+}
+````
+³ýÁ˲ÎÊýÖ®Í⣬ÎÒÃÇ»¹¿ÉÒÔ·ÃÎÊÆäËû HTTP ÇëÇ󲿷֣ºcookie ºÍ±êÍ·¡£
+
+ÎÒÃÇ¿ÉÒÔ·Ö±ðʹÓÃ×¢½â@CookieValue ºÍ@RequestHeader À´·ÃÎÊËüÃÇ¡£
+
+
+## 6. Response Handling Annotations
+ÔÚ½ÓÏÂÀ´µÄ²¿·ÖÖУ¬ÎÒÃǽ«¿´µ½ÔÚ Spring MVC ÖвÙ×÷ HTTP ÏìÓ¦µÄ×î³£¼û×¢ÊÍ¡£
+
+### 6.1 @ResponseBody
+Èç¹ûÎÒÃÇÓÃ@ResponseBody ±ê¼ÇÇëÇó´¦Àí³ÌÐò·½·¨£¬Spring »á½«·½·¨µÄ½á¹ûÊÓΪÏìÓ¦±¾Éí£º
+
+````
+@ResponseBody
+@RequestMapping("/hello")
+String hello() {
+return "Hello World!";
+}
+````
+Èç¹ûÎÒÃÇÓÃÕâ¸ö×¢½âÀ´×¢½â @Controller À࣬ËùÓÐÇëÇó´¦Àí³ÌÐò·½·¨¶¼½«Ê¹ÓÃËü¡£
+
+### 6.2 @ExceptionHandler
+
+ʹÓôË×¢ÊÍ£¬ÎÒÃÇ¿ÉÒÔÉùÃ÷Ò»¸ö×Ô¶¨Òå´íÎó´¦Àí³ÌÐò·½·¨¡£ µ±ÇëÇó´¦Àí³ÌÐò·½·¨Å׳öÈκÎÖ¸¶¨µÄÒ쳣ʱ£¬Spring µ÷Óô˷½·¨¡£
+
+²¶»ñµÄÒì³£¿ÉÒÔ×÷Ϊ²ÎÊý´«µÝ¸ø·½·¨£º
+````
+@ExceptionHandler(IllegalArgumentException.class)
+void onIllegalArgumentException(IllegalArgumentException exception) {
+// ...
+}
+````
+
+### 6.3 @ResponseStatus
+Èç¹ûÎÒÃÇʹÓôË×¢ÊͶÔÇëÇó´¦Àí³ÌÐò·½·¨½øÐÐ×¢ÊÍ£¬Ôò¿ÉÒÔÖ¸¶¨ÏìÓ¦µÄËùÐè HTTP ״̬¡£ ÎÒÃÇ¿ÉÒÔʹÓà code ²ÎÊý»òÆä±ðÃû value ²ÎÊýÀ´ÉùÃ÷״̬´úÂë¡£
+
+´ËÍ⣬ÎÒÃÇ¿ÉÒÔʹÓà reason ²ÎÊýÌṩÔÒò¡£
+
+ÎÒÃÇÒ²¿ÉÒÔ½«ËüÓë@ExceptionHandler Ò»ÆðʹÓãº
+
+@ExceptionHandler(IllegalArgumentException.class)
+@ResponseStatus(HttpStatus.BAD_REQUEST)
+void onIllegalArgumentException(IllegalArgumentException exception) {
+// ...
+}
+
+ÓÐ¹Ø HTTP ÏìӦ״̬µÄ¸ü¶àÐÅÏ¢£¬Çë·ÃÎʱ¾ÎÄ¡£
+
+## 7 ÆäËû Web×¢½â
+һЩעÊͲ»Ö±½Ó¹ÜÀí HTTP ÇëÇó»òÏìÓ¦¡£ ÔÚ½ÓÏÂÀ´µÄ²¿·ÖÖУ¬ÎÒÃǽ«½éÉÜ×î³£¼ûµÄ¡£
+
+### 7.1 @Controller
+ÎÒÃÇ¿ÉÒÔʹÓÃ@Controller ¶¨ÒåÒ»¸öSpring MVC ¿ØÖÆÆ÷¡£ Óйظü¶àÐÅÏ¢£¬Çë·ÃÎÊÎÒÃǹØÓÚ Spring Bean Annotations µÄÎÄÕ¡£
+
+### 7.2 @RestController
+@RestController ½áºÏÁË@Controller ºÍ@ResponseBody¡£
+
+Òò´Ë£¬ÒÔÏÂÉùÃ÷ÊǵÈЧµÄ£º
+
+````
+@Controller
+@ResponseBody
+class VehicleRestController {
+// ...
+}
+````
+
+````
+@RestController
+class VehicleRestController {
+// ...
+}
+````
+### 7.3 @ModelAttribute
+ͨ¹ýÕâ¸ö×¢½â£¬ÎÒÃÇ¿ÉÒÔͨ¹ýÌṩģÐͼüÀ´·ÃÎÊÒѾ´æÔÚÓÚ MVC @Controller Ä£ÐÍÖеÄÔªËØ£º
+
+````
+@PostMapping("/assemble")
+void assembleVehicle(@ModelAttribute("vehicle") Vehicle vehicleInModel) {
+// ...
+}
+````
+Óë@PathVariable ºÍ@RequestParam Ò»Ñù£¬Èç¹û²ÎÊý¾ßÓÐÏàͬµÄÃû³Æ£¬ÎÒÃDz»±ØÖ¸¶¨Ä£Ðͼü£º
+
+````
+@PostMapping("/assemble")
+void assembleVehicle(@ModelAttribute Vehicle vehicle) {
+// ...
+}
+````
+´ËÍ⣬@ModelAttribute»¹ÓÐÒ»¸öÓÃ;£ºÈç¹ûÎÒÃÇÓÃËü×¢½âÒ»¸ö·½·¨£¬Spring»á×Ô¶¯½«·½·¨µÄ·µ»ØÖµÌí¼Óµ½Ä£ÐÍÖУº
+
+````
+@ModelAttribute("vehicle")
+Vehicle getVehicle() {
+// ...
+}
+````
+ºÍÒÔǰһÑù£¬ÎÒÃDz»±ØÖ¸¶¨Ä£Ðͼü£¬Spring ĬÈÏʹÓ÷½·¨µÄÃû³Æ£º
+````
+@ModelAttribute
+Vehicle vehicle() {
+// ...
+}
+````
+ÔÚ Spring µ÷ÓÃÇëÇó´¦Àí³ÌÐò·½·¨Ö®Ç°£¬Ëü»áµ÷ÓÃÀàÖÐËùÓÐ @ModelAttribute ×¢Ê͵ķ½·¨¡£
+
+ÓÐ¹Ø @ModelAttribute µÄ¸ü¶àÐÅÏ¢£¬Çë²ÎÔı¾ÎÄ¡£
+
+### 7.4 @CrossOrigin
+@CrossOrigin Ϊ´ø×¢Ê͵ÄÇëÇó´¦Àí³ÌÐò·½·¨ÆôÓÿçÓòͨÐÅ£º
+
+````
+@CrossOrigin
+@RequestMapping("/hello")
+String hello() {
+return "Hello World!";
+}
+````
+Èç¹ûÎÒÃÇÓÃËü±ê¼ÇÒ»¸öÀ࣬ËüÊÊÓÃÓÚÆäÖеÄËùÓÐÇëÇó´¦Àí³ÌÐò·½·¨¡£
+
+ÎÒÃÇ¿ÉÒÔʹÓôË×¢Ê͵IJÎÊý΢µ÷ CORS ÐÐΪ¡£
+
+ÓйØÏêϸÐÅÏ¢£¬Çë·ÃÎʱ¾ÎÄ¡£
+
+# SpringBoot×¢½â
+## 1 ¸ÅÊö
+Spring Boot ͨ¹ýÆä×Ô¶¯ÅäÖù¦ÄÜʹÅäÖà Spring ±äµÃ¸ü¼ÓÈÝÒס£
+
+ÔÚ±¾¿ìËٽ̳ÌÖУ¬ÎÒÃǽ«Ì½Ë÷ org.springframework.boot.autoconfigure ºÍ org.springframework.boot.autoconfigure.condition °üÖеÄ×¢½â¡£
+
+## 2 @SpringBootApplication
+ÎÒÃÇʹÓÃÕâ¸ö×¢½âÀ´±ê¼Ç Spring Boot Ó¦ÓóÌÐòµÄÖ÷Àࣺ
+
+@SpringBootApplication
+ÎÒÃÇʹÓÃÕâ¸ö×¢½âÀ´±ê¼Ç Spring Boot Ó¦ÓóÌÐòµÄÖ÷Àࣺ
+````
+@SpringBootApplication
+class VehicleFactoryApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(VehicleFactoryApplication.class, args);
+ }
+}
+````
+@SpringBootApplication ·â×°ÁË@Configuration¡¢@EnableAutoConfiguration ºÍ@ComponentScan ×¢½â¼°ÆäĬÈÏÊôÐÔ¡£
+
+## 3 @EnableAutoConfiguration
+
+@EnableAutoConfiguration£¬¹ËÃû˼Ò壬ÆôÓÃ×Ô¶¯ÅäÖᣠÕâÒâζ×Å Spring Boot ÔÚÆäÀà·¾¶ÖвéÕÒ×Ô¶¯ÅäÖà bean ²¢×Ô¶¯Ó¦ÓÃËüÃÇ¡£
+
+Çë×¢Ò⣬ÎÒÃDZØÐ뽫´Ë×¢ÊÍÓë@Configuration Ò»ÆðʹÓãº
+
+````
+@Configuration
+@EnableAutoConfiguration
+class VehicleFactoryConfig {}
+````
+
+## 4 @ConfigurationÒÔ¼°Ïà¹ØÀà
+
+@ConfigurationµÄ×÷Ó㺱ê×¢ÔÚÀàÉÏ£¬ÅäÖÃspringÈÝÆ÷(Ó¦ÓÃÉÏÏÂÎÄ)¡£
+
+ÒÔÍùÎÒÃÇÔÚspringÖÐÅäÖÃbean»áʹÓõ½xmlÅäÖÃÎļþ£¬¶¨ÒåÒ»¸ö¸öbean£¬ÔÚspringbootÖУ¬ÎªÁË×öµ½ÁãÅäÖã¬spring¿ò¼ÜÌṩÁË@ConfigurationÕâÒ»×¢½â
+
+Ï൱ÓڰѸÃÀà×÷ΪspringµÄxmlÅäÖÃÎļþÖеÄ
+
+@Configuration×¢½âµÄÀàÖУ¬Ê¹ÓÃ@Bean×¢½â±ê×¢µÄ·½·¨£¬·µ»ØµÄÀàÐͶ¼»áÖ±½Ó×¢²áΪbean¡£
+
+@Configure×¢½âµÄ¶¨ÒåÈçÏ£º
+````
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Component
+public @interface Configuration {
+String value() default "";
+}
+````
+´Ó¶¨ÒåÀ´¿´£¬µ×²ãÊǺ¬ÓÐ@Component £¬ËùÒÔ@Configuration ¾ßÓÐºÍ @Component µÄ×÷Óá£Òò´Ëcontext:component-scan/»òÕß@ComponentScan¶¼ÄÜ´¦Àí@Configuration×¢½âµÄÀà¡£
+
+ͨ³££¬µ±ÎÒÃDZàд×Ô¶¨Òå×Ô¶¯ÅäÖÃʱ£¬ÎÒÃÇÏ£Íû Spring ÓÐÌõ¼þµØÊ¹ÓÃËüÃÇ¡£ ÎÒÃÇ¿ÉÒÔͨ¹ý±¾½ÚÖеÄ×¢ÊÍÀ´ÊµÏÖÕâÒ»µã¡£
+
+ÎÒÃÇ¿ÉÒÔ½«´Ë²¿·ÖÖеÄ×¢ÊÍ·ÅÔÚ@Configuration Àà»ò@Bean ·½·¨ÉÏ¡£
+
+ÔÚ½ÓÏÂÀ´µÄ²¿·ÖÖУ¬ÎÒÃǽ«Ö»½éÉÜÿ¸öÌõ¼þ±³ºóµÄ»ù±¾¸ÅÄî¡£ ÓûÁ˽â¸ü¶àÐÅÏ¢£¬Çë·ÃÎÊÕâÆªÎÄÕ¡£
+
+### 4.1 @ConditionalOnClass and @ConditionalOnMissingClass
+ºÜÃ÷ÏÔÕâÊÇÒ»¸ö´øÓÐÌõ¼þÅжϵÄÅäÖÃ×¢½â£¬ÒªÖªµÀ£¬ºÜ¶àʱºòÎÒÃǰ´Ðè¼ÓÔØbeanµÄ£¬ÉõÖÁÊǸù¾ÝÍⲿjar°üÊÇ·ñ´æÔÚÀ´½øÐмÓÔØºÍÅжϵġ£
+
+ÕâÖÖʱºò£¬¾ÍÒª¸ù¾ÝÍⲿÀàÊÇ·ñ´æÔÚÀ´¾ö¶¨ÊÇ·ñÊÇ·ñ¼ÓÔØ¸Ãbean
+
+ʹÓÃÕâЩÌõ¼þ£¬Èç¹û×¢ÊͲÎÊýÖеÄÀà´æÔÚ/²»´æÔÚ£¬Spring ½«½öʹÓñê¼ÇµÄ×Ô¶¯ÅäÖà bean£º
+
+````
+@Configuration
+@ConditionalOnClass(DataSource.class)
+class MySQLAutoconfiguration {
+//...
+}
+````
+
+### 4.2 @ConditionalOnBean and @ConditionalOnMissingBean
+
+µ±ÎÒÃÇÏëÒª¸ù¾ÝÌØ¶¨ bean µÄ´æÔÚ»ò²»´æÔÚÀ´¶¨ÒåÌõ¼þʱ£¬ÎÒÃÇ¿ÉÒÔʹÓÃÕâЩעÊÍ£º
+
+ºÍÉÏÃæÒ»¸ö×¢½âÉÔÓÐЩ²»Í¬£¬ÒòΪÎÒÃǵÄÅжÏÌõ¼þ±ä³ÉÁËbean
+
+````
+@Bean
+@ConditionalOnBean(name = "dataSource")
+LocalContainerEntityManagerFactoryBean entityManagerFactory() {
+// ...
+}
+````
+### 4.3 @ConditionalOnProperty
+ͨ¹ýÕâ¸ö×¢½â£¬ÎÒÃÇ¿ÉÒÔ¶ÔÊôÐÔµÄÖµÉèÖÃÌõ¼þ
+
+ҪעÒ⣬ÕâÀïµÄÊôÐÔÖµÀ´Ô´ÓÚapplication.propertiesÎļþÖеÄÅäÖÃ
+
+````
+@Bean
+@ConditionalOnProperty(
+name = "usemysql",
+havingValue = "local"
+)
+DataSource dataSource() {
+// ...
+}
+````
+
+### 4.4 @ConditionalOnResource
+
+ÎÒÃÇ¿ÉÒÔÈà Spring ½öÔÚ´æÔÚÌØ¶¨×ÊԴʱʹÓö¨Ò壺
+¹ËÃû˼Ò壬ҪÇóclasspath´æÔÚÕâ¸ö×ÊÔ´Îļþʱ²Å½øÐмÓÔØ£¬ÕâÒ²ÊǺܳ£ÓõÄÒ»¸ö×¢½â¡£
+
+````
+
+@ConditionalOnResource(resources = "classpath:mysql.properties")
+Properties ditionalProperties() {
+// ...
+}
+````
+
+### 4.5 @ConditionalOnWebApplication and @ConditionalOnNotWebApplication
+Õâ¸ö×¢½âͨ³£ÓÃÓÚºÍwebÓÐÇ¿¹ØÁª£¬»òÕßÍêÈ«ÎÞ¹ØÁªµÄÅäÖÃÉÏ
+
+ʹÓÃÕâЩעÊÍ£¬ÎÒÃÇ¿ÉÒÔ¸ù¾Ýµ±Ç°Ó¦ÓóÌÐòÊÇ·ñÊÇ Web Ó¦ÓóÌÐòÀ´´´½¨Ìõ¼þ£º
+````
+
+@ConditionalOnWebApplication
+HealthCheckController healthCheckController() {
+// ...
+}
+````
+
+### 4.6 @ConditionalExpression
+springbootÕæµÄΪÎÒÃÇÏëµ½ÁËËùÓÐÇé¿ö£¬Èç¹ûÉÏÃæµÄ×¢½â»¹²»ÄÜÂú×ãÄãµÄÒªÇó£¬ÄÇô¸É´à¾ÍÈÃÄã×Ô¼ºÐ´£¬ÕâÏÂÓ¦¸ÃûÓÐÎÊÌâ°É£¿
+
+ÎÒÃÇ¿ÉÒÔÔÚ¸ü¸´ÔÓµÄÇé¿öÏÂʹÓÃÕâ¸ö×¢½â¡£ µ± SpEL ±í´ïʽ±»ÆÀ¹ÀÎªÕæÊ±£¬Spring ½«Ê¹Óñê¼ÇµÄ¶¨Ò壺
+
+````
+@Bean
+@ConditionalOnExpression("${usemysql} && ${mysqlserver == 'local'}")
+DataSource dataSource() {
+// ...
+}
+````
+
+### 4.7 @Conditional
+ʲô£¬»¹ÓÐÎÊÌ⣿
+ÄÇspringbootÒ²²»ÔÙÌṩʲô±í´ïʽ¸øÄãÁË£¬Ö±½ÓÈÃÓû§Ð´Ò»¸öÅжÏÌõ¼þ£¬¸æËßÎÒtrue»òÕßfalse¾ÍÐÐÁË
+
+¶ÔÓÚ¸ü¸´ÔÓµÄÌõ¼þ£¬ÎÒÃÇ¿ÉÒÔ´´½¨Ò»¸öÆÀ¹À×Ô¶¨ÒåÌõ¼þµÄÀà¡£ ÎÒÃǸæËß Spring ½«Õâ¸ö×Ô¶¨ÒåÌõ¼þÓë @Conditional Ò»ÆðʹÓãº
+
+````
+@Conditional(HibernateCondition.class)
+Properties ditionalProperties() {
+//...
+}
+````
+
+## 5 ×ܽá
+ÔÚ±¾ÎÄÖУ¬ÎÒÃǸÅÊöÁËÈçºÎ΢µ÷×Ô¶¯ÅäÖùý³Ì²¢Îª×Ô¶¨Òå×Ô¶¯ÅäÖà bean ÌṩÌõ¼þ¡£
+
+# ²Î¿¼ÎÄÕÂ
+https://www.baeldung.com/spring-annotations
diff --git "a/docs/spring/Spring\344\270\255\345\257\271\344\272\216\346\225\260\346\215\256\345\272\223\347\232\204\350\256\277\351\227\256.md" "b/docs/spring/Spring\344\270\255\345\257\271\344\272\216\346\225\260\346\215\256\345\272\223\347\232\204\350\256\277\351\227\256.md"
new file mode 100644
index 0000000..69bfc96
--- /dev/null
+++ "b/docs/spring/Spring\344\270\255\345\257\271\344\272\216\346\225\260\346\215\256\345\272\223\347\232\204\350\256\277\351\227\256.md"
@@ -0,0 +1,1183 @@
+
+## ÅäÖÃÊý¾ÝÔ´
+
+### Spring ÅäÖÃÊý¾ÝÔ´
+
+Spring ÅäÖÃÊý¾ÝÔ´ÓжàÖÖ·½Ê½£¬ÏÂÃæÒ»Ò»Áо٣º
+
+#### [#](https://dunwu.github.io/spring-tutorial/pages/1b774c/#%E4%BD%BF%E7%94%A8-jndi-%E6%95%B0%E6%8D%AE%E6%BA%90)ʹÓà JNDI Êý¾ÝÔ´
+
+Èç¹û Spring Ó¦Óò¿ÊðÔÚÖ§³Ö JNDI µÄ WEB ·þÎñÆ÷ÉÏ£¨Èç WebSphere¡¢JBoss¡¢Tomcat µÈ£©£¬¾Í¿ÉÒÔʹÓà JNDI »ñÈ¡Êý¾ÝÔ´¡£
+
+
+
+```
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+
+
+#### [#](https://dunwu.github.io/spring-tutorial/pages/1b774c/#%E4%BD%BF%E7%94%A8%E6%95%B0%E6%8D%AE%E5%BA%93%E8%BF%9E%E6%8E%A5%E6%B1%A0)ʹÓÃÊý¾Ý¿âÁ¬½Ó³Ø
+
+Spring ±¾Éí²¢Ã»ÓÐÌṩÊý¾Ý¿âÁ¬½Ó³ØµÄʵÏÖ£¬ÐèÒª×ÔÐÐÑ¡ÔñºÏÊʵÄÊý¾Ý¿âÁ¬½Ó³Ø¡£ÏÂÃæÊÇÒ»¸öʹÓà [Druid (opens new window)](https://github.com/alibaba/druid)×÷ΪÊý¾Ý¿âÁ¬½Ó³ØµÄʾÀý£º
+
+
+
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+
+
+#### [#](https://dunwu.github.io/spring-tutorial/pages/1b774c/#%E5%9F%BA%E4%BA%8E-jdbc-%E9%A9%B1%E5%8A%A8%E7%9A%84%E6%95%B0%E6%8D%AE%E6%BA%90)»ùÓÚ JDBC Çý¶¯µÄÊý¾ÝÔ´
+
+
+
+```
+
+
+
+
+
+
+```
+
+
+#### ʹÓÃJDBC
+
+×îºó¸üÐÂ: 2022/11/16 20:10 / ÔĶÁ: 946668
+
+* * *
+
+
+
+ÎÒÃÇÔÚÇ°Ãæ½éÉÜ[JDBC±à³Ì](https://www.liaoxuefeng.com/wiki/1252599548343744/1255943820274272)ʱÒѾ½²¹ý£¬Java³ÌÐòʹÓÃJDBC½Ó¿Ú·ÃÎʹØÏµÊý¾Ý¿âµÄʱºò£¬ÐèÒªÒÔϼ¸²½£º
+
+* ´´½¨È«¾Ö`DataSource`ʵÀý£¬±íʾÊý¾Ý¿âÁ¬½Ó³Ø£»
+* ÔÚÐèÒª¶ÁдÊý¾Ý¿âµÄ·½·¨ÄÚ²¿£¬°´Èçϲ½Öè·ÃÎÊÊý¾Ý¿â£º
+ * ´ÓÈ«¾Ö`DataSource`ʵÀý»ñÈ¡`Connection`ʵÀý£»
+ * ͨ¹ý`Connection`ʵÀý´´½¨`PreparedStatement`ʵÀý£»
+ * Ö´ÐÐSQLÓï¾ä£¬Èç¹ûÊDzéѯ£¬Ôòͨ¹ý`ResultSet`¶ÁÈ¡½á¹û¼¯£¬Èç¹ûÊÇÐ޸ģ¬Ôò»ñµÃ`int`½á¹û¡£
+
+ÕýÈ·±àдJDBC´úÂëµÄ¹Ø¼üÊÇʹÓÃ`try ... finally`ÊÍ·Å×ÊÔ´£¬Éæ¼°µ½ÊÂÎñµÄ´úÂëÐèÒªÕýÈ·Ìá½»»ò»Ø¹öÊÂÎñ¡£
+
+ÔÚSpringʹÓÃJDBC£¬Ê×ÏÈÎÒÃÇͨ¹ýIoCÈÝÆ÷´´½¨²¢¹ÜÀíÒ»¸ö`DataSource`ʵÀý£¬È»ºó£¬SpringÌṩÁËÒ»¸ö`JdbcTemplate`£¬¿ÉÒÔ·½±ãµØÈÃÎÒÃDzÙ×÷JDBC£¬Òò´Ë£¬Í¨³£Çé¿öÏ£¬ÎÒÃÇ»áʵÀý»¯Ò»¸ö`JdbcTemplate`¡£¹ËÃû˼Ò壬Õâ¸öÀàÖ÷ҪʹÓÃÁË[Templateģʽ](https://www.liaoxuefeng.com/wiki/1252599548343744/1281319636041762)¡£
+
+±àдʾÀý´úÂë»òÕß²âÊÔ´úÂëʱ£¬ÎÒÃÇÇ¿ÁÒÍÆ¼öʹÓÃ[HSQLDB](http://hsqldb.org/)Õâ¸öÊý¾Ý¿â£¬ËüÊÇÒ»¸öÓÃJava±àдµÄ¹ØÏµÊý¾Ý¿â£¬¿ÉÒÔÒÔÄÚ´æÄ£Ê½»òÕßÎļþģʽÔËÐУ¬±¾ÉíÖ»ÓÐÒ»¸öjar°ü£¬·Ç³£ÊʺÏÑÝʾ´úÂë»òÕß²âÊÔ´úÂë¡£
+
+ÎÒÃÇÒÔʵ¼Ê¹¤³ÌΪÀý£¬ÏÈ´´½¨Maven¹¤³Ì`spring-data-jdbc`£¬È»ºóÒýÈëÒÔÏÂÒÀÀµ£º
+
+* org.springframework:spring-context:6.0.0
+* org.springframework:spring-jdbc:6.0.0
+* jakarta.annotation:jakarta.annotation-api:2.1.1
+* com.zaxxer:HikariCP:5.0.1
+* org.hsqldb:hsqldb:2.7.1
+
+ÔÚ`AppConfig`ÖУ¬ÎÒÃÇÐèÒª´´½¨ÒÔϼ¸¸ö±ØÐëµÄBean£º
+
+```
+@Configuration
+@ComponentScan
+@PropertySource("jdbc.properties")
+public class AppConfig {
+
+ @Value("${jdbc.url}")
+ String jdbcUrl;
+
+ @Value("${jdbc.username}")
+ String jdbcUsername;
+
+ @Value("${jdbc.password}")
+ String jdbcPassword;
+
+ @Bean
+ DataSource createDataSource() {
+ HikariConfig config = new HikariConfig();
+ config.setJdbcUrl(jdbcUrl);
+ config.setUsername(jdbcUsername);
+ config.setPassword(jdbcPassword);
+ config.addDataSourceProperty("autoCommit", "true");
+ config.addDataSourceProperty("connectionTimeout", "5");
+ config.addDataSourceProperty("idleTimeout", "60");
+ return new HikariDataSource(config);
+ }
+
+ @Bean
+ JdbcTemplate createJdbcTemplate(@Autowired DataSource dataSource) {
+ return new JdbcTemplate(dataSource);
+ }
+}
+
+```
+
+ÔÚÉÏÊöÅäÖÃÖУº
+
+1. ͨ¹ý`@PropertySource("jdbc.properties")`¶ÁÈ¡Êý¾Ý¿âÅäÖÃÎļþ£»
+2. ͨ¹ý`@Value("${jdbc.url}")`×¢ÈëÅäÖÃÎļþµÄÏà¹ØÅäÖã»
+3. ´´½¨Ò»¸öDataSourceʵÀý£¬ËüµÄʵ¼ÊÀàÐÍÊÇ`HikariDataSource`£¬´´½¨Ê±ÐèÒªÓõ½×¢ÈëµÄÅäÖã»
+4. ´´½¨Ò»¸öJdbcTemplateʵÀý£¬ËüÐèҪעÈë`DataSource`£¬ÕâÊÇͨ¹ý·½·¨²ÎÊýÍê³É×¢ÈëµÄ¡£
+
+×îºó£¬Õë¶ÔHSQLDBдһ¸öÅäÖÃÎļþ`jdbc.properties`£º
+
+```
+# Êý¾Ý¿âÎļþÃûΪtestdb:
+jdbc.url=jdbc:hsqldb:file:testdb
+
+# HsqldbĬÈϵÄÓû§ÃûÊÇsa£¬¿ÚÁîÊÇ¿Õ×Ö·û´®:
+jdbc.username=sa
+jdbc.password=
+
+```
+
+¿ÉÒÔͨ¹ýHSQLDB×Ô´øµÄ¹¤¾ßÀ´³õʼ»¯Êý¾Ý¿â±í£¬ÕâÀïÎÒÃÇдһ¸öBean£¬ÔÚSpringÈÝÆ÷Æô¶¯Ê±×Ô¶¯´´½¨Ò»¸ö`users`±í£º
+
+```
+@Component
+public class DatabaseInitializer {
+ @Autowired
+ JdbcTemplate jdbcTemplate;
+
+ @PostConstruct
+ public void init() {
+ jdbcTemplate.update("CREATE TABLE IF NOT EXISTS users (" //
+ + "id BIGINT IDENTITY NOT NULL PRIMARY KEY, " //
+ + "email VARCHAR(100) NOT NULL, " //
+ + "password VARCHAR(100) NOT NULL, " //
+ + "name VARCHAR(100) NOT NULL, " //
+ + "UNIQUE (email))");
+ }
+}
+
+```
+
+ÏÖÔÚ£¬ËùÓÐ×¼±¸¹¤×÷¶¼ÒÑÍê±Ï¡£ÎÒÃÇÖ»ÐèÒªÔÚÐèÒª·ÃÎÊÊý¾Ý¿âµÄBeanÖУ¬×¢Èë`JdbcTemplate`¼´¿É£º
+
+```
+@Component
+public class UserService {
+ @Autowired
+ JdbcTemplate jdbcTemplate;
+ ...
+}
+
+```
+
+### JdbcTemplateÓ÷¨
+
+SpringÌṩµÄ`JdbcTemplate`²ÉÓÃTemplateģʽ£¬ÌṩÁËһϵÁÐÒԻص÷ÎªÌØµãµÄ¹¤¾ß·½·¨£¬Ä¿µÄÊDZÜÃâ·±ËöµÄ`try...catch`Óï¾ä¡£
+
+ÎÒÃÇÒÔ¾ßÌåµÄʾÀýÀ´ËµÃ÷JdbcTemplateµÄÓ÷¨¡£
+
+Ê×ÏÈÎÒÃÇ¿´`T execute(ConnectionCallback action)`·½·¨£¬ËüÌṩÁËJdbcµÄ`Connection`¹©ÎÒÃÇʹÓãº
+
+```
+public User getUserById(long id) {
+ // ×¢Òâ´«ÈëµÄÊÇConnectionCallback:
+ return jdbcTemplate.execute((Connection conn) -> {
+ // ¿ÉÒÔÖ±½ÓʹÓÃconnʵÀý£¬²»ÒªÊÍ·ÅËü£¬»Øµ÷½áÊøºóJdbcTemplate×Ô¶¯ÊÍ·Å:
+ // ÔÚÄÚ²¿ÊÖ¶¯´´½¨µÄPreparedStatement¡¢ResultSet±ØÐëÓÃtry(...)ÊÍ·Å:
+ try (var ps = conn.prepareStatement("SELECT * FROM users WHERE id = ?")) {
+ ps.setObject(1, id);
+ try (var rs = ps.executeQuery()) {
+ if (rs.next()) {
+ return new User( // new User object:
+ rs.getLong("id"), // id
+ rs.getString("email"), // email
+ rs.getString("password"), // password
+ rs.getString("name")); // name
+ }
+ throw new RuntimeException("user not found by id.");
+ }
+ }
+ });
+}
+
+```
+
+Ò²¾ÍÊÇ˵£¬ÉÏÊö»Øµ÷·½·¨ÔÊÐí»ñÈ¡Connection£¬È»ºó×öÈκλùÓÚConnectionµÄ²Ù×÷¡£
+
+ÎÒÃÇÔÙ¿´`T execute(String sql, PreparedStatementCallback action)`µÄÓ÷¨£º
+
+```
+public User getUserByName(String name) {
+ // ÐèÒª´«ÈëSQLÓï¾ä£¬ÒÔ¼°PreparedStatementCallback:
+ return jdbcTemplate.execute("SELECT * FROM users WHERE name = ?", (PreparedStatement ps) -> {
+ // PreparedStatementʵÀýÒѾÓÉJdbcTemplate´´½¨£¬²¢Ôڻص÷ºó×Ô¶¯ÊÍ·Å:
+ ps.setObject(1, name);
+ try (var rs = ps.executeQuery()) {
+ if (rs.next()) {
+ return new User( // new User object:
+ rs.getLong("id"), // id
+ rs.getString("email"), // email
+ rs.getString("password"), // password
+ rs.getString("name")); // name
+ }
+ throw new RuntimeException("user not found by id.");
+ }
+ });
+}
+
+```
+
+×îºó£¬ÎÒÃÇ¿´`T queryForObject(String sql, RowMapper rowMapper, Object... args)`·½·¨£º
+
+```
+public User getUserByEmail(String email) {
+ // ´«ÈëSQL£¬²ÎÊýºÍRowMapperʵÀý:
+ return jdbcTemplate.queryForObject("SELECT * FROM users WHERE email = ?",
+ (ResultSet rs, int rowNum) -> {
+ // ½«ResultSetµÄµ±Ç°ÐÐÓ³ÉäΪһ¸öJavaBean:
+ return new User( // new User object:
+ rs.getLong("id"), // id
+ rs.getString("email"), // email
+ rs.getString("password"), // password
+ rs.getString("name")); // name
+ },
+ email);
+}
+
+```
+
+ÔÚ`queryForObject()`·½·¨ÖУ¬´«ÈëSQLÒÔ¼°SQL²ÎÊýºó£¬`JdbcTemplate`»á×Ô¶¯´´½¨`PreparedStatement`£¬×Ô¶¯Ö´Ðвéѯ²¢·µ»Ø`ResultSet`£¬ÎÒÃÇÌṩµÄ`RowMapper`ÐèÒª×öµÄÊÂÇé¾ÍÊǰÑ`ResultSet`µÄµ±Ç°ÐÐÓ³Éä³ÉÒ»¸öJavaBean²¢·µ»Ø¡£Õû¸ö¹ý³ÌÖУ¬Ê¹ÓÃ`Connection`¡¢`PreparedStatement`ºÍ`ResultSet`¶¼²»ÐèÒªÎÒÃÇÊÖ¶¯¹ÜÀí¡£
+
+`RowMapper`²»Ò»¶¨·µ»ØJavaBean£¬Êµ¼ÊÉÏËü¿ÉÒÔ·µ»ØÈκÎJava¶ÔÏó¡£ÀýÈ磬ʹÓÃ`SELECT COUNT(*)`²éѯʱ£¬¿ÉÒÔ·µ»Ø`Long`£º
+
+```
+public long getUsers() {
+ return jdbcTemplate.queryForObject("SELECT COUNT(*) FROM users", (ResultSet rs, int rowNum) -> {
+ // SELECT COUNT(*)²éѯֻÓÐÒ»ÁУ¬È¡µÚÒ»ÁÐÊý¾Ý:
+ return rs.getLong(1);
+ });
+}
+
+```
+
+Èç¹ûÎÒÃÇÆÚÍû·µ»Ø¶àÐмǼ£¬¶ø²»ÊÇÒ»ÐУ¬¿ÉÒÔÓÃ`query()`·½·¨£º
+
+```
+public List getUsers(int pageIndex) {
+ int limit = 100;
+ int offset = limit * (pageIndex - 1);
+ return jdbcTemplate.query("SELECT * FROM users LIMIT ? OFFSET ?",
+ new BeanPropertyRowMapper<>(User.class),
+ limit, offset);
+}
+
+```
+
+ÉÏÊö`query()`·½·¨´«ÈëµÄ²ÎÊýÈÔÈ»ÊÇSQL¡¢SQL²ÎÊýÒÔ¼°`RowMapper`ʵÀý¡£ÕâÀïÎÒÃÇÖ±½ÓʹÓÃSpringÌṩµÄ`BeanPropertyRowMapper`¡£Èç¹ûÊý¾Ý¿â±íµÄ½á¹¹Ç¡ºÃºÍJavaBeanµÄÊôÐÔÃû³ÆÒ»Ö£¬ÄÇô`BeanPropertyRowMapper`¾Í¿ÉÒÔÖ±½Ó°ÑÒ»ÐмǼ°´ÁÐÃûת»»ÎªJavaBean¡£
+
+Èç¹ûÎÒÃÇÖ´ÐеIJ»ÊDzéѯ£¬¶øÊDzåÈë¡¢¸üкÍɾ³ý²Ù×÷£¬ÄÇôÐèҪʹÓÃ`update()`·½·¨£º
+
+```
+public void updateUser(User user) {
+ // ´«ÈëSQL£¬SQL²ÎÊý£¬·µ»Ø¸üеÄÐÐÊý:
+ if (1 != jdbcTemplate.update("UPDATE users SET name = ? WHERE id = ?", user.getName(), user.getId())) {
+ throw new RuntimeException("User not found by id");
+ }
+}
+
+```
+
+Ö»ÓÐÒ»ÖÖ`INSERT`²Ù×÷±È½ÏÌØÊ⣬ÄǾÍÊÇÈç¹ûijһÁÐÊÇ×ÔÔöÁУ¨ÀýÈç×ÔÔöÖ÷¼ü£©£¬Í¨³££¬ÎÒÃÇÐèÒª»ñÈ¡²åÈëºóµÄ×ÔÔöÖµ¡£`JdbcTemplate`ÌṩÁËÒ»¸ö`KeyHolder`À´¼ò»¯ÕâÒ»²Ù×÷£º
+
+```
+public User register(String email, String password, String name) {
+ // ´´½¨Ò»¸öKeyHolder:
+ KeyHolder holder = new GeneratedKeyHolder();
+ if (1 != jdbcTemplate.update(
+ // ²ÎÊý1:PreparedStatementCreator
+ (conn) -> {
+ // ´´½¨PreparedStatementʱ£¬±ØÐëÖ¸¶¨RETURN_GENERATED_KEYS:
+ var ps = conn.prepareStatement("INSERT INTO users(email, password, name) VALUES(?, ?, ?)",
+ Statement.RETURN_GENERATED_KEYS);
+ ps.setObject(1, email);
+ ps.setObject(2, password);
+ ps.setObject(3, name);
+ return ps;
+ },
+ // ²ÎÊý2:KeyHolder
+ holder)
+ ) {
+ throw new RuntimeException("Insert failed.");
+ }
+ // ´ÓKeyHolderÖлñÈ¡·µ»ØµÄ×ÔÔöÖµ:
+ return new User(holder.getKey().longValue(), email, password, name);
+}
+
+```
+
+`JdbcTemplate`»¹ÓÐÐí¶àÖØÔØ·½·¨£¬ÕâÀïÎÒÃDz»Ò»Ò»½éÉÜ¡£ÐèҪǿµ÷µÄÊÇ£¬`JdbcTemplate`Ö»ÊǶÔJDBC²Ù×÷µÄÒ»¸ö¼òµ¥·â×°£¬ËüµÄÄ¿µÄÊǾ¡Á¿¼õÉÙÊÖ¶¯±àд`try(resource) {...}`µÄ´úÂ룬¶ÔÓÚ²éѯ£¬Ö÷Ҫͨ¹ý`RowMapper`ʵÏÖÁËJDBC½á¹û¼¯µ½Java¶ÔÏóµÄת»»¡£
+
+ÎÒÃÇ×ܽáÒ»ÏÂ`JdbcTemplate`µÄÓ÷¨£¬ÄǾÍÊÇ£º
+
+* Õë¶Ô¼òµ¥²éѯ£¬ÓÅÑ¡`query()`ºÍ`queryForObject()`£¬ÒòΪֻÐèÌṩSQLÓï¾ä¡¢²ÎÊýºÍ`RowMapper`£»
+* Õë¶Ô¸üвÙ×÷£¬ÓÅÑ¡`update()`£¬ÒòΪֻÐèÌṩSQLÓï¾äºÍ²ÎÊý£»
+* Èκθ´ÔӵIJÙ×÷£¬×îÖÕÒ²¿ÉÒÔͨ¹ý`execute(ConnectionCallback)`ʵÏÖ£¬ÒòΪÄõ½`Connection`¾Í¿ÉÒÔ×öÈκÎJDBC²Ù×÷¡£
+
+ʵ¼ÊÉÏÎÒÃÇʹÓÃ×î¶àµÄÈÔÈ»ÊǸ÷ÖÖ²éѯ¡£Èç¹ûÔÚÉè¼Æ±í½á¹¹µÄʱºò£¬Äܹ»ºÍJavaBeanµÄÊôÐÔÒ»Ò»¶ÔÓ¦£¬ÄÇôֱ½ÓʹÓÃ`BeanPropertyRowMapper`¾ÍºÜ·½±ã¡£Èç¹û±í½á¹¹ºÍJavaBean²»Ò»ÖÂÔõô°ì£¿ÄǾÍÐèÒªÉÔ΢¸Äдһϲéѯ£¬Ê¹½á¹û¼¯µÄ½á¹¹ºÍJavaBean±£³ÖÒ»Ö¡£
+
+ÀýÈ磬±íµÄÁÐÃûÊÇ`office_address`£¬¶øJavaBeanÊôÐÔÊÇ`workAddress`£¬¾ÍÐèÒªÖ¸¶¨±ðÃû£¬¸Äд²éѯÈçÏ£º
+
+```
+SELECT id, email, office_address AS workAddress, name FROM users WHERE email = ?
+```
+
+ʹÓÃ`JdbcTemplate`µÄʱºò£¬ÎÒÃÇÓõÃ×î¶àµÄ·½·¨¾ÍÊÇ`List query(String, RowMapper, Object...)`¡£Õâ¸ö`RowMapper`µÄ×÷ÓþÍÊǰÑ`ResultSet`µÄÒ»ÐмǼӳÉäΪJava Bean¡£
+
+ÕâÖְѹØÏµÊý¾Ý¿âµÄ±í¼Ç¼ӳÉäΪJava¶ÔÏóµÄ¹ý³Ì¾ÍÊÇORM£ºObject-Relational Mapping¡£ORM¼È¿ÉÒ԰ѼǼת»»³ÉJava¶ÔÏó£¬Ò²¿ÉÒÔ°ÑJava¶ÔÏóת»»ÎªÐмǼ¡£
+
+ʹÓÃ`JdbcTemplate`ÅäºÏ`RowMapper`¿ÉÒÔ¿´×÷ÊÇ×îÔʼµÄORM¡£Èç¹ûҪʵÏÖ¸ü×Ô¶¯»¯µÄORM£¬¿ÉÒÔÑ¡Ôñ³ÉÊìµÄORM¿ò¼Ü£¬ÀýÈç[Hibernate](https://hibernate.org/)¡£
+
+ÎÒÃÇÀ´¿´¿´ÈçºÎÔÚSpringÖм¯³ÉHibernate¡£
+
+Hibernate×÷ΪORM¿ò¼Ü£¬Ëü¿ÉÒÔÌæ´ú`JdbcTemplate`£¬µ«HibernateÈÔÈ»ÐèÒªJDBCÇý¶¯£¬ËùÒÔ£¬ÎÒÃÇÐèÒªÒýÈëJDBCÇý¶¯¡¢Á¬½Ó³Ø£¬ÒÔ¼°Hibernate±¾Éí¡£ÔÚMavenÖУ¬ÎÒÃǼÓÈëÒÔÏÂÒÀÀµÏ
+
+* org.springframework:spring-context:6.0.0
+* org.springframework:spring-orm:6.0.0
+* jakarta.annotation:jakarta.annotation-api:2.1.1
+* jakarta.persistence:jakarta.persistence-api:3.1.0
+* org.hibernate:hibernate-core:6.1.4.Final
+* com.zaxxer:HikariCP:5.0.1
+* org.hsqldb:hsqldb:2.7.1
+
+ÔÚ`AppConfig`ÖУ¬ÎÒÃÇÈÔÈ»ÐèÒª´´½¨`DataSource`¡¢ÒýÈëJDBCÅäÖÃÎļþ£¬ÒÔ¼°ÆôÓÃÉùÃ÷ʽÊÂÎñ£º
+
+```
+@Configuration
+@ComponentScan
+@EnableTransactionManagement
+@PropertySource("jdbc.properties")
+public class AppConfig {
+ @Bean
+ DataSource createDataSource() {
+ ...
+ }
+}
+
+```
+
+ΪÁËÆôÓÃHibernate£¬ÎÒÃÇÐèÒª´´½¨Ò»¸ö`LocalSessionFactoryBean`£º
+
+```
+public class AppConfig {
+ @Bean
+ LocalSessionFactoryBean createSessionFactory(@Autowired DataSource dataSource) {
+ var props = new Properties();
+ props.setProperty("hibernate.hbm2ddl.auto", "update"); // Éú²ú»·¾³²»ÒªÊ¹ÓÃ
+ props.setProperty("hibernate.dialect", "org.hibernate.dialect.HSQLDialect");
+ props.setProperty("hibernate.show_sql", "true");
+ var sessionFactoryBean = new LocalSessionFactoryBean();
+ sessionFactoryBean.setDataSource(dataSource);
+ // ɨÃèÖ¸¶¨µÄpackage»ñÈ¡ËùÓÐentity class:
+ sessionFactoryBean.setPackagesToScan("com.itranswarp.learnjava.entity");
+ sessionFactoryBean.setHibernateProperties(props);
+ return sessionFactoryBean;
+ }
+}
+
+```
+
+×¢ÒâÎÒÃÇÔÚ[¶¨ÖÆBean](https://www.liaoxuefeng.com/wiki/1252599548343744/1308043627200545)Öн²µ½¹ý`FactoryBean`£¬`LocalSessionFactoryBean`ÊÇÒ»¸ö`FactoryBean`£¬Ëü»áÔÙ×Ô¶¯´´½¨Ò»¸ö`SessionFactory`£¬ÔÚHibernateÖУ¬`Session`ÊÇ·â×°ÁËÒ»¸öJDBC `Connection`µÄʵÀý£¬¶ø`SessionFactory`ÊÇ·â×°ÁËJDBC `DataSource`µÄʵÀý£¬¼´`SessionFactory`³ÖÓÐÁ¬½Ó³Ø£¬Ã¿´ÎÐèÒª²Ù×÷Êý¾Ý¿âµÄʱºò£¬`SessionFactory`´´½¨Ò»¸öеÄ`Session`£¬Ï൱ÓÚ´ÓÁ¬½Ó³Ø»ñÈ¡µ½Ò»¸öеÄ`Connection`¡£`SessionFactory`¾ÍÊÇHibernateÌṩµÄ×îºËÐĵÄÒ»¸ö¶ÔÏ󣬵«`LocalSessionFactoryBean`ÊÇSpringÌṩµÄΪÁËÈÃÎÒÃÇ·½±ã´´½¨`SessionFactory`µÄÀà¡£
+
+×¢Òâµ½ÉÏÃæ´´½¨`LocalSessionFactoryBean`µÄ´úÂ룬Ê×ÏÈÓÃ`Properties`³ÖÓÐHibernate³õʼ»¯`SessionFactory`ʱÓõ½µÄËùÓÐÉèÖ㬳£ÓõÄÉèÖÃÇë²Î¿¼[HibernateÎĵµ](https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#configurations)£¬ÕâÀïÎÒÃÇÖ»¶¨ÒåÁË3¸öÉèÖãº
+
+* `hibernate.hbm2ddl.auto=update`£º±íʾ×Ô¶¯´´½¨Êý¾Ý¿âµÄ±í½á¹¹£¬×¢Òâ²»ÒªÔÚÉú²ú»·¾³ÖÐÆôÓã»
+* `hibernate.dialect=org.hibernate.dialect.HSQLDialect`£ºÖ¸Ê¾HibernateʹÓõÄÊý¾Ý¿âÊÇHSQLDB¡£HibernateʹÓÃÒ»ÖÖHQLµÄ²éѯÓï¾ä£¬ËüºÍSQLÀàËÆ£¬µ«ÕæÕýÔÚ¡°·Ò롱³ÉSQLʱ£¬»á¸ù¾ÝÉ趨µÄÊý¾Ý¿â¡°·½ÑÔ¡±À´Éú³ÉÕë¶ÔÊý¾Ý¿âÓÅ»¯µÄSQL£»
+* `hibernate.show_sql=true`£ºÈÃHibernate´òÓ¡Ö´ÐеÄSQL£¬Õâ¶ÔÓÚµ÷ÊԷdz£ÓÐÓã¬ÎÒÃÇ¿ÉÒÔ·½±ãµØ¿´µ½HibernateÉú³ÉµÄSQLÓï¾äÊÇ·ñ·ûºÏÎÒÃǵÄÔ¤ÆÚ¡£
+
+³ýÁËÉèÖÃ`DataSource`ºÍ`Properties`Ö®Í⣬עÒâµ½`setPackagesToScan()`ÎÒÃÇ´«ÈëÁËÒ»¸ö`package`Ãû³Æ£¬ËüָʾHibernateɨÃèÕâ¸ö°üÏÂÃæµÄËùÓÐJavaÀ࣬×Ô¶¯ÕÒ³öÄÜÓ³ÉäΪÊý¾Ý¿â±í¼Ç¼µÄJavaBean¡£ºóÃæÎÒÃÇ»á×ÐϸÌÖÂÛÈçºÎ±àд·ûºÏHibernateÒªÇóµÄJavaBean¡£
+
+½ô½Ó×Å£¬ÎÒÃÇ»¹ÐèÒª´´½¨`HibernateTransactionManager`£º
+
+```
+public class AppConfig {
+ @Bean
+ PlatformTransactionManager createTxManager(@Autowired SessionFactory sessionFactory) {
+ return new HibernateTransactionManager(sessionFactory);
+ }
+}
+
+```
+
+`HibernateTransactionManager`ÊÇÅäºÏHibernateʹÓÃÉùÃ÷ʽÊÂÎñËù±ØÐëµÄ¡£µ½´ËΪֹ£¬ËùÓеÄÅäÖö¼¶¨ÒåÍê±Ï£¬ÎÒÃÇÀ´¿´¿´ÈçºÎ½«Êý¾Ý¿â±í½á¹¹Ó³ÉäΪJava¶ÔÏó¡£
+
+¿¼²ìÈçϵÄÊý¾Ý¿â±í£º
+
+```
+CREATE TABLE user
+ id BIGINT NOT NULL AUTO_INCREMENT,
+ email VARCHAR(100) NOT NULL,
+ password VARCHAR(100) NOT NULL,
+ name VARCHAR(100) NOT NULL,
+ createdAt BIGINT NOT NULL,
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `email` (`email`)
+);
+
+```
+
+ÆäÖУ¬`id`ÊÇ×ÔÔöÖ÷¼ü£¬`email`¡¢`password`¡¢`name`ÊÇ`VARCHAR`ÀàÐÍ£¬`email`´øÎ¨Ò»Ë÷ÒýÒÔÈ·±£Î¨Ò»ÐÔ£¬`createdAt`´æ´¢ÕûÐÍÀàÐ͵Äʱ¼ä´Á¡£ÓÃJavaBean±íʾÈçÏ£º
+
+```
+public class User {
+ private Long id;
+ private String email;
+ private String password;
+ private String name;
+ private Long createdAt;
+
+ // getters and setters
+ ...
+}
+
+```
+
+ÕâÖÖÓ³Éä¹ØÏµÊ®·ÖÒ×¶®£¬µ«ÎÒÃÇÐèÒªÌí¼ÓһЩע½âÀ´¸æËßHibernateÈçºÎ°Ñ`User`ÀàÓ³Éäµ½±í¼Ç¼£º
+
+```
+@Entity
+public class User {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(nullable = false, updatable = false)
+ public Long getId() { ... }
+
+ @Column(nullable = false, unique = true, length = 100)
+ public String getEmail() { ... }
+
+ @Column(nullable = false, length = 100)
+ public String getPassword() { ... }
+
+ @Column(nullable = false, length = 100)
+ public String getName() { ... }
+
+ @Column(nullable = false, updatable = false)
+ public Long getCreatedAt() { ... }
+}
+
+```
+
+Èç¹ûÒ»¸öJavaBean±»ÓÃÓÚÓ³É䣬ÎÒÃǾͱê¼ÇÒ»¸ö`@Entity`¡£Ä¬ÈÏÇé¿öÏ£¬Ó³ÉäµÄ±íÃûÊÇ`user`£¬Èç¹ûʵ¼ÊµÄ±íÃû²»Í¬£¬ÀýÈçʵ¼Ê±íÃûÊÇ`users`£¬¿ÉÒÔ×·¼ÓÒ»¸ö`@Table(name="users")`±íʾ£º
+
+```
+@Entity
+@Table(name="users)
+public class User {
+ ...
+}
+
+```
+
+ÿ¸öÊôÐÔµ½Êý¾Ý¿âÁеÄÓ³ÉäÓÃ`@Column()`±êʶ£¬`nullable`ָʾÁÐÊÇ·ñÔÊÐíΪ`NULL`£¬`updatable`ָʾ¸ÃÁÐÊÇ·ñÔÊÐí±»ÓÃÔÚ`UPDATE`Óï¾ä£¬`length`ָʾ`String`ÀàÐ͵ÄÁеij¤¶È£¨Èç¹ûûÓÐÖ¸¶¨£¬Ä¬ÈÏÊÇ`255`£©¡£
+
+¶ÔÓÚÖ÷¼ü£¬»¹ÐèÒªÓÃ`@Id`±êʶ£¬×ÔÔöÖ÷¼üÔÙ×·¼ÓÒ»¸ö`@GeneratedValue`£¬ÒÔ±ãHibernateÄܶÁÈ¡µ½×ÔÔöÖ÷¼üµÄÖµ¡£
+
+ϸÐĵÄͯЬ¿ÉÄÜ»¹×¢Òâµ½£¬Ö÷¼ü`id`¶¨ÒåµÄÀàÐͲ»ÊÇ`long`£¬¶øÊÇ`Long`¡£ÕâÊÇÒòΪHibernateÈç¹û¼ì²âµ½Ö÷¼üΪ`null`£¬¾Í²»»áÔÚ`INSERT`Óï¾äÖÐÖ¸¶¨Ö÷¼üµÄÖµ£¬¶øÊÇ·µ»ØÓÉÊý¾Ý¿âÉú³ÉµÄ×ÔÔöÖµ£¬·ñÔò£¬HibernateÈÏΪÎÒÃǵijÌÐòÖ¸¶¨ÁËÖ÷¼üµÄÖµ£¬»áÔÚ`INSERT`Óï¾äÖÐÖ±½ÓÁгö¡£`long`ÐÍ×Ö¶Î×ÜÊǾßÓÐĬÈÏÖµ`0`£¬Òò´Ë£¬Ã¿´Î²åÈëµÄÖ÷¼üÖµ×ÜÊÇ0£¬µ¼Ö³ýµÚÒ»´ÎÍâºóÐø²åÈë¶¼½«Ê§°Ü¡£
+
+`createdAt`ËäÈ»ÊÇÕûÐÍ£¬µ«ÎÒÃDz¢Ã»ÓÐʹÓÃ`long`£¬¶øÊÇ`Long`£¬ÕâÊÇÒòΪʹÓûù±¾ÀàÐͻᵼÖÂfindByExample²éѯ»áÌí¼ÓÒâÍâµÄÌõ¼þ£¬ÕâÀïÖ»ÐèÀμǣ¬×÷ΪӳÉäʹÓõÄJavaBean£¬ËùÓÐÊôÐÔ¶¼Ê¹Óðü×°ÀàÐͶø²»ÊÇ»ù±¾ÀàÐÍ¡£
+
+ʹÓÃHibernateʱ£¬²»ÒªÊ¹Óûù±¾ÀàÐ͵ÄÊôÐÔ£¬×ÜÊÇʹÓðü×°ÀàÐÍ£¬ÈçLong»òInteger¡£
+
+ÀàËÆµÄ£¬ÎÒÃÇÔÙ¶¨ÒåÒ»¸ö`Book`Àࣺ
+
+```
+@Entity
+public class Book {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(nullable = false, updatable = false)
+ public Long getId() { ... }
+
+ @Column(nullable = false, length = 100)
+ public String getTitle() { ... }
+
+ @Column(nullable = false, updatable = false)
+ public Long getCreatedAt() { ... }
+}
+
+```
+
+Èç¹û×Ðϸ¹Û²ì`User`ºÍ`Book`£¬»á·¢ÏÖËüÃǶ¨ÒåµÄ`id`¡¢`createdAt`ÊôÐÔÊÇÒ»ÑùµÄ£¬ÕâÔÚÊý¾Ý¿â±í½á¹¹µÄÉè¼ÆÖкܳ£¼û£º¶ÔÓÚÿ¸ö±í£¬Í¨³£ÎÒÃÇ»áͳһʹÓÃÒ»ÖÖÖ÷¼üÉú³É»úÖÆ£¬²¢Ìí¼Ó`createdAt`±íʾ´´½¨Ê±¼ä£¬`updatedAt`±íʾÐÞ¸Äʱ¼äµÈͨÓÃ×ֶΡ£
+
+²»±ØÔÚ`User`ºÍ`Book`ÖÐÖØ¸´¶¨ÒåÕâЩͨÓÃ×ֶΣ¬ÎÒÃÇ¿ÉÒÔ°ÑËüÃÇÌáµ½Ò»¸ö³éÏóÀàÖУº
+
+```
+@MappedSuperclass
+public abstract class AbstractEntity {
+
+ private Long id;
+ private Long createdAt;
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(nullable = false, updatable = false)
+ public Long getId() { ... }
+
+ @Column(nullable = false, updatable = false)
+ public Long getCreatedAt() { ... }
+
+ @Transient
+ public ZonedDateTime getCreatedDateTime() {
+ return Instant.ofEpochMilli(this.createdAt).atZone(ZoneId.systemDefault());
+ }
+
+ @PrePersist
+ public void preInsert() {
+ setCreatedAt(System.currentTimeMillis());
+ }
+}
+
+```
+
+¶ÔÓÚ`AbstractEntity`À´Ëµ£¬ÎÒÃÇÒª±ê×¢Ò»¸ö`@MappedSuperclass`±íʾËüÓÃÓڼ̳С£´ËÍ⣬עÒâµ½ÎÒÃǶ¨ÒåÁËÒ»¸ö`@Transient`·½·¨£¬Ëü·µ»ØÒ»¸ö¡°ÐéÄ⡱µÄÊôÐÔ¡£ÒòΪ`getCreatedDateTime()`ÊǼÆËãµÃ³öµÄÊôÐÔ£¬¶ø²»ÊÇ´ÓÊý¾Ý¿â±í¶Á³öµÄÖµ£¬Òò´Ë±ØÐëÒª±ê×¢`@Transient`£¬·ñÔòHibernate»á³¢ÊÔ´ÓÊý¾Ý¿â¶ÁÈ¡ÃûΪ`createdDateTime`Õâ¸ö²»´æÔÚµÄ×ֶδӶø³ö´í¡£
+
+ÔÙ×¢Òâµ½`@PrePersist`±êʶµÄ·½·¨£¬Ëü±íʾÔÚÎÒÃǽ«Ò»¸öJavaBean³Ö¾Ã»¯µ½Êý¾Ý¿â֮ǰ£¨¼´Ö´ÐÐINSERTÓï¾ä£©£¬Hibernate»áÏÈÖ´Ðи÷½·¨£¬ÕâÑùÎÒÃǾͿÉÒÔ×Ô¶¯ÉèÖúÃ`createdAt`ÊôÐÔ¡£
+
+ÓÐÁË`AbstractEntity`£¬ÎÒÃǾͿÉÒÔ´ó·ù¼ò»¯`User`ºÍ`Book`£º
+
+```
+@Entity
+public class User extends AbstractEntity {
+
+ @Column(nullable = false, unique = true, length = 100)
+ public String getEmail() { ... }
+
+ @Column(nullable = false, length = 100)
+ public String getPassword() { ... }
+
+ @Column(nullable = false, length = 100)
+ public String getName() { ... }
+}
+
+```
+
+×¢Ò⵽ʹÓõÄËùÓÐ×¢½â¾ùÀ´×Ô`jakarta.persistence`£¬ËüÊÇJPA¹æ·¶µÄÒ»²¿·Ö¡£ÕâÀïÎÒÃÇÖ»½éÉÜʹÓÃ×¢½âµÄ·½Ê½ÅäÖÃHibernateÓ³Éä¹ØÏµ£¬²»ÔÙ½éÉÜ´«Í³µÄ±È½Ï·±ËöµÄXMLÅäÖá£Í¨¹ýSpring¼¯³ÉHibernateʱ£¬Ò²²»ÔÙÐèÒª`hibernate.cfg.xml`ÅäÖÃÎļþ£¬ÓÃÒ»¾ä»°×ܽ᣺
+
+ʹÓÃSpring¼¯³ÉHibernate£¬ÅäºÏJPA×¢½â£¬ÎÞÐèÈκζîÍâµÄXMLÅäÖá£
+
+ÀàËÆ`User`¡¢`Book`ÕâÑùµÄÓÃÓÚORMµÄJava Bean£¬ÎÒÃÇͨ³£³ÆÖ®ÎªEntity Bean¡£
+
+×îºó£¬ÎÒÃÇÀ´¿´¿´Èç¹û¶Ô`user`±í½øÐÐÔöɾ¸Ä²é¡£ÒòΪʹÓÃÁËHibernate£¬Òò´Ë£¬ÎÒÃÇÒª×öµÄ£¬Êµ¼ÊÉÏÊǶÔ`User`Õâ¸öJavaBean½øÐС°Ôöɾ¸Ä²é¡±¡£ÎÒÃDZàдһ¸ö`UserService`£¬×¢Èë`SessionFactory`£º
+
+```
+@Component
+@Transactional
+public class UserService {
+ @Autowired
+ SessionFactory sessionFactory;
+}
+
+```
+
+### Insert²Ù×÷
+
+Òª³Ö¾Ã»¯Ò»¸ö`User`ʵÀý£¬ÎÒÃÇÖ»Ðèµ÷ÓÃ`persist()`·½·¨¡£ÒÔ`register()`·½·¨ÎªÀý£¬´úÂëÈçÏ£º
+
+```
+public User register(String email, String password, String name) {
+ // ´´½¨Ò»¸öUser¶ÔÏó:
+ User user = new User();
+ // ÉèÖúø÷¸öÊôÐÔ:
+ user.setEmail(email);
+ user.setPassword(password);
+ user.setName(name);
+ // ²»ÒªÉèÖÃid£¬ÒòΪʹÓÃÁË×ÔÔöÖ÷¼ü
+ // ±£´æµ½Êý¾Ý¿â:
+ sessionFactory.getCurrentSession().persist(user);
+ // ÏÖÔÚÒѾ×Ô¶¯»ñµÃÁËid:
+ System.out.println(user.getId());
+ return user;
+}
+
+```
+
+### Delete²Ù×÷
+
+ɾ³ýÒ»¸ö`User`Ï൱ÓÚ´Ó±íÖÐɾ³ý¶ÔÓ¦µÄ¼Ç¼¡£×¢ÒâHibernate×ÜÊÇÓÃ`id`À´É¾³ý¼Ç¼£¬Òò´Ë£¬ÒªÕýÈ·ÉèÖÃ`User`µÄ`id`ÊôÐÔ²ÅÄÜÕý³£É¾³ý¼Ç¼£º
+
+```
+public boolean deleteUser(Long id) {
+ User user = sessionFactory.getCurrentSession().byId(User.class).load(id);
+ if (user != null) {
+ sessionFactory.getCurrentSession().remove(user);
+ return true;
+ }
+ return false;
+}
+
+```
+
+ͨ¹ýÖ÷¼üɾ³ý¼Ç¼ʱ£¬Ò»¸ö³£¼ûµÄÓ÷¨ÊÇÏȸù¾ÝÖ÷¼ü¼ÓÔØ¸Ã¼Ç¼£¬ÔÙɾ³ý¡£×¢Òâµ½µ±¼Ç¼²»´æÔÚʱ£¬`load()`·µ»Ø`null`¡£
+
+### Update²Ù×÷
+
+¸üмǼÏ൱ÓÚÏȸüÐÂ`User`µÄÖ¸¶¨ÊôÐÔ£¬È»ºóµ÷ÓÃ`merge()`·½·¨£º
+
+```
+public void updateUser(Long id, String name) {
+ User user = sessionFactory.getCurrentSession().byId(User.class).load(id);
+ user.setName(name);
+ sessionFactory.getCurrentSession().merge(user);
+}
+
+```
+
+Ç°ÃæÎÒÃÇÔÚ¶¨Òå`User`ʱ£¬¶ÔÓеÄÊôÐÔ±ê×¢ÁË`@Column(updatable=false)`¡£HibernateÔÚ¸üмǼʱ£¬ËüÖ»»á°Ñ`@Column(updatable=true)`µÄÊôÐÔ¼ÓÈëµ½`UPDATE`Óï¾äÖУ¬ÕâÑù¿ÉÒÔÌṩһ²ã¶îÍâµÄ°²È«ÐÔ£¬¼´Èç¹û²»Ð¡ÐÄÐÞ¸ÄÁË`User`µÄ`email`¡¢`createdAt`µÈÊôÐÔ£¬Ö´ÐÐ`update()`ʱ²¢²»»á¸üжÔÓ¦µÄÊý¾Ý¿âÁС£µ«Ò²±ØÐëÀμǣºÕâ¸ö¹¦ÄÜÊÇHibernateÌṩµÄ£¬Èç¹ûÈÆ¹ýHibernateÖ±½Óͨ¹ýJDBCÖ´ÐÐ`UPDATE`Óï¾äÈÔÈ»¿ÉÒÔ¸üÐÂÊý¾Ý¿âµÄÈÎÒâÁеÄÖµ¡£
+
+×îºó£¬ÎÒÃDZàдµÄ´ó²¿·Ö·½·¨¶¼ÊǸ÷ÖÖ¸÷ÑùµÄ²éѯ¡£¸ù¾Ý`id`²éѯÎÒÃÇ¿ÉÒÔÖ±½Óµ÷ÓÃ`load()`£¬Èç¹ûҪʹÓÃÌõ¼þ²éѯ£¬ÀýÈ磬¼ÙÉèÎÒÃÇÏëÖ´ÐÐÒÔϲéѯ£º
+
+```
+SELECT * FROM user WHERE email = ? AND password = ?
+
+```
+
+ÎÒÃÇÀ´¿´¿´¿ÉÒÔʹÓÃʲô²éѯ¡£
+
+### ʹÓÃHQL²éѯ
+
+Ò»ÖÖ³£ÓõIJéѯÊÇÖ±½Ó±àдHibernateÄÚÖõÄHQL²éѯ£º
+
+```
+List list = sessionFactory.getCurrentSession()
+ .createQuery("from User u where u.email = ?1 and u.password = ?2", User.class)
+ .setParameter(1, email).setParameter(2, password)
+ .list();
+
+```
+
+ºÍSQLÏà±È£¬HQLʹÓÃÀàÃûºÍÊôÐÔÃû£¬ÓÉHibernate×Ô¶¯×ª»»ÎªÊµ¼ÊµÄ±íÃûºÍÁÐÃû¡£ÏêϸµÄHQLÓï·¨¿ÉÒԲο¼[HibernateÎĵµ](https://docs.jboss.org/hibernate/orm/6.1/userguide/html_single/Hibernate_User_Guide.html#query-language)¡£
+
+³ýÁË¿ÉÒÔÖ±½Ó´«ÈëHQL×Ö·û´®Í⣬Hibernate»¹¿ÉÒÔʹÓÃÒ»ÖÖ`NamedQuery`£¬Ëü¸ø²éѯÆð¸öÃû×Ö£¬È»ºó±£´æÔÚ×¢½âÖС£Ê¹ÓÃ`NamedQuery`ʱ£¬ÎÒÃÇÒªÏÈÔÚ`User`Àà±ê×¢£º
+
+```
+@NamedQueries(
+ @NamedQuery(
+ // ²éѯÃû³Æ:
+ name = "login",
+ // ²éѯÓï¾ä:
+ query = "SELECT u FROM User u WHERE u.email = :e AND u.password = :pwd"
+ )
+)
+@Entity
+public class User extends AbstractEntity {
+ ...
+}
+
+```
+
+×¢Òâµ½ÒýÈëµÄ`NamedQuery`ÊÇ`jakarta.persistence.NamedQuery`£¬ËüºÍÖ±½Ó´«ÈëHQLÓе㲻ͬµÄÊÇ£¬Õ¼Î»·ûʹÓÃ`:e`ºÍ`:pwd`¡£
+
+ʹÓÃ`NamedQuery`Ö»ÐèÒªÒýÈë²éѯÃûºÍ²ÎÊý£º
+
+```
+public User login(String email, String password) {
+ List list = sessionFactory.getCurrentSession()
+ .createNamedQuery("login", User.class) // ´´½¨NamedQuery
+ .setParameter("e", email) // °ó¶¨e²ÎÊý
+ .setParameter("pwd", password) // °ó¶¨pwd²ÎÊý
+ .list();
+ return list.isEmpty() ? null : list.get(0);
+}
+
+```
+
+Ö±½ÓдHQLºÍʹÓÃ`NamedQuery`¸÷ÓÐÓÅÁÓ¡£Ç°Õß¿ÉÒÔÔÚ´úÂëÖÐÖ±¹ÛµØ¿´µ½²éѯÓï¾ä£¬ºóÕß¿ÉÒÔÔÚ`User`Ààͳһ¹ÜÀíËùÓÐÏà¹Ø²éѯ¡£
+
+ÉÏÒ»½ÚÎÒÃǽ²ÁËÔÚSpringÖм¯³ÉHibernate¡£HibernateÊǵÚÒ»¸ö±»¹ã·ºÊ¹ÓõÄORM¿ò¼Ü£¬µ«ÊǺܶàС»ï°é»¹Ìý˵¹ýJPA£ºJava Persistence API£¬ÕâÓÖÊÇɶ£¿
+
+ÔÚÌÖÂÛJPA֮ǰ£¬ÎÒÃÇҪעÒâµ½JavaEEÔçÔÚ1999Äê¾Í·¢²¼ÁË£¬²¢ÇÒÓÐServlet¡¢JMSµÈÖî¶à±ê×¼¡£ºÍÆäËûƽ̨²»Í¬£¬JavaÊÀ½çÔçÆÚ·Ç³£ÈÈÖÔÓÚ±ê×¼ÏÈÐУ¬¸÷¼Ò¸ú½ø£º´ó¼ÒÏÈ×øÏÂÀ´°Ñ½Ó¿Ú¶¨ÁË£¬È»ºó£¬¸÷×ԻؼҸɻîȥʵÏÖ½Ó¿Ú£¬ÕâÑù£¬Óû§¾Í¿ÉÒÔÔÚ²»Í¬µÄ³§¼ÒÌṩµÄ²úÆ·½øÐÐÑ¡Ôñ£¬»¹¿ÉÒÔËæÒâÇл»£¬ÒòΪÓû§±àд´úÂëµÄʱºòÖ»ÐèÒªÒýÓýӿڣ¬²¢²»ÐèÒªÒýÓþßÌåµÄµ×²ãʵÏÖ£¨ÏëÏëJDBC£©¡£
+
+JPA¾ÍÊÇJavaEEµÄÒ»¸öORM±ê×¼£¬ËüµÄʵÏÖÆäʵºÍHibernateûɶ±¾ÖÊÇø±ð£¬µ«ÊÇÓû§Èç¹ûʹÓÃJPA£¬ÄÇôÒýÓõľÍÊÇ`jakarta.persistence`Õâ¸ö¡°±ê×¼¡±°ü£¬¶ø²»ÊÇ`org.hibernate`ÕâÑùµÄµÚÈý·½°ü¡£ÒòΪJPAÖ»Êǽӿڣ¬ËùÒÔ£¬»¹ÐèҪѡÔñÒ»¸öʵÏÖ²úÆ·£¬¸úJDBC½Ó¿ÚºÍMySQLÇý¶¯Ò»¸öµÀÀí¡£
+
+ÎÒÃÇʹÓÃJPAʱҲÍêÈ«¿ÉÒÔÑ¡ÔñHibernate×÷Ϊµ×²ãʵÏÖ£¬µ«Ò²¿ÉÒÔÑ¡ÔñÆäËüµÄJPAÌṩ·½£¬±ÈÈç[EclipseLink](https://www.eclipse.org/eclipselink/)¡£SpringÄÚÖÃÁËJPAµÄ¼¯³É£¬²¢Ö§³ÖÑ¡ÔñHibernate»òEclipseLink×÷ΪʵÏÖ¡£ÕâÀïÎÒÃÇÈÔÈ»ÒÔÖ÷Á÷µÄHibernate×÷ΪJPAʵÏÖΪÀý×Ó£¬ÑÝʾJPAµÄ»ù±¾Ó÷¨¡£
+
+ºÍʹÓÃHibernateÒ»Ñù£¬ÎÒÃÇÖ»ÐèÒªÒýÈëÈçÏÂÒÀÀµ£º
+
+* org.springframework:spring-context:6.0.0
+* org.springframework:spring-orm:6.0.0
+* jakarta.annotation:jakarta.annotation-api:2.1.1
+* jakarta.persistence:jakarta.persistence-api:3.1.0
+* org.hibernate:hibernate-core:6.1.4.Final
+* com.zaxxer:HikariCP:5.0.1
+* org.hsqldb:hsqldb:2.7.1
+
+ʵ¼ÊÉÏÎÒÃÇÕâÀïÒýÈëµÄÒÀÀµºÍÉÏÒ»½Ú¼¯³ÉHibernateÒýÈëµÄÒÀÀµÍêȫһÑù£¬ÒòΪHibernate¼ÈÌṩÁËËü×Ô¼ºµÄ½Ó¿Ú£¬Ò²ÌṩÁËJPA½Ó¿Ú£¬ÎÒÃÇÓÃJPA½Ó¿Ú¾ÍÏ൱ÓÚͨ¹ýJPA²Ù×÷Hibernate¡£
+
+È»ºó£¬ÔÚ`AppConfig`ÖÐÆôÓÃÉùÃ÷ʽÊÂÎñ¹ÜÀí£¬´´½¨`DataSource`£º
+
+```
+@Configuration
+@ComponentScan
+@EnableTransactionManagement
+@PropertySource("jdbc.properties")
+public class AppConfig {
+ @Bean
+ DataSource createDataSource() { ... }
+}
+
+```
+
+ʹÓÃHibernateʱ£¬ÎÒÃÇÐèÒª´´½¨Ò»¸ö`LocalSessionFactoryBean`£¬²¢ÈÃËüÔÙ×Ô¶¯´´½¨Ò»¸ö`SessionFactory`¡£Ê¹ÓÃJPAÒ²ÊÇÀàËÆµÄ£¬ÎÒÃÇÒ²´´½¨Ò»¸ö`LocalContainerEntityManagerFactoryBean`£¬²¢ÈÃËüÔÙ×Ô¶¯´´½¨Ò»¸ö`EntityManagerFactory`£º
+
+```
+@Bean
+public LocalContainerEntityManagerFactoryBean createEntityManagerFactory(@Autowired DataSource dataSource) {
+ var emFactory = new LocalContainerEntityManagerFactoryBean();
+ // ×¢ÈëDataSource:
+ emFactory.setDataSource(dataSource);
+ // ɨÃèÖ¸¶¨µÄpackage»ñÈ¡ËùÓÐentity class:
+ emFactory.setPackagesToScan(AbstractEntity.class.getPackageName());
+ // ʹÓÃHibernate×÷ΪJPAʵÏÖ:
+ emFactory.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
+ // ÆäËûÅäÖÃÏî:
+ var props = new Properties();
+ props.setProperty("hibernate.hbm2ddl.auto", "update"); // Éú²ú»·¾³²»ÒªÊ¹ÓÃ
+ props.setProperty("hibernate.dialect", "org.hibernate.dialect.HSQLDialect");
+ props.setProperty("hibernate.show_sql", "true");
+ emFactory.setJpaProperties(props);
+ return emFactory;
+}
+
+```
+
+¹Û²ìÉÏÊö´úÂ룬³ýÁËÐèҪעÈë`DataSource`ºÍÉ趨×Ô¶¯É¨ÃèµÄ`package`Í⣬»¹ÐèÒªÖ¸¶¨JPAµÄÌṩÉÌ£¬ÕâÀïʹÓÃSpringÌṩµÄÒ»¸ö`HibernateJpaVendorAdapter`£¬×îºó£¬Õë¶ÔHibernate×Ô¼ºÐèÒªµÄÅäÖã¬ÒÔ`Properties`µÄÐÎʽעÈë¡£
+
+×îºó£¬ÎÒÃÇ»¹ÐèҪʵÀý»¯Ò»¸ö`JpaTransactionManager`£¬ÒÔʵÏÖÉùÃ÷ʽÊÂÎñ£º
+
+```
+@Bean
+PlatformTransactionManager createTxManager(@Autowired EntityManagerFactory entityManagerFactory) {
+ return new JpaTransactionManager(entityManagerFactory);
+}
+
+```
+
+ÕâÑù£¬ÎÒÃǾÍÍê³ÉÁËJPAµÄÈ«²¿³õʼ»¯¹¤×÷¡£ÓÐЩͯЬ¿ÉÄÜ´ÓÍøÉÏËÑË÷µÃÖªJPAÐèÒª`persistence.xml`ÅäÖÃÎļþ£¬ÒÔ¼°¸´ÔÓµÄ`orm.xml`Îļþ¡£ÕâÀïÎÒÃǸºÔðµØ¸æËß´ó¼Ò£¬Ê¹ÓÃSpring+Hibernate×÷ΪJPAʵÏÖ£¬ÎÞÐèÈκÎÅäÖÃÎļþ¡£
+
+ËùÓÐEntity BeanµÄÅäÖúÍÉÏÒ»½ÚÍêÈ«Ïàͬ£¬È«²¿²ÉÓÃAnnotation±ê×¢¡£ÎÒÃÇÏÖÔÚÖ»Ðè¹ØÐľßÌåµÄÒµÎñÀàÈçºÎͨ¹ýJPA½Ó¿Ú²Ù×÷Êý¾Ý¿â¡£
+
+»¹ÊÇÒÔ`UserService`ΪÀý£¬³ýÁ˱ê×¢`@Component`ºÍ`@Transactional`Í⣬ÎÒÃÇÐèҪעÈëÒ»¸ö`EntityManager`£¬µ«ÊDz»ÒªÊ¹ÓÃ`Autowired`£¬¶øÊÇ`@PersistenceContext`£º
+
+```
+@Component
+@Transactional
+public class UserService {
+ @PersistenceContext
+ EntityManager em;
+}
+
+```
+
+ÎÒÃǻعËÒ»ÏÂJDBC¡¢HibernateºÍJPAÌṩµÄ½Ó¿Ú£¬Êµ¼ÊÉÏ£¬ËüÃǵĹØÏµÈçÏ£º
+
+| JDBC | Hibernate | JPA |
+| --- | --- | --- |
+| DataSource | SessionFactory | EntityManagerFactory |
+| Connection | Session | EntityManager |
+
+`SessionFactory`ºÍ`EntityManagerFactory`Ï൱ÓÚ`DataSource`£¬`Session`ºÍ`EntityManager`Ï൱ÓÚ`Connection`¡£Ã¿´ÎÐèÒª·ÃÎÊÊý¾Ý¿âµÄʱºò£¬ÐèÒª»ñȡеÄ`Session`ºÍ`EntityManager`£¬ÓÃÍêºóÔٹرա£
+
+µ«ÊÇ£¬×¢Òâµ½`UserService`×¢ÈëµÄ²»ÊÇ`EntityManagerFactory`£¬¶øÊÇ`EntityManager`£¬²¢ÇÒ±ê×¢ÁË`@PersistenceContext`¡£ÄѵÀʹÓÃJPA¿ÉÒÔÔÊÐí¶àÏ̲߳Ù×÷ͬһ¸ö`EntityManager`£¿
+
+ʵ¼ÊÉÏÕâÀï×¢ÈëµÄ²¢²»ÊÇÕæÕýµÄ`EntityManager`£¬¶øÊÇÒ»¸ö`EntityManager`µÄ´úÀíÀ࣬Ï൱ÓÚ£º
+
+```
+public class EntityManagerProxy implements EntityManager {
+ private EntityManagerFactory emf;
+}
+
+```
+
+SpringÓöµ½±ê×¢ÁË`@PersistenceContext`µÄ`EntityManager`»á×Ô¶¯×¢Èë´úÀí£¬¸Ã´úÀí»áÔÚ±ØÒªµÄʱºò×Ô¶¯´ò¿ª`EntityManager`¡£»»¾ä»°Ëµ£¬¶àÏß³ÌÒýÓõÄ`EntityManager`ËäÈ»ÊÇͬһ¸ö´úÀíÀ࣬µ«¸Ã´úÀíÀàÄÚ²¿Õë¶Ô²»Í¬Ï̻߳ᴴ½¨²»Í¬µÄ`EntityManager`ʵÀý¡£
+
+¼òµ¥×ܽáһϣ¬±ê×¢ÁË`@PersistenceContext`µÄ`EntityManager`¿ÉÒÔ±»¶àḬ̈߳²È«µØ¹²Ïí¡£
+
+Òò´Ë£¬ÔÚ`UserService`µÄÿ¸öÒµÎñ·½·¨Àֱ½ÓʹÓÃ`EntityManager`¾ÍºÜ·½±ã¡£ÒÔÖ÷¼ü²éѯΪÀý£º
+
+```
+public User getUserById(long id) {
+ User user = this.em.find(User.class, id);
+ if (user == null) {
+ throw new RuntimeException("User not found by id: " + id);
+ }
+ return user;
+}
+
+```
+
+ÓëHQL²éѯÀàËÆ£¬JPAʹÓÃJPQL²éѯ£¬ËüµÄÓï·¨ºÍHQL»ù±¾²î²»¶à£º
+
+```
+public User fetchUserByEmail(String email) {
+ // JPQL²éѯ:
+ TypedQuery query = em.createQuery("SELECT u FROM User u WHERE u.email = :e", User.class);
+ query.setParameter("e", email);
+ List list = query.getResultList();
+ if (list.isEmpty()) {
+ return null;
+ }
+ return list.get(0);
+}
+
+```
+
+ͬÑùµÄ£¬JPAÒ²Ö§³Ö`NamedQuery`£¬¼´Ïȸø²éѯÆð¸öÃû×Ö£¬ÔÙ°´Ãû×Ö´´½¨²éѯ£º
+
+```
+public User login(String email, String password) {
+ TypedQuery query = em.createNamedQuery("login", User.class);
+ query.setParameter("e", email);
+ query.setParameter("pwd", password);
+ List list = query.getResultList();
+ return list.isEmpty() ? null : list.get(0);
+}
+
+```
+
+`NamedQuery`ͨ¹ý×¢½â±ê×¢ÔÚ`User`ÀàÉÏ£¬ËüµÄ¶¨ÒåºÍÉÏÒ»½ÚµÄ`User`ÀàÒ»Ñù£º
+
+```
+@NamedQueries(
+ @NamedQuery(
+ name = "login",
+ query = "SELECT u FROM User u WHERE u.email=:e AND u.password=:pwd"
+ )
+)
+@Entity
+public class User {
+ ...
+}
+
+```
+
+¶ÔÊý¾Ý¿â½øÐÐÔöɾ¸ÄµÄ²Ù×÷£¬¿ÉÒÔ·Ö±ðʹÓÃ`persist()`¡¢`remove()`ºÍ`merge()`·½·¨£¬²ÎÊý¾ùΪEntity Bean±¾Éí£¬Ê¹Ó÷dz£¼òµ¥£¬ÕâÀï²»ÔÙ¶àÊö¡£
+
+#### ¼¯³ÉMyBatis
+
+×îºó¸üÐÂ: 2022/11/16 21:07 / ÔĶÁ: 601258
+
+* * *
+
+
+
+ʹÓÃHibernate»òJPA²Ù×÷Êý¾Ý¿âʱ£¬ÕâÀàORM¸ÉµÄÖ÷Òª¹¤×÷¾ÍÊǰÑResultSetµÄÿһÐбä³ÉJava Bean£¬»òÕß°ÑJava Bean×Ô¶¯×ª»»µ½INSERT»òUPDATEÓï¾äµÄ²ÎÊýÖУ¬´Ó¶øÊµÏÖORM¡£
+
+¶øORM¿ò¼ÜÖ®ËùÒÔÖªµÀÈçºÎ°ÑÐÐÊý¾ÝÓ³Éäµ½Java Bean£¬ÊÇÒòΪÎÒÃÇÔÚJava BeanµÄÊôÐÔÉϸøÁË×ã¹»µÄ×¢½â×÷ΪԪÊý¾Ý£¬ORM¿ò¼Ü»ñÈ¡Java BeanµÄ×¢½âºó£¬¾ÍÖªµÀÈçºÎ½øÐÐË«ÏòÓ³Éä¡£
+
+ÄÇô£¬ORM¿ò¼ÜÊÇÈçºÎ¸ú×ÙJava BeanµÄÐ޸ģ¬ÒÔ±ãÔÚ`update()`²Ù×÷ÖиüбØÒªµÄÊôÐÔ£¿
+
+´ð°¸ÊÇʹÓÃ[Proxyģʽ](https://www.liaoxuefeng.com/wiki/1252599548343744/1281319432618017)£¬´ÓORM¿ò¼Ü¶ÁÈ¡µÄUserʵÀýʵ¼ÊÉϲ¢²»ÊÇUserÀ࣬¶øÊÇ´úÀíÀ࣬´úÀíÀà¼Ì³Ð×ÔUserÀ࣬µ«Õë¶Ôÿ¸ösetter·½·¨×öÁ˸²Ð´£º
+
+```
+public class UserProxy extends User {
+ boolean _isNameChanged;
+
+ public void setName(String name) {
+ super.setName(name);
+ _isNameChanged = true;
+ }
+}
+
+```
+
+ÕâÑù£¬´úÀíÀà¿ÉÒÔ¸ú×Ùµ½Ã¿¸öÊôÐԵı仯¡£
+
+Õë¶ÔÒ»¶Ô¶à»ò¶à¶ÔÒ»¹ØÏµÊ±£¬´úÀíÀà¿ÉÒÔÖ±½Óͨ¹ýgetter·½·¨²éѯÊý¾Ý¿â£º
+
+```
+public class UserProxy extends User {
+ Session _session;
+ boolean _isNameChanged;
+
+ public void setName(String name) {
+ super.setName(name);
+ _isNameChanged = true;
+ }
+
+ /**
+ * »ñÈ¡User¶ÔÏó¹ØÁªµÄAddress¶ÔÏó:
+ */
+ public Address getAddress() {
+ Query q = _session.createQuery("from Address where userId = :userId");
+ q.setParameter("userId", this.getId());
+ List list = query.list();
+ return list.isEmpty() ? null : list(0);
+ }
+}
+
+```
+
+ΪÁËʵÏÖÕâÑùµÄ²éѯ£¬UserProxy±ØÐë±£´æHibernateµÄµ±Ç°Session¡£µ«ÊÇ£¬µ±ÊÂÎñÌá½»ºó£¬Session×Ô¶¯¹Ø±Õ£¬´ËʱÔÙ»ñÈ¡`getAddress()`½«ÎÞ·¨·ÃÎÊÊý¾Ý¿â£¬»òÕß»ñÈ¡µÄ²»ÊÇÊÂÎñÒ»ÖµÄÊý¾Ý¡£Òò´Ë£¬ORM¿ò¼Ü×ÜÊÇÒýÈëÁËAttached/Detached״̬£¬±íʾµ±Ç°´ËJava Beanµ½µ×ÊÇÔÚSessionµÄ·¶Î§ÄÚ£¬»¹ÊÇÍÑÀëÁËSession±ä³ÉÁËÒ»¸ö¡°ÓÎÀ롱¶ÔÏ󡣺ܶà³õѧÕßÎÞ·¨ÕýÈ·Àí½â״̬±ä»¯ºÍÊÂÎñ±ß½ç£¬¾Í»áÔì³É´óÁ¿µÄ`PersistentObjectException`Òì³£¡£ÕâÖÖÒþʽ״̬ʹµÃÆÕͨJava BeanµÄÉúÃüÖÜÆÚ±äµÃ¸´ÔÓ¡£
+
+´ËÍ⣬HibernateºÍJPAΪÁËʵÏÖ¼æÈݶàÖÖÊý¾Ý¿â£¬ËüʹÓÃHQL»òJPQL²éѯ£¬¾¹ýÒ»µÀת»»£¬±ä³ÉÌØ¶¨Êý¾Ý¿âµÄSQL£¬ÀíÂÛÉÏÕâÑù¿ÉÒÔ×öµ½ÎÞ·ìÇл»Êý¾Ý¿â£¬µ«ÕâÒ»²ã×Ô¶¯×ª»»³ýÁËÉÙÐíµÄÐÔÄÜ¿ªÏúÍ⣬¸øSQL¼¶±ðµÄÓÅ»¯´øÀ´ÁËÂé·³¡£
+
+×îºó£¬ORM¿ò¼Üͨ³£ÌṩÁË»º´æ£¬²¢ÇÒ»¹·ÖΪһ¼¶»º´æºÍ¶þ¼¶»º´æ¡£Ò»¼¶»º´æÊÇÖ¸ÔÚÒ»¸öSession·¶Î§ÄڵĻº´æ£¬³£¼ûµÄÇé¾°ÊǸù¾ÝÖ÷¼ü²éѯʱ£¬Á½´Î²éѯ¿ÉÒÔ·µ»ØÍ¬Ò»ÊµÀý£º
+
+```
+User user1 = session.load(User.class, 123);
+User user2 = session.load(User.class, 123);
+
+```
+
+¶þ¼¶»º´æÊÇÖ¸¿çSessionµÄ»º´æ£¬Ò»°ãĬÈϹرգ¬ÐèÒªÊÖ¶¯ÅäÖ᣶þ¼¶»º´æ¼«´óµÄÔö¼ÓÁËÊý¾ÝµÄ²»Ò»ÖÂÐÔ£¬ÔÒòÔÚÓÚSQL·Ç³£Áé»î£¬³£³£»áµ¼ÖÂÒâÍâµÄ¸üС£ÀýÈ磺
+
+```
+// Ïß³Ì1¶ÁÈ¡:
+User user1 = session1.load(User.class, 123);
+...
+// Ò»¶Îʱ¼äºó£¬Ïß³Ì2¶ÁÈ¡:
+User user2 = session2.load(User.class, 123);
+
+```
+
+µ±¶þ¼¶»º´æÉúЧµÄʱºò£¬Á½¸öÏ̶߳ÁÈ¡µÄUserʵÀýÊÇÒ»ÑùµÄ£¬µ«ÊÇ£¬Êý¾Ý¿â¶ÔÓ¦µÄÐмǼÍêÈ«¿ÉÄܱ»Ð޸ģ¬ÀýÈ磺
+
+```
+-- ¸øÀÏÓû§Ôö¼Ó100»ý·Ö:
+UPDATE users SET bonus = bonus + 100 WHERE createdAt <= ?
+
+```
+
+ORMÎÞ·¨ÅжÏ`id=123`µÄÓû§ÊÇ·ñÊܸÃ`UPDATE`Óï¾äÓ°Ïì¡£¿¼Âǵ½Êý¾Ý¿âͨ³£»áÖ§³Ö¶à¸öÓ¦ÓóÌÐò£¬´ËUPDATEÓï¾ä¿ÉÄÜÓÉÆäËû½ø³ÌÖ´ÐУ¬ORM¿ò¼Ü¾Í¸ü²»ÖªµÀÁË¡£
+
+ÎÒÃǰÑÕâÖÖORM¿ò¼Ü³ÆÖ®ÎªÈ«×Ô¶¯ORM¿ò¼Ü¡£
+
+¶Ô±ÈSpringÌṩµÄJdbcTemplate£¬ËüºÍORM¿ò¼ÜÏà±È£¬Ö÷ÒªÓм¸µã²î±ð£º
+
+1. ²éѯºóÐèÒªÊÖ¶¯ÌṩMapperʵÀýÒÔ±ã°ÑResultSetµÄÿһÐбäΪJava¶ÔÏó£»
+2. Ôöɾ¸Ä²Ù×÷ËùÐèµÄ²ÎÊýÁÐ±í£¬ÐèÒªÊÖ¶¯´«È룬¼´°ÑUserʵÀý±äΪ[user.id, user.name, user.email]ÕâÑùµÄÁÐ±í£¬±È½ÏÂé·³¡£
+
+µ«ÊÇJdbcTemplateµÄÓÅÊÆÔÚÓÚËüµÄÈ·¶¨ÐÔ£º¼´Ã¿´Î¶ÁÈ¡²Ù×÷Ò»¶¨ÊÇÊý¾Ý¿â²Ù×÷¶ø²»ÊÇ»º´æ£¬ËùÖ´ÐеÄSQLÊÇÍêȫȷ¶¨µÄ£¬È±µã¾ÍÊÇ´úÂë±È½Ï·±Ëö£¬¹¹Ôì`INSERT INTO users VALUES (?,?,?)`¸üÊǸ´ÔÓ¡£
+
+ËùÒÔ£¬½éÓÚÈ«×Ô¶¯ORMÈçHibernateºÍÊÖдȫ²¿ÈçJdbcTemplateÖ®¼ä£¬»¹ÓÐÒ»ÖÖ°ë×Ô¶¯µÄORM£¬ËüÖ»¸ºÔð°ÑResultSet×Ô¶¯Ó³Éäµ½Java Bean£¬»òÕß×Ô¶¯Ìî³äJava Bean²ÎÊý£¬µ«ÈÔÐè×Ô¼ºÐ´³öSQL¡£[MyBatis](https://mybatis.org/)¾ÍÊÇÕâÑùÒ»ÖÖ°ë×Ô¶¯»¯ORM¿ò¼Ü¡£
+
+ÎÒÃÇÀ´¿´¿´ÈçºÎÔÚSpringÖм¯³ÉMyBatis¡£
+
+Ê×ÏÈ£¬ÎÒÃÇÒªÒýÈëMyBatis±¾Éí£¬Æä´Î£¬ÓÉÓÚSpring²¢Ã»ÓÐÏñHibernateÄÇÑùÄÚÖöÔMyBatisµÄ¼¯³É£¬ËùÒÔ£¬ÎÒÃÇÐèÒªÔÙÒýÈëMyBatis¹Ù·½×Ô¼º¿ª·¢µÄÒ»¸öÓëSpring¼¯³ÉµÄ¿â£º
+
+* org.mybatis:mybatis:3.5.11
+* org.mybatis:mybatis-spring:3.0.0
+
+ºÍÇ°ÃæÒ»Ñù£¬ÏÈ´´½¨`DataSource`ÊDZز»¿ÉÉٵģº
+
+```
+@Configuration
+@ComponentScan
+@EnableTransactionManagement
+@PropertySource("jdbc.properties")
+public class AppConfig {
+ @Bean
+ DataSource createDataSource() { ... }
+}
+
+```
+
+ÔٻعËÒ»ÏÂHibernateºÍJPAµÄ`SessionFactory`Óë`EntityManagerFactory`£¬MyBatisÓëÖ®¶ÔÓ¦µÄÊÇ`SqlSessionFactory`ºÍ`SqlSession`£º
+
+| JDBC | Hibernate | JPA | MyBatis |
+| --- | --- | --- | --- |
+| DataSource | SessionFactory | EntityManagerFactory | SqlSessionFactory |
+| Connection | Session | EntityManager | SqlSession |
+
+¿É¼û£¬ORMµÄÉè¼ÆÌ×·¶¼ÊÇÀàËÆµÄ¡£Ê¹ÓÃMyBatisµÄºËÐľÍÊÇ´´½¨`SqlSessionFactory`£¬ÕâÀïÎÒÃÇÐèÒª´´½¨µÄÊÇ`SqlSessionFactoryBean`£º
+
+```
+@Bean
+SqlSessionFactoryBean createSqlSessionFactoryBean(@Autowired DataSource dataSource) {
+ var sqlSessionFactoryBean = new SqlSessionFactoryBean();
+ sqlSessionFactoryBean.setDataSource(dataSource);
+ return sqlSessionFactoryBean;
+}
+
+```
+
+ÒòΪMyBatis¿ÉÒÔÖ±½ÓʹÓÃSpring¹ÜÀíµÄÉùÃ÷ʽÊÂÎñ£¬Òò´Ë£¬´´½¨ÊÂÎñ¹ÜÀíÆ÷ºÍʹÓÃJDBCÊÇÒ»ÑùµÄ£º
+
+```
+@Bean
+PlatformTransactionManager createTxManager(@Autowired DataSource dataSource) {
+ return new DataSourceTransactionManager(dataSource);
+}
+
+```
+
+ºÍHibernate²»Í¬µÄÊÇ£¬MyBatisʹÓÃMapperÀ´ÊµÏÖÓ³É䣬¶øÇÒMapper±ØÐëÊǽӿڡ£ÎÒÃÇÒÔ`User`ÀàΪÀý£¬ÔÚ`User`ÀàºÍ`users`±íÖ®¼äÓ³ÉäµÄ`UserMapper`±àдÈçÏ£º
+
+```
+public interface UserMapper {
+ @Select("SELECT * FROM users WHERE id = #{id}")
+ User getById(@Param("id") long id);
+}
+
+```
+
+×¢Ò⣺ÕâÀïµÄMapper²»ÊÇ`JdbcTemplate`µÄ`RowMapper`µÄ¸ÅÄËüÊǶ¨Òå·ÃÎÊ`users`±íµÄ½Ó¿Ú·½·¨¡£±ÈÈçÎÒÃǶ¨ÒåÁËÒ»¸ö`User getById(long)`µÄÖ÷¼ü²éѯ·½·¨£¬²»½öÒª¶¨Òå½Ó¿Ú·½·¨±¾Éí£¬»¹ÒªÃ÷ȷд³ö²éѯµÄSQL£¬ÕâÀïÓÃ×¢½â`@Select`±ê¼Ç¡£SQLÓï¾äµÄÈκβÎÊý£¬¶¼Óë·½·¨²ÎÊý°´Ãû³Æ¶ÔÓ¦¡£ÀýÈ磬·½·¨²ÎÊýidµÄÃû×Öͨ¹ý×¢½â`@Param()`±ê¼ÇΪ`id`£¬ÔòSQLÓï¾äÀォÀ´Ìæ»»µÄռλ·û¾ÍÊÇ`#{id}`¡£
+
+Èç¹ûÓжà¸ö²ÎÊý£¬ÄÇôÿ¸ö²ÎÊýÃüÃûºóÖ±½ÓÔÚSQLÖÐд³ö¶ÔÓ¦µÄռλ·û¼´¿É£º
+
+```
+@Select("SELECT * FROM users LIMIT #{offset}, #{maxResults}")
+List getAll(@Param("offset") int offset, @Param("maxResults") int maxResults);
+
+```
+
+×¢Ò⣺MyBatisÖ´Ðвéѯºó£¬½«¸ù¾Ý·½·¨µÄ·µ»ØÀàÐÍ×Ô¶¯°ÑResultSetµÄÿһÐÐת»»ÎªUserʵÀý£¬×ª»»¹æÔòµ±È»Êǰ´ÁÐÃûºÍÊôÐÔÃû¶ÔÓ¦¡£Èç¹ûÁÐÃûºÍÊôÐÔÃû²»Í¬£¬×î¼òµ¥µÄ·½Ê½ÊDZàдSELECTÓï¾äµÄ±ðÃû£º
+
+```
+-- ÁÐÃûÊÇcreated_time£¬ÊôÐÔÃûÊÇcreatedAt:
+SELECT id, name, email, created_time AS createdAt FROM users
+
+```
+
+Ö´ÐÐINSERTÓï¾ä¾ÍÉÔ΢Âé·³µã£¬ÒòΪÎÒÃÇÏ£Íû´«ÈëUserʵÀý£¬Òò´Ë£¬¶¨ÒåµÄ·½·¨½Ó¿ÚÓë`@Insert`×¢½âÈçÏ£º
+
+```
+@Insert("INSERT INTO users (email, password, name, createdAt) VALUES (#{user.email}, #{user.password}, #{user.name}, #{user.createdAt})")
+void insert(@Param("user") User user);
+
+```
+
+ÉÏÊö·½·¨´«ÈëµÄ²ÎÊýÃû³ÆÊÇ`user`£¬²ÎÊýÀàÐÍÊÇUserÀ࣬ÔÚSQLÖÐÒýÓõÄʱºò£¬ÒÔ`#{obj.property}`µÄ·½Ê½Ð´Õ¼Î»·û¡£ºÍHibernateÕâÑùµÄÈ«×Ô¶¯»¯ORMÏà±È£¬MyBatis±ØÐëд³öÍêÕûµÄINSERTÓï¾ä¡£
+
+Èç¹û`users`±íµÄ`id`ÊÇ×ÔÔöÖ÷¼ü£¬ÄÇô£¬ÎÒÃÇÔÚSQLÖв»´«Èë`id`£¬µ«Ï£Íû»ñÈ¡²åÈëºóµÄÖ÷¼ü£¬ÐèÒªÔÙ¼ÓÒ»¸ö`@Options`×¢½â£º
+
+```
+@Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
+@Insert("INSERT INTO users (email, password, name, createdAt) VALUES (#{user.email}, #{user.password}, #{user.name}, #{user.createdAt})")
+void insert(@Param("user") User user);
+
+```
+
+`keyProperty`ºÍ`keyColumn`·Ö±ðÖ¸³öJavaBeanµÄÊôÐÔºÍÊý¾Ý¿âµÄÖ÷¼üÁÐÃû¡£
+
+Ö´ÐÐ`UPDATE`ºÍ`DELETE`Óï¾äÏà¶Ô±È½Ï¼òµ¥£¬ÎÒÃǶ¨Òå·½·¨ÈçÏ£º
+
+```
+@Update("UPDATE users SET name = #{user.name}, createdAt = #{user.createdAt} WHERE id = #{user.id}")
+void update(@Param("user") User user);
+
+@Delete("DELETE FROM users WHERE id = #{id}")
+void deleteById(@Param("id") long id);
+
+```
+
+ÓÐÁË`UserMapper`½Ó¿Ú£¬»¹ÐèÒª¶ÔÓ¦µÄʵÏÖÀà²ÅÄÜÕæÕýÖ´ÐÐÕâЩÊý¾Ý¿â²Ù×÷µÄ·½·¨¡£ËäÈ»¿ÉÒÔ×Ô¼ºÐ´ÊµÏÖÀ࣬µ«ÎÒÃdzýÁ˱àд`UserMapper`½Ó¿ÚÍ⣬»¹ÓÐ`BookMapper`¡¢`BonusMapper`¡¡Ò»¸öÒ»¸öд̫Âé·³£¬Òò´Ë£¬MyBatisÌṩÁËÒ»¸ö`MapperFactoryBean`À´×Ô¶¯´´½¨ËùÓÐMapperµÄʵÏÖÀà¡£¿ÉÒÔÓÃÒ»¸ö¼òµ¥µÄ×¢½âÀ´ÆôÓÃËü£º
+
+```
+@MapperScan("com.itranswarp.learnjava.mapper")
+...ÆäËû×¢½â...
+public class AppConfig {
+ ...
+}
+
+```
+
+ÓÐÁË`@MapperScan`£¬¾Í¿ÉÒÔÈÃMyBatis×Ô¶¯É¨ÃèÖ¸¶¨°üµÄËùÓÐMapper²¢´´½¨ÊµÏÖÀà¡£ÔÚÕæÕýµÄÒµÎñÂß¼ÖУ¬ÎÒÃÇ¿ÉÒÔÖ±½Ó×¢È룺
+
+```
+@Component
+@Transactional
+public class UserService {
+ // ×¢ÈëUserMapper:
+ @Autowired
+ UserMapper userMapper;
+
+ public User getUserById(long id) {
+ // µ÷ÓÃMapper·½·¨:
+ User user = userMapper.getById(id);
+ if (user == null) {
+ throw new RuntimeException("User not found by id.");
+ }
+ return user;
+ }
+}
+
+```
+
+¿É¼û£¬ÒµÎñÂß¼Ö÷Òª¾ÍÊÇͨ¹ý`XxxMapper`¶¨ÒåµÄÊý¾Ý¿â·½·¨À´·ÃÎÊÊý¾Ý¿â¡£
+
+### XMLÅäÖÃ
+
+ÉÏÊöÔÚSpringÖм¯³ÉMyBatisµÄ·½Ê½£¬ÎÒÃÇÖ»ÐèÒªÓõ½×¢½â£¬²¢Ã»ÓÐÈκÎXMLÅäÖÃÎļþ¡£MyBatisÒ²ÔÊÐíʹÓÃXMLÅäÖÃÓ³Éä¹ØÏµºÍSQLÓï¾ä£¬ÀýÈ磬¸üÐÂ`User`ʱ¸ù¾ÝÊôÐÔÖµ¹¹Ô춯̬SQL£º
+
+```
+
+ UPDATE users SET
+
+ name = #{user.name}
+ hobby = #{user.hobby}
+ summary = #{user.summary}
+
+ WHERE id = #{user.id}
+
+
+```
+
+±àдXMLÅäÖõÄÓŵãÊÇ¿ÉÒÔ×é×°³ö¶¯Ì¬SQL£¬²¢ÇÒ°ÑËùÓÐSQL²Ù×÷¼¯ÖÐÔÚÒ»Æð¡£È±µãÊÇÅäÖÃÆðÀ´Ì«·±Ëö£¬µ÷Ó÷½·¨Ê±Èç¹ûÏë²é¿´SQL»¹ÐèÒª¶¨Î»µ½XMLÅäÖÃÖС£ÕâÀïÎÒÃDz»½éÉÜXMLµÄÅäÖ÷½Ê½£¬ÐèÒªÁ˽âµÄͯЬÇë×ÔÐÐÔĶÁ[¹Ù·½Îĵµ](https://mybatis.org/mybatis-3/zh/configuration.html)¡£
+
+ʹÓÃMyBatis×î´óµÄÎÊÌâÊÇËùÓÐSQL¶¼ÐèҪȫ²¿ÊÖд£¬ÓŵãÊÇÖ´ÐеÄSQL¾ÍÊÇÎÒÃÇ×Ô¼ºÐ´µÄSQL£¬¶ÔSQL½øÐÐÓÅ»¯·Ç³£¼òµ¥£¬Ò²¿ÉÒÔ±àдÈÎÒ⸴ÔÓµÄSQL£¬»òÕßʹÓÃÊý¾Ý¿âµÄÌØ¶¨Óï·¨£¬µ«Çл»Êý¾Ý¿â¿ÉÄܾͲ»Ì«ÈÝÒס£ºÃÏûÏ¢ÊǴ󲿷ÖÏîÄ¿²¢Ã»ÓÐÇл»Êý¾Ý¿âµÄÐèÇó£¬ÍêÈ«¿ÉÒÔÕë¶Ôij¸öÊý¾Ý¿â±àд¾¡¿ÉÄÜÓÅ»¯µÄSQL¡£
+
+# ²Î¿¼ÎÄÕÂ
+https://www.w3cschool.cn/wkspring
+https://www.runoob.com/w3cnote/basic-knowledge-summary-of-spring.html
+http://codepub.cn/2015/06/21/Basic-knowledge-summary-of-Spring
+https://dunwu.github.io/spring-tutorial
+https://mszlu.com/java/spring
+http://c.biancheng.net/spring/aop-module.html
\ No newline at end of file
diff --git "a/docs/spring/Spring\344\270\255\345\257\271\344\272\216\346\240\241\351\252\214\345\212\237\350\203\275\347\232\204\346\224\257\346\214\201.md" "b/docs/spring/Spring\344\270\255\345\257\271\344\272\216\346\240\241\351\252\214\345\212\237\350\203\275\347\232\204\346\224\257\346\214\201.md"
new file mode 100644
index 0000000..a77e4a0
--- /dev/null
+++ "b/docs/spring/Spring\344\270\255\345\257\271\344\272\216\346\240\241\351\252\214\345\212\237\350\203\275\347\232\204\346\224\257\346\214\201.md"
@@ -0,0 +1,715 @@
+# Spring УÑé
+
+
+
+Java API ¹æ·¶(`JSR303`)¶¨ÒåÁË`Bean`УÑéµÄ±ê×¼`validation-api`£¬µ«Ã»ÓÐÌṩʵÏÖ¡£`hibernate validation`ÊǶÔÕâ¸ö¹æ·¶µÄʵÏÖ£¬²¢Ôö¼ÓÁËУÑé×¢½âÈç`@Email`¡¢`@Length`µÈ¡£`Spring Validation`ÊǶÔ`hibernate validation`µÄ¶þ´Î·â×°£¬ÓÃÓÚÖ§³Ö`spring mvc`²ÎÊý×Ô¶¯Ð£Ñé¡£
+
+## [#](https://dunwu.github.io/spring-tutorial/pages/fe6aad/#%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8)¿ìËÙÈëÃÅ
+
+### [#](https://dunwu.github.io/spring-tutorial/pages/fe6aad/#%E5%BC%95%E5%85%A5%E4%BE%9D%E8%B5%96)ÒýÈëÒÀÀµ
+
+Èç¹û spring-boot °æ±¾Ð¡ÓÚ 2.3.x£¬spring-boot-starter-web »á×Ô¶¯´«Èë hibernate-validator ÒÀÀµ¡£Èç¹û spring-boot °æ±¾´óÓÚ 2.3.x£¬ÔòÐèÒªÊÖ¶¯ÒýÈëÒÀÀµ£º
+
+
+
+```
+
+ org.hibernate.validator
+ hibernate-validator-parent
+ 6.2.5.Final
+
+
+```
+
+
+
+¶ÔÓÚ web ·þÎñÀ´Ëµ£¬Îª·ÀÖ¹·Ç·¨²ÎÊý¶ÔÒµÎñÔì³ÉÓ°Ï죬ÔÚ Controller ²ãÒ»¶¨Òª×ö²ÎÊýУÑéµÄ£¡´ó²¿·ÖÇé¿öÏ£¬ÇëÇó²ÎÊý·ÖΪÈçÏÂÁ½ÖÖÐÎʽ£º
+
+* POST¡¢PUT ÇëÇó£¬Ê¹Óà requestBody ´«µÝ²ÎÊý£»
+* GET ÇëÇó£¬Ê¹Óà requestParam/PathVariable ´«µÝ²ÎÊý¡£
+
+ʵ¼ÊÉÏ£¬²»¹ÜÊÇ requestBody ²ÎÊýУÑ黹ÊÇ·½·¨¼¶±ðµÄУÑ飬×îÖÕ¶¼Êǵ÷Óà Hibernate Validator Ö´ÐÐУÑ飬Spring Validation Ö»ÊÇ×öÁËÒ»²ã·â×°¡£
+
+### [#](https://dunwu.github.io/spring-tutorial/pages/fe6aad/#%E6%A0%A1%E9%AA%8C%E7%A4%BA%E4%BE%8B)УÑéʾÀý
+
+£¨1£©ÔÚʵÌåÉϱê¼ÇУÑé×¢½â
+
+
+
+```
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class User implements Serializable {
+
+ @NotNull
+ private Long id;
+
+ @NotBlank
+ @Size(min = 2, max = 10)
+ private String name;
+
+ @Min(value = 1)
+ @Max(value = 100)
+ private Integer age;
+
+}
+
+```
+
+
+
+£¨2£©ÔÚ·½·¨²ÎÊýÉÏÉùÃ÷УÑé×¢½â
+
+
+
+```
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("validate1")
+public class ValidatorController {
+
+ /**
+ * {@link RequestBody} ²ÎÊýУÑé
+ */
+ @PostMapping(value = "save")
+ public DataResult save(@Valid @RequestBody User entity) {
+ log.info("±£´æÒ»Ìõ¼Ç¼£º{}", JSONUtil.toJsonStr(entity));
+ return DataResult.ok(true);
+ }
+
+ /**
+ * {@link RequestParam} ²ÎÊýУÑé
+ */
+ @GetMapping(value = "queryByName")
+ public DataResult queryByName(
+ @RequestParam("username")
+ @NotBlank
+ @Size(min = 2, max = 10)
+ String name
+ ) {
+ User user = new User(1L, name, 18);
+ return DataResult.ok(user);
+ }
+
+ /**
+ * {@link PathVariable} ²ÎÊýУÑé
+ */
+ @GetMapping(value = "detail/{id}")
+ public DataResult detail(@PathVariable("id") @Min(1L) Long id) {
+ User user = new User(id, "ÀîËÄ", 18);
+ return DataResult.ok(user);
+ }
+
+}
+
+```
+
+
+
+£¨3£©Èç¹ûÇëÇó²ÎÊý²»Âú×ãУÑ鹿Ôò£¬Ôò»áÅ׳ö?`ConstraintViolationException`?»ò?`MethodArgumentNotValidException`?Òì³£¡£
+
+### [#](https://dunwu.github.io/spring-tutorial/pages/fe6aad/#%E7%BB%9F%E4%B8%80%E5%BC%82%E5%B8%B8%E5%A4%84%E7%90%86)ͳһÒì³£´¦Àí
+
+ÔÚʵ¼ÊÏîÄ¿¿ª·¢ÖУ¬Í¨³£»áÓÃͳһÒì³£´¦ÀíÀ´·µ»ØÒ»¸ö¸üÓѺõÄÌáʾ¡£
+
+
+
+```
+@Slf4j
+@ControllerAdvice
+public class GlobalExceptionHandler {
+
+ /**
+ * ´¦ÀíËùÓв»¿ÉÖªµÄÒì³£
+ */
+ @ResponseBody
+ @ResponseStatus(HttpStatus.OK)
+ @ExceptionHandler(Throwable.class)
+ public Result handleException(Throwable e) {
+ log.error("δ֪Òì³£", e);
+ return new Result(ResultStatus.HTTP_SERVER_ERROR.getCode(), e.getMessage());
+ }
+
+ /**
+ * ͳһ´¦ÀíÇëÇó²ÎÊýУÑéÒì³£(ÆÕͨ´«²Î)
+ *
+ * @param e ConstraintViolationException
+ * @return {@link DataResult}
+ */
+ @ResponseBody
+ @ResponseStatus(HttpStatus.BAD_REQUEST)
+ @ExceptionHandler({ ConstraintViolationException.class })
+ public Result handleConstraintViolationException(final ConstraintViolationException e) {
+ log.error("ConstraintViolationException", e);
+ List errors = new ArrayList<>();
+ for (ConstraintViolation> violation : e.getConstraintViolations()) {
+ Path path = violation.getPropertyPath();
+ List pathArr = StrUtil.split(path.toString(), ',');
+ errors.add(pathArr.get(0) + " " + violation.getMessage());
+ }
+ return new Result(ResultStatus.REQUEST_ERROR.getCode(), CollectionUtil.join(errors, ","));
+ }
+
+ /**
+ * ´¦Àí²ÎÊýУÑéÒì³£
+ *
+ * @param e MethodArgumentNotValidException
+ * @return {@link DataResult}
+ */
+ @ResponseBody
+ @ResponseStatus(HttpStatus.BAD_REQUEST)
+ @ExceptionHandler({ MethodArgumentNotValidException.class })
+ private Result handleMethodArgumentNotValidException(final MethodArgumentNotValidException e) {
+ log.error("MethodArgumentNotValidException", e);
+ List errors = new ArrayList<>();
+ for (ObjectError error : e.getBindingResult().getAllErrors()) {
+ errors.add(((FieldError) error).getField() + " " + error.getDefaultMessage());
+ }
+ return new Result(ResultStatus.REQUEST_ERROR.getCode(), CollectionUtil.join(errors, ","));
+ }
+
+}
+
+```
+
+
+
+## [#](https://dunwu.github.io/spring-tutorial/pages/fe6aad/#%E8%BF%9B%E9%98%B6%E4%BD%BF%E7%94%A8)½ø½×ʹÓÃ
+
+### [#](https://dunwu.github.io/spring-tutorial/pages/fe6aad/#%E5%88%86%E7%BB%84%E6%A0%A1%E9%AA%8C)·Ö×éУÑé
+
+ÔÚʵ¼ÊÏîÄ¿ÖУ¬¿ÉÄܶà¸ö·½·¨ÐèҪʹÓÃͬһ¸ö DTO ÀàÀ´½ÓÊÕ²ÎÊý£¬¶ø²»Í¬·½·¨µÄУÑ鹿ÔòºÜ¿ÉÄÜÊDz»Ò»ÑùµÄ¡£Õâ¸öʱºò£¬¼òµ¥µØÔÚ DTO ÀàµÄ×Ö¶ÎÉϼÓÔ¼Êø×¢½âÎÞ·¨½â¾öÕâ¸öÎÊÌâ¡£Òò´Ë£¬spring-validation Ö§³ÖÁË·Ö×éУÑéµÄ¹¦ÄÜ£¬×¨ÃÅÓÃÀ´½â¾öÕâÀàÎÊÌâ¡£
+
+£¨1£©¶¨Òå·Ö×é
+
+
+
+```
+@Target({ ElementType.FIELD, ElementType.PARAMETER })
+@Retention(RetentionPolicy.RUNTIME)
+public @interface AddCheck { }
+
+@Target({ ElementType.FIELD, ElementType.PARAMETER })
+@Retention(RetentionPolicy.RUNTIME)
+public @interface EditCheck { }
+
+```
+
+
+
+£¨2£©ÔÚʵÌåÉϱê¼ÇУÑé×¢½â
+
+
+
+```
+@Data
+public class User2 {
+
+ @NotNull(groups = EditCheck.class)
+ private Long id;
+
+ @NotNull(groups = { AddCheck.class, EditCheck.class })
+ @Size(min = 2, max = 10, groups = { AddCheck.class, EditCheck.class })
+ private String name;
+
+ @IsMobile(message = "²»ÊÇÓÐЧÊÖ»úºÅ", groups = { AddCheck.class, EditCheck.class })
+ private String mobile;
+
+}
+
+```
+
+
+
+£¨3£©ÔÚ·½·¨Éϸù¾Ý²»Í¬³¡¾°½øÐÐУÑé·Ö×é
+
+
+
+```
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("validate2")
+public class ValidatorController2 {
+
+ /**
+ * {@link RequestBody} ²ÎÊýУÑé
+ */
+ @PostMapping(value = "add")
+ public DataResult add(@Validated(AddCheck.class) @RequestBody User2 entity) {
+ log.info("Ìí¼ÓÒ»Ìõ¼Ç¼£º{}", JSONUtil.toJsonStr(entity));
+ return DataResult.ok(true);
+ }
+
+ /**
+ * {@link RequestBody} ²ÎÊýУÑé
+ */
+ @PostMapping(value = "edit")
+ public DataResult edit(@Validated(EditCheck.class) @RequestBody User2 entity) {
+ log.info("±à¼Ò»Ìõ¼Ç¼£º{}", JSONUtil.toJsonStr(entity));
+ return DataResult.ok(true);
+ }
+
+}
+
+```
+
+
+
+### [#](https://dunwu.github.io/spring-tutorial/pages/fe6aad/#%E5%B5%8C%E5%A5%97%E6%A0%A1%E9%AA%8C)ǶÌ×УÑé
+
+Ç°ÃæµÄʾÀýÖУ¬DTO ÀàÀïÃæµÄ×ֶζ¼ÊÇ»ù±¾Êý¾ÝÀàÐÍºÍ String ÀàÐÍ¡£µ«ÊÇʵ¼Ê³¡¾°ÖУ¬ÓпÉÄÜij¸ö×Ö¶ÎÒ²ÊÇÒ»¸ö¶ÔÏó£¬ÕâÖÖÇé¿öÏÈ£¬¿ÉÒÔʹÓÃǶÌ×УÑé¡£ post ±ÈÈ磬ÉÏÃæ±£´æ User ÐÅÏ¢µÄʱºòͬʱ»¹´øÓÐ Job ÐÅÏ¢¡£ÐèҪעÒâµÄÊÇ£¬´Ëʱ DTO ÀàµÄ¶ÔÓ¦×ֶαØÐë±ê¼Ç@Valid ×¢½â¡£
+
+
+
+```
+@Data
+public class UserDTO {
+
+ @Min(value = 10000000000000000L, groups = Update.class)
+ private Long userId;
+
+ @NotNull(groups = {Save.class, Update.class})
+ @Length(min = 2, max = 10, groups = {Save.class, Update.class})
+ private String userName;
+
+ @NotNull(groups = {Save.class, Update.class})
+ @Length(min = 6, max = 20, groups = {Save.class, Update.class})
+ private String account;
+
+ @NotNull(groups = {Save.class, Update.class})
+ @Length(min = 6, max = 20, groups = {Save.class, Update.class})
+ private String password;
+
+ @NotNull(groups = {Save.class, Update.class})
+ @Valid
+ private Job job;
+
+ @Data
+ public static class Job {
+
+ @Min(value = 1, groups = Update.class)
+ private Long jobId;
+
+ @NotNull(groups = {Save.class, Update.class})
+ @Length(min = 2, max = 10, groups = {Save.class, Update.class})
+ private String jobName;
+
+ @NotNull(groups = {Save.class, Update.class})
+ @Length(min = 2, max = 10, groups = {Save.class, Update.class})
+ private String position;
+ }
+
+ /**
+ * ±£´æµÄʱºòУÑé·Ö×é
+ */
+ public interface Save {
+ }
+
+ /**
+ * ¸üеÄʱºòУÑé·Ö×é
+ */
+ public interface Update {
+ }
+}
+¸´ÖÆ´úÂë
+
+```
+
+
+
+ǶÌ×УÑé¿ÉÒÔ½áºÏ·Ö×éУÑéÒ»ÆðʹÓ᣻¹ÓоÍÊÇǶÌ×¼¯ºÏУÑé»á¶Ô¼¯ºÏÀïÃæµÄÿһÏî¶¼½øÐÐУÑ飬ÀýÈç`List`×ֶλá¶ÔÕâ¸ö list ÀïÃæµÄÿһ¸ö Job ¶ÔÏó¶¼½øÐÐУÑé
+
+### [#](https://dunwu.github.io/spring-tutorial/pages/fe6aad/#%E8%87%AA%E5%AE%9A%E4%B9%89%E6%A0%A1%E9%AA%8C%E6%B3%A8%E8%A7%A3)×Ô¶¨ÒåУÑé×¢½â
+
+£¨1£©×Ô¶¨ÒåУÑé×¢½â?`@IsMobile`
+
+
+
+```
+@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
+@Retention(RUNTIME)
+@Constraint(validatedBy = MobileValidator.class)
+public @interface IsMobile {
+
+ String message();
+
+ Class>[] groups() default {};
+
+ Class extends Payload>[] payload() default {};
+
+}
+
+```
+
+
+
+£¨2£©ÊµÏÖ?`ConstraintValidator`?½Ó¿Ú£¬±àд?`@IsMobile`?УÑé×¢½âµÄ½âÎöÆ÷
+
+
+
+```
+import cn.hutool.core.util.StrUtil;
+import io.github.dunwu.spring.core.validation.annotation.IsMobile;
+import io.github.dunwu.tool.util.ValidatorUtil;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+
+public class MobileValidator implements ConstraintValidator {
+
+ @Override
+ public void initialize(IsMobile isMobile) { }
+
+ @Override
+ public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
+ if (StrUtil.isBlank(s)) {
+ return false;
+ } else {
+ return ValidatorUtil.isMobile(s);
+ }
+ }
+
+}
+
+```
+
+
+
+### [#](https://dunwu.github.io/spring-tutorial/pages/fe6aad/#%E8%87%AA%E5%AE%9A%E4%B9%89%E6%A0%A1%E9%AA%8C)×Ô¶¨ÒåУÑé
+
+¿ÉÒÔͨ¹ýʵÏÖ?`org.springframework.validation.Validator`?½Ó¿ÚÀ´×Ô¶¨ÒåУÑé¡£
+
+ÓÐÒÔÏÂÒªµã
+
+* ʵÏÖ?`supports`?·½·¨
+* ʵÏÖ?`validate`?·½·¨
+ * ͨ¹ý?`Errors`?¶ÔÏóÊÕ¼¯´íÎó
+ * `ObjectError`£º¶ÔÏó£¨Bean£©´íÎó£º
+ * `FieldError`£º¶ÔÏó£¨Bean£©ÊôÐÔ£¨Property£©´íÎó
+ * ͨ¹ý?`ObjectError`?ºÍ?`FieldError`?¹ØÁª?`MessageSource`?ʵÏÖ»ñÈ¡×îÖյĴíÎóÎݸ
+
+
+
+```
+package io.github.dunwu.spring.core.validation;
+
+import io.github.dunwu.spring.core.validation.annotation.Valid;
+import io.github.dunwu.spring.core.validation.config.CustomValidatorConfig;
+import io.github.dunwu.spring.core.validation.entity.Person;
+import org.springframework.stereotype.Component;
+import org.springframework.validation.Errors;
+import org.springframework.validation.ValidationUtils;
+import org.springframework.validation.Validator;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+@Component
+public class CustomValidator implements Validator {
+
+ private final CustomValidatorConfig validatorConfig;
+
+ public CustomValidator(CustomValidatorConfig validatorConfig) {
+ this.validatorConfig = validatorConfig;
+ }
+
+ /**
+ * ±¾Ð£ÑéÆ÷Ö»Õë¶Ô Person ¶ÔÏó½øÐÐУÑé
+ */
+ @Override
+ public boolean supports(Class> clazz) {
+ return Person.class.equals(clazz);
+ }
+
+ @Override
+ public void validate(Object target, Errors errors) {
+ ValidationUtils.rejectIfEmpty(errors, "name", "name.empty");
+
+ List fields = getFields(target.getClass());
+ for (Field field : fields) {
+ Annotation[] annotations = field.getAnnotations();
+ for (Annotation annotation : annotations) {
+ if (annotation.annotationType().getAnnotation(Valid.class) != null) {
+ try {
+ ValidatorRule validatorRule = validatorConfig.findRule(annotation);
+ if (validatorRule != null) {
+ validatorRule.valid(annotation, target, field, errors);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ }
+
+ private List getFields(Class> clazz) {
+ // ÉùÃ÷FieldÊý×é
+ List fields = new ArrayList<>();
+ // Èç¹ûclassÀàÐͲ»Îª¿Õ
+ while (clazz != null) {
+ // Ìí¼ÓÊôÐÔµ½ÊôÐÔÊý×é
+ Collections.addAll(fields, clazz.getDeclaredFields());
+ clazz = clazz.getSuperclass();
+ }
+ return fields;
+ }
+
+}
+
+```
+
+
+
+### [#](https://dunwu.github.io/spring-tutorial/pages/fe6aad/#%E5%BF%AB%E9%80%9F%E5%A4%B1%E8%B4%A5-fail-fast)¿ìËÙʧ°Ü(Fail Fast)
+
+Spring Validation ĬÈÏ»áУÑéÍêËùÓÐ×ֶΣ¬È»ºó²ÅÅ׳öÒì³£¡£¿ÉÒÔͨ¹ýһЩ¼òµ¥µÄÅäÖ㬿ªÆô Fali Fast ģʽ£¬Ò»µ©Ð£Ñéʧ°Ü¾ÍÁ¢¼´·µ»Ø¡£
+
+
+
+```
+@Bean
+public Validator validator() {
+ ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class)
+ .configure()
+ // ¿ìËÙʧ°Üģʽ
+ .failFast(true)
+ .buildValidatorFactory();
+ return validatorFactory.getValidator();
+}
+
+```
+
+
+
+## [#](https://dunwu.github.io/spring-tutorial/pages/fe6aad/#spring-%E6%A0%A1%E9%AA%8C%E5%8E%9F%E7%90%86)Spring УÑéÔÀí
+
+### [#](https://dunwu.github.io/spring-tutorial/pages/fe6aad/#spring-%E6%A0%A1%E9%AA%8C%E4%BD%BF%E7%94%A8%E5%9C%BA%E6%99%AF)Spring УÑéʹÓó¡¾°
+
+* Spring ³£¹æÐ£Ñ飨Validator£©
+* Spring Êý¾Ý°ó¶¨£¨DataBinder£©
+* Spring Web ²ÎÊý°ó¶¨£¨WebDataBinder£©
+* Spring WebMVC/WebFlux ´¦Àí·½·¨²ÎÊýУÑé
+
+### [#](https://dunwu.github.io/spring-tutorial/pages/fe6aad/#validator-%E6%8E%A5%E5%8F%A3%E8%AE%BE%E8%AE%A1)Validator ½Ó¿ÚÉè¼Æ
+
+* ½Ó¿ÚÖ°Ôð
+ * Spring ÄÚ²¿Ð£ÑéÆ÷½Ó¿Ú£¬Í¨¹ý±à³ÌµÄ·½Ê½Ð£ÑéÄ¿±ê¶ÔÏó
+* ºËÐÄ·½·¨
+ * `supports(Class)`£ºÐ£ÑéÄ¿±êÀàÄÜ·ñУÑé
+ * `validate(Object,Errors)`£ºÐ£ÑéÄ¿±ê¶ÔÏ󣬲¢½«Ð£Ñéʧ°ÜµÄÄÚÈÝÊä³öÖÁ Errors ¶ÔÏó
+* ÅäÌ××é¼þ
+ * ´íÎóÊÕ¼¯Æ÷£º`org.springframework.validation.Errors`
+ * Validator ¹¤¾ßÀࣺ`org.springframework.validation.ValidationUtils`
+
+### [#](https://dunwu.github.io/spring-tutorial/pages/fe6aad/#errors-%E6%8E%A5%E5%8F%A3%E8%AE%BE%E8%AE%A1)Errors ½Ó¿ÚÉè¼Æ
+
+* ½Ó¿ÚÖ°Ôð
+ * Êý¾Ý°ó¶¨ºÍУÑé´íÎóÊÕ¼¯½Ó¿Ú£¬Óë Java Bean ºÍÆäÊôÐÔÓÐÇ¿¹ØÁªÐÔ
+* ºËÐÄ·½·¨
+ * `reject`?·½·¨£¨ÖØÔØ£©£ºÊÕ¼¯´íÎóÎݸ
+ * `rejectValue`?·½·¨£¨ÖØÔØ£©£ºÊÕ¼¯¶ÔÏó×Ö¶ÎÖеĴíÎóÎݸ
+* ÅäÌ××é¼þ
+ * Java Bean ´íÎóÃèÊö£º`org.springframework.validation.ObjectError`
+ * Java Bean ÊôÐÔ´íÎóÃèÊö£º`org.springframework.validation.FieldError`
+
+### [#](https://dunwu.github.io/spring-tutorial/pages/fe6aad/#errors-%E6%96%87%E6%A1%88%E6%9D%A5%E6%BA%90)Errors ÎݸÀ´Ô´
+
+Errors ÎݸÉú³É²½Öè
+
+* Ñ¡Ôñ Errors ʵÏÖ£¨È磺`org.springframework.validation.BeanPropertyBindingResult`£©
+* µ÷ÓÃ reject »ò rejectValue ·½·¨
+* »ñÈ¡ Errors ¶ÔÏóÖÐ ObjectError »ò FieldError
+* ½« ObjectError »ò FieldError ÖÐµÄ code ºÍ args£¬¹ØÁª MessageSource ʵÏÖ£¨È磺`ResourceBundleMessageSource`£©
+
+### [#](https://dunwu.github.io/spring-tutorial/pages/fe6aad/#spring-web-%E6%A0%A1%E9%AA%8C%E5%8E%9F%E7%90%86)spring web УÑéÔÀí
+
+#### [#](https://dunwu.github.io/spring-tutorial/pages/fe6aad/#requestbody-%E5%8F%82%E6%95%B0%E6%A0%A1%E9%AA%8C%E5%AE%9E%E7%8E%B0%E5%8E%9F%E7%90%86)RequestBody ²ÎÊýУÑéʵÏÖÔÀí
+
+ÔÚ spring-mvc ÖУ¬`RequestResponseBodyMethodProcessor`?ÊÇÓÃÓÚ½âÎö?`@RequestBody`?±ê×¢µÄ²ÎÊýÒÔ¼°´¦Àí`@ResponseBody`?±ê×¢·½·¨µÄ·µ»ØÖµµÄ¡£ÆäÖУ¬Ö´ÐвÎÊýУÑéµÄÂß¼¿Ï¶¨¾ÍÔÚ½âÎö²ÎÊýµÄ·½·¨?`resolveArgument()`?ÖУº
+
+
+
+```
+@Override
+public Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
+ NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {
+
+ parameter = parameter.nestedIfOptional();
+ Object arg = readWithMessageConverters(webRequest, parameter, parameter.getNestedGenericParameterType());
+ String name = Conventions.getVariableNameForParameter(parameter);
+
+ if (binderFactory != null) {
+ WebDataBinder binder = binderFactory.createBinder(webRequest, arg, name);
+ if (arg != null) {
+ // ³¢ÊÔ½øÐвÎÊýУÑé
+ validateIfApplicable(binder, parameter);
+ if (binder.getBindingResult().hasErrors() && isBindExceptionRequired(binder, parameter)) {
+ // Èç¹û´æÔÚУÑé´íÎó£¬ÔòÅ׳ö MethodArgumentNotValidException
+ throw new MethodArgumentNotValidException(parameter, binder.getBindingResult());
+ }
+ }
+ if (mavContainer != null) {
+ mavContainer.addAttribute(BindingResult.MODEL_KEY_PREFIX + name, binder.getBindingResult());
+ }
+ }
+
+ return adaptArgumentIfNecessary(arg, parameter);
+}
+
+```
+
+
+
+¿ÉÒÔ¿´µ½£¬resolveArgument()µ÷ÓÃÁË validateIfApplicable()½øÐвÎÊýУÑé¡£
+
+
+
+```
+protected void validateIfApplicable(WebDataBinder binder, MethodParameter parameter) {
+ // »ñÈ¡²ÎÊý×¢½â£¬Èç @RequestBody¡¢@Valid¡¢@Validated
+ Annotation[] annotations = parameter.getParameterAnnotations();
+ for (Annotation ann : annotations) {
+ // Ïȳ¢ÊÔ»ñÈ¡ @Validated ×¢½â
+ Validated validatedAnn = AnnotationUtils.getAnnotation(ann, Validated.class);
+ // Èç¹û±ê×¢ÁË @Validated£¬Ö±½Ó¿ªÊ¼Ð£Ñé¡£
+ // Èç¹ûûÓУ¬ÄÇôÅжϲÎÊýǰÊÇ·ñÓÐ Valid ¿ªÍ·µÄ×¢½â¡£
+ if (validatedAnn != null || ann.annotationType().getSimpleName().startsWith("Valid")) {
+ Object hints = (validatedAnn != null ? validatedAnn.value() : AnnotationUtils.getValue(ann));
+ Object[] validationHints = (hints instanceof Object[] ? (Object[]) hints : new Object[] {hints});
+ // Ö´ÐÐУÑé
+ binder.validate(validationHints);
+ break;
+ }
+ }
+}
+
+```
+
+
+
+ÒÔÉÏ´úÂ룬¾Í½âÊÍÁË Spring ΪʲôÄÜͬʱ֧³Ö?`@Validated`¡¢`@Valid`?Á½¸ö×¢½â¡£
+
+½ÓÏÂÀ´£¬¿´Ò»Ï WebDataBinder.validate() µÄʵÏÖ£º
+
+
+
+```
+@Override
+public void validate(Object target, Errors errors, Object... validationHints) {
+ if (this.targetValidator != null) {
+ processConstraintViolations(
+ // ´Ë´¦µ÷Óà Hibernate Validator Ö´ÐÐÕæÕýµÄУÑé
+ this.targetValidator.validate(target, asValidationGroups(validationHints)), errors);
+ }
+}
+
+```
+
+
+
+ͨ¹ýÉÏÃæ´úÂ룬¿ÉÒÔ¿´³ö Spring УÑéʵ¼ÊÉÏÊÇ»ùÓÚ Hibernate Validator µÄ·â×°¡£
+
+#### [#](https://dunwu.github.io/spring-tutorial/pages/fe6aad/#%E6%96%B9%E6%B3%95%E7%BA%A7%E5%88%AB%E7%9A%84%E5%8F%82%E6%95%B0%E6%A0%A1%E9%AA%8C%E5%AE%9E%E7%8E%B0%E5%8E%9F%E7%90%86)·½·¨¼¶±ðµÄ²ÎÊýУÑéʵÏÖÔÀí
+
+Spring Ö§³Ö¸ù¾Ý·½·¨È¥½øÐÐÀ¹½Ø¡¢Ð£Ñ飬ÔÀí¾ÍÔÚÓÚÓ¦ÓÃÁË AOP ¼¼Êõ¡£¾ßÌåÀ´Ëµ£¬ÊÇͨ¹ý?`MethodValidationPostProcessor`?¶¯Ì¬×¢²á AOP ÇÐÃæ£¬È»ºóʹÓÃ?`MethodValidationInterceptor`?¶ÔÇе㷽·¨Ö¯ÈëÔöÇ¿¡£
+
+
+
+```
+public class MethodValidationPostProcessor extends AbstractBeanFactoryAwareAdvisingPostProcessorimplements InitializingBean {
+ @Override
+ public void afterPropertiesSet() {
+ // ΪËùÓÐ @Validated ±ê×¢µÄ Bean ´´½¨ÇÐÃæ
+ Pointcut pointcut = new AnnotationMatchingPointcut(this.validatedAnnotationType, true);
+ // ´´½¨ Advisor ½øÐÐÔöÇ¿
+ this.advisor = new DefaultPointcutAdvisor(pointcut, createMethodValidationAdvice(this.validator));
+ }
+
+ // ´´½¨ Advice£¬±¾ÖʾÍÊÇÒ»¸ö·½·¨À¹½ØÆ÷
+ protected Advice createMethodValidationAdvice(@Nullable Validator validator) {
+ return (validator != null ? new MethodValidationInterceptor(validator) : new MethodValidationInterceptor());
+ }
+}
+
+```
+
+
+
+½Ó×Å¿´Ò»ÏÂ?`MethodValidationInterceptor`£º
+
+
+
+```
+public class MethodValidationInterceptor implements MethodInterceptor {
+ @Override
+ public Object invoke(MethodInvocation invocation) throws Throwable {
+ // ÎÞÐèÔöÇ¿µÄ·½·¨£¬Ö±½ÓÌø¹ý
+ if (isFactoryBeanMetadataMethod(invocation.getMethod())) {
+ return invocation.proceed();
+ }
+ // »ñÈ¡·Ö×éÐÅÏ¢
+ Class>[] groups = determineValidationGroups(invocation);
+ ExecutableValidator execVal = this.validator.forExecutables();
+ Method methodToValidate = invocation.getMethod();
+ Set> result;
+ try {
+ // ·½·¨Èë²ÎУÑ飬×îÖÕ»¹ÊÇίÍиø Hibernate Validator À´Ð£Ñé
+ result = execVal.validateParameters(
+ invocation.getThis(), methodToValidate, invocation.getArguments(), groups);
+ }
+ catch (IllegalArgumentException ex) {
+ ...
+ }
+ // ÓÐÒì³£Ö±½ÓÅ׳ö
+ if (!result.isEmpty()) {
+ throw new ConstraintViolationException(result);
+ }
+ // ÕæÕýµÄ·½·¨µ÷ÓÃ
+ Object returnValue = invocation.proceed();
+ // ¶Ô·µ»ØÖµ×öУÑ飬×îÖÕ»¹ÊÇίÍиøHibernate ValidatorÀ´Ð£Ñé
+ result = execVal.validateReturnValue(invocation.getThis(), methodToValidate, returnValue, groups);
+ // ÓÐÒì³£Ö±½ÓÅ׳ö
+ if (!result.isEmpty()) {
+ throw new ConstraintViolationException(result);
+ }
+ return returnValue;
+ }
+}
+
+```
+
+
+
+ʵ¼ÊÉÏ£¬²»¹ÜÊÇ requestBody ²ÎÊýУÑ黹ÊÇ·½·¨¼¶±ðµÄУÑ飬×îÖÕ¶¼Êǵ÷Óà Hibernate Validator Ö´ÐÐУÑ飬Spring Validation Ö»ÊÇ×öÁËÒ»²ã·â×°¡£
+
+## [#](https://dunwu.github.io/spring-tutorial/pages/fe6aad/#%E9%97%AE%E9%A2%98)ÎÊÌâ
+
+**Spring ÓÐÄÄЩУÑéºËÐÄ×é¼þ**£¿
+
+* ¼ìÑéÆ÷£º`org.springframework.validation.Validator`
+* ´íÎóÊÕ¼¯Æ÷£º`org.springframework.validation.Errors`
+* Java Bean ´íÎóÃèÊö£º`org.springframework.validation.ObjectError`
+* Java Bean ÊôÐÔ´íÎóÃèÊö£º`org.springframework.validation.FieldError`
+* Bean Validation ÊÊÅ䣺`org.springframework.validation.beanvalidation.LocalValidatorFactoryBean`
+
+## [#](https://dunwu.github.io/spring-tutorial/pages/fe6aad/#%E5%8F%82%E8%80%83%E8%B5%84%E6%96%99)²Î¿¼×ÊÁÏ
+
+* [Spring ¹Ù·½ÎĵµÖ® Core Technologies(opens new window)](https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans)
+* [¡¶Ð¡Âí¸ç½² Spring ºËÐıà³Ì˼Ïë¡·(opens new window)](https://time.geekbang.org/course/intro/265)
+* https://juejin.cn/post/6856541106626363399
+
+
+# ²Î¿¼ÎÄÕÂ
+https://www.w3cschool.cn/wkspring
+https://www.runoob.com/w3cnote/basic-knowledge-summary-of-spring.html
+http://codepub.cn/2015/06/21/Basic-knowledge-summary-of-Spring
+https://dunwu.github.io/spring-tutorial
+https://mszlu.com/java/spring
+http://c.biancheng.net/spring/aop-module.html
\ No newline at end of file
diff --git "a/docs/spring/Spring\344\270\255\347\232\204Environment\347\216\257\345\242\203\345\217\230\351\207\217.md" "b/docs/spring/Spring\344\270\255\347\232\204Environment\347\216\257\345\242\203\345\217\230\351\207\217.md"
new file mode 100644
index 0000000..2c2f21a
--- /dev/null
+++ "b/docs/spring/Spring\344\270\255\347\232\204Environment\347\216\257\345\242\203\345\217\230\351\207\217.md"
@@ -0,0 +1,852 @@
+
+
+
+
+Èç½ñ£¬ÖÂÁ¦ÓÚ°ïÖú¿ª·¢ÕßÓøüÉٵĴúÂë¡¢¸ü¿ìµØÐ´³öÉú²ú¼¶ÏµÍ³µÄ Spring Boot ÒÑÈ»³ÉΪ Java Ó¦Óÿª·¢µÄÊÂʵ±ê×¼¡£ÔÚ Spring Boot ÌṩµÄÖÚ¶àÌØÐÔÖУ¬**×Ô¶¯ÅäÖÃ**ÎÞÒÉÊǶÔÌáÉý¿ª·¢ÌåÑé×îÏÔÖøµÄÒ»¸öÌØÐÔ£¬Spring Boot »ùÓÚÕâÒ»ÌØÐÔΪ¿ª·¢ÈËÔ±×Ô¶¯ÉùÃ÷ÁËÈô¸É¿ªÏä¼´Óᢾ߱¸Ä³Ò»¹¦ÄÜµÄ Bean¡£´ó¶àÊýÇé¿öÏ£¬×Ô¶¯ÅäÖÃµÄ Bean ¸ÕºÃÄÜÂú×ã´ó¼ÒµÄÐèÇ󣬵«ÔÚijЩÇé¿öÏ£¬²»µÃ²»ÍêÕûµØ¸²¸ÇËüÃÇ£¬Õâ¸öʱºòÖ»ÐèÒªÖØÐÂÉùÃ÷Ïà¹ØÀàÐ굀 Bean ¼´¿É£¬ÒòΪ¾ø´ó¶àÊý×Ô¶¯ÅäÖÃµÄ Bean ¶¼»áÓÉ`@ConditionalOnMissingBean`×¢½âÐÞÊΡ£ÐÒÔ˵ÄÊÇ£¬Èç¹ûÖ»ÊÇÏë΢µ÷һЩϸ½Ú£¬±ÈÈç¸Ä¸Ä¶Ë¿ÚºÅ (server.port) ºÍÊý¾ÝÔ´ URL (spring.datasource.url) £¬ÄÇѹ¸ùû±ØÒªÖØÐÂÉùÃ÷`ServerProperties`ºÍ`DataSourceProperties`ÕâÁ© Bean À´¸²¸Ç×Ô¶¯ÅäÖÃµÄ Bean¡£ Spring Boot Ϊ×Ô¶¯ÅäÖÃµÄ Bean ÌṩÁË1000¶à¸öÓÃÓÚ΢µ÷µÄÊôÐÔ£¬µ±ÐèÒªµ÷ÕûÉèÖÃʱ£¬Ö»ÐèÒªÔÚ»·¾³±äÁ¿¡¢ÃüÁîÐвÎÊý»òÅäÖÃÎļþ (application.properties/application.yml) ÖнøÐÐÖ¸¶¨¼´¿É£¬Õâ¾ÍÊÇ Spring Boot µÄ`Externalized Configuration` (ÅäÖÃÍ⻯) ÌØÐÔ¡£
+
+µ±È»£¬ÍⲿÅäÖÃÔ´²¢²»¾ÖÏÞÓÚ»·¾³±äÁ¿¡¢ÃüÁîÐвÎÊýºÍÅäÖÃÎļþÕâÈýÖÖ£¬¸ÐÐËȤµÄ¶ÁÕß¿ÉÒÔ×ÔÐÐÔĶÁ Spring Boot ¹Ù·½Îĵµ¡£ÔÚ Spring ÖУ¬`BeanFactory`°çÑÝ×Å Bean ÈÝÆ÷µÄ½ÇÉ«£¬¶ø`Environment`ͬÑù¶¨Î»ÎªÒ»¸öÈÝÆ÷£¬¼´ÍⲿÅäÖÃÔ´ÖеÄÊôÐÔ¶¼»á±»Ìí¼Óµ½ _Environment_ ÖС£**ÔÚ΢·þÎñ´óÐÐÆäµÀµÄ½ñÌ죬ÍⲿÅäÖÃÔ´ÓÖÑÜÉú³öÁË_Disconf_¡¢_Apollo_ ºÍ _Nacos_ µÈ·Ö²¼Ê½ÅäÖÃÖÐÐÄ£¬µ«ÔÚ Spring µÄµØÅÌ£¬»¹ÊÇÒªÈëÏçËæË×£¬´ÓÅäÖÃÖÐÐÄÖжÁÈ¡µ½µÄÊôÐÔÒÀÈ»»á±»×·¼Óµ½ _Environment_ ÖÐ**¡£
+
+±ÊÕßÖ®ËùÒÔдÕâÆªÎÄÕ£¬ÊÇÊÜ`jasypt`×é¼þµÄÆô·¢¡£µÚÒ»´Î½Ó´¥ËüÊÇÔÚ2018Ä꣬µ±Ê±¾ÍºÜºÃÆæÕâÍæÒâ¶ù¾¿¾¹ÊÇÈçºÎʵÏÖ¶ÔÃô¸ÐÊôÐÔ¼Ó½âÃܵģ»ÏÖÔÚÀ´¿´£¬ÒªÏëʵÏÖÕâôһ¸ö¶«¶«£¬²»½öÐèÒªÊìϤ Bean µÄÉúÃüÖÜÆÚ¡¢IoC ÈÝÆ÷ÍØÕ¹µã (IoC Container Extension Points) ºÍ Spring Boot µÄÆô¶¯Á÷³ÌµÈ֪ʶ£¬»¹ÐèÒªÕÆÎÕ _Environment_¡£
+
+> jasypt ÉÏÊÖÊ®·Ö¼òµ¥¡£Ê×ÏÈͨ¹ý`jasypt-maven-plugin`ÕâÒ» maven ²å¼þΪÃô¸ÐÊôÐÔÖµÉú³ÉÃÜÎÄ£¬È»ºóÓÃ`ENC(ÃÜÎÄ)`Ìæ»»Ãô¸ÐÊôÐÔÖµ¼´¿É¡£ÈçÏ£º
+>
+> ```
+> jasypt.encryptor.password=crimson_typhoon
+>
+> spring.datasource.url=jdbc:mysql://HOST:PORT/db_sql_boy?characterEncoding=UTF-8
+> spring.datasource.hikari.driver-class-name=com.mysql.cj.jdbc.Driver
+> spring.datasource.hikari.username=root
+> spring.datasource.hikari.password=ENC(qS8+DEIlHxvhPHgn1VaW3oHkn2twrmwNOHewWLIfquAXiCDBrKwvIhDoqalKyhIF)
+> ¸´ÖÆ´úÂë
+> ```
+
+## 1 ÈÏʶ Environmnent
+
+ÔÚʵ¼Ê¹¤×÷ÖУ¬ÎÒÃÇÓë _Environment_ ´ò½»µÀµÄ»ú»á²¢²»¶à£»Èç¹ûÒµÎñ Bean ȷʵÐèÒª»ñÈ¡ÍⲿÅäÖÃÔ´ÖеÄijһÊôÐÔÖµ£¬¿ÉÒÔÊÖ¶¯½« _Environment_ ×¢Èëµ½¸ÃÒµÎñ Bean ÖУ¬Ò²¿ÉÒÔÖ±½ÓʵÏÖ`EnvironmentAware`½Ó¿Ú£¬µÃµ½ _Environment_ ÀàÐ굀 Bean ʵÀýÖ®ºó¿ÉÒÔͨ¹ý`getProperty()`»ñÈ¡¾ßÌåÊôÐÔÖµ¡£_Environment_ ½Ó¿ÚÄÚÈÝÈçÏÂËùʾ£º
+
+```
+public interface Environment extends PropertyResolver {
+ String[] getActiveProfiles();
+ String[] getDefaultProfiles();
+ boolean acceptsProfiles(Profiles profiles);
+}
+
+public interface PropertyResolver {
+ boolean containsProperty(String key);
+ String getProperty(String key);
+ String getProperty(String key, String defaultValue);
+ T getProperty(String key, Class targetType);
+ T getProperty(String key, Class targetType, T defaultValue);
+ String resolvePlaceholders(String text);
+}
+¸´ÖÆ´úÂë
+```
+
+**´ó¼Ò²»ÒªÊÜ _Environment_ ÖÐ _getProperty()_ ·½·¨µÄÎóµ¼£¬ÍⲿÅäÖÃÔ´ÖеÄÊôÐÔ²¢²»ÊÇÒÔµ¥¸öÊôÐÔΪά¶È±»Ìí¼Óµ½ _Environment_ Öе쬶øÊÇÒÔ`PropertySource`Ϊά¶È**¡£_PropertySource_ ÊǶÔÊôÐÔÔ´Ãû³ÆºÍ¸ÃÊôÐÔÔ´ÖÐÒ»×éÊôÐԵijéÏó£¬`MapPropertySource`ÊÇÒ»ÖÖ×î¼òµ¥µÄʵÏÖ£¬Ëüͨ¹ý _Map_ À´³ÐÔØÏà¹ØµÄÊôÐÔ¡£_PropertySource_ ÄÚÈÝÈçÏ£º
+
+```
+public abstract class PropertySource {
+ protected final String name;
+ protected final T source;
+
+ public PropertySource(String name, T source) {
+ this.name = name;
+ this.source = source;
+ }
+
+ public String getName() { return this.name; }
+ public T getSource() { return this.source; }
+ public abstract Object getProperty(String name);
+}
+¸´ÖÆ´úÂë
+```
+
+´ÓÉÏÊö _PropertySource_ ÄÚÈÝÀ´¿´£¬_PropertySource_ ×ÔÉíÊǾ߱¸¸ù¾ÝÊôÐÔÃû»ñÈ¡ÊôÐÔÖµÕâÒ»ÄÜÁ¦µÄ¡£
+
+#### ****getProperty()ÄÚ²¿Ö´ÐÐÂß¼****
+
+
+
+Ò»°ã£¬_Environment_ ʵÏÖÀàÖлá³ÖÓÐÒ»¸ö`PropertyResolver`ÀàÐ͵ijÉÔ±±äÁ¿£¬½ø¶ø½»ÓÉ _PropertyResolver_ ¸ºÔðÖ´ÐÐ _getProperty()_ Âß¼¡£_PropertyResolver_ ʵÏÖÀàÖÐÓÖ»á³ÖÓÐÁ½¸ö³ÉÔ±±äÁ¿£¬·Ö±ðÊÇ£º`ConversionService`Óë`PropertySources`£»Ê×ÏÈ£¬_PropertyResolver_ ±éÀú `PropertySources` ÖÐµÄ _PropertySource_£¬»ñÈ¡ÔÉúÊôÐÔÖµ£»È»ºóίÅÉ _ConversionService_ ¶ÔÔÉúÊôÐÔÖµ½øÐÐÊý¾ÝÀàÐÍת»» (Èç¹ûÓбØÒªµÄ»°)¡£**ËäÈ» PropertySource ×ÔÉíÊǾ߱¸¸ù¾ÝÊôÐÔÃû»ñÈ¡ÊôÐÔÖµÕâÒ»ÄÜÁ¦µÄ£¬µ«²»¾ß±¸Õ¼Î»·û½âÎöÓëÀàÐÍת»»ÄÜÁ¦£¬ÓÚÊÇÔÚÖмäÒýÈë¾ß±¸ÕâÁ½ÖÖÄÜÁ¦µÄ PropertyResolver£¬ ÕâÒ²Ó¡Ö¤ÁËÒ»¸ö¶Î×Ó£ºÔÚ¼ÆËã»ú¿ÆÑ§ÖУ¬Ã»ÓÐʲôÎÊÌâÊÇÔÚÖмä¼ÓÒ»²ã½â¾ö²»Á˵ģ¬Èç¹ûÓУ¬ÄǾÍÔÙ¼ÓÒ»²ã**¡£
+
+#### ****PropertySourceÄÚ²¿¸üÐÂÂß¼****
+
+
+
+_Environment_ ʵÏÖÀàÖгýÁ˳ÖÓÐ`PropertyResolver`ÀàÐ͵ijÉÔ±±äÁ¿Í⣬»¹ÓÐÒ»¸ö`MutablePropertySources`ÀàÐ͵ijÉÔ±±äÁ¿£¬µ«²¢²»Ìṩֱ½Ó²Ù×÷¸Ã _MutablePropertySources_ µÄ·½·¨£¬ÎÒÃÇÖ»ÄÜͨ¹ý`getPropertySources()`·½·¨»ñÈ¡ _MutablePropertySources_ ʵÀý£¬È»ºó½èÖú _MutablePropertySources_ ÖеÄ`addFirst()`¡¢`addLast()`ºÍ`replace()`µÈ·½·¨È¥¸üР_PropertySource_¡£_MutablePropertySources_ ÊÇ _PropertySources_ Ψһһ¸öʵÏÖÀ࣬ÈçÏÂͼËùʾ£º
+
+
+
+×ܵÄÀ´Ëµ£¬_Environment_ ÊÇ¶Ô _PropertySource_ ºÍ _Profile_ µÄ¶¥¼¶³éÏó£¬ÏÂÃæ½éÉÜ _Profile_ µÄ¸ÅÄî¡£µ±Ó¦ÓóÌÐòÐèÒª²¿Êðµ½²»Í¬µÄÔËÐл·¾³Ê±£¬Ò»Ð©ÊôÐÔÏîͨ³£»áÓÐËù²»Í¬£¬±ÈÈ磬Êý¾ÝÔ´ URL ÔÚ¿ª·¢»·¾³ºÍ²âÊÔ»·¾³¾Í»á²»Ò»Ñù¡£Spring ´Ó3.1°æ±¾¿ªÊ¼Ö§³Ö»ùÓÚ _Profile_ µÄÌõ¼þ»¯ÅäÖá£
+
+**Profile in Spring 3.1**
+
+ÔÚ Spring ·¢²¼3.1°æ±¾Ê±£¬Spring Boot »¹Î´ÎÊÊÀ£¬¿ÉÒÔ˵´ËʱµÄ _Profile_ ÌØÐÔ»¹ÊÇÓÐЩ**覴Ã**µÄ£¬µ«è¦²»ÑÚ褡£Ö÷ÒªÌåÏÖÔÚ£ºÕë¶ÔͬһÀàÐ굀 Bean£¬±ØÐëÉùÃ÷¶à´Î¡£Ò»ÆðÀ´¸ÐÊÜÏÂÕâÖÖС覴ãº
+
+```
+@Configuration(proxyBeanMethods = false)
+public class DataSourceConfig {
+ @Bean
+ @Profile("dev")
+ public DataSource devDataSource () {
+ return DataSourceBuilder.create()
+ .driverClassName("com.mysql.jdbc.Driver")
+ .url("jdbc:mysql://DEV_HOST:PORT/db_sql_boy?characterEncoding=UTF-8")
+ .username("dev")
+ .password("dev")
+ .build();
+ }
+
+ @Bean
+ @Profile("test")
+ public DataSource testDataSource () {
+ return DataSourceBuilder.create()
+ .driverClassName("com.mysql.jdbc.Driver")
+ .url("jdbc:mysql://TEST_HOST:PORT/db_sql_boy?characterEncoding=UTF-8")
+ .username("test")
+ .password("test")
+ .build();
+ }
+}
+¸´ÖÆ´úÂë
+```
+
+**Profile in Spring Boot**
+
+Spring Boot ·¢²¼ºó£¬`@Profile`×¢½â¿ÉÒÔÈÓµ½¾ÅÏöÔÆÍâÁË¡£¹Ù·½¿ª·¢´óÀп϶¨Ò²Òâʶµ½ _Profile in Spring 3.1_ ÖÐÕâÖÖ覴ã¬ÓÚÊÇÔÚ Spring Boot µÄµÚÒ»°æ±¾ _(1.0.0.RELEASE)_ ÖÐ¾ÍÆÈ²»¼°´ýµØÖ§³ÖΪ _application.properties_ ºÍ _application.yml_ ÀïµÄÊôÐÔÏîÅäÖà _Profile_ ÁË¡£»»¸ö¿Ú棬һÆðÀ´¸ÐÊÜÏÂÕâÖÖÓÅÑÅ£º
+
+```
+@Configuration(proxyBeanMethods = false)
+public class DataSourceConfig {
+ @Bean
+ public DataSource devDataSource (DataSourceProperties dataSourceProperties) {
+ return DataSourceBuilder.create()
+ .driverClassName(dataSourceProperties.getDriverClassName())
+ .url(dataSourceProperties.getUrl())
+ .username(dataSourceProperties.getUsername())
+ .password(dataSourceProperties.getPassword())
+ .build();
+ }
+}
+¸´ÖÆ´úÂë
+```
+
+_application-dev.properties_ ÄÚÈÝÈçÏ£º
+
+```
+spring.datasource.url=jdbc:mysql://DEV_HOST:PORT/db_sql_boy?characterEncoding=UTF-8
+spring.datasource.hikari.driver-class-name=com.mysql.jdbc.Driver
+spring.datasource.hikari.password=dev
+spring.datasource.hikari.username=dev
+¸´ÖÆ´úÂë
+```
+
+_application-test.properties_ ÄÚÈÝÈçÏ£º
+
+```
+spring.datasource.url=jdbc:mysql://TEST_HOST:PORT/db_sql_boy?characterEncoding=UTF-8
+spring.datasource.hikari.driver-class-name=com.mysql.jdbc.Driver
+spring.datasource.hikari.password=test
+spring.datasource.hikari.username=test
+¸´ÖÆ´úÂë
+```
+
+ÔÚÔÉú Spring 3.1 ºÍ Spring Boot ÖУ¬¾ùÊÇͨ¹ý`spring.profiles.active`À´Îª _Environment_ Ö¸¶¨¼¤»îµÄ _Profile_£¬·ñÔò_Environment_ ÖÐĬÈϼ¤»îµÄ _Profile_ Ãû³ÆÎª`default`¡£Ð´µ½ÕâÀ±ÊÕßÄÔº£ÖÐÉÁÏÖÒ»¸öÎÊÌ⣺һ°ã£¬`@Profile` ×¢½âÖ÷ÒªÓë _@Configuration_ ×¢½â»ò _@Bean_ ×¢½â´îÅäʹÓã¬Èç¹û _spring.profiles.active_ µÄֵΪ _dev_ ʱ£¬ÄÇôÄÇЩÓÉ _@Configuration_ »ò _@Bean_ ×¢½â±ê¼Ç (µ«Ã»ÓÐ`@Profile`×¢½âµÄÉíÓ°¹þ) µÄ Bean »¹»á±»½âÎöΪÈô¸É`BeanDefinition`ʵÀýÂ𣿴ð°¸ÊÇ»áµÄ¡£`ConfigurationClassPostProcessor`¸ºÔ𽫠_@Configuration_ ÅäÖÃÀà½âÎöΪ _BeanDefinition_£¬Ôڴ˹ý³ÌÖлáÖ´ÐÐ`ConditionEvaluator`µÄ`shouldSkip()`·½·¨£¬Ö÷ÒªÄÚÈÝÈçÏ£º
+
+```
+public class ConditionEvaluator {
+ public boolean shouldSkip(AnnotatedTypeMetadata metadata, ConfigurationCondition.ConfigurationPhase phase) {
+ if (metadata == null || !metadata.isAnnotated(Conditional.class.getName())) {
+ return false;
+ }
+
+ if (phase == null) {
+ if (metadata instanceof AnnotationMetadata &&
+ ConfigurationClassUtils.isConfigurationCandidate((AnnotationMetadata) metadata)) {
+ return shouldSkip(metadata, ConfigurationCondition.ConfigurationPhase.PARSE_CONFIGURATION);
+ }
+ return shouldSkip(metadata, ConfigurationCondition.ConfigurationPhase.REGISTER_BEAN);
+ }
+
+ List conditions = new ArrayList<>();
+ for (String[] conditionClasses : getConditionClasses(metadata)) {
+ for (String conditionClass : conditionClasses) {
+ Condition condition = getCondition(conditionClass, this.context.getClassLoader());
+ conditions.add(condition);
+ }
+ }
+
+ AnnotationAwareOrderComparator.sort(conditions);
+
+ for (Condition condition : conditions) {
+ ConfigurationCondition.ConfigurationPhase requiredPhase = null;
+ if (condition instanceof ConfigurationCondition) {
+ requiredPhase = ((ConfigurationCondition) condition).getConfigurationPhase();
+ }
+ if ((requiredPhase == null || requiredPhase == phase) && !condition.matches(this.context, metadata)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
+¸´ÖÆ´úÂë
+```
+
+`shouldSkip()`·½·¨µÚÒ»ÐÐ _if_ Óï¾ä¾ÍÊǴ𰸣¬`@Profile`×¢½âÓÉ`@Conditional(ProfileCondition.class)`ÐÞÊΣ¬ÄÇÈç¹ûÒ»¸öÅäÖÃÀàÍ·ÉÏûÓÐ`Condition`µÄÉíÓ°£¬Ö±½Ó·µ»Ø`false`ÁË£¬ÄǾÍÊDz»Ìø¹ý¸ÃÅäÖÃÀàµÄÒâ˼ඣ¡
+
+_Environment_ ÖеÄÕâЩ _PropertySource_ ¾¿¾¹ÓÐɶÓ𡣿µ±È»ÊÇΪÁËÌî³ä _Bean_ à¶£¬·Ï»°²»¶à˵£¬ÉÏͼ¡£
+
+
+
+> ±ÊÕßÒÔǰ¶¼ÊÇÓà visio ºÍ processOn »Í¼£¬µÚÒ»´ÎÌåÑé draw.io£¬Ã»Ïëµ½Èç´ËÓÅÐ㣬ǿÁÒ°²ÀûÒ»²¨£¡
+
+## 2 Environmnent ³õʼ»¯Á÷³Ì
+
+±¾½ÚÖ÷Òª½éÉÜ Spring Boot ÔÚÆô¶¯¹ý³ÌÖÐÏò _Environmnt_ Öо¿¾¹×¢²áÁËÄÄЩ _PropertySource_¡£Æô¶¯Èë¿ÚλÓÚ`SpringApplication`ÖеÄ`run(String... args)`·½·¨£¬ÈçÏ£º
+
+```
+public class SpringApplication {
+ public ConfigurableApplicationContext run(String... args) {
+ StopWatch stopWatch = new StopWatch();
+ stopWatch.start();
+ DefaultBootstrapContext bootstrapContext = createBootstrapContext();
+ ConfigurableApplicationContext context = null;
+ configureHeadlessProperty();
+ SpringApplicationRunListeners listeners = getRunListeners(args);
+ listeners.starting(bootstrapContext, this.mainApplicationClass);
+ try {
+ ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
+ ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
+ configureIgnoreBeanInfo(environment);
+ Banner printedBanner = printBanner(environment);
+ context = createApplicationContext();
+ context.setApplicationStartup(this.applicationStartup);
+ prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
+ refreshContext(context);
+ afterRefresh(context, applicationArguments);
+ stopWatch.stop();
+ if (this.logStartupInfo) {
+ new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
+ }
+ listeners.started(context);
+ callRunners(context, applicationArguments);
+ } catch (Throwable ex) {
+ handleRunFailure(context, ex, listeners);
+ throw new IllegalStateException(ex);
+ }
+
+ try {
+ listeners.running(context);
+ } catch (Throwable ex) {
+ handleRunFailure(context, ex, null);
+ throw new IllegalStateException(ex);
+ }
+ return context;
+ }
+}
+¸´ÖÆ´úÂë
+```
+
+¿ÉÒÔÃ÷ÏÔ¿´³ö£¬_Environmnt_ µÄ³õʼ»¯ÊÇÔÚ`refreshContext(context)`֮ǰÍê³ÉµÄ£¬ÕâÊǺÁÎÞÒÉÎʵġ£_run()_ ·½·¨ºÜ¸´ÔÓ£¬µ«Óë±¾ÎÄÖ÷ÌâÆõºÏµÄÂß¼Ö»ÓÐ**Ò»**´¦£º
+
+```
+prepareEnvironment(listeners, bootstrapContext, applicationArguments);
+¸´ÖÆ´úÂë
+```
+
+ÏÂÃæ·Ö±ð·ÖÎöÕâÁ½´¦ºËÐÄÂß¼¡£
+
+### 2.1 prepareEnvironment()
+
+ÏÔÈ»£¬ºËÐÄÄÚÈݶ¼ÔÚ`prepareEnvironment()`·½·¨ÄÚ£¬ÏÂÃæ·ÖС½ÚÖðÒ»·ÖÎö¡£
+
+```
+public class SpringApplication {
+ private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,
+ DefaultBootstrapContext bootstrapContext,
+ ApplicationArguments applicationArguments) {
+ // 2.1.1
+ ConfigurableEnvironment environment = getOrCreateEnvironment();
+ // 2.1.2
+ configureEnvironment(environment, applicationArguments.getSourceArgs());
+ // 2.1.3
+ ConfigurationPropertySources.attach(environment);
+ // 2.1.4
+ listeners.environmentPrepared(bootstrapContext, environment);
+ DefaultPropertiesPropertySource.moveToEnd(environment);
+ bindToSpringApplication(environment);
+ ConfigurationPropertySources.attach(environment);
+ return environment;
+ }
+}
+¸´ÖÆ´úÂë
+```
+
+#### 2.1.1 getOrCreateEnvironment()
+
+`getOrCreateEnvironment()`Ö÷Òª¸ºÔð¹¹½¨ _Environment_ ʵÀý¡£Èç¹ûµ±Ç°Ó¦ÓÃÊÇ»ùÓÚ`ͬ²½×èÈûI/O`Ä£Ð͵ģ¬Ôò _Environment_ Ñ¡ÓÃ`ApplicationServletEnvironment`£»Ïà·´µØ£¬Èç¹ûµ±Ç°Ó¦ÓÃÊÇ»ùÓÚ`Òì²½·Ç×èÈûI/O`Ä£Ð͵ģ¬Ôò _Environment_ Ñ¡ÓÃ`ApplicationReactiveWebEnvironment`¡£ÎÒÃǹ¤×÷Öлù±¾¶¼ÊÇ»ùÓÚ Spring MVC ¿ª·¢Ó¦Óã¬Spring MVC ÊÇÒ»¿î¹¹½¨ÓÚ`Servlet API`Ö®ÉÏ¡¢»ùÓÚͬ²½×èÈû I/O Ä£Ð͵ÄÖ÷Á÷ Java Web ¿ª·¢¿ò¼Ü£¬ÕâÖÖ I/O Ä£ÐÍÒâζ×ÅÒ»¸ö HTTP ÇëÇó¶ÔÓ¦Ò»¸öỊ̈߳¬¼´Ã¿Ò»¸ö HTTP ÇëÇó¶¼ÊÇÔÚ¸÷×ÔÏß³ÌÉÏÏÂÎÄÖÐÍê³É´¦ÀíµÄ¡£_ApplicationServletEnvironment_ ¼Ì³Ð¹ØÏµÈçÏÂͼËùʾ£º
+
+
+
+´ÓÉÏͼ¿ÉÒÔ¿´³ö _ApplicationServletEnvironment_ ¼Ò×åÏ൱ÅÓ´ó£¬ÔÚÖ´ÐÐ _ApplicationServletEnvironment_ ¹¹Ôì·½·¨µÄʱºò±ØÈ»»á´¥·¢¸÷¼¶¸¸À๹Ôì·½·¨ÖеÄÂß¼£¬**ÒÀ´ÎΪ**£º
+
+```
+public abstract class AbstractEnvironment implements ConfigurableEnvironment {
+ public AbstractEnvironment() {
+ this(new MutablePropertySources());
+ }
+
+ protected AbstractEnvironment(MutablePropertySources propertySources) {
+ this.propertySources = propertySources;
+ // createPropertyResolver(propertySources)
+ // |___ ConfigurationPropertySources.createPropertyResolver(propertySources)
+ // |___ new ConfigurationPropertySourcesPropertyResolver(propertySources)
+ this.propertyResolver = createPropertyResolver(propertySources);
+ customizePropertySources(propertySources);
+ }
+}
+¸´ÖÆ´úÂë
+```
+
+```
+public class StandardServletEnvironment extends StandardEnvironment implements ConfigurableWebEnvironment {
+ @Override
+ protected void customizePropertySources(MutablePropertySources propertySources) {
+ propertySources.addLast(new StubPropertySource("servletConfigInitParams"));
+ propertySources.addLast(new StubPropertySource("servletContextInitParams"));
+ super.customizePropertySources(propertySources);
+ }
+}
+¸´ÖÆ´úÂë
+```
+
+```
+public class StandardEnvironment extends AbstractEnvironment {
+ @Override
+ protected void customizePropertySources(MutablePropertySources propertySources) {
+ propertySources.addLast(
+ new PropertiesPropertySource("systemProperties", (Map) System.getProperties()));
+ propertySources.addLast(
+ new SystemEnvironmentPropertySource("systemEnvironment", (Map) System.getenv()));
+ }
+}
+¸´ÖÆ´úÂë
+```
+
+Ëæ×Å _ApplicationServletEnvironment_ ¹¹Ôì·½·¨µÄÖ´ÐУ¬´ËʱÔÚ _Environment_ Àï _MutablePropertySources_ ÀàÐ͵ijÉÔ±±äÁ¿`propertySources`ÖÐÒѾÓÐÁË**ËÄ**¸ö _PropertySource_ ÁË£¬Ãû³ÆÒÀ´ÎÊÇ£º`servletConfigInitParams`¡¢`servletContextInitParams`¡¢`systemProperties`ºÍ`systemEnvironment`¡£´ËÍ⣬ҲҪ¼Çס _ApplicationServletEnvironment_ ÖеÄÁ½¸öÖØÒª³ÉÔ±±äÁ¿£¬¼´`MutablePropertySources`ºÍ`ConfigurationPropertySourcesPropertyResolver`¡£
+
+#### 2.1.2 configureEnvironment()
+
+`configureEnvironment()`·½·¨ÖеÄÂß¼Ò²ºÜ¼òµ¥¹þ¡£Ê×ÏÈ£¬Îª _Environment_ ÖÐµÄ _PropertySourcesPropertyResolver_ É趨 _ConversionService_£»È»ºó£¬Ïò _Environment_ ÖÐµÄ _MutablePropertySources_ ×·¼ÓÒ»¸öÃû³ÆÎª`commandLineArgs`µÄ _PropertySource_ ʵÀý£¬×¢ÒâʹÓõÄÊÇ`addFirst()`·½·¨Å¶£¬ÕâÒâζ×ÅÕâ¸öÃû³ÆÎª`commandLineArgs`µÄ _PropertySource_ ÓÅÏȼ¶ÊÇ×î¸ßµÄ¡£Ö÷ÒªÂß¼ÈçÏ£º
+
+```
+public class SpringApplication {
+ protected void configureEnvironment(ConfigurableEnvironment environment, String[] args) {
+ if (this.addConversionService) {
+ environment.getPropertyResolver().setConversionService(new ApplicationConversionService());
+ }
+ if (this.addCommandLineProperties && args.length > 0) {
+ MutablePropertySources sources = environment.getPropertySources();
+ sources.addFirst(new SimpleCommandLinePropertySource(args));
+ }
+ }
+}
+¸´ÖÆ´úÂë
+```
+
+¼ÌÐø`SimpleCommandLinePropertySource`£º
+
+```
+public class SimpleCommandLinePropertySource extends CommandLinePropertySource {
+ public SimpleCommandLinePropertySource(String... args) {
+ // Æä¸¸À๹Ôì·½·¨Îª£ºsuper("commandLineArgs", source)
+ super(new SimpleCommandLineArgsParser().parse(args));
+ }
+}
+¸´ÖÆ´úÂë
+```
+
+ÃüÁîÐвÎÊý»¹ÊDZȽϳ£Óõ쬱ÈÈçÎÒÃÇÔÚÆô¶¯ Spring Boot Ó¦ÓÃʱ»áÕâÑùÉùÃ÷ÃüÁîÐвÎÊý£º`java -jar app.jar --server.port=8088`¡£
+
+#### 2.1.3 ConfigurationPropertySources.attach()
+
+`attach()`·½·¨Ö÷Òª¾ÍÊÇÔÚ _Environment_ ÖÐ _MutablePropertySources_ µÄÍ·²¿Î»ÖòåÈë¼ÓÒ»¸öÃû³ÆÎª`configurationProperties`µÄ _PropertySource_ ʵÀý¡£Ö÷ÒªÂß¼ÈçÏ£º
+
+```
+public final class ConfigurationPropertySources {
+ public static void attach(org.springframework.core.env.Environment environment) {
+ MutablePropertySources sources = ((ConfigurableEnvironment) environment).getPropertySources();
+ PropertySource> attached = getAttached(sources);
+ if (attached != null && attached.getSource() != sources) {
+ sources.remove(ATTACHED_PROPERTY_SOURCE_NAME);
+ attached = null;
+ }
+ if (attached == null) {
+ sources.addFirst(new ConfigurationPropertySourcesPropertySource("configurationProperties", new SpringConfigurationPropertySources(sources)));
+ }
+ }
+
+ static PropertySource> getAttached(MutablePropertySources sources) {
+ return (sources != null) ? sources.get("configurationProperties") : null;
+ }
+}
+¸´ÖÆ´úÂë
+```
+
+±ÊÕß¶¢×ÅÕâÍæÒâ¶ù¿´Á˺þã¬Ñ¹¸ùû¿´³öÕâ¸öÃû³ÆÎª`configurationProperties`µÄ _PropertySource_ ¾¿¾¹ÓÐɶÓá£×îºó£¬»¹ÊÇÔÚ¹Ù·½ÎĵµÖйØÓÚ`Relaxed Binding` (¿íËɰó¶¨) µÄÃèÊöÖв³öÁËЩ¶ËÄß¡£»¹ÊÇͨ¹ý´úÂëÀ´½â¶Á±È½ÏÖ±½Ó¡£Ê×ÏÈ£¬ÔÚ _application.properties_ ÖÐ×·¼ÓÒ»¸öÅäÖÃÏ`a.b.my-first-key=hello spring environment`£»È»ºó£¬Í¨¹ý _Environment_ È¡³öÕâ¸öÅäÖÃÏîµÄÖµ£¬ÈçÏ£º
+
+```
+@SpringBootApplication
+public class DemoApplication {
+ public static void main(String[] args) {
+ ConfigurableApplicationContext configurableApplicationContext = SpringApplication.run(DemoApplication.class, args);
+ ConfigurableWebEnvironment environment = (ConfigurableWebEnvironment)
+ configurableApplicationContext.getBean(Environment.class);
+ System.out.println(environment.getProperty("a.b.my-first-key"));
+ }
+}
+¸´ÖÆ´úÂë
+```
+
+Æô¶¯Ó¦Óú󣬿ØÖÆÌ¨´òÓ¡³öÁË _hello spring environment_ ×ÖÑù£¬ÕâÓëÔ¤ÆÚÊÇÏà·ûµÄ¡£¿Éµ±ÎÒÃÇͨ¹ý`environment.getProperty("a.b.myfirstkey")`»òÕß`environment.getProperty("a.b.my-firstkey")`ÒÀÈ»Äܹ»»ñÈ¡µ½ÅäÖÃÏîµÄÄÚÈÝ¡£`a.b.myfirstkey`ºÍ`a.b.my-firstkey`²¢²»ÊÇÅäÖÃÎļþÖеÄÊôÐÔÃû³Æ£¬Ö»ÊÇÏàËÆ¶øÒÑ£¬ÕâµÄÈ·ºÜ**¿íËÉ**°¡£¬¹þ¹þ¡£¸ÐÐËȤµÄ¶ÁÕß¿ÉÒÔ×ÔÐÐ DEBUG ¿´¿´ÆäÖеÄÔÀí¡£
+
+#### 2.1.4 listeners.environmentPrepared()
+
+Çúڰ壬¸÷λ´óÀУ¬Õâ¸öÒª¿¼µÄ £¡`environmentPrepared()`·½·¨»á¹ã²¥Ò»¸ö`ApplicationEnvironmentPreparedEvent`ʼþ£¬½Ó×ÅÓÉ`EnvironmentPostProcessorApplicationListener`ÏìÓ¦¸Ãʼþ£¬ÕâÓ¦¸ÃÊǵäÐ͵Ä**¹Û²ìÕßģʽ**¡£Ö÷ÒªÄÚÈÝÈçÏ£º
+
+```
+public class SpringApplicationRunListeners {
+ private final List listeners;
+
+ void environmentPrepared(ConfigurableBootstrapContext bootstrapContext, ConfigurableEnvironment environment) {
+ doWithListeners("spring.boot.application.environment-prepared",
+ (listener) -> listener.environmentPrepared(bootstrapContext, environment));
+ }
+
+ private void doWithListeners(String stepName, Consumer listenerAction) {
+ StartupStep step = this.applicationStartup.start(stepName);
+ this.listeners.forEach(listenerAction);
+ step.end();
+ }
+}
+
+public class EventPublishingRunListener implements SpringApplicationRunListener, Ordered {
+ @Override
+ public void environmentPrepared(ConfigurableBootstrapContext bootstrapContext,
+ ConfigurableEnvironment environment) {
+ this.initialMulticaster.multicastEvent(
+ new ApplicationEnvironmentPreparedEvent(bootstrapContext, this.application, this.args, environment));
+ }
+}
+
+public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {
+ @Override
+ public void multicastEvent(ApplicationEvent event) {
+ multicastEvent(event, resolveDefaultEventType(event));
+ }
+
+ @Override
+ public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
+ ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
+ Executor executor = getTaskExecutor();
+ for (ApplicationListener> listener : getApplicationListeners(event, type)) {
+ if (executor != null) {
+ executor.execute(() -> invokeListener(listener, event));
+ } else {
+ invokeListener(listener, event);
+ }
+ }
+ }
+}
+¸´ÖÆ´úÂë
+```
+
+ÏÂÃæÀ´¿´Ò»ÏÂ`EnvironmentPostProcessorApplicationListener`µÄÂ®É½ÕæÃæÄ¿£º
+
+```
+public class EnvironmentPostProcessorApplicationListener implements SmartApplicationListener, Ordered {
+ @Override
+ public void onApplicationEvent(ApplicationEvent event) {
+ if (event instanceof ApplicationEnvironmentPreparedEvent) {
+ onApplicationEnvironmentPreparedEvent((ApplicationEnvironmentPreparedEvent) event);
+ }
+ if (event instanceof ApplicationPreparedEvent) {
+ onApplicationPreparedEvent();
+ }
+ if (event instanceof ApplicationFailedEvent) {
+ onApplicationFailedEvent();
+ }
+ }
+ private void onApplicationEnvironmentPreparedEvent(ApplicationEnvironmentPreparedEvent event) {
+ ConfigurableEnvironment environment = event.getEnvironment();
+ SpringApplication application = event.getSpringApplication();
+ for (EnvironmentPostProcessor postProcessor : getEnvironmentPostProcessors(application.getResourceLoader(), event.getBootstrapContext())) {
+ postProcessor.postProcessEnvironment(environment, application);
+ }
+ }
+}
+¸´ÖÆ´úÂë
+```
+
+`EnvironmentPostProcessor`ÊÇ Spring Boot Ϊ _Environment_ Á¿Éí´òÔìµÄÀ©Õ¹µã¡£ÕâÀïÒýÓùٷ½ÎĵµÖбȽϾ«Á¶µÄÒ»¾ä»°£º_Allows for customization of the application's Environment prior to the application context being refreshed_¡£_EnvironmentPostProcessor_ ÊÇÒ»¸öº¯ÊýÐÔ½Ó¿Ú£¬ÄÚÈÝÈçÏ£º
+
+```
+public interface EnvironmentPostProcessor {
+ void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application);
+}
+¸´ÖÆ´úÂë
+```
+
+ÔÚÉÏÊö _EnvironmentPostProcessorApplicationListener_ ʼþ´¦ÀíÂß¼ÖУ¬`getEnvironmentPostProcessors`¸ºÔð¼ÓÔØ³öËùÓÐµÄ _EnvironmentPostProcessor_ ¡£¿´Ò»ÏÂÄÚ²¿¼ÓÔØÂß¼£º
+
+```
+public interface EnvironmentPostProcessorsFactory {
+ static EnvironmentPostProcessorsFactory fromSpringFactories(ClassLoader classLoader) {
+ return new ReflectionEnvironmentPostProcessorsFactory(
+ classLoader,
+ SpringFactoriesLoader.loadFactoryNames(EnvironmentPostProcessor.class, classLoader)
+ );
+ }
+}
+¸´ÖÆ´úÂë
+```
+
+¼ÌÐø½øÈë`SpringFactoriesLoader`һ̽¾¿¾¹£º
+
+```
+public final class SpringFactoriesLoader {
+
+ public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
+
+ public static List loadFactoryNames(Class> factoryType, ClassLoader classLoader) {
+ ClassLoader classLoaderToUse = classLoader;
+ if (classLoaderToUse == null) {
+ classLoaderToUse = SpringFactoriesLoader.class.getClassLoader();
+ }
+ String factoryTypeName = factoryType.getName();
+ return loadSpringFactories(classLoaderToUse).getOrDefault(factoryTypeName, Collections.emptyList());
+ }
+
+ private static Map> loadSpringFactories(ClassLoader classLoader) {
+ Map> result = cache.get(classLoader);
+ if (result != null) {
+ return result;
+ }
+
+ result = new HashMap<>();
+ try {
+ Enumeration urls = classLoader.getResources(FACTORIES_RESOURCE_LOCATION);
+ while (urls.hasMoreElements()) {
+ URL url = urls.nextElement();
+ UrlResource resource = new UrlResource(url);
+ Properties properties = PropertiesLoaderUtils.loadProperties(resource);
+ for (Map.Entry, ?> entry : properties.entrySet()) {
+ String factoryTypeName = ((String) entry.getKey()).trim();
+ String[] factoryImplementationNames = StringUtils.commaDelimitedListToStringArray((String) entry.getValue());
+ for (String factoryImplementationName : factoryImplementationNames) {
+ result.computeIfAbsent(factoryTypeName, key -> new ArrayList<>())
+ .add(factoryImplementationName.trim());
+ }
+ }
+ }
+ result.replaceAll((factoryType, implementations) -> implementations.stream().distinct()
+ .collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList)));
+ cache.put(classLoader, result);
+ } catch (IOException ex) {
+ throw new IllegalArgumentException("Unable to load factories from location [" + FACTORIES_RESOURCE_LOCATION + "]", ex);
+ }
+ return result;
+ }
+}
+¸´ÖÆ´úÂë
+```
+
+> **Spring SPI**
+>
+> > _SpringFactoriesLoader_ ÕâÒ»Ì×Âß¼¾ÍÊÇ Spring ÖеÄ`SPI`»úÖÆ£»Ö±°×µã˵£¬¾ÍÊÇ´Ó`classpath`ϵÄ`META-INF/spring.factories` ÎļþÖмÓÔØ _EnvironmentPostProcessor_ £¬Èç¹û´ó¼ÒÓÐÐèÇó¾Í½«×Ô¼ºÊµÏÖµÄ _EnvironmentPostProcessor_ ·Åµ½¸ÃÎļþÖоÍÐÐÁË¡£ÆäʵÓë`JDK`ÖеÄ`SPI`»úÖÆºÜÀàËÆ¹þ¡£
+
+ÔÚµ±Ç°°æ±¾£¬Spring Boot ÄÚÖÃÁË7¸ö _EnvironmentPostProcessor_ ʵÏÖÀà¡£½ÓÏÂÀ´Ìô¼¸¸ö±È½ÏµäÐ͵ķÖÎöÏ¡£
+
+**RandomValuePropertySourceEnvironmentPostProcessor**
+
+`RandomValuePropertySourceEnvironmentPostProcessor`Ïò _Environment_ ÖÐ×·¼ÓÁËÒ»¸öÃû³ÆÎª`random`µÄ _PropertySource_£¬¼´`RandomValuePropertySource`¡£ÄÚÈÝÈçÏ£º
+
+```
+public class RandomValuePropertySourceEnvironmentPostProcessor implements EnvironmentPostProcessor, Ordered {
+ public static final int ORDER = Ordered.HIGHEST_PRECEDENCE + 1;
+ private final Log logger;
+
+ public RandomValuePropertySourceEnvironmentPostProcessor(Log logger) {
+ this.logger = logger;
+ }
+
+ @Override
+ public int getOrder() {
+ return ORDER;
+ }
+
+ @Override
+ public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
+ RandomValuePropertySource.addToEnvironment(environment, this.logger);
+ }
+}
+¸´ÖÆ´úÂë
+```
+
+ÄÇôÕâ¸ö _RandomValuePropertySource_ ÓÐɶ×÷ÓÃÄØ£¿Ö÷Òª¾ÍÊÇÓÃÓÚÉú³ÉËæ»úÊý£¬±ÈÈ磺`environment.getProperty("random.int(5,10)")`¿ÉÒÔ»ñȡһ¸öËæ»úÊý¡£ÒÔ`random.int`ΪÊôÐÔÃû¿ÉÒÔ»ñȡһ¸ö _int_ ÀàÐ͵ÄËæ»úÊý£»ÒÔ`random.long`ΪÊôÐÔÃû¿ÉÒÔ»ñȡһ¸ö _long_ ÀàÐ͵ÄËæ»úÊý£»ÒÔ`random.int(5,10)`ΪÊôÐÔÃû¿ÉÒÔ»ñȡһ¸ö _[5, 10}_ Çø¼äÄÚ _int_ ÀàÐ͵ÄËæ»úÊý£¬¸ü¶àÍæ·¨´ó¼Ò×ÔÐÐ̽Ë÷¡£
+
+_SystemEnvironmentPropertySourceEnvironmentPostProcessor_
+
+µ±Ç°£¬_Environment_ ÖÐÒѾ´æÔÚÒ»¸öÃû³ÆÎª`systemEnvironment`µÄ _PropertySource_£¬¼´`SystemEnvironmentPropertySource`¡£`SystemEnvironmentPropertySourceEnvironmentPostProcessor`ÓÃÓÚ½«¸Ã _SystemEnvironmentPropertySource_ Ìæ»»Îª`OriginAwareSystemEnvironmentPropertySource`£¬Õ¦Óе㡰ÍÑ¿ã×Ó·ÅÆ¨£¬¶à´ËÒ»¾Ù¡±µÄ¸Ð¾õÄØ£¬¹þ¹þ¡£
+
+```
+public class SystemEnvironmentPropertySourceEnvironmentPostProcessor implements EnvironmentPostProcessor, Ordered {
+ public static final int DEFAULT_ORDER = SpringApplicationJsonEnvironmentPostProcessor.DEFAULT_ORDER - 1;
+ private int order = DEFAULT_ORDER;
+
+ @Override
+ public int getOrder() {
+ return this.order;
+ }
+
+ @Override
+ public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
+ String sourceName = "systemEnvironment";
+ PropertySource> propertySource = environment.getPropertySources().get(sourceName);
+ if (propertySource != null) {
+ replacePropertySource(environment, sourceName, propertySource, application.getEnvironmentPrefix());
+ }
+ }
+ private void replacePropertySource(ConfigurableEnvironment environment, String sourceName,
+ PropertySource> propertySource, String environmentPrefix) {
+ Map originalSource = (Map) propertySource.getSource();
+ SystemEnvironmentPropertySource source = new OriginAwareSystemEnvironmentPropertySource(sourceName, originalSource, environmentPrefix);
+ environment.getPropertySources().replace(sourceName, source);
+ }
+}
+¸´ÖÆ´úÂë
+```
+
+**SpringApplicationJsonEnvironmentPostProcessor**
+
+ÎÒÃÇÔÚͨ¹ý`java -jar -Dspring.application.json={"name":"duxiaotou"} app.jar`Æô¶¯ Spring Boot Ó¦ÓõÄʱºò£¬¸ÃÊôÐԻᱻ×Ô¶¯Ìí¼Óµ½ JVM ϵͳÊôÐÔÖÐ (Æäʵ _-Dkey=value_ ÕâÖÖÐÎʽµÄÊôÐÔ¾ùÊÇÈç´Ë)£¬ÆäµÈЧÓÚ`System.setProperty(key, value)`£»¶øµ±´æÔÚ`SPRING_APPLICATION_JSON`Õâһϵͳ±äÁ¿Ê±£¬×ÔȻҲ»áÔÚ`System.getenv()`ÖгöÏÖ¡£Ç°ÃæÔø¾Ìáµ½¹ý`System.getProperties()`´ú±íµÄÊÇ`systemProperties`ÕâÒ» _PropertySource_£¬¶ø`System.getenv()`Ôò´ú±íµÄÊÇ`systemEnvironment`ÕâÒ» _PropertySource_¡£`SpringApplicationJsonEnvironmentPostProcessor`¾ÍÊÇÓÃÓÚ´ÓÕâÁ½¸ö _PropertySource_ ÖгéÈ¡³ö _spring.application.json_ »ò _SPRING_APPLICATION_JSON_ µÄ _JSON_ ´®£¬½ø¶øµ¥¶ÀÏò _Environment_ ÖÐ×·¼ÓÒ»¸öÃû³ÆÎª`spring.application.json`µÄ _PropertySource_£¬¼´`JsonPropertySource`¡£
+
+**ConfigDataEnvironmentPostProcessor**
+
+`ConfigDataEnvironmentPostProcessor`¸ºÔð½«`optional:classpath:/`¡¢`optional:classpath:/config/`¡¢`optional:file:./`¡¢`optional:file:./config/`ºÍ`optional:file:./config/*/`ÕâЩĿ¼Ï嵀 _application.properties_ ÅäÖÃÎļþ¼ÓÔØ³öÀ´£»Èç¹û»¹Ö¸¶¨ÁË _spring.profiles.active_µÄ»°£¬Í¬Ê±Ò²»á½«ÕâЩĿ¼Ï嵀 _application-{profile}.properties_ ÅäÖÃÎļþ¼ÓÔØ³öÀ´¡£×îÖÕ£¬_ConfigDataEnvironmentPostProcessor_ ½«»áÏò _Environment_ ÖÐ×·¼ÓÁ½¸ö`OriginTrackedMapPropertySource`£¬ÕâÁ© _PropertySource_ λÓÚ _Environment_ µÄβ²¿£»ÆäÖÐ _application-{profile}.properties_ Ëù´ú±íµÄ _OriginTrackedMapPropertySource_ ÊÇÅÅÔÚ _application.properties_ Ëù´ú±íµÄ _OriginTrackedMapPropertySource_ Ç°ÃæµÄ£¬ÕâÒ»µãÍ¦ÖØÒª¡£
+
+## 3 jasypt ºËÐÄÔÀí½â¶Á
+
+> `jasypt`»ù´¡×é¼þ¿âÓë`jasypt-spring-boot-starter`ÊDz»Í¬×÷ÕßдµÄ£¬ºóÕßÖ»ÊÇΪ jasypt ×é¼þ¿ª·¢ÁË Spring Boot µÄÆð²½ÒÀÀµ×é¼þ¶øÒÑ¡£±¾ÎÄËù·ÖÎöµÄÆäʵ¾ÍÊÇÕâ¸öÆð²½ÒÀÀµ×é¼þ¡£
+
+_application.properties_ ÅäÖÃÎļþÖйØÓÚÊý¾ÝÔ´µÄÃÜÂëÊÇÒ»¸ö¼ÓÃܺóµÄÃÜÎÄ£¬ÈçÏ£º
+
+```
+spring.datasource.hikari.password=ENC(4+t9a5QG8NkNdWVS6UjIX3dj18UtYRMqU6eb3wUKjivOiDHFLZC/RTK7HuWWkUtV)
+¸´ÖÆ´úÂë
+```
+
+µ±`HikariDataSource`Íê³ÉÊôÐÔÌî³ä²Ù×÷ºó£¬¸Ã Bean ÖÐ _password_ ×ֶεÄÖµÕ¦¾Í±äΪ½âÃܺóµÄ _qwe@1234_ ÕâÒ»Ã÷ÎÄÁËÄØ£¿ÏÔÈ»£¬Spring Boot Ϊ _Environment_ ÌṩµÄ`EnvironmentPostProcessor`ÕâÒ»ÍØÕ¹µã¿ÉÒÔʵÏÖ͵Ìì»»ÈÕ£¡µ«×÷ÕßûÓÐÓÃËü£¬¶øÊÇʹÓÃÁË Spring ÖеÄÒ»¸ö _IoC ÍØÕ¹µã_£¬¼´`BeanFactoryPostProcessor`£¬ÕâÒ²ÊÇÍêÈ«¿ÉÒԵģ¬ÒòΪµ±Ö´Ðе½ _BeanFactoryPostProcessor_ ÖеÄ`postProcessBeanFactory()`Â߼ʱ£¬Ö»ÊÇÍê³ÉÁËËùÓÐ`BeanDefinition`µÄ¼ÓÔØ£¬µ«»¹Ã»ÓÐʵÀý»¯ _BeanDefinition_ ¸÷×ÔËù¶ÔÓ¦µÄ Bean¡£
+
+ÏÂÃæ¿´Ò»ÏÂ`EnableEncryptablePropertiesBeanFactoryPostProcessor`ÖеÄÄÚÈÝ£º
+
+```
+public class EnableEncryptablePropertiesBeanFactoryPostProcessor implements BeanFactoryPostProcessor, Ordered {
+
+ private final ConfigurableEnvironment environment;
+ private final EncryptablePropertySourceConverter converter;
+
+ public EnableEncryptablePropertiesBeanFactoryPostProcessor(ConfigurableEnvironment environment, EncryptablePropertySourceConverter converter) {
+ this.environment = environment;
+ this.converter = converter;
+ }
+
+ @Override
+ public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
+ MutablePropertySources propSources = environment.getPropertySources();
+ converter.convertPropertySources(propSources);
+ }
+
+ @Override
+ public int getOrder() {
+ return Ordered.LOWEST_PRECEDENCE - 100;
+ }
+}
+¸´ÖÆ´úÂë
+```
+
+ÉÏÊöÔ´Âë±íÃ÷¸Ã _BeanFactoryPostProcessor_ ½èÖú`EncryptablePropertySourceConverter`¶Ô _MutablePropertySources_ ×öÁËÒ»²ãת»»£¬ÄÇôת»»³ÉɶÁËÄØ£¿
+
+½Ó×Å£¬¸ú½ø _EncryptablePropertySourceConverter_£¬ºËÐÄÄÚÈÝÈçÏ£º
+
+```
+public class EncryptablePropertySourceConverter {
+
+ public void convertPropertySources(MutablePropertySources propSources) {
+ propSources.stream()
+ .filter(ps -> !(ps instanceof EncryptablePropertySource))
+ .map(this::makeEncryptable)
+ .collect(toList())
+ .forEach(ps -> propSources.replace(ps.getName(), ps));
+ }
+
+ public PropertySource makeEncryptable(PropertySource propertySource) {
+ if (propertySource instanceof EncryptablePropertySource
+ || skipPropertySourceClasses.stream().anyMatch(skipClass -> skipClass.equals(propertySource.getClass()))) {
+ return propertySource;
+ }
+ PropertySource encryptablePropertySource = convertPropertySource(propertySource);
+ return encryptablePropertySource;
+ }
+
+ private PropertySource convertPropertySource(PropertySource propertySource) {
+ PropertySource encryptablePropertySource;
+ if (propertySource instanceof SystemEnvironmentPropertySource) {
+ encryptablePropertySource = (PropertySource) new EncryptableSystemEnvironmentPropertySourceWrapper((SystemEnvironmentPropertySource) propertySource, propertyResolver, propertyFilter);
+ } else if (propertySource instanceof MapPropertySource) {
+ encryptablePropertySource = (PropertySource) new EncryptableMapPropertySourceWrapper((MapPropertySource) propertySource, propertyResolver, propertyFilter);
+ } else if (propertySource instanceof EnumerablePropertySource) {
+ encryptablePropertySource = new EncryptableEnumerablePropertySourceWrapper<>((EnumerablePropertySource) propertySource, propertyResolver, propertyFilter);
+ } else {
+ encryptablePropertySource = new EncryptablePropertySourceWrapper<>(propertySource, propertyResolver, propertyFilter);
+ }
+ return encryptablePropertySource;
+ }
+}
+¸´ÖÆ´úÂë
+```
+
+ÏÔÈ»£¬Ëü½«Ïà¹ØÔÉú _PropertySource_ ת»»ÎªÁËÒ»¸ö`EncryptablePropertySourceWrapper`£¬ÄÇÕâ¸ö¿Ï¶¨¿ÉÒÔʵÏÖÃÜÎĽâÃÜ£¬±ØÐëµÄ£¡
+
+¼ÌÐø£¬¸ú½ø`EncryptablePropertySourceWrapper`£¬ÄÚÈÝÈçÏ£º
+
+```
+public class EncryptablePropertySourceWrapper extends PropertySource implements EncryptablePropertySource {
+ private final CachingDelegateEncryptablePropertySource encryptableDelegate;
+
+ public EncryptablePropertySourceWrapper(PropertySource delegate, EncryptablePropertyResolver resolver, EncryptablePropertyFilter filter) {
+ super(delegate.getName(), delegate.getSource());
+ encryptableDelegate = new CachingDelegateEncryptablePropertySource<>(delegate, resolver, filter);
+ }
+
+ @Override
+ public Object getProperty(String name) {
+ return encryptableDelegate.getProperty(name);
+ }
+
+ @Override
+ public PropertySource getDelegate() {
+ return encryptableDelegate;
+ }
+}
+¸´ÖÆ´úÂë
+```
+
+ʧÍû£¡Ã»¿´³öɶ½âÃÜÂß¼£¬µ«´ÓÆä _getProperty_ ·½·¨À´¿´£¬½«¾ßÌå½âÎöÂ߼ίÅɸøÁË`CachingDelegateEncryptablePropertySource`¡£
+
+û°ì·¨£¬Ö»Äܵ½ _CachingDelegateEncryptablePropertySource_ ÖÐһ̽¾¿¾¹ÁË£º
+
+```
+public class CachingDelegateEncryptablePropertySource extends PropertySource implements EncryptablePropertySource {
+ private final PropertySource delegate;
+ private final EncryptablePropertyResolver resolver;
+ private final EncryptablePropertyFilter filter;
+ private final Map cache;
+
+ public CachingDelegateEncryptablePropertySource(PropertySource delegate, EncryptablePropertyResolver resolver, EncryptablePropertyFilter filter) {
+ super(delegate.getName(), delegate.getSource());
+ this.delegate = delegate;
+ this.resolver = resolver;
+ this.filter = filter;
+ this.cache = new HashMap<>();
+ }
+
+ @Override
+ public PropertySource getDelegate() {
+ return delegate;
+ }
+
+ @Override
+ public Object getProperty(String name) {
+ if (cache.containsKey(name)) {
+ return cache.get(name);
+ }
+ synchronized (name.intern()) {
+ if (!cache.containsKey(name)) {
+ Object resolved = getProperty(resolver, filter, delegate, name);
+ if (resolved != null) {
+ cache.put(name, resolved);
+ }
+ }
+ return cache.get(name);
+ }
+ }
+}
+¸´ÖÆ´úÂë
+```
+
+ÖÕÓÚ£¬¸ú½øµ½`EncryptablePropertySource`Öп´µ½Á˽âÃܵÄ×îÖÕÂß¼¡£ÆäÖУ¬`EncryptablePropertyDetector`¸ºÔð̽²âÏà¹ØÊôÐÔÊÇ·ñÐèÒª¶ÔÆä½âÃÜ£¬Ö÷Ҫͨ¹ýÅжϸÃÊôÐÔÖµÊÇ·ñÓÉ`ENC()`°ü¹ü¡£
+
+```
+public interface EncryptablePropertySource extends OriginLookup {
+ default Object getProperty(EncryptablePropertyResolver resolver, EncryptablePropertyFilter filter, PropertySource source, String name) {
+ Object value = source.getProperty(name);
+ if (value != null && filter.shouldInclude(source, name) && value instanceof String) {
+ String stringValue = String.valueOf(value);
+ return resolver.resolvePropertyValue(stringValue);
+ }
+ return value;
+ }
+}
+
+public class DefaultPropertyResolver implements EncryptablePropertyResolver {
+
+ private final Environment environment;
+ private StringEncryptor encryptor;
+ private EncryptablePropertyDetector detector;
+
+ @Override
+ public String resolvePropertyValue(String value) {
+ return Optional.ofNullable(value)
+ .map(environment::resolvePlaceholders)
+ .filter(detector::isEncrypted)
+ .map(resolvedValue -> {
+ try {
+ String unwrappedProperty = detector.unwrapEncryptedValue(resolvedValue.trim());
+ String resolvedProperty = environment.resolvePlaceholders(unwrappedProperty);
+ return encryptor.decrypt(resolvedProperty);
+ } catch (EncryptionOperationNotPossibleException e) {
+ throw new DecryptionException("Unable to decrypt property: " + value + " resolved to: " + resolvedValue + ". Decryption of Properties failed, make sure encryption/decryption " +
+ "passwords match", e);
+ }
+ })
+ .orElse(value);
+ }
+}
+¸´ÖÆ´úÂë
+```
+
+## 4 ×ܽá
+
+×ܽáÐÔµÄÎÄ×־Ͳ»ÔÙ˵ÁË£¬±ÊÕßÏÖÔÚÎÄ˼Ȫӿ£¬·ñÔòÓÖÄÜË®300×Ö¡£×îºó£¬Ï£Íû´ó¼Ò¼ÇסÔÚµ±Ç° Spring Boot °æ±¾ÖУ¬ÓÉ`ApplicationServletEnvironment`°çÑÝ _Environment_£¬Æä×îÖÕ½«Î¯ÅÉ`ConfigurationPropertySourcesPropertyResolver`È¥»ñÈ¡ÊôÐÔÖµ¡£
+
+## 5 ²Î¿¼Îĵµ
+
+1. [docs.spring.io/spring-boot¡](https://link.juejin.cn?target=https%3A%2F%2Fdocs.spring.io%2Fspring-boot%2Fdocs%2F2.5.7%2Freference%2Fhtml%2Ffeatures.html "https://docs.spring.io/spring-boot/docs/2.5.7/reference/html/features.html")
+
+
+
+×÷Õߣº³ÌÐòÔ³¶ÅСͷ
+Á´½Ó£ºhttps://juejin.cn/post/7098299623759937543
+À´Ô´£ºÏ¡ÍÁ¾ò½ð
+Öø×÷Ȩ¹é×÷ÕßËùÓС£ÉÌÒµ×ªÔØÇëÁªÏµ×÷Õß»ñµÃÊÚȨ£¬·ÇÉÌÒµ×ªÔØÇë×¢Ã÷³ö´¦¡£
+
+# ²Î¿¼ÎÄÕÂ
+https://www.w3cschool.cn/wkspring
+https://www.runoob.com/w3cnote/basic-knowledge-summary-of-spring.html
+http://codepub.cn/2015/06/21/Basic-knowledge-summary-of-Spring
+https://dunwu.github.io/spring-tutorial
+https://mszlu.com/java/spring
+http://c.biancheng.net/spring/aop-module.html
\ No newline at end of file
diff --git "a/docs/spring/Spring\344\270\255\347\232\204\344\272\213\344\273\266\345\244\204\347\220\206\346\234\272\345\210\266.md" "b/docs/spring/Spring\344\270\255\347\232\204\344\272\213\344\273\266\345\244\204\347\220\206\346\234\272\345\210\266.md"
new file mode 100644
index 0000000..6acb8a1
--- /dev/null
+++ "b/docs/spring/Spring\344\270\255\347\232\204\344\272\213\344\273\266\345\244\204\347\220\206\346\234\272\345\210\266.md"
@@ -0,0 +1,270 @@
+
+
+
+
+# Spring ÖеÄʼþ´¦Àí
+
+
+
+2022-05-16 15:29 ¸üÐÂ
+
+
+
+
+
+
+
+
+
+## Spring ÖеÄʼþ´¦Àí
+
+ÄãÒѾ¿´µ½ÁËÔÚËùÓÐÕ½ÚÖÐ Spring µÄºËÐÄÊÇ?**ApplicationContext**£¬Ëü¸ºÔð¹ÜÀí beans µÄÍêÕûÉúÃüÖÜÆÚ¡£µ±¼ÓÔØ beans ʱ£¬ApplicationContext ·¢²¼Ä³Ð©ÀàÐ͵Äʼþ¡£ÀýÈ磬µ±ÉÏÏÂÎÄÆô¶¯Ê±£¬ContextStartedEvent ·¢²¼£¬µ±ÉÏÏÂÎÄֹͣʱ£¬ContextStoppedEvent ·¢²¼¡£
+
+ͨ¹ý ApplicationEvent ÀàºÍ ApplicationListener ½Ó¿ÚÀ´ÌṩÔÚ ApplicationContext Öд¦Àíʼþ¡£Èç¹ûÒ»¸ö bean ʵÏÖ ApplicationListener£¬ÄÇôÿ´Î ApplicationEvent ±»·¢²¼µ½ ApplicationContext ÉÏ£¬ÄǸö bean »á±»Í¨Öª¡£
+
+Spring ÌṩÁËÒÔϵıê׼ʼþ£º
+
+| ÐòºÅ | Spring ÄÚÖÃʼþ & ÃèÊö |
+| --- | --- |
+| 1 | **ContextRefreshedEvent**ApplicationContext ±»³õʼ»¯»òË¢ÐÂʱ£¬¸Ãʼþ±»·¢²¼¡£ÕâÒ²¿ÉÒÔÔÚ ConfigurableApplicationContext ½Ó¿ÚÖÐʹÓà refresh() ·½·¨À´·¢Éú¡£ |
+| 2 | **ContextStartedEvent**µ±Ê¹Óà ConfigurableApplicationContext ½Ó¿ÚÖÐµÄ start() ·½·¨Æô¶¯ ApplicationContext ʱ£¬¸Ãʼþ±»·¢²¼¡£Äã¿ÉÒÔµ÷²éÄãµÄÊý¾Ý¿â£¬»òÕßÄã¿ÉÒÔÔÚ½ÓÊܵ½Õâ¸öʼþºóÖØÆôÈκÎÍ£Ö¹µÄÓ¦ÓóÌÐò¡£ |
+| 3 | **ContextStoppedEvent**µ±Ê¹Óà ConfigurableApplicationContext ½Ó¿ÚÖÐµÄ stop() ·½·¨Í£Ö¹ ApplicationContext ʱ£¬·¢²¼Õâ¸öʼþ¡£Äã¿ÉÒÔÔÚ½ÓÊܵ½Õâ¸öʼþºó×ö±ØÒªµÄÇåÀíµÄ¹¤×÷¡£ |
+| 4 | **ContextClosedEvent**µ±Ê¹Óà ConfigurableApplicationContext ½Ó¿ÚÖÐµÄ close() ·½·¨¹Ø±Õ ApplicationContext ʱ£¬¸Ãʼþ±»·¢²¼¡£Ò»¸öÒѹرյÄÉÏÏÂÎĵ½´ïÉúÃüÖÜÆÚÄ©¶Ë£»Ëü²»Äܱ»Ë¢Ð»òÖØÆô¡£ |
+| 5 | **RequestHandledEvent**ÕâÊÇÒ»¸ö web-specific ʼþ£¬¸æËßËùÓÐ bean HTTP ÇëÇóÒѾ±»·þÎñ¡£ |
+
+ÓÉÓÚ Spring µÄʼþ´¦ÀíÊǵ¥Ï̵߳ģ¬ËùÒÔÈç¹ûÒ»¸öʼþ±»·¢²¼£¬Ö±ÖÁ²¢ÇÒ³ý·ÇËùÓеĽÓÊÕÕߵõ½µÄ¸ÃÏûÏ¢£¬¸Ã½ø³Ì±»×èÈû²¢ÇÒÁ÷³Ì½«²»»á¼ÌÐø¡£Òò´Ë£¬Èç¹ûʼþ´¦Àí±»Ê¹Óã¬ÔÚÉè¼ÆÓ¦ÓóÌÐòʱӦעÒâ¡£
+
+## ¼àÌýÉÏÏÂÎÄʼþ
+
+ΪÁ˼àÌýÉÏÏÂÎÄʼþ£¬Ò»¸ö bean Ó¦¸ÃʵÏÖÖ»ÓÐÒ»¸ö·½·¨?**onApplicationEvent()**?µÄ ApplicationListener ½Ó¿Ú¡£Òò´Ë£¬ÎÒÃÇдһ¸öÀý×ÓÀ´¿´¿´Ê¼þÊÇÈçºÎ´«²¥µÄ£¬ÒÔ¼°ÈçºÎ¿ÉÒÔÓôúÂëÀ´Ö´ÐлùÓÚijЩʼþËùÐèµÄÈÎÎñ¡£
+
+ÈÃÎÒÃÇÔÚÇ¡µ±µÄλÖÃʹÓà Eclipse IDE£¬È»ºó°´ÕÕÏÂÃæµÄ²½ÖèÀ´´´½¨Ò»¸ö Spring Ó¦ÓóÌÐò£º
+
+| ²½Öè | ÃèÊö |
+| --- | --- |
+| 1 | ´´½¨Ò»¸öÃû³ÆÎª SpringExample µÄÏîÄ¿£¬²¢ÇÒÔÚ´´½¨ÏîÄ¿µÄ?**src**?Îļþ¼ÐÖд´½¨Ò»¸ö°ü com.tutorialspoint¡£ |
+| 2 | ʹÓà Add External JARs Ñ¡ÏÌí¼ÓËùÐèµÄ Spring ¿â£¬½âÊͼû Spring Hello World Example Õ½ڡ£ |
+| 3 | ÔÚ com.tutorialspoint °üÖд´½¨ Java Àà HelloWorld¡¢CStartEventHandler¡¢CStopEventHandler ºÍ MainApp¡£ |
+| 4 | ÔÚ?**src**?Îļþ¼ÐÖд´½¨ Bean µÄÅäÖÃÎļþ Beans.xml¡£ |
+| 5 | ×îºóÒ»²½ÊÇ´´½¨µÄËùÓÐ Java ÎļþºÍ Bean ÅäÖÃÎļþµÄÄÚÈÝ£¬²¢ÔËÐÐÓ¦ÓóÌÐò£¬½âÊÍÈçÏÂËùʾ¡£ |
+
+ÕâÀïÊÇ?**HelloWorld.java**?ÎļþµÄÄÚÈÝ£º
+
+```
+package com.tutorialspoint;
+public class HelloWorld {
+ private String message;
+ public void setMessage(String message){
+ this.message = message;
+ }
+ public void getMessage(){
+ System.out.println("Your Message : " + message);
+ }
+}
+```
+
+ÏÂÃæÊÇ?**CStartEventHandler.java**?ÎļþµÄÄÚÈÝ£º
+
+```
+package com.tutorialspoint;
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.event.ContextStartedEvent;
+public class CStartEventHandler
+ implements ApplicationListener{
+ public void onApplicationEvent(ContextStartedEvent event) {
+ System.out.println("ContextStartedEvent Received");
+ }
+}
+```
+
+ÏÂÃæÊÇ?**CStopEventHandler.java**?ÎļþµÄÄÚÈÝ£º
+
+```
+package com.tutorialspoint;
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.event.ContextStoppedEvent;
+public class CStopEventHandler
+ implements ApplicationListener{
+ public void onApplicationEvent(ContextStoppedEvent event) {
+ System.out.println("ContextStoppedEvent Received");
+ }
+}
+```
+
+ÏÂÃæÊÇ?**MainApp.java**?ÎļþµÄÄÚÈÝ£º
+
+```
+package com.tutorialspoint;
+
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+public class MainApp {
+ public static void main(String[] args) {
+ ConfigurableApplicationContext context =
+ new ClassPathXmlApplicationContext("Beans.xml");
+
+ // Let us raise a start event.
+ context.start();
+
+ HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
+
+ obj.getMessage();
+
+ // Let us raise a stop event.
+ context.stop();
+ }
+}
+```
+
+ÏÂÃæÊÇÅäÖÃÎļþ?**Beans.xml**?Îļþ£º
+
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+Ò»µ©ÄãÍê³ÉÁË´´½¨Ô´ºÍ bean µÄÅäÖÃÎļþ£¬ÎÒÃǾͿÉÒÔÔËÐиÃÓ¦ÓóÌÐò¡£Èç¹ûÄãµÄÓ¦ÓóÌÐòÒ»Çж¼Õý³££¬½«Êä³öÒÔÏÂÏûÏ¢£º
+
+```
+ContextStartedEvent Received
+Your Message : Hello World!
+ContextStoppedEvent Received
+```
+
+
+
+
+
+
+
+## Spring ÖеÄ×Ô¶¨Òåʼþ
+
+±àдºÍ·¢²¼×Ô¼ºµÄ×Ô¶¨ÒåʼþÓÐÐí¶à²½Öè¡£°´ÕÕÔÚÕâÒ»Õ¸ø³öµÄ˵Ã÷À´±àд£¬·¢²¼ºÍ´¦Àí×Ô¶¨Òå Spring ʼþ¡£
+
+| ²½Öè | ÃèÊö |
+| --- | --- |
+| 1 | ´´½¨Ò»¸öÃû³ÆÎª SpringExample µÄÏîÄ¿£¬²¢ÇÒÔÚ´´½¨ÏîÄ¿µÄ?**src**?Îļþ¼ÐÖд´½¨Ò»¸ö°ü com.tutorialspoint¡£ |
+| 2 | ʹÓà Add External JARs Ñ¡ÏÌí¼ÓËùÐèµÄ Spring ¿â£¬½âÊͼû Spring Hello World Example Õ½ڡ£ |
+| 3 | ͨ¹ýÀ©Õ¹?**ApplicationEvent**,´´½¨Ò»¸öʼþÀà CustomEvent¡£Õâ¸öÀà±ØÐ붨ÒåÒ»¸öĬÈϵĹ¹Ô캯Êý£¬ËüÓ¦¸Ã´Ó ApplicationEvent ÀàÖм̳еĹ¹Ô캯Êý¡£ |
+| 4 | Ò»µ©¶¨ÒåʼþÀ࣬Äã¿ÉÒÔ´ÓÈκÎÀàÖз¢²¼Ëü£¬¼Ù¶¨ EventClassPublisher ʵÏÖÁË ApplicationEventPublisherAware¡£Ä㻹ÐèÒªÔÚ XML ÅäÖÃÎļþÖÐÉùÃ÷Õâ¸öÀà×÷Ϊһ¸ö bean£¬Ö®ËùÒÔÈÝÆ÷¿ÉÒÔʶ±ð bean ×÷Ϊʼþ·¢²¼Õߣ¬ÊÇÒòΪËüʵÏÖÁË ApplicationEventPublisherAware ½Ó¿Ú¡£ |
+| 5 | ·¢²¼µÄʼþ¿ÉÒÔÔÚÒ»¸öÀàÖб»´¦Àí£¬¼Ù¶¨ EventClassHandler ʵÏÖÁË ApplicationListener ½Ó¿Ú£¬¶øÇÒʵÏÖÁË×Ô¶¨ÒåʼþµÄ onApplicationEvent ·½·¨¡£ |
+| 6 | ÔÚ?**src**?Îļþ¼ÐÖд´½¨ bean µÄÅäÖÃÎļþ Beans.xml ºÍ MainApp À࣬Ëü¿ÉÒÔ×÷Ϊһ¸ö Spring Ó¦ÓóÌÐòÀ´ÔËÐС£ |
+| 7 | ×îºóÒ»²½ÊÇ´´½¨µÄËùÓÐ Java ÎļþºÍ Bean ÅäÖÃÎļþµÄÄÚÈÝ£¬²¢ÔËÐÐÓ¦ÓóÌÐò£¬½âÊÍÈçÏÂËùʾ¡£ |
+
+Õâ¸öÊÇ?**CustomEvent.java**?ÎļþµÄÄÚÈÝ£º
+
+```
+package com.tutorialspoint;
+import org.springframework.context.ApplicationEvent;
+public class CustomEvent extends ApplicationEvent{
+ public CustomEvent(Object source) {
+ super(source);
+ }
+ public String toString(){
+ return "My Custom Event";
+ }
+}
+
+```
+
+ÏÂÃæÊÇ?**CustomEventPublisher.java**?ÎļþµÄÄÚÈÝ£º
+
+```
+package com.tutorialspoint;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.context.ApplicationEventPublisherAware;
+public class CustomEventPublisher
+ implements ApplicationEventPublisherAware {
+ private ApplicationEventPublisher publisher;
+ public void setApplicationEventPublisher
+ (ApplicationEventPublisher publisher){
+ this.publisher = publisher;
+ }
+ public void publish() {
+ CustomEvent ce = new CustomEvent(this);
+ publisher.publishEvent(ce);
+ }
+}
+```
+
+ÏÂÃæÊÇ?**CustomEventHandler.java**?ÎļþµÄÄÚÈÝ£º
+
+```
+package com.tutorialspoint;
+import org.springframework.context.ApplicationListener;
+public class CustomEventHandler
+ implements ApplicationListener{
+ public void onApplicationEvent(CustomEvent event) {
+ System.out.println(event.toString());
+ }
+}
+```
+
+ÏÂÃæÊÇ?**MainApp.java**?ÎļþµÄÄÚÈÝ£º
+
+```
+package com.tutorialspoint;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+public class MainApp {
+ public static void main(String[] args) {
+ ConfigurableApplicationContext context =
+ new ClassPathXmlApplicationContext("Beans.xml");
+ CustomEventPublisher cvp =
+ (CustomEventPublisher) context.getBean("customEventPublisher");
+ cvp.publish();
+ cvp.publish();
+ }
+}
+```
+
+ÏÂÃæÊÇÅäÖÃÎļþ?**Beans.xml**£º
+
+```
+
+
+
+
+
+
+
+
+
+```
+
+Ò»µ©ÄãÍê³ÉÁË´´½¨Ô´ºÍ bean µÄÅäÖÃÎļþºó£¬ÎÒÃǾͿÉÒÔÔËÐиÃÓ¦ÓóÌÐò¡£Èç¹ûÄãµÄÓ¦ÓóÌÐòÒ»Çж¼Õý³££¬½«Êä³öÒÔÏÂÐÅÏ¢£º
+
+```
+My Custom Event
+My Custom Event
+```
+
+# ²Î¿¼ÎÄÕÂ
+https://www.w3cschool.cn/wkspring
+https://www.runoob.com/w3cnote/basic-knowledge-summary-of-spring.html
+http://codepub.cn/2015/06/21/Basic-knowledge-summary-of-Spring
+https://dunwu.github.io/spring-tutorial
+https://mszlu.com/java/spring
+http://c.biancheng.net/spring/aop-module.html
\ No newline at end of file
diff --git "a/docs/spring/Spring\344\270\255\347\232\204\350\265\204\346\272\220\347\256\241\347\220\206.md" "b/docs/spring/Spring\344\270\255\347\232\204\350\265\204\346\272\220\347\256\241\347\220\206.md"
new file mode 100644
index 0000000..09874af
--- /dev/null
+++ "b/docs/spring/Spring\344\270\255\347\232\204\350\265\204\346\272\220\347\256\241\347\220\206.md"
@@ -0,0 +1,309 @@
+## Resource ½Ó¿Ú
+
+Ïà¶Ô±ê×¼ URL ·ÃÎÊ»úÖÆ£¬Spring µÄ `org.springframework.core.io.Resource` ½Ó¿Ú³éÏóÁ˶Եײã×ÊÔ´µÄ·ÃÎʽӿڣ¬ÌṩÁËÒ»Ì׸üºÃµÄ·ÃÎÊ·½Ê½¡£
+
+
+
+```
+public interface Resource extends InputStreamSource {
+
+ boolean exists();
+
+ boolean isReadable();
+
+ boolean isOpen();
+
+ boolean isFile();
+
+ URL getURL() throws IOException;
+
+ URI getURI() throws IOException;
+
+ File getFile() throws IOException;
+
+ ReadableByteChannel readableChannel() throws IOException;
+
+ long contentLength() throws IOException;
+
+ long lastModified() throws IOException;
+
+ Resource createRelative(String relativePath) throws IOException;
+
+ String getFilename();
+
+ String getDescription();
+}
+
+```
+
+
+
+ÕýÈç `Resource` ½Ó¿ÚµÄ¶¨ÒåËùʾ£¬ËüÀ©Õ¹ÁË `InputStreamSource` ½Ó¿Ú¡£`Resource` ×îºËÐĵķ½·¨ÈçÏ£º
+
+* `getInputStream()` - ¶¨Î»²¢ÇÒ´ò¿ªµ±Ç°×ÊÔ´£¬·µ»Øµ±Ç°×ÊÔ´µÄ `InputStream`¡£Ã¿´Îµ÷Óö¼»á·µ»ØÒ»¸öÐ嵀 `InputStream`¡£µ÷ÓÃÕßÐèÒª¸ºÔð¹Ø±ÕÁ÷¡£
+* `exists()` - Åжϵ±Ç°×ÊÔ´ÊÇ·ñÕæµÄ´æÔÚ¡£
+* `isOpen()` - Åжϵ±Ç°×ÊÔ´ÊÇ·ñÊÇÒ»¸öÒÑ´ò¿ªµÄ `InputStream`¡£Èç¹ûΪ true£¬Ôò `InputStream` ²»Äܱ»¶à´Î¶ÁÈ¡£¬±ØÐëÖ»¶Áȡһ´ÎÈ»ºó¹Ø±ÕÒÔ±ÜÃâ×ÊԴй©¡£¶ÔËùÓг£ÓÃ×ÊԴʵÏÖ·µ»Ø false£¬`InputStreamResource` ³ýÍâ¡£
+* `getDescription()` - ·µ»Øµ±Ç°×ÊÔ´µÄÃèÊö£¬µ±´¦Àí×ÊÔ´³ö´íʱ£¬×ÊÔ´µÄÃèÊö»áÓÃÓÚ´íÎóÐÅÏ¢µÄÊä³ö¡£Ò»°ãÀ´Ëµ£¬×ÊÔ´µÄÃèÊöÊÇÒ»¸öÍêÈ«ÏÞ¶¨µÄÎļþÃû³Æ£¬»òÕßÊǵ±Ç°×ÊÔ´µÄÕæÊµ URL¡£
+
+³£¼û Spring ×ÊÔ´½Ó¿Ú£º
+
+| ÀàÐÍ | ½Ó¿Ú |
+| --- | --- |
+| ÊäÈëÁ÷ | `org.springframework.core.io.InputStreamSource` |
+| Ö»¶Á×ÊÔ´ | `org.springframework.core.io.Resource` |
+| ¿Éд×ÊÔ´ | `org.springframework.core.io.WritableResource` |
+| ±àÂë×ÊÔ´ | `org.springframework.core.io.support.EncodedResource` |
+| ÉÏÏÂÎÄ×ÊÔ´ | `org.springframework.core.io.ContextResource` |
+
+
+
+
+
+## [#](https://dunwu.github.io/spring-tutorial/pages/a1549f/#%E5%86%85%E7%BD%AE%E7%9A%84-resource-%E5%AE%9E%E7%8E%B0)ÄÚÖÃµÄ Resource ʵÏÖ
+
+Spring °üÀ¨¼¸¸öÄÚÖÃµÄ Resource ʵÏÖ£º
+
+| ×ÊÔ´À´Ô´ | ǰ׺ | ˵Ã÷ |
+| --- | --- | --- |
+| [`UrlResource`(opens new window)](https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#resources-implementations-urlresource) | `file:`¡¢`https:`¡¢`ftp:` µÈ | `UrlResource` ·â×°ÁËÒ»¸ö `java.net.URL` ¶ÔÏó£¬**ÓÃÓÚ·ÃÎÊ¿Éͨ¹ý URL ·ÃÎʵÄÈκζÔÏó**£¬ÀýÈçÎļþ¡¢HTTPS Ä¿±ê¡¢FTP Ä¿±êµÈ¡£ËùÓÐ URL ¶¼¿ÉÒÔͨ¹ý±ê×¼»¯µÄ×Ö·û´®ÐÎʽ±íʾ£¬Òò´Ë¿ÉÒÔʹÓÃÊʵ±µÄ±ê×¼»¯Ç°×ºÀ´Ö¸Ê¾Ò»ÖÖ URL ÀàÐÍÓëÁíÒ»ÖÖ URL ÀàÐ͵ÄÇø±ð¡£ Õâ°üÀ¨£º`file`£ºÓÃÓÚ·ÃÎÊÎļþϵͳ·¾¶£»`https`£ºÓÃÓÚͨ¹ý HTTPS ÐÒé·ÃÎÊ×ÊÔ´£»`ftp`£ºÓÃÓÚͨ¹ý FTP ·ÃÎÊ×ÊÔ´µÈµÈ¡£ |
+| [`ClassPathResource`(opens new window)](https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#resources-implementations-classpathresource) | `classpath:` | `ClassPathResource` **´ÓÀà·¾¶ÉϼÓÔØ×ÊÔ´**¡£ËüʹÓÃÏß³ÌÉÏÏÂÎļÓÔØÆ÷¡¢¸ø¶¨µÄÀà¼ÓÔØÆ÷»òÖ¸¶¨µÄ class ÀàÐÍÖеÄÈÎÒâÒ»¸öÀ´¼ÓÔØ×ÊÔ´¡£ |
+| [`FileSystemResource`(opens new window)](https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#resources-implementations-filesystemresource) | `file:` | `FileSystemResource` **ÊÇ `java.io.File` µÄ×ÊԴʵÏÖ**¡£Ëü»¹Ö§³Ö `java.nio.file.Path` £¬Ó¦Óà Spring µÄ±ê×¼¶Ô×Ö·û´®Â·¾¶½øÐÐת»»¡£`FileSystemResource` Ö§³Ö½âÎöΪÎļþºÍ URL¡£ |
+| [`PathResource`(opens new window)](https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#resources-implementations-pathresource) | ÎÞ | `PathResource` ÊÇ `java.nio.file.Path` µÄ×ÊԴʵÏÖ¡£ |
+| [`ServletContextResource`(opens new window)](https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#resources-implementations-servletcontextresource) | ÎÞ | `ServletContextResource` **ÊÇ `ServletContext` µÄ×ÊԴʵÏÖ**¡£Ëü±íʾÏàÓ¦ Web Ó¦ÓóÌÐò¸ùĿ¼ÖеÄÏà¶Ô·¾¶¡£ |
+| [`InputStreamResource`(opens new window)](https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#resources-implementations-inputstreamresource) | ÎÞ | `InputStreamResource` **ÊÇÖ¸¶¨ `InputStream` µÄ×ÊԴʵÏÖ**¡£×¢Ò⣺Èç¹û¸Ã `InputStream` Òѱ»´ò¿ª£¬Ôò²»¿ÉÒÔ¶à´Î¶ÁÈ¡¸ÃÁ÷¡£ |
+| [`ByteArrayResource`(opens new window)](https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#resources-implementations-bytearrayresource) | ÎÞ | `ByteArrayResource` ÊÇÖ¸¶¨µÄ¶þ½øÖÆÊý×éµÄ×ÊԴʵÏÖ¡£Ëü»áΪ¸ø¶¨µÄ×Ö½ÚÊý×é´´½¨Ò»¸ö `ByteArrayInputStream`¡£ |
+
+
+
+## [#](https://dunwu.github.io/spring-tutorial/pages/a1549f/#resourceloader-%E6%8E%A5%E5%8F%A3)ResourceLoader ½Ó¿Ú
+
+`ResourceLoader` ½Ó¿ÚÓÃÓÚ¼ÓÔØ `Resource` ¶ÔÏ󡣯䶍ÒåÈçÏ£º
+
+
+
+```
+public interface ResourceLoader {
+
+ Resource getResource(String location);
+
+ ClassLoader getClassLoader();
+}
+
+```
+
+
+
+Spring ÖÐÖ÷ÒªµÄ ResourceLoader ʵÏÖ£º
+
+
+
+Spring ÖУ¬ËùÓÐµÄ `ApplicationContext` ¶¼ÊµÏÖÁË `ResourceLoader` ½Ó¿Ú¡£Òò´Ë£¬ËùÓÐ `ApplicationContext` ¶¼¿ÉÒÔͨ¹ý `getResource()` ·½·¨»ñÈ¡ `Resource` ʵÀý¡£
+
+¡¾Ê¾Àý¡¿
+
+
+
+```
+// Èç¹ûûÓÐÖ¸¶¨×ÊԴǰ׺£¬Spring »á³¢ÊÔ·µ»ØºÏÊʵÄ×ÊÔ´
+Resource template = ctx.getResource("some/resource/path/myTemplate.txt");
+// Èç¹ûÖ¸¶¨ classpath: ǰ׺£¬Spring »áÇ¿ÖÆÊ¹Óà ClassPathResource
+Resource template = ctx.getResource("classpath:some/resource/path/myTemplate.txt");
+// Èç¹ûÖ¸¶¨ file:¡¢http µÈ URL ǰ׺£¬Spring »áÇ¿ÖÆÊ¹Óà UrlResource
+Resource template = ctx.getResource("file:///some/resource/path/myTemplate.txt");
+Resource template = ctx.getResource("http://myhost.com/resource/path/myTemplate.txt");
+
+```
+
+
+
+ϱíÁоÙÁË Spring ¸ù¾Ý¸÷ÖÖλÖ÷¾¶¼ÓÔØ×ÊÔ´µÄ²ßÂÔ£º
+
+| ǰ׺ | ÑùÀý | ˵Ã÷ |
+| --- | --- | --- |
+| `classpath:` | `classpath:com/myapp/config.xml` | ´ÓÀà·¾¶¼ÓÔØ |
+| `file:` | `file:///data/config.xml` | ÒÔ URL ÐÎʽ´ÓÎļþϵͳ¼ÓÔØ |
+| `http:` | `http://myserver/logo.png` | ÒÔ URL ÐÎʽ¼ÓÔØ |
+| ÎÞ | `/data/config.xml` | ÓɵײãµÄ ApplicationContext ʵÏÖ¾ö¶¨ |
+
+
+
+## [#](https://dunwu.github.io/spring-tutorial/pages/a1549f/#resourcepatternresolver-%E6%8E%A5%E5%8F%A3)ResourcePatternResolver ½Ó¿Ú
+
+`ResourcePatternResolver` ½Ó¿ÚÊÇ `ResourceLoader` ½Ó¿ÚµÄÀ©Õ¹£¬ËüµÄ×÷ÓÃÊǶ¨Òå²ßÂÔ£¬¸ù¾ÝλÖÃģʽ½âÎö `Resource` ¶ÔÏó¡£
+
+
+
+```
+public interface ResourcePatternResolver extends ResourceLoader {
+
+ String CLASSPATH_ALL_URL_PREFIX = "classpath*:";
+
+ Resource[] getResources(String locationPattern) throws IOException;
+}
+
+```
+
+
+
+`PathMatchingResourcePatternResolver` ÊÇÒ»¸ö¶ÀÁ¢µÄʵÏÖ£¬¿ÉÒÔÔÚ `ApplicationContext` Ö®ÍâʹÓã¬Ò²¿ÉÒÔ±» `ResourceArrayPropertyEditor` ÓÃÓÚÌî³ä `Resource[]` bean ÊôÐÔ¡£`PathMatchingResourcePatternResolver` Äܹ»½«Ö¸¶¨µÄ×ÊԴλÖ÷¾¶½âÎöΪһ¸ö»ò¶à¸öÆ¥ÅäµÄ `Resource` ¶ÔÏó¡£
+
+> ×¢Ò⣺Èκαê×¼ `ApplicationContext` ÖеÄĬÈÏ `ResourceLoader` ʵ¼ÊÉÏÊÇ `PathMatchingResourcePatternResolver` µÄÒ»¸öʵÀý£¬ËüʵÏÖÁË `ResourcePatternResolver` ½Ó¿Ú¡£
+
+## [#](https://dunwu.github.io/spring-tutorial/pages/a1549f/#resourceloaderaware-%E6%8E%A5%E5%8F%A3)ResourceLoaderAware ½Ó¿Ú
+
+`ResourceLoaderAware` ½Ó¿ÚÊÇÒ»¸öÌØÊâµÄ»Øµ÷½Ó¿Ú£¬ÓÃÀ´±ê¼ÇÌṩ `ResourceLoader` ÒýÓõĶÔÏó¡£`ResourceLoaderAware` ½Ó¿Ú¶¨ÒåÈçÏ£º
+
+
+
+```
+public interface ResourceLoaderAware {
+ void setResourceLoader(ResourceLoader resourceLoader);
+}
+
+```
+
+
+
+µ±Ò»¸öÀàʵÏÖ `ResourceLoaderAware` ²¢²¿Êðµ½Ó¦ÓóÌÐòÉÏÏÂÎÄÖУ¨×÷Ϊ Spring ¹ÜÀíµÄ bean£©Ê±£¬Ëü»á±»Ó¦ÓóÌÐòÉÏÏÂÎÄʶ±ðΪ `ResourceLoaderAware`£¬È»ºó£¬Ó¦ÓóÌÐòÉÏÏÂÎÄ»áµ÷Óà `setResourceLoader(ResourceLoader)`£¬½«×ÔÉí×÷Ϊ²ÎÊýÌṩ£¨Çë¼Çס£¬Spring ÖеÄËùÓÐÓ¦ÓóÌÐòÉÏÏÂÎĶ¼ÊµÏÖ `ResourceLoader` ½Ó¿Ú£©¡£
+
+ÓÉÓÚ `ApplicationContext` ÊÇÒ»¸ö `ResourceLoader`£¬¸Ã bean »¹¿ÉÒÔʵÏÖ `ApplicationContextAware` ½Ó¿Ú²¢Ö±½ÓʹÓÃÌṩµÄÓ¦ÓóÌÐòÉÏÏÂÎÄÀ´¼ÓÔØ×ÊÔ´¡£ µ«ÊÇ£¬Ò»°ãÀ´Ëµ£¬Èç¹ûÄúÖ»ÐèÒªÕâЩ£¬×îºÃʹÓÃרÃÅµÄ `ResourceLoader` ½Ó¿Ú¡£ ¸Ã´úÂ뽫½öñîºÏµ½×ÊÔ´¼ÓÔØ½Ó¿Ú£¨¿ÉÒÔ±»ÊÓΪʵÓóÌÐò½Ó¿Ú£©£¬¶ø²»ñîºÏµ½Õû¸ö Spring `ApplicationContext` ½Ó¿Ú¡£
+
+ÔÚÓ¦ÓóÌÐòÖУ¬»¹¿ÉÒÔʹÓà `ResourceLoader` µÄ×Ô¶¯×°Åä×÷ΪʵÏÖ `ResourceLoaderAware` ½Ó¿ÚµÄÌæ´ú·½·¨¡£´«Í³µÄ¹¹Ô캯ÊýºÍ `byType` ×Ô¶¯×°ÅäģʽÄܹ»·Ö±ðΪ¹¹Ô캯Êý²ÎÊý»ò setter ·½·¨²ÎÊýÌṩ `ResourceLoader`¡£ ΪÁË»ñµÃ¸ü´óµÄÁé»îÐÔ£¨°üÀ¨×Ô¶¯×°Åä×ֶκͶà²ÎÊý·½·¨µÄÄÜÁ¦£©£¬Ç뿼ÂÇʹÓûùÓÚ×¢½âµÄ×Ô¶¯×°Å书ÄÜ¡£ ÔÚÕâÖÖÇé¿öÏ£¬`ResourceLoader` »á×Ô¶¯Á¬½Óµ½ÐèÒª `ResourceLoader` ÀàÐ͵Ä×ֶΡ¢¹¹Ô캯Êý²ÎÊý»ò·½·¨²ÎÊýÖУ¬Ö»ÒªÏà¹Ø×ֶΡ¢¹¹Ô캯Êý»ò·½·¨´øÓÐ `@Autowired` ×¢½â¼´¿É¡£
+
+## [#](https://dunwu.github.io/spring-tutorial/pages/a1549f/#%E8%B5%84%E6%BA%90%E4%BE%9D%E8%B5%96)×ÊÔ´ÒÀÀµ
+
+Èç¹û bean ±¾ÉíҪͨ¹ýijÖÖ¶¯Ì¬¹ý³ÌÀ´È·¶¨ºÍÌṩ×ÊԴ·¾¶£¬ÄÇô bean ¿ÉÒÔʹÓà `ResourceLoader` »ò `ResourcePatternResolver` ½Ó¿ÚÀ´¼ÓÔØ×ÊÔ´¡£ ÀýÈ磬¿¼ÂǼÓÔØÄ³ÖÖÄ£°å£¬ÆäÖÐËùÐèµÄÌØ¶¨×ÊÔ´È¡¾öÓÚÓû§µÄ½ÇÉ«¡£ Èç¹û×ÊÔ´ÊǾ²Ì¬µÄ£¬ÍêÈ«Ïû³ý `ResourceLoader` ½Ó¿Ú£¨»ò `ResourcePatternResolver` ½Ó¿Ú£©µÄʹÓã¬Èà bean ¹«¿ªËüÐèÒªµÄ `Resource` ÊôÐÔ£¬²¢ÆÚÍû½«ËüÃÇ×¢ÈëÆäÖÐÊÇÓÐÒâÒåµÄ¡£
+
+ʹעÈëÕâЩÊôÐÔ±äµÃ¼òµ¥µÄÔÒòÊÇËùÓÐÓ¦ÓóÌÐòÉÏÏÂÎͼע²á²¢Ê¹ÓÃÒ»¸öÌØÊâµÄ JavaBeans `PropertyEditor`£¬Ëü¿ÉÒÔ½« `String` ·¾¶×ª»»Îª `Resource` ¶ÔÏó¡£ ÀýÈ磬ÏÂÃæµÄ MyBean ÀàÓÐÒ»¸ö `Resource` ÀàÐ͵ÄÄ£°åÊôÐÔ¡£
+
+¡¾Ê¾Àý¡¿
+
+
+
+```
+
+
+
+
+```
+
+
+
+Çë×¢Ò⣬ÅäÖÃÖÐÒýÓõÄÄ£°å×ÊԴ·¾¶Ã»ÓÐǰ׺£¬ÒòΪӦÓóÌÐòÉÏÏÂÎı¾Éí½«ÓÃ×÷ `ResourceLoader`£¬×ÊÔ´±¾Éí½«¸ù¾ÝÐèҪͨ¹ý `ClassPathResource`£¬`FileSystemResource` »ò ServletContextResource ¼ÓÔØ£¬¾ßÌåÈ¡¾öÓÚÉÏÏÂÎĵÄÈ·ÇÐÀàÐÍ¡£
+
+Èç¹ûÐèÒªÇ¿ÖÆÊ¹ÓÃÌØ¶¨µÄ×ÊÔ´ÀàÐÍ£¬Ôò¿ÉÒÔʹÓÃǰ׺¡£ ÒÔÏÂÁ½¸öʾÀýÏÔʾÈçºÎÇ¿ÖÆÊ¹Óà `ClassPathResource` ºÍ `UrlResource`£¨ºóÕßÓÃÓÚ·ÃÎÊÎļþϵͳÎļþ£©¡£
+
+
+
+```
+
+
+
+```
+
+
+
+¿ÉÒÔͨ¹ý `@Value` ×¢½â¼ÓÔØ×ÊÔ´Îļþ `myTemplate.txt`£¬Ê¾ÀýÈçÏ£º
+
+
+
+```
+@Component
+public class MyBean {
+
+ private final Resource template;
+
+ public MyBean(@Value("${template.path}") Resource template) {
+ this.template = template;
+ }
+
+ // ...
+}
+
+```
+
+
+
+Spring µÄ `PropertyEditor` »á¸ù¾Ý×ÊÔ´ÎļþµÄ·¾¶×Ö·û´®£¬¼ÓÔØ `Resource` ¶ÔÏ󣬲¢½«Æä×¢Èëµ½ MyBean µÄ¹¹Ôì·½·¨¡£
+
+Èç¹ûÏëÒª¼ÓÔØ¶à¸ö×ÊÔ´Îļþ£¬¿ÉÒÔʹÓà `classpath*:` ǰ׺£¬ÀýÈ磺`classpath*:/config/templates/*.txt`¡£
+
+
+
+```
+@Component
+public class MyBean {
+
+ private final Resource[] templates;
+
+ public MyBean(@Value("${templates.path}") Resource[] templates) {
+ this.templates = templates;
+ }
+
+ // ...
+}
+
+```
+
+
+
+## [#](https://dunwu.github.io/spring-tutorial/pages/a1549f/#%E5%BA%94%E7%94%A8%E4%B8%8A%E4%B8%8B%E6%96%87%E5%92%8C%E8%B5%84%E6%BA%90%E8%B7%AF%E5%BE%84)Ó¦ÓÃÉÏÏÂÎĺÍ×ÊԴ·¾¶
+
+### [#](https://dunwu.github.io/spring-tutorial/pages/a1549f/#%E6%9E%84%E9%80%A0%E5%BA%94%E7%94%A8%E4%B8%8A%E4%B8%8B%E6%96%87)¹¹ÔìÓ¦ÓÃÉÏÏÂÎÄ
+
+Ó¦ÓÃÉÏÏÂÎĹ¹Ô캯Êý£¨Õë¶ÔÌØ¶¨µÄÓ¦ÓÃÉÏÏÂÎÄÀàÐÍ£©Í¨³£½«×Ö·û´®»ò×Ö·û´®Êý×é×÷Ϊ×ÊÔ´µÄλÖ÷¾¶£¬ÀýÈç¹¹³ÉÉÏÏÂÎ͍ÒåµÄ XML Îļþ¡£
+
+¡¾Ê¾Àý¡¿
+
+
+
+```
+ApplicationContext ctx = new ClassPathXmlApplicationContext("conf/appContext.xml");
+ApplicationContext ctx = new FileSystemXmlApplicationContext("conf/appContext.xml");
+ApplicationContext ctx = new FileSystemXmlApplicationContext("classpath:conf/appContext.xml");
+ApplicationContext ctx = new ClassPathXmlApplicationContext(
+ new String[] {"services.xml", "daos.xml"}, MessengerService.class);
+
+```
+
+
+
+### [#](https://dunwu.github.io/spring-tutorial/pages/a1549f/#%E4%BD%BF%E7%94%A8%E9%80%9A%E9%85%8D%E7%AC%A6%E6%9E%84%E9%80%A0%E5%BA%94%E7%94%A8%E4%B8%8A%E4%B8%8B%E6%96%87)ʹÓÃͨÅä·û¹¹ÔìÓ¦ÓÃÉÏÏÂÎÄ
+
+ApplicationContext ¹¹ÔìÆ÷µÄÖеÄ×ÊԴ·¾¶¿ÉÒÔÊǵ¥Ò»µÄ·¾¶£¨¼´Ò»¶ÔÒ»µØÓ³É䵽Ŀ±ê×ÊÔ´£©£»Ò²¿ÉÒÔÊÇͨÅä·ûÐÎʽ¡ª¡ª¿É°üº¬ classpath*£ºÒ²¿ÉÒÔÊÇǰ׺»ò ant ·ç¸ñµÄÕýÔò±í´ïʽ£¨Ê¹Óà spring µÄ PathMatcher À´Æ¥Å䣩¡£
+
+ʾÀý£º
+
+
+
+```
+ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath*:conf/appContext.xml");
+
+```
+
+
+
+ʹÓà `classpath*` ±íʾÀà·¾¶ÏÂËùÓÐÆ¥ÅäÎļþÃû³ÆµÄ×ÊÔ´¶¼»á±»»ñÈ¡(±¾ÖÊÉϾÍÊǵ÷ÓÃÁË ClassLoader.getResources(¡) ·½·¨£©£¬½Ó׎«»ñÈ¡µ½µÄ×ÊÔ´×é×°³É×îÖÕµÄÓ¦ÓÃÉÏÏÂÎÄ¡£
+
+ÔÚλÖ÷¾¶µÄÆäÓಿ·Ö£¬`classpath*:` ǰ׺¿ÉÒÔÓë PathMatcher ½áºÏʹÓã¬È磺`classpath*:META-INF/*-beans.xml`¡£
+
+## [#](https://dunwu.github.io/spring-tutorial/pages/a1549f/#%E9%97%AE%E9%A2%98)ÎÊÌâ
+
+Spring ÅäÖÃ×ÊÔ´ÖÐÓÐÄÄЩ³£¼ûÀàÐÍ£¿
+
+* XML ×ÊÔ´
+* Properties ×ÊÔ´
+* YAML ×ÊÔ´
+
+## [#](https://dunwu.github.io/spring-tutorial/pages/a1549f/#%E5%8F%82%E8%80%83%E8%B5%84%E6%96%99)²Î¿¼×ÊÁÏ
+
+* [Spring ¹Ù·½ÎĵµÖ® Core Technologies(opens new window)](https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans)
+* [¡¶Ð¡Âí¸ç½² Spring ºËÐıà³Ì˼Ïë¡·](https://time.geekbang.org/course/intro/265)
+
+# ²Î¿¼ÎÄÕÂ
+https://www.w3cschool.cn/wkspring
+https://www.runoob.com/w3cnote/basic-knowledge-summary-of-spring.html
+http://codepub.cn/2015/06/21/Basic-knowledge-summary-of-Spring
+https://dunwu.github.io/spring-tutorial
+https://mszlu.com/java/spring
+http://c.biancheng.net/spring/aop-module.html
\ No newline at end of file
diff --git "a/docs/spring/Spring\344\270\255\347\232\204\351\205\215\347\275\256\345\205\203\346\225\260\346\215\256\357\274\210\347\256\241\347\220\206\351\205\215\347\275\256\347\232\204\345\237\272\346\234\254\346\225\260\346\215\256\357\274\211.md" "b/docs/spring/Spring\344\270\255\347\232\204\351\205\215\347\275\256\345\205\203\346\225\260\346\215\256\357\274\210\347\256\241\347\220\206\351\205\215\347\275\256\347\232\204\345\237\272\346\234\254\346\225\260\346\215\256\357\274\211.md"
new file mode 100644
index 0000000..8589b50
--- /dev/null
+++ "b/docs/spring/Spring\344\270\255\347\232\204\351\205\215\347\275\256\345\205\203\346\225\260\346\215\256\357\274\210\347\256\241\347\220\206\351\205\215\347\275\256\347\232\204\345\237\272\346\234\254\346\225\260\346\215\256\357\274\211.md"
@@ -0,0 +1,298 @@
+
+
+# Spring ÅäÖÃÔªÊý¾Ý
+
+
+
+## [#](https://dunwu.github.io/spring-tutorial/pages/55f315/#spring-%E9%85%8D%E7%BD%AE%E5%85%83%E4%BF%A1%E6%81%AF)Spring ÅäÖÃÔªÐÅÏ¢
+
+* Spring Bean ÅäÖÃÔªÐÅÏ¢ - BeanDefinition
+* Spring Bean ÊôÐÔÔªÐÅÏ¢ - PropertyValues
+* Spring ÈÝÆ÷ÅäÖÃÔªÐÅÏ¢
+* Spring Íⲿ»¯ÅäÖÃÔªÐÅÏ¢ - PropertySource
+* Spring Profile ÔªÐÅÏ¢ - @Profile
+
+## [#](https://dunwu.github.io/spring-tutorial/pages/55f315/#spring-bean-%E9%85%8D%E7%BD%AE%E5%85%83%E4%BF%A1%E6%81%AF)Spring Bean ÅäÖÃÔªÐÅÏ¢
+
+Bean ÅäÖÃÔªÐÅÏ¢ - BeanDefinition
+
+* GenericBeanDefinition£ºÍ¨ÓÃÐÍ BeanDefinition
+* RootBeanDefinition£ºÎÞ Parent µÄ BeanDefinition »òÕߺϲ¢ºó BeanDefinition
+* AnnotatedBeanDefinition£º×¢½â±ê×¢µÄ BeanDefinition
+
+## [#](https://dunwu.github.io/spring-tutorial/pages/55f315/#spring-bean-%E5%B1%9E%E6%80%A7%E5%85%83%E4%BF%A1%E6%81%AF)Spring Bean ÊôÐÔÔªÐÅÏ¢
+
+* Bean ÊôÐÔÔªÐÅÏ¢ - PropertyValues
+ * ¿ÉÐÞ¸ÄʵÏÖ - MutablePropertyValues
+ * ÔªËØ³ÉÔ± - PropertyValue
+* Bean ÊôÐÔÉÏÏÂÎÄ´æ´¢ - AttributeAccessor
+* Bean ÔªÐÅÏ¢ÔªËØ - BeanMetadataElement
+
+## [#](https://dunwu.github.io/spring-tutorial/pages/55f315/#spring-%E5%AE%B9%E5%99%A8%E9%85%8D%E7%BD%AE%E5%85%83%E4%BF%A1%E6%81%AF)Spring ÈÝÆ÷ÅäÖÃÔªÐÅÏ¢
+
+Spring XML ÅäÖÃÔªÐÅÏ¢ - beans ÔªËØÏà¹Ø
+
+| beans ÔªËØÊôÐÔ | ĬÈÏÖµ | ʹÓó¡¾° |
+| --- | --- | --- |
+| profile | null£¨Áô¿Õ£© | Spring Profiles ÅäÖÃÖµ |
+| default-lazy-init | default | µ± outter beans ¡°default-lazy-init¡± ÊôÐÔ´æÔÚʱ£¬¼Ì³Ð¸ÃÖµ£¬·ñÔòΪ¡°false¡± |
+| default-merge | default | µ± outter beans ¡°default-merge¡± ÊôÐÔ´æÔÚʱ£¬¼Ì³Ð¸ÃÖµ£¬·ñÔòΪ¡°false¡± |
+| default-autowire | default | µ± outter beans ¡°default-autowire¡± ÊôÐÔ´æÔÚʱ£¬¼Ì³Ð¸ÃÖµ£¬·ñÔòΪ¡°no¡± |
+| default-autowire-candidates | null£¨Áô¿Õ£© | ĬÈÏ Spring Beans Ãû³Æ pattern |
+| default-init-method | null£¨Áô¿Õ£© | ĬÈÏ Spring Beans ×Ô¶¨Òå³õʼ»¯·½·¨ |
+| default-destroy-method | null£¨Áô¿Õ£© | ĬÈÏ Spring Beans ×Ô¶¨ÒåÏú»Ù·½·¨ |
+
+Spring XML ÅäÖÃÔªÐÅÏ¢ - Ó¦ÓÃÉÏÏÂÎÄÏà¹Ø
+
+| XML ÔªËØ | ʹÓó¡¾° |
+| --- | --- |
+| ` ` | ¼¤»î Spring ×¢½âÇý¶¯ |
+| ` ` | Spring @Component ÒÔ¼°×Ô¶¨Òå×¢½âɨÃè |
+| ` ` | ¼¤»î Spring LoadTimeWeaver |
+| ` ` | ±©Â¶ Spring Beans ×÷Ϊ JMX Beans |
+| ` ` | ½«µ±Ç°Æ½Ì¨×÷Ϊ MBeanServer |
+| ` ` | ¼ÓÔØÍⲿ»¯ÅäÖÃ×ÊÔ´×÷Ϊ Spring ÊôÐÔÅä |
+| ` ` | ÀûÓÃÍⲿ»¯ÅäÖÃ×ÊÔ´¸²¸Ç Spring Êô |
+
+## [#](https://dunwu.github.io/spring-tutorial/pages/55f315/#%E5%9F%BA%E4%BA%8E-xml-%E6%96%87%E4%BB%B6%E8%A3%85%E8%BD%BD-spring-bean-%E9%85%8D%E7%BD%AE%E5%85%83%E4%BF%A1%E6%81%AF)»ùÓÚ XML Îļþ×°ÔØ Spring Bean ÅäÖÃÔªÐÅÏ¢
+
+µ×²ãʵÏÖ - XmlBeanDefinitionReader
+
+| XML ÔªËØ | ʹÓó¡¾° |
+| --- | --- |
+| ` ` | µ¥ XML ×ÊԴϵĶà¸ö Spring Beans ÅäÖà |
+| ` ` | µ¥¸ö Spring Bean ¶¨Ò壨BeanDefinition£©ÅäÖà |
+| ` ` | Ϊ Spring Bean ¶¨Ò壨BeanDefinition£©Ó³Éä±ðÃû |
+| ` ` | ¼ÓÔØÍⲿ Spring XML ÅäÖÃ×ÊÔ´ |
+
+## [#](https://dunwu.github.io/spring-tutorial/pages/55f315/#%E5%9F%BA%E4%BA%8E-properties-%E6%96%87%E4%BB%B6%E8%A3%85%E8%BD%BD-spring-bean-%E9%85%8D%E7%BD%AE%E5%85%83%E4%BF%A1%E6%81%AF)»ùÓÚ Properties Îļþ×°ÔØ Spring Bean ÅäÖÃÔªÐÅÏ¢
+
+µ×²ãʵÏÖ - PropertiesBeanDefinitionReader
+
+| Properties ÊôÐÔÃû | ʹÓó¡¾° |
+| --- | --- |
+| `class` | Bean ÀàÈ«³ÆÏÞ¶¨Ãû |
+| `abstract` | ÊÇ·ñΪ³éÏóµÄ BeanDefinition |
+| `parent` | Ö¸¶¨ parent BeanDefinition Ãû³Æ |
+| `lazy-init` | ÊÇ·ñΪÑÓ³Ù³õʼ»¯ |
+| `ref` | ÒýÓÃÆäËû Bean µÄÃû³Æ |
+| `scope` | ÉèÖà Bean µÄ scope ÊôÐÔ |
+| ${n} | n ±íʾµÚ n+1 ¸ö¹¹ÔìÆ÷²ÎÊý |
+
+## [#](https://dunwu.github.io/spring-tutorial/pages/55f315/#%E5%9F%BA%E4%BA%8E-java-%E6%B3%A8%E8%A7%A3%E8%A3%85%E8%BD%BD-spring-bean-%E9%85%8D%E7%BD%AE%E5%85%83%E4%BF%A1%E6%81%AF)»ùÓÚ Java ×¢½â×°ÔØ Spring Bean ÅäÖÃÔªÐÅÏ¢
+
+Spring ģʽע½â
+
+| Spring ×¢½â | ³¡¾°ËµÃ÷ | Æðʼ°æ±¾ |
+| --- | --- | --- |
+| `@Repository` | Êý¾Ý²Ö´¢Ä£Ê½×¢½â | 2.0 |
+| `@Component` | ͨÓÃ×é¼þģʽע½â | 2.5 |
+| `@Service` | ·þÎñģʽע½â | 2.5 |
+| `@Controller` | Web ¿ØÖÆÆ÷ģʽע½â | 2.5 |
+| `@Configuration` | ÅäÖÃÀàģʽע½â | 3.0 |
+
+Spring Bean ¶¨Òå×¢½â
+
+| Spring ×¢½â | ³¡¾°ËµÃ÷ | Æðʼ°æ±¾ |
+| --- | --- | --- |
+| `@Bean` | Ìæ»» XML ÔªËØ?`` | 3.0 |
+| `@DependsOn` | Ìæ´ú XML ÊôÐÔ?` ` | 3.0 |
+| `@Lazy` | Ìæ´ú XML ÊôÐÔ?` ` | 3.0 |
+| `@Primary` | Ìæ»» XML ÔªËØ?` ` | 3.0 |
+| `@Role` | Ìæ»» XML ÔªËØ?` ` | 3.1 |
+| `@Lookup` | Ìæ´ú XML ÊôÐÔ?`` | 4.1 |
+
+Spring Bean ÒÀÀµ×¢Èë×¢½â
+
+| Spring ×¢½â | ³¡¾°ËµÃ÷ | Æðʼ°æ±¾ |
+| --- | --- | --- |
+| `@Autowired` | Bean ÒÀÀµ×¢È룬֧³Ö¶àÖÖÒÀÀµ²éÕÒ·½Ê½ | 2.5 |
+| `@Qualifier` | ϸÁ£¶ÈµÄ @Autowired ÒÀÀµ²éÕÒ | 2.5 |
+
+?
+
+| Java ×¢½â | ³¡¾°ËµÃ÷ | Æðʼ°æ±¾ |
+| --- | --- | --- |
+| @Resource | ÀàËÆÓÚ @Autowired | 2.5 |
+| @Inject | ÀàËÆÓÚ @Autowired | 2.5 |
+
+Spring Bean Ìõ¼þ×°Åä×¢½â
+
+| Spring ×¢½â | ³¡¾°ËµÃ÷ | Æðʼ°æ±¾ |
+| --- | --- | --- |
+| @Profile | ÅäÖû¯Ìõ¼þ×°Åä | 3.1 |
+| @Conditional | ±à³ÌÌõ¼þ×°Åä | 4.0 |
+
+Spring Bean ÉúÃüÖÜÆÚ»Øµ÷×¢½â
+
+| Spring ×¢½â | ³¡¾°ËµÃ÷ | Æðʼ°æ±¾ |
+| --- | --- | --- |
+| @PostConstruct | Ìæ»» XML ÔªËØ? »ò InitializingBean | 2.5 |
+| @PreDestroy | Ìæ»» XML ÔªËØ? »ò DisposableBean | 2.5 |
+
+Spring BeanDefinition ½âÎöÓë×¢²á
+
+| Spring ×¢½â | ³¡¾°ËµÃ÷ | Æðʼ°æ±¾ |
+| --- | --- | --- |
+| XML ×ÊÔ´ | XmlBeanDefinitionReader | 1.0 |
+| Properties ×ÊÔ´ | PropertiesBeanDefinitionReader | 1.0 |
+| Java ×¢½â | AnnotatedBeanDefinitionReader | 3.0 |
+
+## [#](https://dunwu.github.io/spring-tutorial/pages/55f315/#spring-bean-%E9%85%8D%E7%BD%AE%E5%85%83%E4%BF%A1%E6%81%AF%E5%BA%95%E5%B1%82%E5%AE%9E%E7%8E%B0)Spring Bean ÅäÖÃÔªÐÅÏ¢µ×²ãʵÏÖ
+
+### [#](https://dunwu.github.io/spring-tutorial/pages/55f315/#spring-xml-%E8%B5%84%E6%BA%90-beandefinition-%E8%A7%A3%E6%9E%90%E4%B8%8E%E6%B3%A8%E5%86%8C)Spring XML ×ÊÔ´ BeanDefinition ½âÎöÓë×¢²á
+
+ºËÐÄ API - XmlBeanDefinitionReader
+
+* ×ÊÔ´ - Resource
+* µ×²ã - BeanDefinitionDocumentReader
+ * XML ½âÎö - Java DOM Level 3 API
+ * BeanDefinition ½âÎö - BeanDefinitionParserDelegate
+ * BeanDefinition ×¢²á - BeanDefinitionRegistry
+
+### [#](https://dunwu.github.io/spring-tutorial/pages/55f315/#spring-properties-%E8%B5%84%E6%BA%90-beandefinition-%E8%A7%A3%E6%9E%90%E4%B8%8E%E6%B3%A8%E5%86%8C)Spring Properties ×ÊÔ´ BeanDefinition ½âÎöÓë×¢²á
+
+ºËÐÄ API - PropertiesBeanDefinitionReader
+
+* ×ÊÔ´
+ * ×Ö½ÚÁ÷ - Resource
+ * ×Ö·ûÁ÷ - EncodedResouce
+* µ×²ã
+ * ´æ´¢ - java.util.Properties
+ * BeanDefinition ½âÎö - API ÄÚ²¿ÊµÏÖ
+ * BeanDefinition ×¢²á - BeanDefinitionRegistry
+
+### [#](https://dunwu.github.io/spring-tutorial/pages/55f315/#spring-java-%E6%B3%A8%E5%86%8C-beandefinition-%E8%A7%A3%E6%9E%90%E4%B8%8E%E6%B3%A8%E5%86%8C)Spring Java ×¢²á BeanDefinition ½âÎöÓë×¢²á
+
+ºËÐÄ API - AnnotatedBeanDefinitionReader
+
+* ×ÊÔ´
+ * Àà¶ÔÏó - java.lang.Class
+* µ×²ã
+ * Ìõ¼þÆÀ¹À - ConditionEvaluator
+ * Bean ·¶Î§½âÎö - ScopeMetadataResolver
+ * BeanDefinition ½âÎö - ÄÚ²¿ API ʵÏÖ
+ * BeanDefinition ´¦Àí - AnnotationConfigUtils.processCommonDefinitionAnnotations
+ * BeanDefinition ×¢²á - BeanDefinitionRegistry
+
+## [#](https://dunwu.github.io/spring-tutorial/pages/55f315/#%E5%9F%BA%E4%BA%8E-xml-%E6%96%87%E4%BB%B6%E8%A3%85%E8%BD%BD-spring-ioc-%E5%AE%B9%E5%99%A8%E9%85%8D%E7%BD%AE%E5%85%83%E4%BF%A1%E6%81%AF)»ùÓÚ XML Îļþ×°ÔØ Spring IoC ÈÝÆ÷ÅäÖÃÔªÐÅÏ¢
+
+Spring IoC ÈÝÆ÷Ïà¹Ø XML ÅäÖÃ
+
+| ÃüÃû¿Õ¼ä | ËùÊôÄ£¿é | Schema ×ÊÔ´ URL |
+| --- | --- | --- |
+| beans | spring-beans | https://www.springframework.org/schema/beans/spring-beans.xsd |
+| context | spring-context | https://www.springframework.org/schema/context/spring-context.xsd |
+| aop | spring-aop | https://www.springframework.org/schema/aop/spring-aop.xsd |
+| tx | spring-tx | https://www.springframework.org/schema/tx/spring-tx.xsd |
+| util | spring-beans | beans https://www.springframework.org/schema/util/spring-util.xsd |
+| tool | spring-beans | https://www.springframework.org/schema/tool/spring-tool.xsd |
+
+## [#](https://dunwu.github.io/spring-tutorial/pages/55f315/#%E5%9F%BA%E4%BA%8E-java-%E6%B3%A8%E8%A7%A3%E8%A3%85%E8%BD%BD-spring-ioc-%E5%AE%B9%E5%99%A8%E9%85%8D%E7%BD%AE%E5%85%83%E4%BF%A1%E6%81%AF)»ùÓÚ Java ×¢½â×°ÔØ Spring IoC ÈÝÆ÷ÅäÖÃÔªÐÅÏ¢
+
+Spring IoC ÈÝÆ÷×°Åä×¢½â
+
+| Spring ×¢½â | ³¡¾°ËµÃ÷ | Æðʼ°æ±¾ |
+| --- | --- | --- |
+| @ImportResource | Ìæ»» XML ÔªËØ?`` | 3.0 |
+| @Import | µ¼Èë Configuration Class | 3.0 |
+| @ComponentScan | ɨÃèÖ¸¶¨ package ϱê×¢ Spring ģʽע½âµÄÀà | 3.1 |
+
+Spring IoC ÅäÊôÊôÐÔ×¢½â
+
+| Spring ×¢½â | ³¡¾°ËµÃ÷ | Æðʼ°æ±¾ |
+| --- | --- | --- |
+| @PropertySource | ÅäÖÃÊôÐÔ³éÏó PropertySource ×¢½â | 3.1 |
+| @PropertySources | @PropertySource ¼¯ºÏ×¢½â | 4.0 |
+
+## [#](https://dunwu.github.io/spring-tutorial/pages/55f315/#%E5%9F%BA%E4%BA%8E-extensible-xml-authoring-%E6%89%A9%E5%B1%95-springxml-%E5%85%83%E7%B4%A0)»ùÓÚ Extensible XML authoring À©Õ¹ SpringXML ÔªËØ
+
+Spring XML À©Õ¹
+
+* ±àд XML Schema Îļþ£º¶¨Òå XML ½á¹¹
+* ×Ô¶¨Òå NamespaceHandler ʵÏÖ£ºÃüÃû¿Õ¼ä°ó¶¨
+* ×Ô¶¨Òå BeanDefinitionParser ʵÏÖ£ºXML ÔªËØÓë BeanDefinition ½âÎö
+* ×¢²á XML À©Õ¹£ºÃüÃû¿Õ¼äÓë XML Schema Ó³Éä
+
+## [#](https://dunwu.github.io/spring-tutorial/pages/55f315/#extensible-xml-authoring-%E6%89%A9%E5%B1%95%E5%8E%9F%E7%90%86)Extensible XML authoring À©Õ¹ÔÀí
+
+### [#](https://dunwu.github.io/spring-tutorial/pages/55f315/#%E8%A7%A6%E5%8F%91%E6%97%B6%E6%9C%BA)´¥·¢Ê±»ú
+
+* AbstractApplicationContext#obtainFreshBeanFactory
+ * AbstractRefreshableApplicationContext#refreshBeanFactory
+ * AbstractXmlApplicationContext#loadBeanDefinitions
+ * ...
+ * XmlBeanDefinitionReader#doLoadBeanDefinitions
+ * ...
+ * BeanDefinitionParserDelegate#parseCustomElement
+
+### [#](https://dunwu.github.io/spring-tutorial/pages/55f315/#%E6%A0%B8%E5%BF%83%E6%B5%81%E7%A8%8B)ºËÐÄÁ÷³Ì
+
+BeanDefinitionParserDelegate#parseCustomElement(org.w3c.dom.Element, BeanDefinition)
+
+* »ñÈ¡ namespace
+* ͨ¹ý namespace ½âÎö NamespaceHandler
+* ¹¹Ôì ParserContext
+* ½âÎöÔªËØ£¬»ñÈ¡ BeanDefinintion
+
+## [#](https://dunwu.github.io/spring-tutorial/pages/55f315/#%E5%9F%BA%E4%BA%8E-properties-%E6%96%87%E4%BB%B6%E8%A3%85%E8%BD%BD%E5%A4%96%E9%83%A8%E5%8C%96%E9%85%8D%E7%BD%AE)»ùÓÚ Properties Îļþ×°ÔØÍⲿ»¯ÅäÖÃ
+
+×¢½âÇý¶¯
+
+* @org.springframework.context.annotation.PropertySource
+* @org.springframework.context.annotation.PropertySources
+
+API ±à³Ì
+
+* org.springframework.core.env.PropertySource
+* org.springframework.core.env.PropertySources
+
+## [#](https://dunwu.github.io/spring-tutorial/pages/55f315/#%E5%9F%BA%E4%BA%8E-yaml-%E6%96%87%E4%BB%B6%E8%A3%85%E8%BD%BD%E5%A4%96%E9%83%A8%E5%8C%96%E9%85%8D%E7%BD%AE)»ùÓÚ YAML Îļþ×°ÔØÍⲿ»¯ÅäÖÃ
+
+API ±à³Ì
+
+* org.springframework.beans.factory.config.YamlProcessor
+ * org.springframework.beans.factory.config.YamlMapFactoryBean
+ * org.springframework.beans.factory.config.YamlPropertiesFactoryBean
+
+## [#](https://dunwu.github.io/spring-tutorial/pages/55f315/#%E9%97%AE%E9%A2%98)ÎÊÌâ
+
+**Spring ƒÈ½¨ XML Schema ³£¼ûÓÐÄÄЩ**£¿
+
+| ÃüÃû¿Õ¼ä | ËùÊôÄ£¿é | Schema ×ÊÔ´ URL |
+| --- | --- | --- |
+| beans | spring-beans | https://www.springframework.org/schema/beans/spring-beans.xsd |
+| context | spring-context | https://www.springframework.org/schema/context/spring-context.xsd |
+| aop | spring-aop | https://www.springframework.org/schema/aop/spring-aop.xsd |
+| tx | spring-tx | https://www.springframework.org/schema/tx/spring-tx.xsd |
+| util | spring-beans | beans https://www.springframework.org/schema/util/spring-util.xsd |
+| tool | spring-beans | https://www.springframework.org/schema/tool/spring-tool.xsd |
+
+**Spring ÅäÖÃÔªÐÅÏ¢¾ßÌåÓÐÄÄЩ**£¿
+
+* Bean ÅäÖÃÔªÐÅÏ¢£ºÍ¨¹ýý½é£¨Èç XML¡¢Proeprties µÈ£©£¬½âÎö BeanDefinition
+* IoC ÈÝÆ÷ÅäÖÃÔªÐÅÏ¢£ºÍ¨¹ýý½é£¨Èç XML¡¢Proeprties µÈ£©£¬¿ØÖÆ IoC ÈÝÆ÷ÐÐΪ£¬±ÈÈç×¢½âÇý¶¯¡¢AOP µÈ
+* Íⲿ»¯ÅäÖãºÍ¨¹ý×ÊÔ´³éÏó£¨Èç Proeprties¡¢YAML µÈ£©£¬¿ØÖÆ PropertySource
+* Spring Profile£ºÍ¨¹ýÍⲿ»¯ÅäÖã¬ÌṩÌõ¼þ·ÖÖ§Á÷³Ì
+
+**Extensible XML authoring µÄȱµã**£¿
+
+* ¸ß¸´ÔÓ¶È£º¿ª·¢ÈËÔ±ÐèÒªÊìϤ XML Schema£¬spring.handlers£¬spring.schemas ÒÔ¼° Spring API
+* ǶÌ×ÔªËØÖ§³Ö½ÏÈõ£ºÍ¨³£ÐèҪʹÓ÷½·¨µÝ¹é»òÕ߯äǶÌ×½âÎöµÄ·½Ê½´¦ÀíǶÌ×£¨×Ó£©ÔªËØ
+* XML ´¦ÀíÐÔÄܽϲSpring XML »ùÓÚ DOM Level 3 API ʵÏÖ£¬¸Ã API ±ãÓÚÀí½â£¬È»¶øÐÔÄܽϲî
+* XML ¿ò¼ÜÒÆÖ²ÐԲºÜÄÑÊÊÅä¸ßÐÔÄܺͱãÀûÐ﵀ XML ¿ò¼Ü£¬Èç JAXB
+
+## [#](https://dunwu.github.io/spring-tutorial/pages/55f315/#%E5%8F%82%E8%80%83%E8%B5%84%E6%96%99)²Î¿¼×ÊÁÏ
+
+* [Spring ¹Ù·½ÎĵµÖ® Core Technologies(opens new window)](https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans)
+* [¡¶Ð¡Âí¸ç½² Spring ºËÐıà³Ì˼Ïë¡·(opens new window)](https://time.geekbang.org/course/intro/265)
+
+
+
+# ²Î¿¼ÎÄÕÂ
+https://www.w3cschool.cn/wkspring
+https://www.runoob.com/w3cnote/basic-knowledge-summary-of-spring.html
+http://codepub.cn/2015/06/21/Basic-knowledge-summary-of-Spring
+https://dunwu.github.io/spring-tutorial
+https://mszlu.com/java/spring
+http://c.biancheng.net/spring/aop-module.html
\ No newline at end of file
diff --git "a/docs/spring/Spring\344\272\213\345\212\241\345\237\272\346\234\254\347\224\250\346\263\225.md" "b/docs/spring/Spring\344\272\213\345\212\241\345\237\272\346\234\254\347\224\250\346\263\225.md"
new file mode 100644
index 0000000..85723ac
--- /dev/null
+++ "b/docs/spring/Spring\344\272\213\345\212\241\345\237\272\346\234\254\347\224\250\346\263\225.md"
@@ -0,0 +1,430 @@
+# SpringÊÂÎñºËÐĽӿÚ
+
+[Spring](http://www.voidme.com/spring) µÄÊÂÎñ¹ÜÀíÊÇ»ùÓÚ AOP ʵÏֵ쬶ø AOP ÊÇÒÔ·½·¨Îªµ¥Î»µÄ¡£Spring µÄÊÂÎñÊôÐÔ·Ö±ðΪ´«²¥ÐÐΪ¡¢¸ôÀë¼¶±ð¡¢Ö»¶ÁºÍ³¬Ê±ÊôÐÔ£¬ÕâЩÊôÐÔÌṩÁËÊÂÎñÓ¦Óõķ½·¨ºÍÃèÊö²ßÂÔ¡£
+
+ÔÚ [Java](http://www.voidme.com/java) EE ¿ª·¢¾³£²ÉÓõķֲãģʽÖУ¬Spring µÄÊÂÎñ´¦ÀíλÓÚÒµÎñÂß¼²ã£¬ËüÌṩÁËÕë¶ÔÊÂÎñµÄ½â¾ö·½°¸¡£
+
+ÔÚ Spring ½âѹ°üµÄ libs Ŀ¼ÖУ¬°üº¬Ò»¸öÃû³ÆÎª spring-tx-3.2.13.RELEASE.jar µÄÎļþ£¬¸ÃÎļþÊÇ Spring ÌṩµÄÓÃÓÚÊÂÎñ¹ÜÀíµÄ JAR °ü£¬ÆäÖаüÀ¨ÊÂÎñ¹ÜÀíµÄÈý¸öºËÐĽӿڣºPlatformTransactionManager¡¢TransactionDefinition ºÍ TransactionStatus¡£
+
+½«¸Ã JAR °üµÄºó׺Ãû jar ¸Ä³É zip µÄÐÎʽºó£¬½âѹѹËõ°ü£¬½øÈë½âѹÎļþ¼ÐÖÐµÄ \org\springframework\transaction Ŀ¼ºó£¬¸ÃĿ¼ÖеÄÎļþÈçͼ 1 Ëùʾ¡£
+
+
+ͼ 1 ÊÂÎñ¹ÜÀíºËÐĽӿÚ
+
+ÔÚͼ 1 ÖУ¬·½¿òËù±ê×¢µÄÈý¸öÎļþ¾ÍÊDZ¾½Ú½«Òª½²½âµÄºËÐĽӿڡ£ÕâÈý¸öºËÐĽӿڵÄ×÷Óü°ÆäÌṩµÄ·½·¨ÈçÏ¡£
+
+#### 1\. PlatformTransactionManager
+
+PlatformTransactionManager ½Ó¿ÚÊÇ Spring ÌṩµÄƽ̨ÊÂÎñ¹ÜÀíÆ÷£¬ÓÃÓÚ¹ÜÀíÊÂÎñ¡£¸Ã½Ó¿ÚÖÐÌṩÁËÈý¸öÊÂÎñ²Ù×÷·½·¨£¬¾ßÌåÈçÏ¡£
+
+* TransactionStatus getTransaction£¨TransactionDefinition definition£©£ºÓÃÓÚ»ñÈ¡ÊÂÎñ״̬ÐÅÏ¢¡£
+* void commit£¨TransactionStatus status£©£ºÓÃÓÚÌá½»ÊÂÎñ¡£
+* void rollback£¨TransactionStatus status£©£ºÓÃÓڻعöÊÂÎñ¡£
+
+ÔÚÏîÄ¿ÖУ¬Spring ½« xml ÖÐÅäÖõÄÊÂÎñÏêϸÐÅÏ¢·â×°µ½¶ÔÏó TransactionDefinition ÖУ¬È»ºóͨ¹ýÊÂÎñ¹ÜÀíÆ÷µÄ getTransaction() ·½·¨»ñµÃÊÂÎñµÄ״̬£¨TransactionStatus£©£¬²¢¶ÔÊÂÎñ½øÐÐÏÂÒ»²½µÄ²Ù×÷¡£
+
+#### 2\. TransactionDefinition
+
+TransactionDefinition ½Ó¿ÚÊÇÊÂÎñ¶¨Ò壨ÃèÊö£©µÄ¶ÔÏó£¬ËüÌṩÁËÊÂÎñÏà¹ØÐÅÏ¢»ñÈ¡µÄ·½·¨£¬ÆäÖаüÀ¨Îå¸ö²Ù×÷£¬¾ßÌåÈçÏ¡£
+
+* String getName()£º»ñÈ¡ÊÂÎñ¶ÔÏóÃû³Æ¡£
+* int getIsolationLevel()£º»ñÈ¡ÊÂÎñµÄ¸ôÀë¼¶±ð¡£
+* int getPropagationBehavior()£º»ñÈ¡ÊÂÎñµÄ´«²¥ÐÐΪ¡£
+* int getTimeout()£º»ñÈ¡ÊÂÎñµÄ³¬Ê±Ê±¼ä¡£
+* boolean isReadOnly()£º»ñÈ¡ÊÂÎñÊÇ·ñÖ»¶Á¡£
+
+ÔÚÉÏÊöÎå¸ö·½·¨µÄÃèÊöÖУ¬ÊÂÎñµÄ´«²¥ÐÐΪÊÇÖ¸ÔÚͬһ¸ö·½·¨ÖУ¬²»Í¬²Ù×÷ǰºóËùʹÓõÄÊÂÎñ¡£´«²¥ÐÐΪµÄÖÖÀàÈç±í 1 Ëùʾ¡£
+
+±í 1 ´«²¥ÐÐΪµÄÖÖÀà
+| ÊôÐÔÃû³Æ | Öµ | Ãè Êö |
+| --- | --- | --- |
+| PROPAGATION_REQUIRED | required | Ö§³Öµ±Ç°ÊÂÎñ¡£Èç¹û A ·½·¨ÒѾÔÚÊÂÎñÖУ¬Ôò B ÊÂÎñ½«Ö±½ÓʹÓ᣷ñÔò½«´´½¨ÐÂÊÂÎñ |
+| PROPAGATION_SUPPORTS | supports | Ö§³Öµ±Ç°ÊÂÎñ¡£Èç¹û A ·½·¨ÒѾÔÚÊÂÎñÖУ¬Ôò B ÊÂÎñ½«Ö±½ÓʹÓ᣷ñÔò½«ÒÔ·ÇÊÂÎñ״ִ̬ÐÐ |
+| PROPAGATION_MANDATORY | mandatory | Ö§³Öµ±Ç°ÊÂÎñ¡£Èç¹û A ·½·¨Ã»ÓÐÊÂÎñ£¬ÔòÅ׳öÒì³£ |
+| PROPAGATION_REQUIRES_NEW | requires_new | ½«´´½¨ÐµÄÊÂÎñ£¬Èç¹û A ·½·¨ÒѾÔÚÊÂÎñÖУ¬Ôò½« A ÊÂÎñ¹ÒÆð |
+| PROPAGATION_NOT_SUPPORTED | not_supported | ²»Ö§³Öµ±Ç°ÊÂÎñ£¬×ÜÊÇÒÔ·ÇÊÂÎñ״ִ̬ÐС£Èç¹û A ·½·¨ÒѾÔÚÊÂÎñÖУ¬Ôò½«Æä¹ÒÆð |
+| PROPAGATION_NEVER | never | ²»Ö§³Öµ±Ç°ÊÂÎñ£¬Èç¹û A ·½·¨ÔÚÊÂÎñÖУ¬ÔòÅ׳öÒì³£ |
+| PROPAGATION.NESTED | nested | ǶÌ×ÊÂÎñ£¬µ×²ã½«Ê¹Óà Savepoint ÐγÉǶÌ×ÊÂÎñ |
+
+ÔÚÊÂÎñ¹ÜÀí¹ý³ÌÖУ¬´«²¥ÐÐΪ¿ÉÒÔ¿ØÖÆÊÇ·ñÐèÒª´´½¨ÊÂÎñÒÔ¼°ÈçºÎ´´½¨ÊÂÎñ¡£
+
+ͨ³£Çé¿öÏ£¬Êý¾ÝµÄ²éѯ²»»á¸Ä±äÔÊý¾Ý£¬ËùÒÔ²»ÐèÒª½øÐÐÊÂÎñ¹ÜÀí£¬¶ø¶ÔÓÚÊý¾ÝµÄÔö¼Ó¡¢Ð޸ĺÍɾ³ýµÈ²Ù×÷£¬±ØÐë½øÐÐÊÂÎñ¹ÜÀí¡£Èç¹ûûÓÐÖ¸¶¨ÊÂÎñµÄ´«²¥ÐÐΪ£¬Ôò Spring3 ĬÈϵĴ«²¥ÐÐΪÊÇ required¡£
+
+#### 3\. TransactionStatus
+
+TransactionStatus ½Ó¿ÚÊÇÊÂÎñµÄ״̬£¬ËüÃèÊöÁËijһʱ¼äµãÉÏÊÂÎñµÄ״̬ÐÅÏ¢¡£ÆäÖаüº¬Áù¸ö²Ù×÷£¬¾ßÌåÈç±í 2 Ëùʾ¡£
+
+±í 2 ÊÂÎñµÄ²Ù×÷
+| Ãû³Æ | ˵Ã÷ |
+| --- | --- |
+| void flush() | Ë¢ÐÂÊÂÎñ |
+| boolean hasSavepoint() | »ñÈ¡ÊÇ·ñ´æÔÚ±£´æµã |
+| boolean isCompleted() | »ñÈ¡ÊÂÎñÊÇ·ñÍê³É |
+| boolean isNewTransaction() | »ñÈ¡ÊÇ·ñÊÇÐÂÊÂÎñ |
+| boolean isRollbackOnly() | »ñÈ¡ÊÇ·ñ»Ø¹ö |
+| void setRollbackOnly() | ÉèÖÃÊÂÎñ»Ø¹ö |
+
+# SpringÉùÃ÷ʽÊÂÎñ¹ÜÀí£¨»ùÓÚXML·½Ê½ÊµÏÖ£©
+
+[Spring](http://www.voidme.com/spring) µÄÊÂÎñ¹ÜÀíÓÐÁ½ÖÖ·½Ê½£ºÒ»ÖÖÊÇ´«Í³µÄ±à³ÌʽÊÂÎñ¹ÜÀí£¬¼´Í¨¹ý±àд´úÂëʵÏÖµÄÊÂÎñ¹ÜÀí£»ÁíÒ»ÖÖÊÇ»ùÓÚ AOP ¼¼ÊõʵÏÖµÄÉùÃ÷ʽÊÂÎñ¹ÜÀí¡£ÓÉÓÚÔÚʵ¼Ê¿ª·¢ÖУ¬±à³ÌʽÊÂÎñ¹ÜÀíºÜÉÙʹÓã¬ËùÒÔÎÒÃÇÖ»¶Ô Spring µÄÉùÃ÷ʽÊÂÎñ¹ÜÀí½øÐÐÏêϸ½²½â¡£
+
+Spring ÉùÃ÷ʽÊÂÎñ¹ÜÀíÔڵײã²ÉÓÃÁË AOP ¼¼Êõ£¬Æä×î´óµÄÓŵãÔÚÓÚÎÞÐëͨ¹ý±à³ÌµÄ·½Ê½¹ÜÀíÊÂÎñ£¬Ö»ÐèÒªÔÚÅäÖÃÎļþÖнøÐÐÏà¹ØµÄ¹æÔòÉùÃ÷£¬¾Í¿ÉÒÔ½«ÊÂÎñ¹æÔòÓ¦Óõ½ÒµÎñÂß¼ÖС£
+
+Spring ʵÏÖÉùÃ÷ʽÊÂÎñ¹ÜÀíÖ÷ÒªÓÐÁ½ÖÖ·½Ê½£º
+
+* »ùÓÚ XML ·½Ê½µÄÉùÃ÷ʽÊÂÎñ¹ÜÀí¡£
+* ͨ¹ý Annotation ×¢½â·½Ê½µÄÊÂÎñ¹ÜÀí¡£
+
+±¾½Úͨ¹ýÒøÐÐתÕ˵ݸÀý½²½âÈçºÎʹÓà XML µÄ·½Ê½ÊµÏÖ Spring µÄÉùÃ÷ʽÊÂÎñ´¦Àí¡£
+
+#### 1\. ´´½¨ÏîÄ¿
+
+ÔÚ MyEclipse Öд´½¨Ò»¸öÃûΪ springDemo03 µÄ Web ÏîÄ¿£¬½« Spring Ö§³ÖºÍÒÀÀµµÄ JAR °ü¸´ÖƵ½ Web ÏîÄ¿µÄ lib Ŀ¼ÖУ¬²¢Ìí¼Óµ½Àà·¾¶Ï¡£ËùÌí¼ÓµÄ JAR °üÈçͼ 1 Ëùʾ¡£
+
+
+ͼ 1 ÐèÒªµ¼ÈëµÄJAR°ü
+
+´Óͼ 1 ÖпÉÒÔ¿´³ö£¬ÕâÀïÔö¼Óµ¼ÈëÁË spring-tx-3.2.13.RELEASE.jar£¨ÊÂÎñ¹ÜÀí£©£¬ÒÔ¼° [MySQL](http://www.voidme.com/mysql) Çý¶¯¡¢JDBC ºÍ C3P0 µÄ JAR °ü¡£
+
+#### 2\. ´´½¨Êý¾Ý¿â¡¢±íÒÔ¼°²åÈëÊý¾Ý
+
+ÔÚ MySQL Öд´½¨Ò»¸öÃûΪ spring µÄÊý¾Ý¿â£¬È»ºóÔÚ¸ÃÊý¾Ý¿âÖд´½¨Ò»¸ö account ±í£¬²¢Ïò±íÖвåÈëÁ½ÌõÊý¾Ý£¬Æä SQL Ö´ÐÐÓï¾äÈçÏÂËùʾ£º
+
+ CREATE DATABASE spring;
+USE spring;
+CREATE TABLE account (
+ id INT (11) PRIMARY KEY AUTO_INCREMENT,
+ username VARCHAR(20) NOT NULL,
+ money INT DEFAULT NULL
+);
+INSERT INTO account VALUES (1,'zhangsan',1000);
+INSERT INTO account VALUES (2,'lisi',1000);
+
+Ö´ÐкóµÄ account ±íÖеÄÊý¾ÝÈçͼ 2 Ëùʾ¡£
+
+
+ͼ 2 Ö´Ðнá¹û
+
+#### 3\. ´´½¨ c3p0-db.properties
+
+ÔÚÏîÄ¿µÄ src Ï´´½¨Ò»¸öÃûΪ c3p0-db.properties µÄÅäÖÃÎļþ£¬ÕâÀïʹÓà C3P0 Êý¾ÝÔ´£¬ÐèÒªÔÚ¸ÃÎļþÖÐÌí¼ÓÈçÏÂÅäÖãº
+
+jdbc.driverClass = com.mysql.jdbc.Driver
+jdbc.jdbcUrl = jdbc:mysql://localhost:3306/spring
+jdbc.user = root
+jdbc.password = root
+
+#### 4\. ʵÏÖ DAO
+
+#### 1£©´´½¨ AccountDao ½Ó¿Ú
+
+ÔÚÏîÄ¿µÄ src Ŀ¼Ï´´½¨Ò»¸öÃûΪ com.mengma.dao µÄ°ü£¬ÔڸðüÏ´´½¨Ò»¸ö½Ó¿Ú AccountDao£¬²¢ÔÚ½Ó¿ÚÖд´½¨»ã¿îºÍÊÕ¿îµÄ·½·¨£¬ÈçÏÂËùʾ¡£
+
+ package com.mengma.dao;
+
+public interface AccountDao {
+ // »ã¿î
+ public void out(String outUser, int money);
+
+ // ÊÕ¿î
+ public void in(String inUser, int money);
+}
+
+ÉÏÊö´úÂëÖУ¬¶¨ÒåÁË out() ºÍ in() Á½¸ö·½·¨£¬·Ö±ðÓÃÓÚ±íʾ»ã¿îºÍÊÕ¿î¡£
+
+#### 2£©´´½¨DAO²ã½Ó¿ÚʵÏÖÀà
+
+ÔÚÏîÄ¿µÄ src Ŀ¼Ï´´½¨Ò»¸öÃûΪ com.mengma.dao.impl µÄ°ü£¬ÔڸðüÏ´´½¨ÊµÏÖÀà AccountDaoImpl£¬ÈçÏÂËùʾ¡£
+
+ package com.mengma.dao.impl;
+
+import org.springframework.jdbc.core.JdbcTemplate;
+import com.mengma.dao.AccountDao;
+
+public class AccountDaoImpl implements AccountDao {
+ private JdbcTemplate jdbcTemplate;
+
+ public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
+ this.jdbcTemplate = jdbcTemplate;
+ }
+
+ // »ã¿îµÄʵÏÖ·½·¨
+ public void out(String outUser, int money) {
+ this.jdbcTemplate.update("update account set money =money-?"
+ + "where username =?", money, outUser);
+ }
+
+ // ÊÕ¿îµÄʵÏÖ·½·¨
+ public void in(String inUser, int money) {
+ this.jdbcTemplate.update("update account set money =money+?"
+ + "where username =?", money, inUser);
+ }
+}
+
+ÉÏÊö´úÂëÖУ¬Ê¹Óà JdbcTemplate ÀàµÄ update() ·½·¨ÊµÏÖÁ˸üвÙ×÷¡£
+
+#### 5\. ʵÏÖ Service
+
+#### 1£©´´½¨ Service ²ã½Ó¿Ú
+
+ÔÚÏîÄ¿µÄ src Ŀ¼Ï´´½¨Ò»¸öÃûΪ com.mengma.service µÄ°ü£¬ÔڸðüÏ´´½¨½Ó¿Ú AccountService£¬ÈçÏÂËùʾ¡£
+
+ package com.mengma.service;
+
+public interface AccountService {
+ // תÕË
+ public void transfer(String outUser, String inUser, int money);
+}
+
+#### 2£©´´½¨ Service ²ã½Ó¿ÚʵÏÖÀà
+
+ÔÚÏîÄ¿µÄ src Ŀ¼Ï´´½¨Ò»¸öÃûΪ com.mengma.service.impl µÄ°ü£¬ÔڸðüÏ´´½¨ÊµÏÖÀà AccountServiceImpl£¬ÈçÏÂËùʾ¡£
+
+ package com.mengma.service.impl;
+
+import com.mengma.dao.AccountDao;
+
+public class AccountServiceImpl {
+ private AccountDao accountDao;
+
+ public void setAccountDao(AccountDao accountDao) {
+ this.accountDao = accountDao;
+ }
+
+ public void transfer(String outUser, String inUser, int money) {
+ this.accountDao.out(outUser, money);
+ this.accountDao.in(inUser, money);
+ }
+}
+
+ÉÏÊö´úÂëÖпÉÒÔ¿´³ö£¬¸ÃÀàʵÏÖÁË AccountService ½Ó¿Ú£¬²¢¶ÔתÕ˵ķ½·¨½øÐÐÁËʵÏÖ£¬¸ù¾Ý²ÎÊýµÄ²»Í¬µ÷Óà DAO ²ãÏàÓ¦µÄ·½·¨¡£
+
+#### 6\. ´´½¨ Spring ÅäÖÃÎļþ
+
+ÔÚÏîÄ¿µÄ src Ŀ¼Ï´´½¨ Spirng ÅäÖÃÎļþ applicationContext.xml£¬±à¼ºóÈçÏÂËùʾ¡£
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ÉÏÊö´úÂëÖУ¬Ê×ÏÈÔÚ ±ê¼ÇµÄµÚ 6¡¢13 ºÍ 14 ÐдúÂë·Ö±ðÌí¼ÓÁË AOP ËùÐèµÄÃüÃû¿Õ¼äÉùÃ÷¡£µÚ 42¡«50 ÐдúÂëʹÓà ±ê¼ÇÅäÖÃÊÂÎñ֪ͨÄÚÈÝ¡£
+
+µÚ 52¡«58 ÐдúÂëʹÓà ±ê¼Ç¶¨ÒåÇÐÃæ£¬ÆäÖÐµÚ 54 ÐдúÂëÓ¦ÓÃÁË AspectJ ±í´ïʽ£¬´ú±í com.mengma.service °üÏÂËùÓÐÀàµÄËùÓз½·¨¶¼Ó¦ÓÃÊÂÎñ¹æÔò£¬µÚ 57 ÐдúÂëʹÓà ±ê¼Ç½«ÇÐÈëµãÓëÊÂÎñ֪ͨÕûºÏ£¬»ùÓÚ AOP µÄÉùÃ÷ʽÊÂÎñÅäÖÃÍê³É¡£
+
+#### 7\. ´´½¨²âÊÔÀà
+
+ÔÚÏîÄ¿µÄ src Ŀ¼Ï´´½¨ com.mengma.test µÄ°ü£¬ÔڸðüÏ´´½¨²âÊÔÀà AccountTest£¬ÈçÏÂËùʾ¡£
+
+ package com.mengma.test;
+import org.junit.Test;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+import com.mengma.service.AccountService;
+public class AccountTest {
+ @Test
+ public void test() {
+ // »ñµÃSpringÈÝÆ÷£¬²¢²Ù×÷
+ String xmlPath = "applicationContext.xml";
+ ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
+ xmlPath);
+ AccountService accountService = (AccountService) applicationContext
+ .getBean("accountService");
+ accountService.transfer("zhangsan", "lisi", 100);
+ }
+}
+
+ÉÏÊö´úÂëÖÐÄ£ÄâÁËÒøÐÐתÕËÒµÎñ£¬´Ó zhangsan µÄÕË»§Ïò lisi µÄÕË»§ÖÐתÈë 100 Ôª¡£Ê¹Óà JUnit ²âÊÔÔËÐÐ test() ·½·¨£¬ÔËÐгɹ¦ºó£¬²éѯ account ±í£¬Èçͼ 3 Ëùʾ¡£
+
+´Óͼ 3 µÄ²éѯ½á¹ûÖпÉÒÔ¿´³ö£¬zhangsan ³É¹¦Ïò lisi תÕË 100 Ôª¡£
+
+
+ͼ 3 ²éѯ½á¹û
+
+ÏÂÃæÍ¨¹ýÐ޸ݸÀýÄ£ÄâתÕËʧ°ÜµÄÇé¿ö£¬ÔÚµÄ transfer() ·½·¨ÖÐÌí¼ÓÒ»ÐдúÂë¡°int i=1/0£»¡±Ä£Äâϵͳ¶ÏµçµÄÇé¿ö£¬¾ßÌå´úÂëÈçÏÂËùʾ£º
+
+ public void transfer(String outUser, String inUser, int money) {
+ this.accountDao.out(outUser, money);
+ //Ä£Äâ¶Ïµç
+ int i = 1/0;
+ this.accountDao.in(inUser, money);
+}
+
+ÖØÐ²âÊÔÔËÐÐ test() ·½·¨£¬JUnit ¿ØÖÆÌ¨Êä³öµÄÐÅÏ¢Èçͼ 4 Ëùʾ¡£
+
+
+ͼ 4 ¿ØÖÆÌ¨Êä³ö½á¹û
+
+´Óͼ 4 ÖпÉÒÔ¿´³ö£¬ÔÚÖ´ÐвâÊÔ·½·¨Ê±£¬³öÏÖÁ˳ýÒÔ 0 µÄÒì³£ÐÅÏ¢¡£´ËʱÔٴβéѯ account ±í£¬Æä²éѯ½á¹ûÈçͼ 5 Ëùʾ¡£
+
+´Óͼ 5 µÄ²éѯ½á¹ûÖпÉÒÔ¿´³ö£¬±íÖеÄÊý¾Ý²¢Ã»Óз¢Éú±ä»¯¡£ÓÉÓÚ³ÌÐòÔÚÖ´Ðйý³ÌÖÐÅ׳öÁËÒì³££¬ÊÂÎñ²»ÄÜÕý³£±»Ìá½»£¬ËùÒÔתÕËʧ°Ü¡£ÓÉ´Ë¿ÉÖª£¬Spring µÄÊÂÎñ¹ÜÀíÉúЧÁË¡£
+
+
+ͼ 5 ²éѯ½á¹û
+
+# SpringÉùÃ÷ʽÊÂÎñ¹ÜÀí£¨»ùÓÚAnnotation×¢½â·½Ê½ÊµÏÖ£©
+
+ÔÚ [Spring](http://www.voidme.com/spring) ÖУ¬³ýÁËʹÓûùÓÚ XML µÄ·½Ê½¿ÉÒÔʵÏÖÉùÃ÷ʽÊÂÎñ¹ÜÀíÒÔÍ⣬»¹¿ÉÒÔͨ¹ý Annotation ×¢½âµÄ·½Ê½ÊµÏÖÉùÃ÷ʽÊÂÎñ¹ÜÀí¡£
+
+ʹÓà Annotation µÄ·½Ê½·Ç³£¼òµ¥£¬Ö»ÐèÒªÔÚÏîÄ¿ÖÐ×öÁ½¼þÊ£¬¾ßÌåÈçÏ¡£
+
+#### 1£©ÔÚ Spring ÈÝÆ÷ÖÐ×¢²áÇý¶¯£¬´úÂëÈçÏÂËùʾ£º
+
+
+
+#### 2£©ÔÚÐèҪʹÓÃÊÂÎñµÄÒµÎñÀà»òÕß·½·¨ÖÐÌí¼Ó×¢½â @Transactional£¬²¢ÅäÖà @Transactional µÄ²ÎÊý¡£¹ØÓÚ @Transactional µÄ²ÎÊýÈçͼ 1 Ëùʾ¡£
+
+
+ͼ 1 @Transactional²ÎÊýÁбí
+
+ÏÂÃæÍ¨¹ýÐ޸ġ¶ [Spring»ùÓÚXMLʵÏÖÊÂÎñ¹ÜÀí](http://www.voidme.com/spring/spring-transaction-management-by-xml)¡·½Ì³ÌÖÐÒøÐÐתÕ˵ݸÀý½²½âÈçºÎʹÓà Annotation ×¢½âµÄ·½Ê½ÊµÏÖ Spring ÉùÃ÷ʽÊÂÎñ¹ÜÀí¡£
+
+#### 1\. ×¢²áÇý¶¯
+
+ÐÞ¸Ä Spring ÅäÖÃÎļþ applicationContext.xml£¬Ð޸ĺóÈçÏÂËùʾ¡£
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ÉÏÊö´úÂëÖпÉÒÔ¿´³ö£¬ÓëÔÀ´µÄÅäÖÃÎļþÏà±È£¬ÕâÀïÖ»ÐÞ¸ÄÁËÊÂÎñ¹ÜÀíÆ÷²¿·Ö£¬ÐÂÌí¼Ó²¢×¢²áÁËÊÂÎñ¹ÜÀíÆ÷µÄÇý¶¯¡£
+
+ÐèҪעÒâµÄÊÇ£¬ÔÚѧϰ AOP ×¢½â·½Ê½¿ª·¢Ê±£¬ÐèÒªÔÚÅäÖÃÎļþÖпªÆô×¢½â´¦ÀíÆ÷£¬Ö¸¶¨É¨ÃèÄÄЩ°üϵÄ×¢½â£¬ÕâÀïûÓпªÆô×¢½â´¦ÀíÆ÷ÊÇÒòΪÔÚµÚ 33¡«35 ÐÐÊÖ¶¯ÅäÖÃÁË AccountServiceImpl£¬¶ø @Transactional ×¢½â¾ÍÅäÖÃÔÚ¸ÃÀàÖУ¬ËùÒÔ»áÖ±½ÓÉúЧ¡£
+
+#### 2\. Ìí¼Ó @Transactional ×¢½â
+
+ÐÞ¸Ä AccountServiceImpl£¬ÔÚÎļþÖÐÌí¼Ó @Transactional ×¢½â¼°²ÎÊý£¬Ìí¼ÓºóÈçÏÂËùʾ¡£
+
+ package com.mengma.service.impl;
+
+import org.springframework.transaction.annotation.Isolation;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.mengma.dao.AccountDao;
+
+@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, readOnly = false)
+public class AccountServiceImpl {
+ private AccountDao accountDao;
+
+ public void setAccountDao(AccountDao accountDao) {
+ this.accountDao = accountDao;
+ }
+
+ public void transfer(String outUser, String inUser, int money) {
+ this.accountDao.out(outUser, money);
+ // Ä£Äâ¶Ïµç
+ int i = 1 / 0;
+ this.accountDao.in(inUser, money);
+ }
+}
+
+ÐèҪעÒâµÄÊÇ£¬ÔÚʹÓà @Transactional ×¢½âʱ£¬²ÎÊýÖ®¼äÓá°£¬¡±½øÐзָô¡£
+
+ʹÓà JUnit ²âÊÔÔÙ´ÎÔËÐÐ test() ·½·¨Ê±£¬¿ØÖÆÌ¨Í¬Ñù»áÊä³öÈçͼ 2 ËùʾµÄÒì³£ÐÅÏ¢£¬Õâ˵Ã÷ʹÓûùÓÚ Annotation ×¢½âµÄ·½Ê½Í¬ÑùʵÏÖÁË Spring µÄÉùÃ÷ʽÊÂÎñ¹ÜÀí¡£Èç¹û×¢Ê͵ôÄ£Äâ¶ÏµçµÄ´úÂë½øÐвâÊÔ£¬ÔòתÕ˲Ù×÷¿ÉÒÔÕý³£Íê³É¡£
+
+
+ͼ 2 ÔËÐнá¹û
+
+# ²Î¿¼ÎÄÕÂ
+https://www.w3cschool.cn/wkspring
+https://www.runoob.com/w3cnote/basic-knowledge-summary-of-spring.html
+http://codepub.cn/2015/06/21/Basic-knowledge-summary-of-Spring
+https://dunwu.github.io/spring-tutorial
+https://mszlu.com/java/spring
+http://c.biancheng.net/spring/aop-module.html
\ No newline at end of file
diff --git "a/docs/spring/Spring\345\220\210\351\233\206.md" "b/docs/spring/Spring\345\220\210\351\233\206.md"
new file mode 100644
index 0000000..931264e
--- /dev/null
+++ "b/docs/spring/Spring\345\220\210\351\233\206.md"
@@ -0,0 +1,22 @@
+# Spring
+
+
+# SpringÔ´Âë·ÖÎö
+
+# SpringMVC
+
+# SpringMVC Ô´Âë·ÖÎö
+
+# SpringBoot
+## springbootµÄǰÊÀ½ñÉú
+## springbootµÄ»ù±¾Ê¹ÓÃ
+## springbootµÄ³£¼û×¢½â
+## springbootµÄºËÐÄ×é¼þ
+## springbootµÄ»ù±¾ÔÀí
+## springbootÔ´Âë½âÎö
+
+# SpringBoot Ô´Âë·ÖÎö
+
+# SpringCloud
+# SpringCloud Ô´Âë·ÖÎö
+
diff --git "a/docs/spring/Spring\345\256\271\345\231\250\344\270\216IOC.md" "b/docs/spring/Spring\345\256\271\345\231\250\344\270\216IOC.md"
new file mode 100644
index 0000000..35623db
--- /dev/null
+++ "b/docs/spring/Spring\345\256\271\345\231\250\344\270\216IOC.md"
@@ -0,0 +1,157 @@
+IoC ÊÇ Inversion of Control µÄ¼òд£¬ÒëΪ¡°¿ØÖÆ·´×ª¡±£¬Ëü²»ÊÇÒ»Ãż¼Êõ£¬¶øÊÇÒ»ÖÖÉè¼ÆË¼Ï룬ÊÇÒ»¸öÖØÒªµÄÃæÏò¶ÔÏó±à³Ì·¨Ôò£¬Äܹ»Ö¸µ¼ÎÒÃÇÈçºÎÉè¼Æ³öËÉñîºÏ¡¢¸üÓÅÁ¼µÄ³ÌÐò¡£
+
+Spring ͨ¹ý IoC ÈÝÆ÷À´¹ÜÀíËùÓÐ Java ¶ÔÏóµÄʵÀý»¯ºÍ³õʼ»¯£¬¿ØÖƶÔÏóÓë¶ÔÏóÖ®¼äµÄÒÀÀµ¹ØÏµ¡£ÎÒÃǽ«ÓÉ IoC ÈÝÆ÷¹ÜÀíµÄ Java ¶ÔÏó³ÆÎª Spring Bean£¬ËüÓëʹÓùؼü×Ö new ´´½¨µÄ Java ¶ÔÏóûÓÐÈκÎÇø±ð¡£
+
+IoC ÈÝÆ÷ÊÇ Spring ¿ò¼ÜÖÐ×îÖØÒªµÄºËÐÄ×é¼þÖ®Ò»£¬Ëü¹á´©ÁË Spring ´Óµ®Éúµ½³É³¤µÄÕû¸ö¹ý³Ì¡£
+
+## ¿ØÖÆ·´×ª£¨IoC£©
+
+ÔÚ´«Í³µÄ Java Ó¦ÓÃÖУ¬Ò»¸öÀàÏëÒªµ÷ÓÃÁíÒ»¸öÀàÖеÄÊôÐÔ»ò·½·¨£¬Í¨³£»áÏÈÔÚÆä´úÂëÖÐͨ¹ý new Object() µÄ·½Ê½½«ºóÕߵĶÔÏó´´½¨³öÀ´£¬È»ºó²ÅÄÜʵÏÖÊôÐÔ»ò·½·¨µÄµ÷Óá£ÎªÁË·½±ãÀí½âºÍÃèÊö£¬ÎÒÃÇ¿ÉÒÔ½«Ç°Õß³ÆÎª¡°µ÷ÓÃÕß¡±£¬½«ºóÕß³ÆÎª¡°±»µ÷ÓÃÕß¡±¡£Ò²¾ÍÊÇ˵£¬µ÷ÓÃÕßÕÆÎÕ×ű»µ÷ÓÃÕß¶ÔÏó´´½¨µÄ¿ØÖÆÈ¨¡£
+
+µ«ÔÚ Spring Ó¦ÓÃÖУ¬Java ¶ÔÏó´´½¨µÄ¿ØÖÆÈ¨ÊÇÕÆÎÕÔÚ IoC ÈÝÆ÷ÊÖÀïµÄ£¬Æä´óÖ²½ÖèÈçÏ¡£
+
+¿ª·¢ÈËԱͨ¹ý XML ÅäÖÃÎļþ¡¢×¢½â¡¢Java ÅäÖÃÀàµÈ·½Ê½£¬¶Ô Java ¶ÔÏó½øÐж¨Ò壬ÀýÈçÔÚ XML ÅäÖÃÎļþÖÐʹÓà ±êÇ©¡¢ÔÚ Java ÀàÉÏʹÓà @Component ×¢½âµÈ¡£
+Spring Æô¶¯Ê±£¬IoC ÈÝÆ÷»á×Ô¶¯¸ù¾Ý¶ÔÏó¶¨Ò壬½«ÕâЩ¶ÔÏó´´½¨²¢¹ÜÀíÆðÀ´¡£ÕâЩ±» IoC ÈÝÆ÷´´½¨²¢¹ÜÀíµÄ¶ÔÏó±»³ÆÎª Spring Bean¡£
+µ±ÎÒÃÇÏëҪʹÓÃij¸ö Bean ʱ£¬¿ÉÒÔÖ±½Ó´Ó IoC ÈÝÆ÷ÖлñÈ¡£¨ÀýÈçͨ¹ý ApplicationContext µÄ getBean() ·½·¨£©£¬¶ø²»ÐèÒªÊÖ¶¯Í¨¹ý´úÂ루ÀýÈç new Obejct() µÄ·½Ê½£©´´½¨¡£
+
+IoC ´øÀ´µÄ×î´ó¸Ä±ä²»ÊÇ´úÂë²ãÃæµÄ£¬¶øÊÇ´Ó˼Ïë²ãÃæÉÏ·¢ÉúÁË¡°Ö÷´Ó»»Î»¡±µÄ¸Ä±ä¡£Ô±¾µ÷ÓÃÕßÊÇÖ÷¶¯µÄÒ»·½£¬ËüÏëҪʹÓÃʲô×ÊÔ´¾Í»áÖ÷¶¯³ö»÷£¬×Ô¼º´´½¨£»µ«ÔÚ Spring Ó¦ÓÃÖУ¬IoC ÈÝÆ÷ÕÆÎÕ×ÅÖ÷¶¯È¨£¬µ÷ÓÃÕßÔò±ä³ÉÁ˱»¶¯µÄÒ»·½£¬±»¶¯µÄµÈ´ý IoC ÈÝÆ÷´´½¨ËüËùÐèÒªµÄ¶ÔÏó£¨Bean£©¡£
+
+Õâ¸ö¹ý³ÌÔÚÖ°Ôð²ãÃæ·¢ÉúÁË¿ØÖÆÈ¨µÄ·´×ª£¬°ÑÔ±¾µ÷ÓÃÕßͨ¹ý´úÂëʵÏֵĶÔÏóµÄ´´½¨£¬·´×ª¸ø IoC ÈÝÆ÷À´°ïæʵÏÖ£¬Òò´ËÎÒÃǽ«Õâ¸ö¹ý³Ì³ÆÎª Spring µÄ¡°¿ØÖÆ·´×ª¡±¡£
+
+## ÒÀÀµ×¢È루DI£©
+
+ÔÚÁ˽âÁË IoC Ö®ºó£¬ÎÒÃÇ»¹ÐèÒªÁ˽âÁíÍâÒ»¸ö·Ç³£ÖØÒªµÄ¸ÅÄÒÀÀµ×¢Èë¡£
+
+ÒÀÀµ×¢È루Denpendency Injection£¬¼òдΪ DI£©ÊÇ Martin Fowler ÔÚ 2004 ÄêÔÚ¶Ô¡°¿ØÖÆ·´×ª¡±½øÐнâÊÍʱÌá³öµÄ¡£Martin Fowler ÈÏΪ¡°¿ØÖÆ·´×ª¡±Ò»´ÊºÜ»Þɬ£¬ÎÞ·¨ÈÃÈ˺ÜÖ±½ÓµÄÀí½â¡°µ½µ×ÊÇÄÄÀﷴתÁË¡±£¬Òò´ËËû½¨ÒéʹÓá°ÒÀÀµ×¢È롱À´´úÌæ¡°¿ØÖÆ·´×ª¡±¡£
+
+ÔÚÃæÏò¶ÔÏóÖУ¬¶ÔÏóºÍ¶ÔÏóÖ®¼äÊÇ´æÔÚÒ»ÖÖ½Ð×ö¡°ÒÀÀµ¡±µÄ¹ØÏµ¡£¼òµ¥À´Ëµ£¬ÒÀÀµ¹ØÏµ¾ÍÊÇÔÚÒ»¸ö¶ÔÏóÖÐÐèÒªÓõ½ÁíÍâÒ»¸ö¶ÔÏ󣬼´¶ÔÏóÖдæÔÚÒ»¸öÊôÐÔ£¬¸ÃÊôÐÔÊÇÁíÍâÒ»¸öÀàµÄ¶ÔÏó¡£
+
+ÀýÈ磬ÓÐÒ»¸öÃûΪ B µÄ Java À࣬ËüµÄ´úÂëÈçÏ¡£
+
+
+
+
+
+
+
+public class B {
+String bid;
+A a;
+}
+
+
+
+
+
+
+
+´Ó´úÂë¿ÉÒÔ¿´³ö£¬B ÖдæÔÚÒ»¸ö A ÀàÐ͵ĶÔÏóÊôÐÔ a£¬´ËʱÎÒÃǾͿÉÒÔ˵ B µÄ¶ÔÏóÒÀÀµÓÚ¶ÔÏó a¡£¶øÒÀÀµ×¢Èë¾ÍÊǾÍÊÇ»ùÓÚÕâÖÖ¡°ÒÀÀµ¹ØÏµ¡±¶ø²úÉúµÄ¡£
+
+ÎÒÃÇÖªµÀ£¬¿ØÖÆ·´×ªºËÐÄ˼Ïë¾ÍÊÇÓÉ Spring ¸ºÔð¶ÔÏóµÄ´´½¨¡£ÔÚ¶ÔÏó´´½¨¹ý³ÌÖУ¬Spring »á×Ô¶¯¸ù¾ÝÒÀÀµ¹ØÏµ£¬½«ËüÒÀÀµµÄ¶ÔÏó×¢Èëµ½µ±Ç°¶ÔÏóÖУ¬Õâ¾ÍÊÇËùνµÄ¡°ÒÀÀµ×¢È롱¡£
+
+ÒÀÀµ×¢Èë±¾ÖÊÉÏÊÇ [Spring Bean ÊôÐÔ×¢Èë](http://c.biancheng.net/spring/attr-injection.html)µÄÒ»ÖÖ£¬Ö»²»¹ýÕâ¸öÊôÐÔÊÇÒ»¸ö¶ÔÏóÊôÐÔ¶øÒÑ¡£
+
+## IoC µÄ¹¤×÷ÔÀí
+
+ÔÚ Java Èí¼þ¿ª·¢¹ý³ÌÖУ¬ÏµÍ³Öеĸ÷¸ö¶ÔÏóÖ®¼ä¡¢¸÷¸öÄ£¿éÖ®¼ä¡¢Èí¼þϵͳºÍÓ²¼þϵͳ֮¼ä£¬»ò¶à»òÉÙ¶¼´æÔÚÒ»¶¨µÄñîºÏ¹ØÏµ¡£
+
+ÈôÒ»¸öϵͳµÄñîºÏ¶È¹ý¸ß£¬ÄÇô¾Í»áÔì³ÉÄÑÒÔά»¤µÄÎÊÌ⣬µ«ÍêȫûÓÐñîºÏµÄ´úÂ뼸ºõÎÞ·¨Íê³ÉÈκι¤×÷£¬ÕâÊÇÓÉÓÚ¼¸ºõËùÓеŦÄܶ¼ÐèÒª´úÂëÖ®¼äÏ໥Ð×÷¡¢Ï໥ÒÀÀµ²ÅÄÜÍê³É¡£Òò´ËÎÒÃÇÔÚ³ÌÐòÉè¼ÆÊ±£¬Ëù±ü³ÐµÄ˼ÏëÒ»°ã¶¼ÊÇÔÚ²»Ó°Ïìϵͳ¹¦ÄܵÄǰÌáÏ£¬×î´óÏ޶ȵĽµµÍñîºÏ¶È¡£
+
+IoC µ×²ãͨ¹ý¹¤³§Ä£Ê½¡¢Java µÄ·´Éä»úÖÆ¡¢XML ½âÎöµÈ¼¼Êõ£¬½«´úÂëµÄñîºÏ¶È½µµÍµ½×îµÍÏÞ¶È£¬ÆäÖ÷Òª²½ÖèÈçÏ¡£
+
+ÔÚÅäÖÃÎļþ£¨ÀýÈç Bean.xml£©ÖУ¬¶Ô¸÷¸ö¶ÔÏóÒÔ¼°ËüÃÇÖ®¼äµÄÒÀÀµ¹ØÏµ½øÐÐÅäÖã»
+ÎÒÃÇ¿ÉÒÔ°Ñ IoC ÈÝÆ÷µ±×öÒ»¸ö¹¤³§£¬Õâ¸ö¹¤³§µÄ²úÆ·¾ÍÊÇ Spring Bean£»
+ÈÝÆ÷Æô¶¯Ê±»á¼ÓÔØ²¢½âÎöÕâЩÅäÖÃÎļþ£¬µÃµ½¶ÔÏóµÄ»ù±¾ÐÅÏ¢ÒÔ¼°ËüÃÇÖ®¼äµÄÒÀÀµ¹ØÏµ£»
+IoC ÀûÓà Java µÄ·´Éä»úÖÆ£¬¸ù¾ÝÀàÃûÉú³ÉÏàÓ¦µÄ¶ÔÏ󣨼´ Spring Bean£©£¬²¢¸ù¾ÝÒÀÀµ¹ØÏµ½«Õâ¸ö¶ÔÏó×¢Èëµ½ÒÀÀµËüµÄ¶ÔÏóÖС£
+
+ÓÉÓÚ¶ÔÏóµÄ»ù±¾ÐÅÏ¢¡¢¶ÔÏóÖ®¼äµÄÒÀÀµ¹ØÏµ¶¼ÊÇÔÚÅäÖÃÎļþÖж¨ÒåµÄ£¬²¢Ã»ÓÐÔÚ´úÂëÖнôÃÜñîºÏ£¬Òò´Ë¼´Ê¹¶ÔÏó·¢Éú¸Ä±ä£¬ÎÒÃÇÒ²Ö»ÐèÒªÔÚÅäÖÃÎļþÖнøÐÐÐ޸ļ´¿É£¬¶øÎÞÐë¶Ô Java ´úÂë½øÐÐÐ޸ģ¬Õâ¾ÍÊÇ Spring IoC ʵÏÖ½âñîµÄÔÀí¡£
+
+## IoC ÈÝÆ÷µÄÁ½ÖÖʵÏÖ
+
+IoC ˼Ïë»ùÓÚ IoC ÈÝÆ÷ʵÏֵģ¬IoC ÈÝÆ÷µ×²ãÆäʵ¾ÍÊÇÒ»¸ö Bean ¹¤³§¡£Spring ¿ò¼ÜΪÎÒÃÇÌṩÁËÁ½ÖÖ²»Í¬ÀàÐÍ IoC ÈÝÆ÷£¬ËüÃÇ·Ö±ðÊÇ BeanFactory ºÍ ApplicationContext¡£
+
+### BeanFactory
+
+BeanFactory ÊÇ IoC ÈÝÆ÷µÄ»ù±¾ÊµÏÖ£¬Ò²ÊÇ Spring ÌṩµÄ×î¼òµ¥µÄ IoC ÈÝÆ÷£¬ËüÌṩÁË IoC ÈÝÆ÷×î»ù±¾µÄ¹¦ÄÜ£¬ÓÉ org.springframework.beans.factory.BeanFactory ½Ó¿Ú¶¨Òå¡£
+
+BeanFactory ²ÉÓÃÀÁ¼ÓÔØ£¨lazy-load£©»úÖÆ£¬ÈÝÆ÷ÔÚ¼ÓÔØÅäÖÃÎļþʱ²¢²»»áÁ¢¿Ì´´½¨ Java ¶ÔÏó£¬Ö»ÓгÌÐòÖлñÈ¡£¨Ê¹Óã©Õâ¸ö¶Ô¶ÔÏóʱ²Å»á´´½¨¡£
+
+#### ʾÀý 1
+
+ÏÂÃæÎÒÃÇͨ¹ýÒ»¸öʵÀýÑÝʾ£¬À´ÑÝʾÏ BeanFactory µÄʹÓá£
+
+1\. ÔÚ HelloSpring ÏîÄ¿ÖУ¬½« MainApp µÄ´úÂëÐÞ¸ÄΪʹÓà BeanFactory »ñÈ¡ HelloWorld µÄ¶ÔÏ󣬾ßÌå´úÂëÈçÏ¡£
+
+
+
+
+
+
+
+public static void main(String[] args) {
+BeanFactory context = new ClassPathXmlApplicationContext("Beans.xml");
+HelloWorld obj = context.getBean("helloWorld", HelloWorld.class);
+obj.getMessage();
+}
+
+
+
+
+
+
+
+2. ÔËÐÐ MainApp.java£¬¿ØÖÆÌ¨Êä³öÈçÏ¡£
+
+ message : Hello World!
+
+> ×¢Ò⣺BeanFactory ÊÇ Spring ÄÚ²¿Ê¹Óýӿڣ¬Í¨³£Çé¿öϲ»Ìṩ¸ø¿ª·¢ÈËԱʹÓá£
+
+### ApplicationContext
+
+ApplicationContext ÊÇ BeanFactory ½Ó¿ÚµÄ×Ó½Ó¿Ú£¬ÊÇ¶Ô BeanFactory µÄÀ©Õ¹¡£ApplicationContext ÔÚ BeanFactory µÄ»ù´¡ÉÏÔö¼ÓÁËÐí¶àÆóÒµ¼¶µÄ¹¦ÄÜ£¬ÀýÈç AOP£¨ÃæÏòÇÐÃæ±à³Ì£©¡¢¹ú¼Ê»¯¡¢ÊÂÎñÖ§³ÖµÈ¡£
+
+ApplicationContext ½Ó¿ÚÓÐÁ½¸ö³£ÓõÄʵÏÖÀ࣬¾ßÌåÈçÏÂ±í¡£
+
+| ʵÏÖÀà | ÃèÊö | ʾÀý´úÂë |
+| --- | --- | --- |
+| ClassPathXmlApplicationContext | ¼ÓÔØÀà·¾¶ ClassPath ÏÂÖ¸¶¨µÄ XML ÅäÖÃÎļþ£¬²¢Íê³É ApplicationContext µÄʵÀý»¯¹¤×÷ | ApplicationContext applicationContext = new ClassPathXmlApplicationContext(String configLocation); |
+| FileSystemXmlApplicationContext | ¼ÓÔØÖ¸¶¨µÄÎļþϵͳ·¾¶ÖÐÖ¸¶¨µÄ XML ÅäÖÃÎļþ£¬²¢Íê³É ApplicationContext µÄʵÀý»¯¹¤×÷ | ApplicationContext applicationContext = new FileSystemXmlApplicationContext(String configLocation); |
+
+> ÔÚÉϱíµÄʾÀý´úÂëÖУ¬²ÎÊý configLocation ÓÃÓÚÖ¸¶¨ Spring ÅäÖÃÎļþµÄÃû³ÆºÍλÖã¬Èç Beans.xml¡£
+
+#### ʾÀý 2
+
+ÏÂÃæÎÒÃǾÍͨ¹ýÒ»¸öʵÀý£¬À´ÑÝʾ ApplicationContext µÄʹÓá£
+
+1. ÐÞ¸Ä HelloSpring ÏîÄ¿ MainApp ÀàÖÐ main() ·½·¨µÄ´úÂ룬¾ßÌå´úÂëÈçÏ¡£
+
+
+
+
+
+
+````
+public static void main(String[] args) {
+//ʹÓà FileSystemXmlApplicationContext ¼ÓÔØÖ¸¶¨Â·¾¶ÏµÄÅäÖÃÎļþ Bean.xml
+BeanFactory context = new FileSystemXmlApplicationContext("D:\\eclipe workspace\\spring workspace\\HelloSpring\\src\\Beans.xml");
+HelloWorld obj = context.getBean("helloWorld", HelloWorld.class);
+obj.getMessage();
+}
+````
+
+
+
+
+
+
+2. ÔËÐÐ MainApp.java£¬¿ØÖÆÌ¨Êä³öÈçÏ¡£
+
+ message : Hello World!
+
+# ²Î¿¼ÎÄÕÂ
+https://www.w3cschool.cn/wkspring
+https://www.runoob.com/w3cnote/basic-knowledge-summary-of-spring.html
+http://codepub.cn/2015/06/21/Basic-knowledge-summary-of-Spring
+https://dunwu.github.io/spring-tutorial
+https://mszlu.com/java/spring
+http://c.biancheng.net/spring/aop-module.html
\ No newline at end of file
diff --git "a/docs/spring/Spring\345\270\270\350\247\201\346\263\250\350\247\243.md" "b/docs/spring/Spring\345\270\270\350\247\201\346\263\250\350\247\243.md"
new file mode 100644
index 0000000..c5b2238
--- /dev/null
+++ "b/docs/spring/Spring\345\270\270\350\247\201\346\263\250\350\247\243.md"
@@ -0,0 +1,724 @@
+# Spring×¢½â
+## 1 ¸ÅÊö
+
+ÎÒÃǶ¼ÖªµÀSpring×îºËÐĵÄÌØÐÔ¾ÍÊÇIOC+AOP£¬IOCµÄÔÀí¾ÍÊÇʵÏÖÁËÒ»¸öSpringÈÝÆ÷£¬ÓÃÀ´¹ÜÀíËùÓÐSpring BeanʵÀý
+DI£¬Ò²¾ÍÊÇÒÀÀµ×¢È룬ÊÇÎÒÃÇ×÷Ϊ¿ª·¢ÕßÐèÒª¹ØÐĵĺËÐÄ»°Ì⣬ÈçºÎ×¢ÈëÒÀÀµ£¬×¢ÈëÄĸöÒÀÀµ£¬ÊÇÎÒÃÇÐèÒªÃ÷È·ÖªµÀµÄ¡£
+ÔÚÒÔǰ£¬ÎÒÃÇϰ¹ßÓÚÓÃxmlÅäÖÃÎļþÀ´ÉùÃ÷Ò»¸öbean£¬µ«ÏÖÔÚ£¬ÎÒÃǸü¶àµØÊ¹ÓÃ×¢½âºÍ´úÂëÀ´Íê³ÉDIµÄ¹ý³Ì
+
+
+ÎÒÃÇ¿ÉÒÔʹÓà org.springframework.beans.factory.annotation ºÍ org.springframework.context.annotation °üÖеÄ×¢ÊÍÀ´ÆôÓà Spring DI ÒýÇæµÄ¹¦ÄÜ¡£
+
+ÎÒÃÇͨ³£½«ÕâЩ³ÆÎª¡°Spring ºËÐÄ×¢ÊÍ¡±£¬ÎÒÃǽ«ÔÚ±¾½Ì³ÌÖÐ¶ÔÆä½øÐлعˡ£
+
+
+## 2 DIÏà¹Ø×¢½â
+
+### 2.1 @Autowired
+
+ÎÒÃÇ¿ÉÒÔʹÓà @Autowired À´±ê¼Ç Spring ½«Òª½âÎöºÍ×¢ÈëµÄÒÀÀµÏî¡£
+ÎÒÃÇ¿ÉÒÔ½«´Ë×¢ÊÍÓë¹¹Ô캯Êý¡¢setter »ò×Ö¶Î×¢ÈëÒ»ÆðʹÓá£
+Constructor injection:
+
+**¹¹ÔìÆ÷×¢Èë**
+
+````
+class Car {
+ Engine engine;
+
+ @Autowired
+ Car(Engine engine) {
+ this.engine = engine;
+ }
+}
+````
+
+**Setter×¢Èë**
+````
+class Car {
+ Engine engine;
+
+ @Autowired
+ void setEngine(Engine engine) {
+ this.engine = engine;
+ }
+}
+````
+**±äÁ¿×¢Èë**
+````
+class Car {
+ @Autowired
+ Engine engine;
+}
+````
+
+@Autowired ÓÐÒ»¸öÃûΪ required µÄ²¼¶û²ÎÊý£¬Ä¬ÈÏֵΪ true¡£
+
+µ±ËüÕÒ²»µ½ºÏÊ浀 bean À´Á¬½Óʱ£¬Ëü»áµ÷Õû Spring µÄÐÐΪ¡£ µ±Îª true ʱ£¬½«Å׳öÒì³££¬·ñÔò²»Á¬½ÓÈκÎÄÚÈÝ¡£
+
+Çë×¢Ò⣬Èç¹ûÎÒÃÇʹÓù¹Ô캯Êý×¢È룬ÔòËùÓй¹Ô캯Êý²ÎÊý¶¼ÊÇÇ¿ÖÆÐԵġ£
+
+´Ó 4.3 °æ±¾¿ªÊ¼£¬ÎÒÃDz»ÐèÒªÏÔʽµØÊ¹Óà @Autowired ×¢½â¹¹Ô캯Êý£¬³ý·ÇÎÒÃÇÉùÃ÷ÖÁÉÙÁ½¸ö¹¹Ô캯Êý¡£
+
+### 2.2 @Bean
+
+@Bean ±ê¼ÇʵÀý»¯ Spring bean µÄ¹¤³§·½·¨£º
+
+```
+@Bean
+Engine engine() {
+ return new Engine();
+}
+````
+
+µ±ÐèÒª·µ»ØÀàÐ͵ÄÐÂʵÀýʱ£¬Spring »áµ÷ÓÃÕâЩ·½·¨¡£
+
+Éú³ÉµÄ bean Ó빤³§·½·¨Í¬Ãû¡£ Èç¹ûÎÒÃÇÏëÒÔ²»Í¬µÄ·½Ê½ÃüÃû£¬ÎÒÃÇ¿ÉÒÔʹÓôË×¢Ê͵ÄÃû³Æ»òÖµ²ÎÊý£¨²ÎÊýÖµÊDzÎÊýÃû³ÆµÄ±ðÃû£©£º
+
+````
+@Bean("engine")
+Engine getEngine() {
+ return new Engine();
+}
+````
+ÕâÊÇÒ»Öַdz£³£¼ûµÄbeanÉùÃ÷·½Ê½£¬ÒòΪºÜ¶àµÄbean²¢²»ÊÇÎÒÃÇÒ»¿ªÊ¼¾ÍÔÚ´úÂëÀﶨÒåºÃµÄ£¬Ëü¿ÉÄÜÐèÒª»ùÓÚÔËÐÐʱ»·¾³À´½øÐа´Ðè¹¹½¨¡£
+
+ÎÒÃÇ¿ÉÒÔ×ÔÓɵØÉùÃ÷ºÍ¶¨ÒåBean£¬²¢ÇÒÒ²¿ÉÒÔ¸³ÓèËü×Ô¶¨ÒåµÄbeanÃû³Æ¡£
+
+×¢Ò⣬ËùÓÐÓÃ@Bean ×¢Ê͵ķ½·¨¶¼±ØÐëÔÚ@Configuration ÀàÖС£
+
+### 2.3 @Qualifier
+
+ÎÒÃÇʹÓÃ@Qualifier ºÍ@Autowired À´ÌṩÎÒÃÇÏëÒªÔÚ²»Ã÷È·Çé¿öÏÂʹÓõÄbean id »òbean Ãû³Æ¡£
+
+ÀýÈ磬ÒÔÏÂÁ½¸ö bean ʵÏÖÏàͬµÄ½Ó¿Ú£º
+````
+class Bike implements Vehicle {}
+
+class Car implements Vehicle {}
+
+````
+
+Èç¹û Spring ÐèҪעÈëÒ»¸ö Vehicle bean£¬Ëü»áÒÔ¶à¸öÆ¥Å䶨Òå½áÊø¡£ ÔÚÕâÖÖÇé¿öÏ£¬ÎÒÃÇ¿ÉÒÔʹÓà @Qualifier ×¢ÊÍÏÔʽÌṩ bean µÄÃû³Æ¡£
+
+**¹¹ÔìÆ÷×¢Èë**
+````
+@Autowired
+Biker(@Qualifier("bike") Vehicle vehicle) {
+this.vehicle = vehicle;
+}
+````
+
+**Setter×¢Èë**
+
+````
+@Autowired
+void setVehicle(@Qualifier("bike") Vehicle vehicle) {
+this.vehicle = vehicle;
+}
+````
+»òÕß:
+
+````
+@Autowired
+@Qualifier("bike")
+void setVehicle(Vehicle vehicle) {
+this.vehicle = vehicle;
+````
+**±äÁ¿×¢Èë**
+
+````
+@Autowired
+@Qualifier("bike")
+Vehicle vehicle;
+````
+Õâ¸ö×¢½âÎÒÃÇ¿ÉÄÜÆ½³£ÓõIJ»¶à£¬µ«Êǵ±Ò»¸ö½Ó¿ÚÓжà¸öʵÏÖÀàʱ£¬Ëü¾Í»á¾³£ÅÉÉÏÓ󡣡
+
+### 2.4 @Required
+
+@Required ÔÚ setter ·½·¨Éϱê¼ÇÎÒÃÇÏëҪͨ¹ý XML Ìî³äµÄÒÀÀµÏ
+````
+@Required
+void setColor(String color) {
+this.color = color;
+}
+````
+xml
+````
+
+
+
+````
+·ñÔò£¬½«Å׳ö BeanInitializationException¡£
+·Ç³£ÉÙ¼ûµÄÓ÷¨£¬ÖªµÀһϾÍÐÐÁË
+
+### 2.5 @Value
+ÎÒÃÇ¿ÉÒÔʹÓà @Value ½«ÊôÐÔÖµ×¢Èë bean¡£ ËüÓë¹¹Ô캯Êý¡¢setter ºÍ×Ö¶Î×¢Èë¼æÈÝ¡£
+
+ÕâÒ²ÊǷdz£³£ÓõÄÒ»¸ö×¢½â£¬ÒòΪÎÒÃǺܶàʱºò¶¼ÐèÒª´Óapplication.properties»òÕ߯äËûÅäÖÃÎļþÖÐÀ´¶ÁÈ¡ÅäÖÃÊôÐÔÖµ¡£
+
+**¹¹ÔìÆ÷×¢Èë**
+````
+Engine(@Value("8") int cylinderCount) {
+this.cylinderCount = cylinderCount;
+}
+````
+
+**setter×¢Èë**
+
+````
+@Autowired
+void setCylinderCount(@Value("8") int cylinderCount) {
+this.cylinderCount = cylinderCount;
+}
+````
+
+»òÕß:
+````
+
+@Value("8")
+void setCylinderCount(int cylinderCount) {
+this.cylinderCount = cylinderCount;
+}
+````
+
+**±äÁ¿×¢Èë**
+````
+@Value("8")
+int cylinderCount;
+````
+
+µ±È»£¬×¢È뾲ֵ̬ÊÇûÓÐÓõġ£ Òò´Ë£¬ÎÒÃÇ¿ÉÒÔÔÚ @Value ÖÐʹÓÃռλ·û×Ö·û´®À´Á¬½ÓÔÚÍⲿԴÖж¨ÒåµÄÖµ£¬ÀýÈçÔÚ .properties »ò .yaml ÎļþÖС£
+````
+
+engine.fuelType=petrol
+````
+
+ÎÒÃÇ¿ÉÒÔͨ¹ýÒÔÏ·½Ê½×¢Èë engine.fuelType µÄÖµ£º
+
+````
+@Value("${engine.fuelType}")
+String fuelType;
+````
+
+ÎÒÃÇÉõÖÁ¿ÉÒÔʹÓà SpEL À´Ê¹ÓÃ@Value¡£ ¸ü¶à¸ß¼¶Ê¾Àý¿ÉÒÔÔÚÎÒÃǹØÓÚ@Value µÄÎÄÕÂÖÐÕÒµ½¡£
+
+### 2.6 @DependsOn
+ÎÒÃÇ¿ÉÒÔʹÓôË×¢½âÈà Spring ÔÚ×¢½âµÄ bean ֮ǰ³õʼ»¯ÆäËû bean¡£ ͨ³££¬´ËÐÐΪÊÇ×Ô¶¯µÄ£¬»ùÓÚ bean Ö®¼äµÄÏÔʽÒÀÀµ¹ØÏµ¡£
+
+ÎÒÃÇÖ»ÓÐÔÚÒÀÀµÊÇÒþʽµÄʱºò²ÅÐèÒªÕâ¸ö×¢½â£¬±ÈÈçJDBCÇý¶¯¼ÓÔØ»òÕß¾²Ì¬±äÁ¿³õʼ»¯¡£
+
+ÎÒÃÇ¿ÉÒÔÔÚÖ¸¶¨ÒÀÀµ bean Ãû³ÆµÄÒÀÀµÀàÉÏʹÓà @DependsOn¡£ ×¢Ê͵ÄÖµ²ÎÊýÐèÒªÒ»¸ö°üº¬ÒÀÀµ bean Ãû³ÆµÄÊý×飺
+
+````
+@DependsOn("engine")
+class Car implements Vehicle {}
+````
+Alternatively, if we define a bean with the @Bean annotation, the factory method should be annotated with @DependsOn:
+````
+@Bean
+@DependsOn("fuel")
+Engine engine() {
+return new Engine();
+}
+````
+### 2.7 @Lazy
+µ±ÎÒÃÇÏëÀÁ¶èµØ³õʼ»¯ÎÒÃÇµÄ bean ʱ£¬ÎÒÃÇʹÓà @Lazy¡£ ĬÈÏÇé¿öÏ£¬Spring ÔÚÓ¦ÓóÌÐòÉÏÏÂÎĵįô¶¯/Òýµ¼Ê±¼±Çеش´½¨ËùÓе¥Àý bean¡£
+
+µ«ÊÇ£¬ÓÐЩÇé¿öÏÂÎÒÃÇÐèÒªÔÚÇëÇóʱ´´½¨ bean£¬¶ø²»ÊÇÔÚÓ¦ÓóÌÐòÆô¶¯Ê±´´½¨¡£
+
+Õâ¸ö×¢½âµÄÐÐΪ»á¸ù¾ÝÎÒÃÇ·ÅÖÃËüµÄÈ·ÇÐλÖöøÓÐËù²»Í¬¡£ ÎÒÃÇ¿ÉÒÔ°ÑËü·ÅÔÚ£º
+
+Ò»¸ö @Bean ×¢Ê굀 bean ¹¤³§·½·¨£¬ÒÔÑÓ³Ù·½·¨µ÷Óã¨Òò´Ë´´½¨ bean£©
+@Configuration ÀàºÍËùÓаüº¬µÄ@Bean ·½·¨¶¼»áÊܵ½Ó°Ïì
+
+Ò»¸ö @Component À࣬Ëü²»ÊÇ @Configuration À࣬Õâ¸ö bean ½«±»ÑÓ³Ù³õʼ»¯
+
+@Autowired ¹¹Ô캯Êý¡¢setter »ò×ֶΣ¬ÓÃÓÚÑÓ³Ù¼ÓÔØÒÀÀµÏî±¾Éí£¨Í¨¹ý´úÀí£©
+
+````
+@Configuration
+@Lazy
+class VehicleFactoryConfig {
+
+ @Bean
+ @Lazy(false)
+ Engine engine() {
+ return new Engine();
+ }
+}
+````
+ÕâͬÑù²»ÊÇÒ»¸ö³£ÓõÄ×¢½â¡£
+
+µ±ÎÒÃÇά»¤Ò»¸öÓдóÁ¿beanµÄÏîĿʱ£¬»á·¢ÏÖÓкܶàbean¿ÉÄܶ¼Êǰ´ÐèʹÓõ쬲»Ò»¶¨ÐèÒªÔÚÈÝÆ÷³õʼ»¯Ê±¾Í½øÐгõʼ»¯£¬Õâ¿ÉÒÔ°ïÎÒÃǽÚÊ¡ºÜ¶àʱ¼äºÍÐÔÄÜ¡£
+
+
+### 2.8 @Lookup
+ͬÑùÊÇÒ»¸ö±È½ÏÉÙÓõ½µÄ×¢½â
+
+@Lookup »á¸æËß Spring ÔÚÎÒÃǵ÷ÓÃËüʱ·µ»Ø·½·¨·µ»ØÀàÐ͵ÄʵÀý¡£
+
+±¾ÖÊÉÏ£¬Spring ½«¸²¸ÇÎÒÃÇ´ø×¢Ê͵ķ½·¨²¢Ê¹ÓÃÎÒÃÇ·½·¨µÄ·µ»ØÀàÐͺͲÎÊý×÷Ϊ BeanFactory#getBean µÄ²ÎÊý¡£
+
+@Lookup ÊÊÓÃÓÚ£º
+
+½«ÔÐÍ bean ×¢ÈëÎÒÃÇ×Ô¼ºµÄbean£¨ÀàËÆÓÚ Provider£©
+
+Èç¹ûÎÒÃÇÅöÇɾö¶¨ÓµÓÐÒ»¸öÔÐÍ Spring bean£¬ÄÇôÎÒÃǼ¸ºõ»áÁ¢¼´ÃæÁÙÕâÑùµÄÎÊÌ⣺
+
+ÎÒÃǵĵ¥Àý Spring bean ½«ÈçºÎ·ÃÎÊÕâЩÔÐÍ Spring bean£¿
+
+ÏÖÔÚ£¬Provider ¿Ï¶¨ÊÇÒ»ÖÖ·½Ê½£¬¾¡¹Ü @Lookup ÔÚijЩ·½Ãæ¸ü¼ÓͨÓá£
+
+ҪעÒâµÄÊÇ£¬springĬÈÏʹÓõĵ¥Àýbean£¬ËùÒÔÈç¹ûÎÒÃÇҪעÈëÔÐÍbean£¬ÎÒÃDzÅÐèÒª×öÕâÑùµÄ¶îÍ⹤×÷
+
+Ê×ÏÈ£¬ÈÃÎÒÃÇ´´½¨Ò»¸öÔÐÍ bean£¬ÉÔºóÎÒÃǽ«Æä×¢Èëµ½µ¥Àý bean ÖУº
+````
+@Component
+@Scope("prototype")
+public class SchoolNotification {
+// ... prototype-scoped state
+}
+````
+ʹÓÃ@Lookup£¬ÎÒÃÇ¿ÉÒÔͨ¹ýµ¥Àý bean »ñÈ¡ SchoolNotification µÄʵÀý£º
+
+````
+@Component
+public class StudentServices {
+
+ // ... member variables, etc.
+
+ @Lookup
+ public SchoolNotification getNotification() {
+ return null;
+ }
+
+ // ... getters and setters
+}
+````
+Using @Lookup, we can get an instance of SchoolNotification through our singleton bean:
+````
+@Test
+public void whenLookupMethodCalled_thenNewInstanceReturned() {
+// ... initialize context
+StudentServices first = this.context.getBean(StudentServices.class);
+StudentServices second = this.context.getBean(StudentServices.class);
+
+ assertEquals(first, second);
+ assertNotEquals(first.getNotification(), second.getNotification());
+}
+````
+Çë×¢Ò⣬ÔÚ StudentServices ÖУ¬ÎÒÃǽ« getNotification ·½·¨±£ÁôΪ´æ¸ù¡£
+
+ÕâÊÇÒòΪ Spring ͨ¹ýµ÷Óà beanFactory.getBean(StudentNotification.class) ¸²¸ÇÁ˸÷½·¨£¬Òò´ËÎÒÃÇ¿ÉÒÔ½«ÆäÁô¿Õ¡£
+
+
+### 2.9 @Primary
+ÓÐʱÎÒÃÇÐèÒª¶¨Òå¶à¸öÏàͬÀàÐ͵Äbean¡£ ÔÚÕâЩÇé¿öÏ£¬×¢È뽫²»³É¹¦£¬ÒòΪ Spring ²»ÖªµÀÎÒÃÇÐèÒªÄĸö bean¡£
+
+ÎÒÃÇÒѾ¿´µ½ÁË´¦ÀíÕâÖÖÇé¿öµÄÑ¡ÏÓÃ@Qualifier ±ê¼ÇËùÓнÓÏߵ㲢ָ¶¨ËùÐè bean µÄÃû³Æ¡£
+
+È»¶ø£¬´ó¶àÊýʱºòÎÒÃÇÐèÒªÒ»¸öÌØ¶¨µÄ bean£¬ºÜÉÙÐèÒªÆäËû bean¡£
+
+ÎÒÃÇ¿ÉÒÔʹÓÃ@Primary À´¼ò»¯ÕâÖÖÇé¿ö£ºÈç¹ûÎÒÃÇÓÃ@Primary ±ê¼Ç×î³£ÓõÄbean£¬Ëü½«ÔÚunqualifiedµÄ×¢ÈëµãÉϱ»Ñ¡Ôñ£º
+
+````
+@Component
+@Primary
+class Car implements Vehicle {}
+
+@Component
+class Bike implements Vehicle {}
+
+@Component
+class Driver {
+@Autowired
+Vehicle vehicle;
+}
+
+@Component
+class Biker {
+@Autowired
+@Qualifier("bike")
+Vehicle vehicle;
+}
+````
+ÔÚÇ°ÃæµÄʾÀýÖУ¬Æû³µÊÇÖ÷Òª³µÁ¾¡£ Òò´Ë£¬ÔÚ Driver ÀàÖУ¬Spring ×¢ÈëÁËÒ»¸ö Car bean¡£ µ±È»£¬ÔÚ Biker bean ÖУ¬×Ö¶Î vehicle µÄÖµ½«ÊÇÒ»¸ö Bike ¶ÔÏó£¬ÒòΪËüÊÇqualifiedµÄ¡£
+
+### 2.10 @Scope
+
+¶ÔÓÚͨ³£µÄÓ¦ÓÃÀ´Ëµ£¬ÎÒÃÇbeanµÄscopeĬÈ϶¼Êǵ¥ÀýµÄ£¬µ«Êµ¼ÊÉÏspring bean¿ÉÒÔÖ§³Ö¶àÖÖ¶àÑùµÄ×÷Ó÷¶Î§£¬ËüÃÇÓÐ×Ų»Í¬µÄÉúÃüÖÜÆÚ¡£
+
+ÎÒÃÇʹÓÃ@Scope À´¶¨Òå@Component Àà»ò@Bean ¶¨ÒåµÄ·¶Î§¡£ Ëü¿ÉÒÔÊǵ¥Àý¡¢ÔÐÍ¡¢ÇëÇ󡢻Ự¡¢globalSession »òһЩ×Ô¶¨Ò巶Χ¡£
+
+¶ÔÓ¦µÄö¾ÙֵΪ
+````
+singleton
+prototype
+request
+session
+application
+websocket
+````
+
+Àý×Ó
+````
+@Component
+@Scope("prototype")
+class Engine {}
+````
+ÎÒÃÇ¿ÉÒÔÏëÏóһЩ³¡¾°£¬±ÈÈçrequest¡¢session¡¢websocketÕâÀà×÷ÓÃÓòµÄbean£¬Í¨³£Ó¦¸ÃÊǺÍÍøÂçÇëÇóÏà¹ØµÄ£¬±ÈÈçÓô洢Óû§ÐÅÏ¢¡¢sessionÖ®ÀàµÄbean¡£
+
+¾ßÌåÔõôʹÓ㬾ÍÒª¸ù¾ÝÄãµÄ¾ßÌ峡¾°À´Ñ¡ÔñÁË£¬Õâ»áÊÇÒ»¸öºÜ´óµÄ»°Ì⣬ÕâÀï¾ÍÏȲ»Õ¹¿ªÁË£¬ÒÔºó¿ÉÒÔÔÚµ¥¶ÀµÄÎÄÕÂÀï¼ÌÐø½éÉÜ¡£
+
+## 3 ÉÏÏÂÎÄÅäÖÃ×¢½â
+ÎÒÃÇ¿ÉÒÔʹÓñ¾½ÚÖÐÃèÊöµÄ×¢ÊÍÀ´ÅäÖÃÓ¦ÓóÌÐòÉÏÏÂÎÄ¡£
+
+
+### 3.1 @Profile
+
+Èç¹ûÎÒÃÇÏ£Íû Spring ½öÔÚÌØ¶¨ÅäÖÃÎļþ´¦Óڻ״̬ʱʹÓÃ@Component Àà»ò@Bean ·½·¨£¬ÎÒÃÇ¿ÉÒÔʹÓÃ@Profile ¶ÔÆä½øÐбê¼Ç¡£
+
+ÎÒÃÇ¿ÉÒÔʹÓÃ×¢Ê͵ÄÖµ²ÎÊýÅäÖÃÅäÖÃÎļþµÄÃû³Æ£º
+
+ÎÒÃÇͨ³£Õâ¸ö×¢½âÀ´ÅäÖò»Í¬»·¾³µÄÅäÖá£
+±ÈÈçÏÂÃæÕâ¸öÀý×Ó
+
+````
+public interface DatasourceConfig {
+public void setup();
+}
+````
+
+ÏÂÃæÊÇ¿ª·¢»·¾³µÄÅäÖãº
+
+````
+@Component
+@Profile("dev")
+public class DevDatasourceConfig implements DatasourceConfig {
+@Override
+public void setup() {
+System.out.println("Setting up datasource for DEV environment. ");
+}
+}
+````
+ÏÂÃæÊÇÉú²ú»·¾³µÄÅäÖãº
+
+````
+@Component
+@Profile("production")
+public class ProductionDatasourceConfig implements DatasourceConfig {
+@Override
+public void setup() {
+System.out.println("Setting up datasource for PRODUCTION environment. ");
+}
+}
+````
+µ±È»ÎÒÃÇÒ²¿ÉÒÔʹÓÃxml»òÕ߯äËûÀàÐ͵ÄÅäÖÃÎļþÀ´ÃèÊöÕâ¸öÅäÖÃbean
+
+xml
+````
+
+
+
+````
+### 3.2 @Import
+
+ÎÒÃÇ¿ÉÒÔʹÓÃÌØ¶¨µÄ @Configuration À࣬¶øÎÞÐèʹÓôË×¢½â½øÐÐ×é¼þɨÃè¡£ ÎÒÃÇ¿ÉÒÔΪÕâЩÀàÌṩ@Import µÄÖµ²ÎÊý
+
+Õý³£À´Ëµ£¬Èç¹ûÒªÓõ½@Configuration×¢½âµÄbean£¬ÄÇôspringÓ¦ÓñØÐëҪɨÃèµ½¸ÃĿ¼£¬Èç¹ûÇ¡ºÃûÓжԸ÷¾¶½øÐÐɨÃ裬»òÕßÎÒÃÇÖ»ÊÇÏëʹÓ÷¾¶Ïµĵ¥¸öÅäÖÃÀ࣬ÄÇôÎÒÃǾͿÉÒÔʹÓÃ@ImportÀ´µ¼ÈëÕâ¸öÅäÖÃÀàÁË¡£
+
+Õâ¸ö×¢½â»¹ÊǷdz£³£Óõģ¬¿´Ò»ÏÂÏÂÃæÕâ¸öÀý×Ó
+
+````
+@Import(VehiclePartSupplier.class)
+class VehicleFactoryConfig {}
+
+@Configuration
+class VehiclePartSupplier{
+}
+````
+
+### 3.3 @ImportResource
+
+±ÈÈç˵£ºÏÖÔÚÓÐÒ»¸ö bean.xml µÄÅäÖÃÎļþ£¬ÐèÒª½«¸Ã beans.xml Öж¨ÒåµÄ bean¶ÔÏó ¶¼µ¼Èëµ½ Spring Boot »·¾³µÄÈÝÆ÷ÖУ¬¸ÃÈçºÎ²Ù×÷ÄØ£¿
+
+1.Spring ·½Ê½µÄÅäÖÃÎļþ bean.xml ´Ë´¦Ëæ±ã¾Ù¸öʾÀý£¬±ÈÈç˵ xml ÖÐÅäÖÃÁËÒ»¸ö helloService£¬ÈçÏÂËùʾ
+````
+
+
+
+
+
+
+````
+2.ʹÓÃ@ImportResource×¢½â£¬ÒýÈë xml ÅäÖÃ
+````
+/**
+ * Spring BootÀïÃæÃ»ÓÐSpringµÄÅäÖÃÎļþ£¬ÎÒÃÇ×Ô¼º±àдµÄÅäÖÃÎļþ£¬Ò²²»ÄÜ×Ô¶¯Ê¶±ð£»
+ * Èç¹ûÏëÈÃSpringµÄÅäÖÃÎļþÉúЧ£¬¼ÓÔØµ½Spring ÈÝÆ÷ÖÐÀ´£»
+ * ʹÓÃ@ImportResource×¢½â£¬½«Æä±ê×¢ÔÚÒ»¸öÅäÖÃÀàÉÏ(´Ë´¦ÅäÖÃÔÚÆô¶¯Àà)
+ */
+@SpringBootApplication
+@ImportResource(locations = {"classpath:beans.xml"})
+public class BootApplication {
+
+ public static void main(String[] args) {
+ // SpringÓ¦ÓÃÆô¶¯ÆðÀ´
+ SpringApplication.run(BootApplication.class,args);
+
+ }
+}
+
+````
+### 3.4 @PropertySource
+ͨ¹ýÕâ¸ö×¢½â£¬ÎÒÃÇ¿ÉÒÔΪӦÓóÌÐòÉèÖö¨ÒåÊôÐÔÎļþ£º
+
+@PropertySource ×¢½âÌṩÁËÒ»ÖÖ·½±ãµÄÉùÃ÷ÐÔ»úÖÆ£¬ÓÃÓÚ½« PropertySource Ìí¼Óµ½ Spring µÄ Environment ÖУ¬Óë @Configuration ÀàÒ»ÆðʹÓá£
+
+Äã¿ÉÒÔʹÓà @Value È¥ÒýÓö¨ÒåµÄÊôÐÔ£¬ÀýÈ磺@Value("testbean.name")£»Ò²¿ÉÒÔÖ¸¶¨Ä¬ÈÏÖµ£¬È磺@Value("testbean.name:defaultValue")¡£
+
+Ó÷¨Ê¾Àý
+
+¸ø¶¨Ò»¸öÅäÖÃÎļþapp.properties
+````
+testbean.name=myTestBean
+````
+ÒÔÏ @Configuration ÀàʹÓà @PropertySource ½« app.properties ÉèÖøø Environment µÄ PropertySources ¼¯ºÏ¡£
+````
+@Configuration
+@PropertySource("classpath:/com/myco/app.properties")
+public class AppConfig {
+
+ @Autowired
+ Environment env;
+
+ @Bean
+ public TestBean testBean() {
+ TestBean testBean = new TestBean();
+ testBean.setName(env.getProperty("testbean.name"));
+ return testBean;
+ }
+}
+````
+
+×¢Ò⣺ʹÓà @Autowired ½« Environment ¶ÔÏó×¢Èëµ½ÅäÖÃÀàÖУ¬È»ºóÔÚ testBean() ·½·¨ÖÐʹÓá£
+ÒÔÉÏÅäÖÃÖУ¬µ÷Óà testBean.getName() ·½·¨½«·µ»Ø¡°myTestBean¡±×Ö·û´®¡£
+
+@PropertySource ÀûÓÃÁË Java 8 µÄÖØ¸´×¢½âÌØÐÔ£¬ÕâÒâζ×ÅÎÒÃÇ¿ÉÒÔÓÃËü¶à´Î±ê¼ÇÒ»¸öÀࣺ
+
+````
+@Configuration
+@PropertySource("classpath:/annotations.properties")
+@PropertySource("classpath:/vehicle-factory.properties")
+class VehicleFactoryConfig {}
+````
+
+### 3.5 @PropertySources
+Ó÷¨Í¬ÉÏ£¬Ö»²»¹ý£¬ÕâÒ»´ÎÎÒÃÇ¿ÉÒÔʹÓÃÕâ¸ö×¢½âÖ¸¶¨¶à¸ö@PropertySource ÅäÖãº
+````
+@Configuration
+@PropertySources({
+@PropertySource("classpath:/annotations.properties"),
+@PropertySource("classpath:/vehicle-factory.properties")
+})
+class VehicleFactoryConfig {}
+````
+Çë×¢Ò⣬×Ô Java 8 ÒÔÀ´£¬ÎÒÃÇ¿ÉÒÔͨ¹ýÉÏÊöÖØ¸´×¢Ê͹¦ÄÜʵÏÖÏàͬµÄ¹¦ÄÜ¡£
+
+## 4.½áÂÛ
+
+ÔÚ±¾ÎÄÖУ¬ÎÒÃÇ¿´µ½ÁË×î³£¼ûµÄ Spring ºËÐÄ×¢Ê͵ĸÅÊö¡£ ÎÒÃÇ¿´µ½ÁËÈçºÎÅäÖà bean Á¬½ÓºÍÓ¦ÓÃÉÏÏÂÎÄ£¬ÒÔ¼°ÈçºÎΪ×é¼þɨÃè±ê¼ÇÀà¡£
+
+springÌåϵÖеij£¼û×¢½â»¹Óкܶ࣬һƪÎÄÕ²»¿ÉÄÜÈ«²¿¸²¸Ç£¬ÈçÓÐÒÅ©£¬»¶Ó²¹³ä¡£
+
+# Spring Bean×¢½â
+
+## 1 ¸ÅÊö
+ÔÚ±¾½Ì³ÌÖУ¬ÎÒÃǽ«ÌÖÂÛÓÃÓÚ¶¨Ò岻ͬÀàÐÍ bean µÄ×î³£¼ûµÄ Spring bean ×¢ÊÍ¡£
+
+Óм¸ÖÖ·½·¨¿ÉÒÔÔÚ Spring ÈÝÆ÷ÖÐÅäÖà bean¡£ Ê×ÏÈ£¬ÎÒÃÇ¿ÉÒÔʹÓà XML ÅäÖÃÉùÃ÷ËüÃÇ¡£ ÎÒÃÇ»¹¿ÉÒÔÔÚÅäÖÃÀàÖÐʹÓÃ@Bean ×¢½âÀ´ÉùÃ÷ bean¡£
+
+×îºó£¬ÎÒÃÇ¿ÉÒÔʹÓà org.springframework.stereotype °üÖеÄ×¢ÊÍÖ®Ò»À´±ê¼Ç¸ÃÀ࣬²¢½«ÆäÓಿ·ÖÁô¸ø×é¼þɨÃè¡£
+
+## 2 @ComponentScan
+ÕâÊÇÎÒÃǾ³£»áʹÓõÄÒ»¸ö×¢½â£¬ÔÚÎÒÃǵÄÓ¦ÓÃÖУ¬ÓÐʱºò²»Ò»¶¨»áɨÃèËùÓеİü£¬ÌرðÊǵ±ÎÒÃÇҪɨÃèÍⲿjar°üÖеÄbeanʱ£¬Ëü·Ç³£ÓÐÓá£
+
+Ëü¿ÉÒÔ¼ÓÔÚSpringBootApplicationÉÏ£¬Ò²¿ÉÒÔ¼ÓÔÚ@configuration×¢½âÉϵÄÅäÖÃÀàÉÏ
+
+Èç¹ûÆôÓÃÁË×é¼þɨÃ裬Spring ¿ÉÒÔ×Ô¶¯É¨Ãè°üÖÐµÄ bean¡£
+
+@ComponentScan ÅäÖÃʹÓÃ×¢½âÅäÖÃɨÃèÄÄЩ°üµÄÀà¡£
+
+ÎÒÃÇ¿ÉÒÔÖ±½ÓʹÓà basePackages »ò value ²ÎÊýÖ®Ò»Ö¸¶¨»ù±¾°üÃû³Æ£¨value ÊÇ basePackages µÄ±ðÃû£©
+
+````
+@Configuration
+@ComponentScan(basePackages = "com.baeldung.annotations")
+class VehicleFactoryConfig {}
+````
+´ËÍ⣬ÎÒÃÇ¿ÉÒÔʹÓà basePackageClasses ²ÎÊýÖ¸Ïò»ù´¡°üÖеÄÀࣺ
+
+````
+@Configuration
+@ComponentScan(basePackageClasses = VehicleFactoryConfig.class)
+class VehicleFactoryConfig {}
+````
+
+ÕâÁ½¸ö²ÎÊý¶¼ÊÇÊý×飬Òò´ËÎÒÃÇ¿ÉÒÔΪÿ¸ö²ÎÊýÌṩ¶à¸ö°ü¡£
+
+Èç¹ûδָ¶¨²ÎÊý£¬ÔòɨÃè·¢ÉúÔÚ´æÔÚ @ComponentScan ×¢ÊÍÀàµÄͬһ°üÖС£
+
+@ComponentScan ÀûÓÃÁË Java 8 µÄÖØ¸´×¢½âÌØÐÔ£¬ÕâÒâζ×ÅÎÒÃÇ¿ÉÒÔÓÃËü¶à´Î±ê¼ÇÒ»¸öÀࣺ
+
+````
+@Configuration
+@ComponentScan(basePackages = "com.baeldung.annotations")
+@ComponentScan(basePackageClasses = VehicleFactoryConfig.class)
+class VehicleFactoryConfig {}
+````
+
+»òÕߣ¬ÎÒÃÇ¿ÉÒÔʹÓà @ComponentScans Ö¸¶¨¶à¸ö @ComponentScan ÅäÖãº
+
+````
+@Configuration
+@ComponentScans({
+@ComponentScan(basePackages = "com.baeldung.annotations"),
+@ComponentScan(basePackageClasses = VehicleFactoryConfig.class)
+})
+````
+````
+class VehicleFactoryConfig {
+}
+````
+ʹÓà XML ÅäÖÃʱ£¬ÅäÖÃ×é¼þɨÃèͬÑù¼òµ¥£º
+
+````
+
+````
+
+### 3 @Component
+
+@Component ÊÇÀ༶±ðµÄ×¢½â¡£ ÔÚ×é¼þɨÃèÆÚ¼ä£¬Spring Framework »á×Ô¶¯¼ì²âʹÓÃ@Component ×¢½âµÄÀࣺ
+````
+@Component
+class CarUtility {
+// ...
+}
+````
+
+ĬÈÏÇé¿öÏ£¬´ËÀàµÄ bean ʵÀýÓëÀàÃûͬÃû£¬Ê××ÖĸСд¡£ ´ËÍ⣬ÎÒÃÇ¿ÉÒÔʹÓôË×¢Ê͵ĿÉѡֵ²ÎÊýÖ¸¶¨²»Í¬µÄÃû³Æ¡£
+
+ÓÉÓÚ@Repository¡¢@Service¡¢@Configuration ºÍ@Controller ¶¼ÊÇ´øÓÐ@Component µÄ×¢½â£¬ËüÃǹ²ÏíÏàͬµÄbean ÃüÃûÐÐΪ¡£
+
+Spring »¹»áÔÚ×é¼þɨÃè¹ý³ÌÖÐ×Ô¶¯¼ì²âËüÃÇ¡£
+
+ͨ³£À´Ëµ£¬ÎÒÃÇ»áÔÚmvcÓ¦ÓÃÖÐÎÒÃÇ»áÓõ½ÉÏÊö¼¸ÖÖ×¢½â£¬¶øÎÒÃÇÔÚ·ÇwebÓ¦ÓÃÖиü¶àµØ¿ÉÒÔʹÓÃ@componentÀ´×¢½âbean
+
+### 4 @Repository
+
+DAO or Repository classes usually represent the database access layer in an application, and should be annotated with @Repository:
+````
+@Repository
+class VehicleRepository {
+// ...
+}
+````
+ʹÓôË×¢Ê͵ÄÒ»¸öÓŵãÊÇËüÆôÓÃÁË×Ô¶¯³Ö¾ÃÐÔÒ쳣ת»»¡£ µ±Ê¹Óó־ÃÐÔ¿ò¼Ü£¨Èç Hibernate£©Ê±£¬ÔÚʹÓà @Repository ×¢Ê͵ÄÀàÖÐÅ׳öµÄ±¾»úÒì³£½«×Ô¶¯×ª»»Îª Spring µÄ DataAccessExeption µÄ×ÓÀà¡£
+
+ÒªÆôÓÃÒ쳣ת»»£¬ÎÒÃÇÐèÒªÉùÃ÷ÎÒÃÇ×Ô¼ºµÄ PersistenceExceptionTranslationPostProcessor bean£º
+````
+@Bean
+public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
+return new PersistenceExceptionTranslationPostProcessor();
+}
+````
+Çë×¢Ò⣬ÔÚ´ó¶àÊýÇé¿öÏ£¬Spring »á×Ô¶¯Ö´ÐÐÉÏÊö²½Öè¡£
+
+»òÕßͨ¹ý XML ÅäÖãº
+````
+
+````
+
+### 5 @Service
+Ó¦ÓóÌÐòµÄÒµÎñÂ߼ͨ³£×¤ÁôÔÚ·þÎñ²ãÖУ¬Òò´ËÎÒÃǽ«Ê¹ÓÃ@Service ×¢ÊÍÀ´Ö¸Ê¾Ò»¸öÀàÊôÓڸò㣺
+
+````
+@Service
+public class VehicleService {
+// ...
+}
+````
+### 6 @Controller
+@Controller ÊÇÒ»¸öÀ༶±ðµÄ×¢½â£¬Ëü¸æËß Spring Framework Õâ¸öÀà×÷Ϊ Spring MVC ÖеĿØÖÆÆ÷£º
+
+spring»á¶Ô@Controller ×¢½âµÄbean×öºÜ¶àÊÂÇ飬¾ßÌåÄÚÈÝÎÒÃÇ»áÔÚSpringMVCÏà¹ØµÄÄÚÈÝÀ´½²Êö
+
+````
+@Controller
+public class VehicleController {
+// ...
+}
+
+````
+## 7 @Configuration
+
+ÅäÖÃÀà¿ÉÒÔ°üº¬ÓÃ@Bean ×¢Ê굀 bean ¶¨Òå·½·¨£º
+````
+@Configuration
+class VehicleFactoryConfig {
+
+ @Bean
+ Engine engine() {
+ return new Engine();
+ }
+
+}
+````
+## 8 AOP×¢½â
+µ±ÎÒÃÇʹÓà Spring ¹¹ÔìÐÍ×¢ÊÍʱ£¬ºÜÈÝÒ×´´½¨Ò»¸öÇÐÈëµã£¬¸ÃÇÐÈëµãÒÔËùÓоßÓÐÌØ¶¨¹¹ÔìÐ͵ÄÀàΪĿ±ê¡£
+
+ÀýÈ磬¼ÙÉèÎÒÃÇÏë²âÁ¿ DAO ²ã·½·¨µÄÖ´ÐÐʱ¼ä¡£ ÎÒÃǽ«´´½¨ÒÔÏ·½Ã棨ʹÓà AspectJ ×¢ÊÍ£©£¬ÀûÓà @Repository ¹¹ÔìÐÍ£º
+
+```
+@Aspect
+@Component
+public class PerformanceAspect {
+@Pointcut("within(@org.springframework.stereotype.Repository *)")
+public void repositoryClassMethods() {};
+
+ @Around("repositoryClassMethods()")
+ public Object measureMethodExecutionTime(ProceedingJoinPoint joinPoint)
+ throws Throwable {
+ long start = System.nanoTime();
+ Object returnValue = joinPoint.proceed();
+ long end = System.nanoTime();
+ String methodName = joinPoint.getSignature().getName();
+ System.out.println(
+ "Execution of " + methodName + " took " +
+ TimeUnit.NANOSECONDS.toMillis(end - start) + " ms");
+ return returnValue;
+ }
+}
+````
+
+ÔÚ´ËʾÀýÖУ¬ÎÒÃÇ´´½¨ÁËÒ»¸öÇÐÈëµã£¬¸ÃÇÐÈëµãÆ¥ÅäʹÓÃ@Repository ×¢Ê͵ÄÀàÖеÄËùÓз½·¨¡£ È»ºóÎÒÃÇʹÓÃ@Around ֪ͨÀ´¶¨Î»ÄǸöÇÐÈëµã£¬²¢È·¶¨À¹½Ø·½·¨µ÷ÓõÄÖ´ÐÐʱ¼ä¡£
+
+´ËÍ⣬ʹÓÃÕâÖÖ·½·¨£¬ÎÒÃÇ¿ÉÒÔΪÿ¸öÓ¦ÓóÌÐò²ãÌí¼ÓÈÕÖ¾¼Ç¼¡¢ÐÔÄܹÜÀí¡¢Éó¼ÆºÍÆäËûÐÐΪ¡£
+
+µ±È»ÁË£¬aspectJµÄÏà¹Ø×¢½â»¹ºÜ¶à£¬¿ÉÒÔÓÃÀ´ÉùÃ÷ÇÐÃæ£¬Î´À´ÎÒÃÇÒ²»áµ¥¶ÀдÎĽéÉÜ¡£
+
+## 9 ½áÂÛ
+
+ÔÚ±¾ÎÄÖУ¬ÎÒÃǼì²éÁË Spring ¹¹ÔìÐÍ×¢ÊͲ¢ÌÖÂÛÁËËüÃǸ÷×Ô´ú±íµÄÓïÒåÀàÐÍ¡£
+
+ÎÒÃÇ»¹Ñ§Ï°ÁËÈçºÎʹÓÃ×é¼þɨÃèÀ´¸æËßÈÝÆ÷ÔÚÄÄÀï¿ÉÒÔÕÒµ½´ø×¢Ê͵ÄÀà¡£
+
+×îºó£¬ÎÒÃÇÁ˽âÁËÕâЩעÊÍÈçºÎµ¼Ö¸ɾ»¡¢·Ö²ãµÄÉè¼ÆÒÔ¼°Ó¦ÓóÌÐò¹Ø×¢µãÖ®¼äµÄ·ÖÀë¡£ ËüÃÇ»¹Ê¹ÅäÖøüС£¬ÒòΪÎÒÃDz»ÔÙÐèÒªÊÖ¶¯ÏÔʽ¶¨Òå bean¡£
+
+# ²Î¿¼ÎÄÕÂ
+https://www.baeldung.com/spring-annotations
+
diff --git "a/docs/spring/Spring\346\246\202\350\277\260.md" "b/docs/spring/Spring\346\246\202\350\277\260.md"
new file mode 100644
index 0000000..1152df8
--- /dev/null
+++ "b/docs/spring/Spring\346\246\202\350\277\260.md"
@@ -0,0 +1,145 @@
+Spring ÊÇ Java EE ±à³ÌÁìÓòµÄÒ»¿îÇáÁ¿¼¶µÄ¿ªÔ´¿ò¼Ü£¬Óɱ»³ÆÎª¡°Spring Ö®¸¸¡±µÄ Rod Johnson ÓÚ 2002 ÄêÌá³ö²¢´´Á¢£¬ËüµÄÄ¿±ê¾ÍÊÇÒª¼ò»¯ Java ÆóÒµ¼¶Ó¦ÓóÌÐòµÄ¿ª·¢ÄѶȺÍÖÜÆÚ¡£
+
+Spring ×Ôµ®ÉúÒÔÀ´±¸ÊÜÇàíù£¬Ò»Ö±±»¹ã´ó¿ª·¢ÈËÔ±×÷Ϊ Java ÆóÒµ¼¶Ó¦ÓóÌÐò¿ª·¢µÄÊ×Ñ¡¡£Ê±ÖÁ½ñÈÕ£¬Spring ٲȻ³ÉΪÁË Java EE ´úÃû´Ê£¬³ÉΪÁ˹¹½¨ Java EE Ó¦ÓõÄÊÂʵ±ê×¼¡£
+
+## Spring µÄµ®ÉúÓë·¢Õ¹
+
+ÔçÆÚµÄ J2EE£¨Java EE ƽ̨£©ÍƳçÒÔ EJB ΪºËÐĵĿª·¢·½Ê½£¬µ«ÕâÖÖ¿ª·¢·½Ê½ÔÚʵ¼ÊµÄ¿ª·¢¹ý³ÌÖдæÔÚÖÖÖÖ±×¶Ë£¬ÀýÈçʹÓø´ÔÓ¡¢´úÂëÓ·Öס¢´úÂëÇÖÈëÐÔÇ¿¡¢¿ª·¢ÖÜÆÚ³¤¡¢ÒÆÖ²ÄѶȴóµÈ¡£
+
+Rod Johnson ÔÚÆä 2004 Äê±àÖøµÄ³©ÏúÊé¡¶Expert One-on-One J2EE Development without EJB¡·ÖУ¬Õë¶Ô EJB ¸÷ÖÖÓ·Ö׵Ľṹ½øÐÐÁËÖðÒ»µÄ·ÖÎöºÍ·ñ¶¨£¬²¢·Ö±ðÒÔ¸ü¼Ó¼ò½àµÄ·½Ê½½øÐÐÁËÌæ»»¡£
+
+ÔÚÕâ±¾ÊéÖУ¬Rod Johnson ͨ¹ýÒ»¸ö°üº¬ 3 ÍòÐдúÂëµÄ¸½¼þ£¬Õ¹Ê¾ÁËÈçºÎÔÚ²»Ê¹Óà EJB µÄÇé¿öϹ¹½¨Ò»¸ö¸ßÖÊÁ¿¡¢¿ÉÀ©Õ¹µÄ Java Ó¦ÓóÌÐò¡£ÔÚÕâ¸ö¸½¼þÖУ¬Rod Johnson ±àдÁËÉÏÍòÐлù´¡½á¹¹´úÂ룬ÆäÖаüº¬ÁËÐí¶à¿ÉÖØÓÃµÄ Java ½Ó¿ÚºÍÀ࣬ÀýÈç ApplicationContext¡¢BeanFactory µÈ¡£ÕâЩÀàµÄ¸ù°ü±»ÃüÃûΪ com.interface21£¬º¬ÒåΪ£ºÕâÊÇÌṩ¸ø 21 ÊÀ¼ÍµÄÒ»¸ö²Î¿¼¡£
+
+Õâ±¾ÊéÓ°ÏìÉõÔ¶£¬ºóÀ´ Rod Johnson ½« com.interface21 µÄ´úÂ뿪Դ£¬²¢°ÑÕâ¸öпò¼Ü²¢ÃüÃûΪ¡°Spring¡±£¬º¬ÒåΪ£ºSpring ÏñÒ»ÂÆ´º·çÒ»Ñù£¬É¨Æ½´«Í³ J2EE µÄº®¶¬¡£
+
+2003 Äê 2 Ô£¬Spring 0.9 °æ±¾·¢²¼£¬Ëü²ÉÓÃÁË Apache 2.0 ¿ªÔ´ÐÒ飻2004 Äê 4 Ô£¬Spring 1.0 °æ±¾Õýʽ·¢²¼¡£µ½Ä¿Ç°ÎªÖ¹£¬Spring ÒѾ²½Èëµ½ÁËµÚ 5 ¸ö´ó°æ±¾£¬Ò²¾ÍÊÇÎÒÃdz£ËµµÄ Spring 5¡£
+
+## Spring µÄÏÁÒåºÍ¹ãÒå
+
+ÔÚ²»Í¬µÄÓï¾³ÖУ¬Spring Ëù´ú±íµÄº¬ÒåÊDz»Í¬µÄ¡£ÏÂÃæÎÒÃǾͷֱð´Ó¡°¹ãÒ塱ºÍ¡°ÏÁÒ塱Á½¸ö½Ç¶È£¬¶Ô Spring ½øÐнéÉÜ¡£
+
+### ¹ãÒåµÄ Spring£ºSpring ¼¼ÊõÕ»
+
+¹ãÒåÉ쵀 Spring ·ºÖ¸ÒÔ Spring Framework ΪºËÐÄµÄ Spring ¼¼ÊõÕ»¡£
+
+¾¹ýÊ®¶àÄêµÄ·¢Õ¹£¬Spring ÒѾ²»ÔÙÊÇÒ»¸öµ¥´¿µÄÓ¦Óÿò¼Ü£¬¶øÊÇÖð½¥·¢Õ¹³ÉΪһ¸öÓɶà¸ö²»Í¬×ÓÏîÄ¿£¨Ä£¿é£©×é³ÉµÄ³ÉÊì¼¼Êõ£¬ÀýÈç Spring Framework¡¢Spring MVC¡¢SpringBoot¡¢Spring Cloud¡¢Spring Data¡¢Spring Security µÈ£¬ÆäÖÐ Spring Framework ÊÇÆäËû×ÓÏîÄ¿µÄ»ù´¡¡£
+
+ÕâЩ×ÓÏîÄ¿º¸ÇÁË´ÓÆóÒµ¼¶Ó¦Óÿª·¢µ½ÔƼÆËãµÈ¸÷·½ÃæµÄÄÚÈÝ£¬Äܹ»°ïÖú¿ª·¢ÈËÔ±½â¾öÈí¼þ·¢Õ¹¹ý³ÌÖв»¶Ï²úÉúµÄ¸÷ÖÖʵ¼ÊÎÊÌ⣬¸ø¿ª·¢ÈËÔ±´øÀ´Á˸üºÃµÄ¿ª·¢ÌåÑé¡£
+
+| ÏîÄ¿Ãû³Æ | ÃèÊö |
+| --- | --- |
+| Spring Data | Spring ÌṩµÄÊý¾Ý·ÃÎÊÄ£¿é£¬¶Ô JDBC ºÍ ORM ÌṩÁ˺ܺõÄÖ§³Ö¡£Í¨¹ýËü£¬¿ª·¢ÈËÔ±¿ÉÒÔʹÓÃÒ»ÖÖÏà¶ÔͳһµÄ·½Ê½£¬À´·ÃÎÊλÓÚ²»Í¬ÀàÐÍÊý¾Ý¿âÖеÄÊý¾Ý¡£ |
+| Spring Batch | Ò»¿îרÃÅÕë¶ÔÆóÒµ¼¶ÏµÍ³ÖеÄÈÕ³£Åú´¦ÀíÈÎÎñµÄÇáÁ¿¼¶¿ò¼Ü£¬Äܹ»°ïÖú¿ª·¢ÈËÔ±·½±ãµÄ¿ª·¢³ö½¡×³¡¢¸ßЧµÄÅú´¦ÀíÓ¦ÓóÌÐò¡£ |
+| Spring Security | ǰÉíΪ Acegi£¬ÊÇ Spring ÖнϳÉÊìµÄ×ÓÄ£¿éÖ®Ò»¡£ËüÊÇÒ»¿î¿ÉÒÔ¶¨ÖÆ»¯µÄÉí·ÝÑéÖ¤ºÍ·ÃÎÊ¿ØÖÆ¿ò¼Ü¡£ |
+| Spring Mobile | ÊÇ¶Ô Spring MVC µÄÀ©Õ¹£¬ÓÃÀ´¼ò»¯Òƶ¯¶Ë Web Ó¦ÓõĿª·¢¡£ |
+| Spring Boot | ÊÇ Spring ÍŶÓÌṩµÄȫпò¼Ü£¬ËüΪ Spring ÒÔ¼°µÚÈý·½¿âһЩ¿ªÏä¼´ÓõÄÅäÖ㬿ÉÒÔ¼ò»¯ Spring Ó¦ÓõĴ¼°¿ª·¢¹ý³Ì¡£ |
+| Spring Cloud | Ò»¿î»ùÓÚ Spring Boot ʵÏÖµÄ΢·þÎñ¿ò¼Ü¡£Ëü²¢²»ÊÇijһÃż¼Êõ£¬¶øÊÇһϵÁÐ΢·þÎñ½â¾ö·½°¸»ò¿ò¼ÜµÄÓÐÐò¼¯ºÏ¡£Ëü½«ÊÐÃæÉϳÉÊìµÄ¡¢¾¹ýÑéÖ¤µÄ΢·þÎñ¿ò¼ÜÕûºÏÆðÀ´£¬²¢Í¨¹ý Spring Boot µÄ˼Ïë½øÐÐÔÙ·â×°£¬ÆÁ±Îµ÷ÆäÖи´ÔÓµÄÅäÖúÍʵÏÖÔÀí£¬×îÖÕΪ¿ª·¢ÈËÔ±ÌṩÁËÒ»Ì×¼òµ¥Ò×¶®¡¢Òײ¿ÊðºÍÒ×ά»¤µÄ·Ö²¼Ê½ÏµÍ³¿ª·¢¹¤¾ß°ü¡£ |
+
+### ÏÁÒåµÄ Spring£ºSpring Framework
+
+ÏÁÒåµÄ Spring ÌØÖ¸ Spring Framework£¬Í¨³£ÎÒÃǽ«Ëü³ÆÎª Spring ¿ò¼Ü¡£
+
+Spring ¿ò¼ÜÊÇÒ»¸ö·Ö²ãµÄ¡¢ÃæÏòÇÐÃæµÄ Java Ó¦ÓóÌÐòµÄһվʽÇáÁ¿¼¶½â¾ö·½°¸£¬ËüÊÇ Spring ¼¼ÊõÕ»µÄºËÐĺͻù´¡£¬ÊÇΪÁ˽â¾öÆóÒµ¼¶Ó¦Óÿª·¢µÄ¸´ÔÓÐÔ¶ø´´½¨µÄ¡£
+
+Spring ÓÐÁ½¸öºËÐIJ¿·Ö£º IoC ºÍ AOP¡£
+
+| ºËÐÄ | ÃèÊö |
+| --- | --- |
+| IOC | Inverse of Control µÄ¼òд£¬ÒëΪ¡°¿ØÖÆ·´×ª¡±£¬Ö¸°Ñ´´½¨¶ÔÏó¹ý³Ì½»¸ø Spring ½øÐйÜÀí¡£ |
+| AOP | Aspect Oriented Programming µÄ¼òд£¬ÒëΪ¡°ÃæÏòÇÐÃæ±à³Ì¡±¡£AOP ÓÃÀ´·â×°¶à¸öÀàµÄ¹«¹²ÐÐΪ£¬½«ÄÇЩÓëÒµÎñÎ޹أ¬È´ÎªÒµÎñÄ£¿éËù¹²Í¬µ÷ÓõÄÂß¼·â×°ÆðÀ´£¬¼õÉÙϵͳµÄÖØ¸´´úÂ룬½µµÍÄ£¿é¼äµÄñîºÏ¶È¡£ÁíÍ⣬AOP »¹½â¾öһЩϵͳ²ãÃæÉϵÄÎÊÌ⣬±ÈÈçÈÕÖ¾¡¢ÊÂÎñ¡¢È¨Ï޵ȡ£ |
+
+Spring ÊÇÒ»ÖÖ»ùÓÚ Bean µÄ±à³Ì¼¼Êõ£¬ËüÉî¿ÌµØ¸Ä±ä×Å Java ¿ª·¢ÊÀ½ç¡£Spring ʹÓüòµ¥¡¢»ù±¾µÄ Java Bean À´Íê³ÉÒÔǰֻÓÐ EJB ²ÅÄÜÍê³ÉµÄ¹¤×÷£¬Ê¹µÃºÜ¶à¸´ÔӵĴúÂë±äµÃÓÅÑźͼò½à£¬±ÜÃâÁË EJB Ó·Öס¢µÍЧµÄ¿ª·¢Ä£Ê½£¬¼«´óµÄ·½±ãÏîÄ¿µÄºóÆÚά»¤¡¢Éý¼¶ºÍÀ©Õ¹¡£
+
+ÔÚʵ¼Ê¿ª·¢ÖУ¬·þÎñÆ÷¶ËÓ¦ÓóÌÐòͨ³£²ÉÓÃÈý²ãÌåϵ¼Ü¹¹£¬·Ö±ðΪ±íÏֲ㣨web£©¡¢ÒµÎñÂß¼²ã£¨service£©¡¢³Ö¾Ã²ã£¨dao£©¡£
+
+Spring ÖÂÁ¦ÓÚ Java EE Ó¦Óø÷²ãµÄ½â¾ö·½°¸£¬¶Ôÿһ²ã¶¼ÌṩÁ˼¼ÊõÖ§³Ö¡£
+
+* ÔÚ±íÏÖ²ãÌṩÁË¶Ô Spring MVC¡¢Struts2 µÈ¿ò¼ÜµÄÕûºÏ£»
+* ÔÚÒµÎñÂß¼²ãÌṩÁ˹ÜÀíÊÂÎñºÍ¼Ç¼ÈÕÖ¾µÄ¹¦ÄÜ£»
+* Ôڳ־ò㻹¿ÉÒÔÕûºÏ MyBatis¡¢Hibernate ºÍ JdbcTemplate µÈ¼¼Êõ£¬¶ÔÊý¾Ý¿â½øÐзÃÎÊ¡£
+
+Õâ³ä·ÖµØÌåÏÖÁË Spring ÊÇÒ»¸öÈ«ÃæµÄ½â¾ö·½°¸£¬¶ÔÓÚÄÇЩÒѾÓнϺýâ¾ö·½°¸µÄÁìÓò£¬Spring ¾ø²»×öÖØ¸´µÄÊÂÇé¡£
+
+´ÓÉè¼ÆÉÏ¿´£¬Spring ¿ò¼Ü¸øÓèÁË Java ³ÌÐòÔ±¸ü¸ßµÄ×ÔÓɶȣ¬¶ÔÒµ½çµÄ³£¼ûÎÊÌâÒ²ÌṩÁËÁ¼ºÃµÄ½â¾ö·½°¸£¬Òò´ËÔÚ¿ªÔ´ÉçÇøÊܵ½Á˹㷺µÄ»¶Ó£¬²¢ÇÒ±»´ó²¿·Ö¹«Ë¾×÷Ϊ Java ÏîÄ¿¿ª·¢µÄÊ×Ñ¡¿ò¼Ü¡£
+
+## Spring Framework µÄÌØµã
+
+Spring ¿ò¼Ü¾ßÓÐÒÔϼ¸¸öÌØµã¡£
+
+### **·½±ã½âñ¼ò»¯¿ª·¢**
+
+Spring ¾ÍÊÇÒ»¸ö´ó¹¤³§£¬¿ÉÒÔ½«ËùÓжÔÏóµÄ´´½¨ºÍÒÀÀµ¹ØÏµµÄά»¤½»¸ø Spring ¹ÜÀí¡£
+
+### **·½±ã¼¯³É¸÷ÖÖÓÅÐã¿ò¼Ü**
+
+Spring ²»Åųâ¸÷ÖÖÓÅÐãµÄ¿ªÔ´¿ò¼Ü£¬ÆäÄÚ²¿ÌṩÁ˶Ը÷ÖÖÓÅÐã¿ò¼Ü£¨Èç Struts2¡¢Hibernate¡¢MyBatis µÈ£©µÄÖ±½ÓÖ§³Ö¡£
+
+### **½µµÍ Java EE API µÄʹÓÃÄѶÈ**
+
+Spring ¶Ô Java EE ¿ª·¢Öзdz£ÄÑÓõÄһЩ API£¨JDBC¡¢JavaMail¡¢Ô¶³Ìµ÷Óõȣ©¶¼ÌṩÁË·â×°£¬Ê¹ÕâЩ API Ó¦ÓõÄÄѶȴó´ó½µµÍ¡£
+
+### **·½±ã³ÌÐòµÄ²âÊÔ**
+
+Spring Ö§³Ö JUnit4£¬¿ÉÒÔͨ¹ý×¢½â·½±ãµØ²âÊÔ Spring ³ÌÐò¡£
+
+### **AOP ±à³ÌµÄÖ§³Ö**
+
+Spring Ìá¹©ÃæÏòÇÐÃæ±à³Ì£¬¿ÉÒÔ·½±ãµØÊµÏÖ¶Ô³ÌÐò½øÐÐȨÏÞÀ¹½ØºÍÔËÐÐ¼à¿ØµÈ¹¦ÄÜ¡£
+
+### **ÉùÃ÷ʽÊÂÎñµÄÖ§³Ö**
+
+Ö»ÐèҪͨ¹ýÅäÖþͿÉÒÔÍê³É¶ÔÊÂÎñµÄ¹ÜÀí£¬¶øÎÞÐëÊÖ¶¯±à³Ì¡£
+
+Spring ¿ò¼Ü»ù±¾º¸ÇÁËÆóÒµ¼¶Ó¦Óÿª·¢µÄ¸÷¸ö·½Ã棬Ëü°üº¬ÁË 20 ¶à¸ö²»Í¬µÄÄ£¿é¡£
+
+spring-aop spring-context-indexer spring-instrument spring-orm spring-web
+spring-aspects spring-context-support spring-jcl spring-oxm spring-webflux
+spring-beans spring-core spring-jdbc spring-r2dbc spring-webmvc
+spring-context spring-expression spring-jms spring-test spring-websocket
+spring-messaging spring-tx
+
+
+ͼ1£ºSpring¼Ü¹¹Í¼
+
+ÉÏͼÖаüº¬ÁË Spring ¿ò¼ÜµÄËùÓÐÄ£¿é£¬ÕâЩģ¿é¿ÉÒÔÂú×ãÒ»ÇÐÆóÒµ¼¶Ó¦Óÿª·¢µÄÐèÇó£¬ÔÚ¿ª·¢¹ý³ÌÖпÉÒÔ¸ù¾ÝÐèÇóÓÐÑ¡ÔñÐÔµØÊ¹ÓÃËùÐèÒªµÄÄ£¿é¡£ÏÂÃæ·Ö±ð¶ÔÕâЩģ¿éµÄ×÷ÓýøÐмòµ¥½éÉÜ¡£
+
+## 1\. Data Access/Integration£¨Êý¾Ý·ÃÎÊ£¯¼¯³É£©
+
+Êý¾Ý·ÃÎÊ£¯¼¯³É²ã°üÀ¨ JDBC¡¢ORM¡¢OXM¡¢JMS ºÍ Transactions Ä£¿é£¬¾ßÌå½éÉÜÈçÏ¡£
+
+* JDBC Ä£¿é£ºÌṩÁËÒ»¸ö JBDC µÄÑùÀýÄ£°å£¬Ê¹ÓÃÕâЩģ°åÄÜÏû³ý´«Í³Èß³¤µÄ JDBC ±àÂ뻹ÓбØÐëµÄÊÂÎñ¿ØÖÆ£¬¶øÇÒÄÜÏíÊܵ½ Spring ¹ÜÀíÊÂÎñµÄºÃ´¦¡£
+* ORM Ä£¿é£ºÌṩÓëÁ÷Ðеġ°¶ÔÏó-¹ØÏµ¡±Ó³Éä¿ò¼ÜÎ޷켯³ÉµÄ API£¬°üÀ¨ JPA¡¢JDO¡¢Hibernate ºÍ MyBatis µÈ¡£¶øÇÒ»¹¿ÉÒÔʹÓà Spring ÊÂÎñ¹ÜÀí£¬ÎÞÐè¶îÍâ¿ØÖÆÊÂÎñ¡£
+* OXM Ä£¿é£ºÌṩÁËÒ»¸öÖ§³Ö Object /XML Ó³ÉäµÄ³éÏó²ãʵÏÖ£¬Èç JAXB¡¢Castor¡¢XMLBeans¡¢JiBX ºÍ XStream¡£½« Java ¶ÔÏóÓ³Éä³É XML Êý¾Ý£¬»òÕß½«XML Êý¾ÝÓ³Éä³É Java ¶ÔÏó¡£
+* JMS Ä£¿é£ºÖ¸ Java ÏûÏ¢·þÎñ£¬ÌṩһÌ× ¡°ÏûÏ¢Éú²úÕß¡¢ÏûÏ¢Ïû·ÑÕß¡±Ä£°åÓÃÓÚ¸ü¼Ó¼òµ¥µÄʹÓà JMS£¬JMS ÓÃÓÚÓÃÓÚÔÚÁ½¸öÓ¦ÓóÌÐòÖ®¼ä£¬»ò·Ö²¼Ê½ÏµÍ³Öз¢ËÍÏûÏ¢£¬½øÐÐÒ첽ͨÐÅ¡£
+* Transactions ÊÂÎñÄ£¿é£ºÖ§³Ö±à³ÌºÍÉùÃ÷ʽÊÂÎñ¹ÜÀí¡£
+
+## 2\. Web Ä£¿é
+
+Spring µÄ Web ²ã°üÀ¨ Web¡¢Servlet¡¢WebSocket ºÍ Portlet ×é¼þ£¬¾ßÌå½éÉÜÈçÏ¡£
+
+* Web Ä£¿é£ºÌṩÁË»ù±¾µÄ Web ¿ª·¢¼¯³ÉÌØÐÔ£¬ÀýÈç¶àÎļþÉÏ´«¹¦ÄÜ¡¢Ê¹ÓÃµÄ Servlet ¼àÌýÆ÷µÄ IOC ÈÝÆ÷³õʼ»¯ÒÔ¼° Web Ó¦ÓÃÉÏÏÂÎÄ¡£
+* Servlet Ä£¿é£ºÌṩÁËÒ»¸ö Spring MVC Web ¿ò¼ÜʵÏÖ¡£Spring MVC ¿ò¼ÜÌṩÁË»ùÓÚ×¢½âµÄÇëÇó×ÊÔ´×¢Èë¡¢¸ü¼òµ¥µÄÊý¾Ý°ó¶¨¡¢Êý¾ÝÑéÖ¤µÈ¼°Ò»Ì׷dz£Ò×ÓÃµÄ JSP ±êÇ©£¬ÍêÈ«ÎÞ·ìÓë Spring ÆäËû¼¼ÊõÐ×÷¡£
+* WebSocket Ä£¿é£ºÌṩÁ˼òµ¥µÄ½Ó¿Ú£¬Óû§Ö»ÒªÊµÏÖÏìÓ¦µÄ½Ó¿Ú¾Í¿ÉÒÔ¿ìËٵĴ WebSocket Server£¬´Ó¶øÊµÏÖË«ÏòͨѶ¡£
+* Portlet Ä£¿é£ºÌṩÁËÔÚ Portlet »·¾³ÖÐʹÓà MVC ʵÏÖ£¬ÀàËÆ Web-Servlet Ä£¿éµÄ¹¦ÄÜ¡£
+
+## 3\. Core Container£¨Spring µÄºËÐÄÈÝÆ÷£©
+
+Spring µÄºËÐÄÈÝÆ÷ÊÇÆäËûÄ£¿é½¨Á¢µÄ»ù´¡£¬ÓÉ Beans Ä£¿é¡¢Core ºËÐÄÄ£¿é¡¢Context ÉÏÏÂÎÄÄ£¿éºÍ SpEL ±í´ïʽÓïÑÔÄ£¿é×é³É£¬Ã»ÓÐÕâЩºËÐÄÈÝÆ÷£¬Ò²²»¿ÉÄÜÓÐ AOP¡¢Web µÈÉϲãµÄ¹¦ÄÜ¡£¾ßÌå½éÉÜÈçÏ¡£
+
+* Beans Ä£¿é£ºÌṩÁË¿ò¼ÜµÄ»ù´¡²¿·Ö£¬°üÀ¨¿ØÖÆ·´×ªºÍÒÀÀµ×¢Èë¡£
+* Core ºËÐÄÄ£¿é£º·â×°ÁË Spring ¿ò¼ÜµÄµ×²ã²¿·Ö£¬°üÀ¨×ÊÔ´·ÃÎÊ¡¢ÀàÐÍת»»¼°Ò»Ð©³£Óù¤¾ßÀà¡£
+* Context ÉÏÏÂÎÄÄ£¿é£º½¨Á¢ÔÚ Core ºÍ Beans Ä£¿éµÄ»ù´¡Ö®ÉÏ£¬¼¯³É Beans Ä£¿é¹¦Äܲ¢Ìí¼Ó×ÊÔ´°ó¶¨¡¢Êý¾ÝÑéÖ¤¡¢¹ú¼Ê»¯¡¢Java EE Ö§³Ö¡¢ÈÝÆ÷ÉúÃüÖÜÆÚ¡¢Ê¼þ´«²¥µÈ¡£ApplicationContext ½Ó¿ÚÊÇÉÏÏÂÎÄÄ£¿éµÄ½¹µã¡£
+* SpEL Ä£¿é£ºÌṩÁËÇ¿´óµÄ±í´ïʽÓïÑÔÖ§³Ö£¬Ö§³Ö·ÃÎʺÍÐÞ¸ÄÊôÐÔÖµ£¬·½·¨µ÷Óã¬Ö§³Ö·ÃÎʼ°ÐÞ¸ÄÊý×é¡¢ÈÝÆ÷ºÍË÷ÒýÆ÷£¬ÃüÃû±äÁ¿£¬Ö§³ÖËãÊýºÍÂß¼ÔËË㣬֧³Ö´Ó Spring ÈÝÆ÷»ñÈ¡ Bean£¬ËüÒ²Ö§³ÖÁбíͶӰ¡¢Ñ¡ÔñºÍÒ»°ãµÄÁбí¾ÛºÏµÈ¡£
+
+## 4\. AOP¡¢Aspects¡¢Instrumentation ºÍ Messaging
+
+ÔÚ Core Container Ö®ÉÏÊÇ AOP¡¢Aspects µÈÄ£¿é£¬¾ßÌå½éÉÜÈçÏ£º
+
+* AOP Ä£¿é£ºÌṩÁËÃæÏòÇÐÃæ±à³ÌʵÏÖ£¬Ìṩ±ÈÈçÈÕÖ¾¼Ç¼¡¢È¨ÏÞ¿ØÖÆ¡¢ÐÔÄÜͳ¼ÆµÈͨÓù¦ÄܺÍÒµÎñÂß¼·ÖÀëµÄ¼¼Êõ£¬²¢ÇÒÄܶ¯Ì¬µÄ°ÑÕâЩ¹¦ÄÜÌí¼Óµ½ÐèÒªµÄ´úÂëÖУ¬ÕâÑù¸÷˾ÆäÖ°£¬½µµÍÒµÎñÂß¼ºÍͨÓù¦ÄܵÄñîºÏ¡£
+* Aspects Ä£¿é£ºÌṩÓë AspectJ µÄ¼¯³É£¬ÊÇÒ»¸ö¹¦ÄÜÇ¿´óÇÒ³ÉÊìµÄÃæÏòÇÐÃæ±à³Ì£¨AOP£©¿ò¼Ü¡£
+* Instrumentation Ä£¿é£ºÌṩÁËÀ๤¾ßµÄÖ§³ÖºÍÀà¼ÓÔØÆ÷µÄʵÏÖ£¬¿ÉÒÔÔÚÌØ¶¨µÄÓ¦Ó÷þÎñÆ÷ÖÐʹÓá£
+* messaging Ä£¿é£ºSpring 4.0 ÒÔºóÐÂÔöÁËÏûÏ¢£¨Spring-messaging£©Ä£¿é£¬¸ÃÄ£¿éÌṩÁ˶ÔÏûÏ¢´«µÝÌåϵ½á¹¹ºÍÐÒéµÄÖ§³Ö¡£
+
+## 5\. Test Ä£¿é
+
+Test Ä£¿é£ºSpring Ö§³Ö Junit ºÍ TestNG ²âÊÔ¿ò¼Ü£¬¶øÇÒ»¹¶îÍâÌṩÁËһЩ»ùÓÚ Spring µÄ²âÊÔ¹¦ÄÜ£¬±ÈÈçÔÚ²âÊÔ Web ¿ò¼Üʱ£¬Ä£Äâ Http ÇëÇóµÄ¹¦ÄÜ¡£
\ No newline at end of file
diff --git "a/docs/spring/springMVC/SpringMVC\345\270\270\350\247\201\346\263\250\350\247\243.md" "b/docs/spring/springMVC/SpringMVC\345\270\270\350\247\201\346\263\250\350\247\243.md"
new file mode 100644
index 0000000..6bd5272
--- /dev/null
+++ "b/docs/spring/springMVC/SpringMVC\345\270\270\350\247\201\346\263\250\350\247\243.md"
@@ -0,0 +1,232 @@
+## 1. ¸ÅÊö
+ ÔÚ±¾½Ì³ÌÖУ¬ÎÒÃǽ«Ì½Ë÷ org.springframework.web.bind.annotation °üÖÐµÄ Spring Web ×¢ÊÍ¡£
+
+## 2. @RequestMapping
+
+¼òµ¥µØËµ£¬@RequestMapping ±ê¼Ç@Controller ÀàÄÚ²¿µÄÇëÇó´¦Àí³ÌÐò·½·¨£» Ëü¿ÉÒÔʹÓÃÅäÖãº
+
+·¾¶£¬»òÆä±ðÃû¡¢Ãû³ÆºÍÖµ£º·½·¨Ó³Éäµ½Äĸö URL
+·½·¨£º¼æÈÝµÄ HTTP ·½·¨
+params£º¸ù¾Ý HTTP ²ÎÊýµÄ´æÔÚ¡¢²»´æÔÚ»òÖµ¹ýÂËÇëÇó
+headers£º¸ù¾Ý HTTP ±êÍ·µÄ´æÔÚ¡¢²»´æÔÚ»òÖµ¹ýÂËÇëÇó
+ÏûºÄ£º¸Ã·½·¨¿ÉÒÔÔÚ HTTP ÇëÇóÕýÎÄÖÐÏûºÄÄÄЩýÌåÀàÐÍ
+produces£º¸Ã·½·¨¿ÉÒÔÔÚ HTTP ÏìÓ¦ÕýÎÄÖÐÉú³ÉÄÄЩýÌåÀàÐÍ
+ÕâÊÇÒ»¸ö¼òµ¥µÄʾÀý£º
+
+````
+@Controller
+class VehicleController {
+
+ @RequestMapping(value = "/vehicles/home", method = RequestMethod.GET)
+ String home() {
+ return "home";
+ }
+}
+````
+Èç¹ûÎÒÃÇÔÚÀ༶±ðÓ¦ÓôË×¢ÊÍ£¬ÎÒÃÇ¿ÉÒÔΪ @Controller ÀàÖеÄËùÓд¦Àí³ÌÐò·½·¨ÌṩĬÈÏÉèÖᣠΨһµÄÀýÍâÊÇ Spring ²»»áʹÓ÷½·¨¼¶±ðÉèÖø²¸Çµ«»á¸½¼ÓÁ½¸ö·¾¶²¿·ÖµÄ URL¡£
+
+ÀýÈ磬ÏÂÃæµÄÅäÖúÍÉÏÃæµÄЧ¹ûÊÇÒ»ÑùµÄ£º
+
+````
+@Controller
+@RequestMapping(value = "/vehicles", method = RequestMethod.GET)
+class VehicleController {
+
+ @RequestMapping("/home")
+ String home() {
+ return "home";
+ }
+}
+````
+
+´ËÍ⣬@GetMapping¡¢@PostMapping¡¢@PutMapping¡¢@DeleteMapping ºÍ@PatchMapping ÊÇ@RequestMapping µÄ²»Í¬±äÌ壬ÆäHTTP ·½·¨ÒÑ·Ö±ðÉèÖÃΪGET¡¢POST¡¢PUT¡¢DELETE ºÍPATCH¡£
+
+ÕâЩ´Ó Spring 4.3 °æ±¾¿ªÊ¼¿ÉÓá£
+
+## 3 @RequestBody
+
+ÈÃÎÒÃǼÌÐø@RequestBody¡ª¡ªËü½« HTTP ÇëÇóµÄÖ÷ÌåÓ³Éäµ½Ò»¸ö¶ÔÏó£º
+
+````
+@PostMapping("/save")
+void saveVehicle(@RequestBody Vehicle vehicle) {
+// ...
+}
+````
+·´ÐòÁл¯ÊÇ×Ô¶¯µÄ£¬È¡¾öÓÚÇëÇóµÄÄÚÈÝÀàÐÍ¡£
+
+## 4 @PathVariable
+½ÓÏÂÀ´ËµËµ@PathVariable¡£
+
+´Ë×¢ÊÍָʾ·½·¨²ÎÊý°ó¶¨µ½ URI Ä£°å±äÁ¿¡£ ÎÒÃÇ¿ÉÒÔʹÓà @RequestMapping ×¢ÊÍÖ¸¶¨ URI Ä£°å£¬²¢Ê¹Óà @PathVariable ½«·½·¨²ÎÊý°ó¶¨µ½Ä£°å²¿·ÖÖ®Ò»¡£
+
+ÎÒÃÇ¿ÉÒÔʹÓÃÃû³Æ»òÆä±ðÃû£¬¼´Öµ²ÎÊýÀ´ÊµÏÖÕâÒ»µã£º
+
+````
+@RequestMapping("/{id}")
+Vehicle getVehicle(@PathVariable("id") long id) {
+// ...
+}
+````
+Èç¹ûÄ£°åÖв¿·ÖµÄÃû³ÆÓë·½·¨²ÎÊýµÄÃû³ÆÏàÆ¥Å䣬ÎÒÃǾͲ»±ØÔÚ×¢ÊÍÖÐÖ¸¶¨Ëü£º
+
+````
+@RequestMapping("/{id}")
+Vehicle getVehicle(@PathVariable long id) {
+// ...
+}
+````
+´ËÍ⣬ÎÒÃÇ¿ÉÒÔͨ¹ý½«ËùÐèµÄ²ÎÊýÉèÖÃΪ false À´½«Â·¾¶±äÁ¿±ê¼ÇΪ¿ÉÑ¡£º
+
+````
+@RequestMapping("/{id}")
+Vehicle getVehicle(@PathVariable(required = false) long id) {
+// ...
+}
+````
+## 5. @RequestParam
+ We use @RequestParam for accessing HTTP request parameters:
+````
+@RequestMapping
+Vehicle getVehicleByParam(@RequestParam("id") long id) {
+// ...
+}
+````
+Ëü¾ßÓÐÓë @PathVariable ×¢ÊÍÏàͬµÄÅäÖÃÑ¡Ïî¡£
+
+³ýÁËÕâЩÉèÖÃÖ®Í⣬µ± Spring ÔÚÇëÇóÖз¢ÏÖûÓÐÖµ»òΪ¿Õֵʱ£¬ÎÒÃÇ¿ÉÒÔʹÓà @RequestParam Ö¸¶¨×¢ÈëÖµ¡£ Ϊ´Ë£¬ÎÒÃDZØÐëÉèÖà defaultValue ²ÎÊý¡£
+
+ÌṩĬÈÏÖµÒþʽÉèÖà required Ϊ false£º
+````
+@RequestMapping("/buy")
+Car buyCar(@RequestParam(defaultValue = "5") int seatCount) {
+// ...
+}
+````
+³ýÁ˲ÎÊýÖ®Í⣬ÎÒÃÇ»¹¿ÉÒÔ·ÃÎÊÆäËû HTTP ÇëÇ󲿷֣ºcookie ºÍ±êÍ·¡£
+
+ÎÒÃÇ¿ÉÒÔ·Ö±ðʹÓÃ×¢½â@CookieValue ºÍ@RequestHeader À´·ÃÎÊËüÃÇ¡£
+
+
+## 6. Response Handling Annotations
+ÔÚ½ÓÏÂÀ´µÄ²¿·ÖÖУ¬ÎÒÃǽ«¿´µ½ÔÚ Spring MVC ÖвÙ×÷ HTTP ÏìÓ¦µÄ×î³£¼û×¢ÊÍ¡£
+
+### 6.1 @ResponseBody
+Èç¹ûÎÒÃÇÓÃ@ResponseBody ±ê¼ÇÇëÇó´¦Àí³ÌÐò·½·¨£¬Spring »á½«·½·¨µÄ½á¹ûÊÓΪÏìÓ¦±¾Éí£º
+
+````
+@ResponseBody
+@RequestMapping("/hello")
+String hello() {
+return "Hello World!";
+}
+````
+Èç¹ûÎÒÃÇÓÃÕâ¸ö×¢½âÀ´×¢½â @Controller À࣬ËùÓÐÇëÇó´¦Àí³ÌÐò·½·¨¶¼½«Ê¹ÓÃËü¡£
+
+### 6.2 @ExceptionHandler
+
+ʹÓôË×¢ÊÍ£¬ÎÒÃÇ¿ÉÒÔÉùÃ÷Ò»¸ö×Ô¶¨Òå´íÎó´¦Àí³ÌÐò·½·¨¡£ µ±ÇëÇó´¦Àí³ÌÐò·½·¨Å׳öÈκÎÖ¸¶¨µÄÒ쳣ʱ£¬Spring µ÷Óô˷½·¨¡£
+
+²¶»ñµÄÒì³£¿ÉÒÔ×÷Ϊ²ÎÊý´«µÝ¸ø·½·¨£º
+````
+@ExceptionHandler(IllegalArgumentException.class)
+void onIllegalArgumentException(IllegalArgumentException exception) {
+// ...
+}
+````
+
+### 6.3 @ResponseStatus
+Èç¹ûÎÒÃÇʹÓôË×¢ÊͶÔÇëÇó´¦Àí³ÌÐò·½·¨½øÐÐ×¢ÊÍ£¬Ôò¿ÉÒÔÖ¸¶¨ÏìÓ¦µÄËùÐè HTTP ״̬¡£ ÎÒÃÇ¿ÉÒÔʹÓà code ²ÎÊý»òÆä±ðÃû value ²ÎÊýÀ´ÉùÃ÷״̬´úÂë¡£
+
+´ËÍ⣬ÎÒÃÇ¿ÉÒÔʹÓà reason ²ÎÊýÌṩÔÒò¡£
+
+ÎÒÃÇÒ²¿ÉÒÔ½«ËüÓë@ExceptionHandler Ò»ÆðʹÓãº
+
+@ExceptionHandler(IllegalArgumentException.class)
+@ResponseStatus(HttpStatus.BAD_REQUEST)
+void onIllegalArgumentException(IllegalArgumentException exception) {
+// ...
+}
+
+ÓÐ¹Ø HTTP ÏìӦ״̬µÄ¸ü¶àÐÅÏ¢£¬Çë·ÃÎʱ¾ÎÄ¡£
+
+## 7 ÆäËû Web×¢½â
+һЩעÊͲ»Ö±½Ó¹ÜÀí HTTP ÇëÇó»òÏìÓ¦¡£ ÔÚ½ÓÏÂÀ´µÄ²¿·ÖÖУ¬ÎÒÃǽ«½éÉÜ×î³£¼ûµÄ¡£
+
+### 7.1 @Controller
+ÎÒÃÇ¿ÉÒÔʹÓÃ@Controller ¶¨ÒåÒ»¸öSpring MVC ¿ØÖÆÆ÷¡£ Óйظü¶àÐÅÏ¢£¬Çë·ÃÎÊÎÒÃǹØÓÚ Spring Bean Annotations µÄÎÄÕ¡£
+
+### 7.2 @RestController
+@RestController ½áºÏÁË@Controller ºÍ@ResponseBody¡£
+
+Òò´Ë£¬ÒÔÏÂÉùÃ÷ÊǵÈЧµÄ£º
+
+````
+@Controller
+@ResponseBody
+class VehicleRestController {
+// ...
+}
+````
+
+````
+@RestController
+class VehicleRestController {
+// ...
+}
+````
+### 7.3 @ModelAttribute
+ͨ¹ýÕâ¸ö×¢½â£¬ÎÒÃÇ¿ÉÒÔͨ¹ýÌṩģÐͼüÀ´·ÃÎÊÒѾ´æÔÚÓÚ MVC @Controller Ä£ÐÍÖеÄÔªËØ£º
+
+````
+@PostMapping("/assemble")
+void assembleVehicle(@ModelAttribute("vehicle") Vehicle vehicleInModel) {
+// ...
+}
+````
+Óë@PathVariable ºÍ@RequestParam Ò»Ñù£¬Èç¹û²ÎÊý¾ßÓÐÏàͬµÄÃû³Æ£¬ÎÒÃDz»±ØÖ¸¶¨Ä£Ðͼü£º
+
+````
+@PostMapping("/assemble")
+void assembleVehicle(@ModelAttribute Vehicle vehicle) {
+// ...
+}
+````
+´ËÍ⣬@ModelAttribute»¹ÓÐÒ»¸öÓÃ;£ºÈç¹ûÎÒÃÇÓÃËü×¢½âÒ»¸ö·½·¨£¬Spring»á×Ô¶¯½«·½·¨µÄ·µ»ØÖµÌí¼Óµ½Ä£ÐÍÖУº
+
+````
+@ModelAttribute("vehicle")
+Vehicle getVehicle() {
+// ...
+}
+````
+ºÍÒÔǰһÑù£¬ÎÒÃDz»±ØÖ¸¶¨Ä£Ðͼü£¬Spring ĬÈÏʹÓ÷½·¨µÄÃû³Æ£º
+````
+@ModelAttribute
+Vehicle vehicle() {
+// ...
+}
+````
+ÔÚ Spring µ÷ÓÃÇëÇó´¦Àí³ÌÐò·½·¨Ö®Ç°£¬Ëü»áµ÷ÓÃÀàÖÐËùÓÐ @ModelAttribute ×¢Ê͵ķ½·¨¡£
+
+ÓÐ¹Ø @ModelAttribute µÄ¸ü¶àÐÅÏ¢£¬Çë²ÎÔı¾ÎÄ¡£
+
+### 7.4 @CrossOrigin
+@CrossOrigin Ϊ´ø×¢Ê͵ÄÇëÇó´¦Àí³ÌÐò·½·¨ÆôÓÿçÓòͨÐÅ£º
+
+````
+@CrossOrigin
+@RequestMapping("/hello")
+String hello() {
+return "Hello World!";
+}
+````
+Èç¹ûÎÒÃÇÓÃËü±ê¼ÇÒ»¸öÀ࣬ËüÊÊÓÃÓÚÆäÖеÄËùÓÐÇëÇó´¦Àí³ÌÐò·½·¨¡£
+
+ÎÒÃÇ¿ÉÒÔʹÓôË×¢Ê͵IJÎÊý΢µ÷ CORS ÐÐΪ¡£
+
+ÓйØÏêϸÐÅÏ¢£¬Çë·ÃÎʱ¾ÎÄ¡£
+
+
+# ²Î¿¼ÎÄÕÂ
+https://www.baeldung.com/spring-annotations
diff --git "a/docs/spring/\347\254\254\344\270\200\344\270\252Spring\345\272\224\347\224\250.md" "b/docs/spring/\347\254\254\344\270\200\344\270\252Spring\345\272\224\347\224\250.md"
new file mode 100644
index 0000000..b40a369
--- /dev/null
+++ "b/docs/spring/\347\254\254\344\270\200\344\270\252Spring\345\272\224\347\224\250.md"
@@ -0,0 +1,70 @@
+## Ìí¼ÓÒÀÀµ
+ÕâÀïÎÒÃÇ¿ÉÒÔÏ顄 Spring »ù´¡ Jar °üÒÔ¼° Commons-loggin µ¼Èëµ½ÏîÄ¿ÖУ¬ÈôºóÐø¹¦ÄÜÔö¼Ó£¬Ôò¸ù¾ÝÐèÒªÔÙµ¼Èë Spring µÄÆäËû Jar¡£
+
+````
+org.springframework.core-5.3.13.jar
+org.springframework.beans-5.3.13.jar
+spring-context-5.3.13.jar
+spring-expression-5.3.13.jar
+commons.logging-1.2.jar
+````
+µ±È»ÕâÀïÎÒÃÇÍÆ¼öʹÓÃmaven¹ÜÀíÒÀÀµ
+
+## ´´½¨ Java Àà
+ ÔÚ HelloSpring Öд´½¨ net.biancheng.c °ü£¬È»ºóÔÚÕâ¸ö°üÏ´´½¨ HelloWorld.java ºÍ MainApp.java Àà¡£
+
+HelloWorld.java ÀàµÄ´úÂëÈçÏÂ
+````
+package net.biancheng.c;
+public class HelloWorld {
+ private String message;
+ public void setMessage(String message) {
+ this.message = message;
+ }
+ public void getMessage() {
+ System.out.println("message : " + message);
+ }
+}
+````
+MainApp.java ÀàµÄ´úÂëÈçÏÂ
+````
+package net.biancheng.c;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+ public class MainApp {
+ public static void main(String[] args) {
+ ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
+ HelloWorld obj = context.getBean("helloWorld",HelloWorld.class);
+ obj.getMessage();
+ }
+ }
+````
+¹ØÓÚÒÔÉÏ´úÂ룬ÐèҪעÒâÒÔÏÂÁ½µã£º
+
+´´½¨ ApplicationContext ¶ÔÏóʱʹÓÃÁË ClassPathXmlApplicationContext À࣬Õâ¸öÀàÓÃÓÚ¼ÓÔØ Spring ÅäÖÃÎļþ¡¢´´½¨ºÍ³õʼ»¯ËùÓжÔÏó£¨Bean£©¡£
+ApplicationContext.getBean() ·½·¨ÓÃÀ´»ñÈ¡ Bean£¬¸Ã·½·¨·µ»ØÖµÀàÐÍΪ Object£¬Í¨¹ýÇ¿ÖÆÀàÐÍת»»Îª HelloWorld µÄʵÀý¶ÔÏ󣬵÷ÓÃÆäÖÐµÄ getMessage() ·½·¨¡£
+
+## ´´½¨ÅäÖÃÎļþ
+
+ÔÚ src Ŀ¼Ï£¬´´½¨Ò»¸ö Spring ÅäÖÃÎļþ Beans.xml£¬ÄÚÈÝÈçÏ¡£
+````
+
+
+
+
+
+
+````
+ÎÒÃÇÒ²¿ÉÒÔ½«¸ÃÅäÖÃÎļþÃüÃûΪÆäËüÓÐЧµÄÃû³Æ£¬µ«ÐèҪעÒâµÄÊÇ£¬¸ÃÎļþÃû±ØÐëÓë MainApp.java ÖжÁÈ¡µÄÅäÖÃÎļþÃû³ÆÒ»Ö¡£
+
+Beans.xml ÓÃÓÚ¸ø²»Í¬µÄ Bean ·ÖÅäΨһµÄ ID£¬²¢¸øÏàÓ¦µÄ Bean ÊôÐÔ¸³Öµ¡£ÀýÈ磬ÔÚÒÔÉÏ´úÂëÖУ¬ÎÒÃÇ¿ÉÒÔÔÚ²»Ó°ÏìÆäËüÀàµÄÇé¿öÏ£¬¸ø message ±äÁ¿¸³Öµ¡£
+## ÔËÐгÌÐò
+
+ ÔËÐÐ MainApp.java£¬Eclipse IDE ¿ØÖÆÌ¨ÖÐÏÔʾÐÅÏ¢ÈçÏ¡£
+ message : Hello World!
+
+ÖÁ´Ë£¬ÎÒÃǾͳɹ¦´´½¨Á˵ÚÒ»¸ö Spring Ó¦ÓóÌÐò¡£
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index de1628d..a91c75e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,8 +7,28 @@
groupId
JavaTutorial
1.0-SNAPSHOT
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.0.5
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
com.github.houbb
markdown-toc
@@ -51,5 +71,13 @@
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
\ No newline at end of file
diff --git a/src/main/java/Test.java b/src/main/java/Test.java
new file mode 100644
index 0000000..269694c
--- /dev/null
+++ b/src/main/java/Test.java
@@ -0,0 +1,22 @@
+import org.springframework.beans.factory.annotation.Lookup;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author hpl
+ * @date 2023/4/15 14:40
+ */
+@Service
+public class Test {
+
+
+
+
+ public static void main(String[] args) {
+
+ }
+
+
+ public void test(){
+
+ }
+}
From 84e1254e8691ae7e4dad0803dc17c2c8ef33b29a Mon Sep 17 00:00:00 2001
From: h2pl <362294931@qq.com>
Date: Thu, 20 Apr 2023 21:35:59 +0800
Subject: [PATCH 10/39] done
---
ReadMe.md | 69 +-
...10\346\240\270\345\277\203\357\274\211.md" | 7 +-
...\260\203\345\272\246\344\270\216@Async.md" | 240 +
...45\345\277\227\347\256\241\347\220\206.md" | 806 +++
...\210\260\345\244\226\351\203\250Tomcat.md" | 302 +
...42\203\345\267\245\345\205\267Actuator.md" | 5832 +++++++++++++++++
...232\204Starter\346\234\272\345\210\266.md" | 262 +
...72\346\234\254\344\275\277\347\224\250.md" | 122 +-
...07\344\273\266\347\256\241\347\220\206.md" | 2989 +++++++++
...50\347\275\262\345\267\245\345\205\267.md" | 345 +
...52\345\212\250\347\224\237\346\210\220.md" | 625 ++
...345\267\245\345\205\267SpringBootAdmin.md" | 294 +
...45\350\257\206\346\270\205\345\215\225.md" | 0
...05\345\214\226\345\212\237\350\203\275.md" | 179 +
...70\347\224\250\345\212\237\350\203\275.md" | 594 ++
...70\345\244\204\347\220\206\345\231\250.md" | 235 +
...04\346\213\246\346\210\252\345\231\250.md" | 88 +
...76\350\247\243\346\236\220\345\231\250.md" | 181 +
...\277\207\346\273\244\345\231\250Filter.md" | 151 +
...53\351\200\237\345\205\245\351\227\250.md" | 1153 ++++
...07\344\273\266\344\270\212\344\274\240.md" | 237 +
...70\350\247\201\346\263\250\350\247\243.md" | 0
...\243\347\241\256\347\232\204Controller.md" | 0
...67\346\261\202\350\275\254\345\217\221.md" | 0
...4\232SpringMVC\346\246\202\350\277\260.md" | 0
...43\346\236\220\345\216\237\347\220\206.md" | 0
...5\277\265\344\270\216DispatcherServlet.md" | 0
...6@ResponseBody\346\263\250\350\247\243.md" | 0
...75\347\232\204\346\224\257\346\214\201.md" | 32 +-
...57\345\242\203\345\217\230\351\207\217.md" | 15 +-
...04\347\220\206\346\234\272\345\210\266.md" | 34 +-
...54\346\225\260\346\215\256\357\274\211.md" | 20 +-
...72\346\234\254\347\224\250\346\263\225.md" | 488 +-
.../spring/Spring\346\246\202\350\277\260.md" | 36 +-
...37\347\220\206\350\257\246\350\247\243.md" | 0
...37\347\220\206\350\257\246\350\247\243.md" | 0
...4\232SpringAOP\346\246\202\350\277\260.md" | 0
...40\350\275\275\350\277\207\347\250\213.md" | 0
...13\345\212\241\346\246\202\350\277\260.md" | 0
...20\347\240\201\345\211\226\346\236\220.md" | 0
...\274\232Spring\346\246\202\350\277\260.md" | 0
...70\345\277\203\346\265\201\347\250\213.md" | 0
...07\347\250\213\345\210\206\346\236\220.md" | 0
43 files changed, 14849 insertions(+), 487 deletions(-)
create mode 100644 "docs/spring/SpringBoot/SpringBoot\344\270\255\347\232\204\344\273\273\345\212\241\350\260\203\345\272\246\344\270\216@Async.md"
create mode 100644 "docs/spring/SpringBoot/SpringBoot\344\270\255\347\232\204\346\227\245\345\277\227\347\256\241\347\220\206.md"
create mode 100644 "docs/spring/SpringBoot/SpringBoot\345\272\224\347\224\250\344\271\237\345\217\257\344\273\245\351\203\250\347\275\262\345\210\260\345\244\226\351\203\250Tomcat.md"
create mode 100644 "docs/spring/SpringBoot/SpringBoot\347\224\237\344\272\247\347\216\257\345\242\203\345\267\245\345\205\267Actuator.md"
create mode 100644 "docs/spring/SpringBoot/SpringBoot\347\232\204Starter\346\234\272\345\210\266.md"
create mode 100644 "docs/spring/SpringBoot/SpringBoot\347\232\204\351\205\215\347\275\256\346\226\207\344\273\266\347\256\241\347\220\206.md"
create mode 100644 "docs/spring/SpringBoot/SpringBoot\350\207\252\345\270\246\347\232\204\347\203\255\351\203\250\347\275\262\345\267\245\345\205\267.md"
create mode 100644 "docs/spring/SpringBoot/SpringBoot\351\233\206\346\210\220Swagger\345\256\236\347\216\260API\346\226\207\346\241\243\350\207\252\345\212\250\347\224\237\346\210\220.md"
create mode 100644 "docs/spring/SpringBoot/\345\237\272\344\272\216SpringBoot\344\270\255\347\232\204\345\274\200\346\272\220\347\233\221\346\216\247\345\267\245\345\205\267SpringBootAdmin.md"
rename "docs/spring/\347\273\231\344\275\240\344\270\200\344\273\275SpringBoot\347\237\245\350\257\206\346\270\205\345\215\225.md" => "docs/spring/SpringBoot/\347\273\231\344\275\240\344\270\200\344\273\275SpringBoot\347\237\245\350\257\206\346\270\205\345\215\225.md" (100%)
create mode 100644 "docs/spring/SpringMVC/SpringMVC\344\270\255\347\232\204\345\233\275\351\231\205\345\214\226\345\212\237\350\203\275.md"
create mode 100644 "docs/spring/SpringMVC/SpringMVC\344\270\255\347\232\204\345\270\270\347\224\250\345\212\237\350\203\275.md"
create mode 100644 "docs/spring/SpringMVC/SpringMVC\344\270\255\347\232\204\345\274\202\345\270\270\345\244\204\347\220\206\345\231\250.md"
create mode 100644 "docs/spring/SpringMVC/SpringMVC\344\270\255\347\232\204\346\213\246\346\210\252\345\231\250.md"
create mode 100644 "docs/spring/SpringMVC/SpringMVC\344\270\255\347\232\204\350\247\206\345\233\276\350\247\243\346\236\220\345\231\250.md"
create mode 100644 "docs/spring/SpringMVC/SpringMVC\344\270\255\347\232\204\350\277\207\346\273\244\345\231\250Filter.md"
create mode 100644 "docs/spring/SpringMVC/SpringMVC\345\237\272\346\234\254\344\273\213\347\273\215\344\270\216\345\277\253\351\200\237\345\205\245\351\227\250.md"
create mode 100644 "docs/spring/SpringMVC/SpringMVC\345\246\202\344\275\225\345\256\236\347\216\260\346\226\207\344\273\266\344\270\212\344\274\240.md"
rename "docs/spring/springMVC/SpringMVC\345\270\270\350\247\201\346\263\250\350\247\243.md" => "docs/spring/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220/SpringMVC\345\270\270\350\247\201\346\263\250\350\247\243.md" (100%)
rename "docs/spring/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232DispatcherServlet\345\246\202\344\275\225\346\211\276\345\210\260\346\255\243\347\241\256\347\232\204Controller.md" => "docs/spring/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232DispatcherServlet\345\246\202\344\275\225\346\211\276\345\210\260\346\255\243\347\241\256\347\232\204Controller.md" (100%)
rename "docs/spring/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232DispatcherServlet\347\232\204\345\210\235\345\247\213\345\214\226\344\270\216\350\257\267\346\261\202\350\275\254\345\217\221.md" => "docs/spring/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232DispatcherServlet\347\232\204\345\210\235\345\247\213\345\214\226\344\270\216\350\257\267\346\261\202\350\275\254\345\217\221.md" (100%)
rename "docs/spring/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232SpringMVC\346\246\202\350\277\260.md" => "docs/spring/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232SpringMVC\346\246\202\350\277\260.md" (100%)
rename "docs/spring/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232SpringMVC\347\232\204\350\247\206\345\233\276\350\247\243\346\236\220\345\216\237\347\220\206.md" => "docs/spring/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232SpringMVC\347\232\204\350\247\206\345\233\276\350\247\243\346\236\220\345\216\237\347\220\206.md" (100%)
rename "docs/spring/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232SpringMVC\350\256\276\350\256\241\347\220\206\345\277\265\344\270\216DispatcherServlet.md" => "docs/spring/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232SpringMVC\350\256\276\350\256\241\347\220\206\345\277\265\344\270\216DispatcherServlet.md" (100%)
rename "docs/spring/springMVC/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232\346\266\210\346\201\257\350\275\254\346\215\242\345\231\250HttpMessageConverter\344\270\216@ResponseBody\346\263\250\350\247\243.md" => "docs/spring/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220/SpringMVC\346\272\220\347\240\201\345\210\206\346\236\220\357\274\232\346\266\210\346\201\257\350\275\254\346\215\242\345\231\250HttpMessageConverter\344\270\216@ResponseBody\346\263\250\350\247\243.md" (100%)
rename "docs/spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232AOP\345\256\236\347\216\260\345\216\237\347\220\206\350\257\246\350\247\243.md" => "docs/spring/Spring\346\272\220\347\240\201\345\210\206\346\236\220/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232AOP\345\256\236\347\216\260\345\216\237\347\220\206\350\257\246\350\247\243.md" (100%)
rename "docs/spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232JDK\345\222\214cglib\345\212\250\346\200\201\344\273\243\347\220\206\345\216\237\347\220\206\350\257\246\350\247\243.md" => "docs/spring/Spring\346\272\220\347\240\201\345\210\206\346\236\220/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232JDK\345\222\214cglib\345\212\250\346\200\201\344\273\243\347\220\206\345\216\237\347\220\206\350\257\246\350\247\243.md" (100%)
rename "docs/spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232SpringAOP\346\246\202\350\277\260.md" => "docs/spring/Spring\346\272\220\347\240\201\345\210\206\346\236\220/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232SpringAOP\346\246\202\350\277\260.md" (100%)
rename "docs/spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232SpringIOC\345\256\271\345\231\250\347\232\204\345\212\240\350\275\275\350\277\207\347\250\213.md" => "docs/spring/Spring\346\272\220\347\240\201\345\210\206\346\236\220/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232SpringIOC\345\256\271\345\231\250\347\232\204\345\212\240\350\275\275\350\277\207\347\250\213.md" (100%)
rename "docs/spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232Spring\344\272\213\345\212\241\346\246\202\350\277\260.md" => "docs/spring/Spring\346\272\220\347\240\201\345\210\206\346\236\220/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232Spring\344\272\213\345\212\241\346\246\202\350\277\260.md" (100%)
rename "docs/spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232Spring\344\272\213\345\212\241\346\272\220\347\240\201\345\211\226\346\236\220.md" => "docs/spring/Spring\346\272\220\347\240\201\345\210\206\346\236\220/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232Spring\344\272\213\345\212\241\346\272\220\347\240\201\345\211\226\346\236\220.md" (100%)
rename "docs/spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232Spring\346\246\202\350\277\260.md" => "docs/spring/Spring\346\272\220\347\240\201\345\210\206\346\236\220/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232Spring\346\246\202\350\277\260.md" (100%)
rename "docs/spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232\345\210\235\346\216\242SpringIOC\346\240\270\345\277\203\346\265\201\347\250\213.md" => "docs/spring/Spring\346\272\220\347\240\201\345\210\206\346\236\220/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232\345\210\235\346\216\242SpringIOC\346\240\270\345\277\203\346\265\201\347\250\213.md" (100%)
rename "docs/spring/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232\346\207\222\345\212\240\350\275\275\347\232\204\345\215\225\344\276\213Bean\350\216\267\345\217\226\350\277\207\347\250\213\345\210\206\346\236\220.md" => "docs/spring/Spring\346\272\220\347\240\201\345\210\206\346\236\220/Spring\346\272\220\347\240\201\345\211\226\346\236\220\357\274\232\346\207\222\345\212\240\350\275\275\347\232\204\345\215\225\344\276\213Bean\350\216\267\345\217\226\350\277\207\347\250\213\345\210\206\346\236\220.md" (100%)
diff --git a/ReadMe.md b/ReadMe.md
index c8ec78e..c73d49b 100644
--- a/ReadMe.md
+++ b/ReadMe.md
@@ -144,32 +144,67 @@
### Spring
-* [Spring常�注解.md](docs/spring/Spring常�注解.md)
+* [SpringAOP的概念与作用](docs/spring/Spring常�注解.md)
+* [SpringBean的定义与管ç�†ï¼ˆæ ¸å¿ƒï¼‰](docs/spring/Spring常è§�注解.md)
+* [Springä¸å¯¹äºŽæ•°æ�®åº“的访问](docs/spring/Spring常è§�注解.md)
+* [Springä¸å¯¹äºŽæ ¡éªŒåŠŸèƒ½çš„æ”¯æŒ�](docs/spring/Spring常è§�注解.md)
+* [Springä¸çš„Environment环境å�˜é‡�](docs/spring/Spring常è§�注解.md)
+* [Springä¸çš„事件处ç�†æœºåˆ¶](docs/spring/Spring常è§�注解.md)
+* [Springä¸çš„资æº�管ç�†](docs/spring/Spring常è§�注解.md)
+* [Springä¸çš„é…�置元数æ�®ï¼ˆç®¡ç�†é…�置的基本数æ�®ï¼‰](docs/spring/Spring常è§�注解.md)
+* [Spring事务基本用法](docs/spring/Spring常�注解.md)
+* [Spring�集](docs/spring/Spring常�注解.md)
+* [Spring容器与IOC](docs/spring/Spring常�注解.md)
+* [Spring常�注解](docs/spring/Spring常�注解.md)
+* [Spring概述](docs/spring/Spring常�注解.md)
+* [第一个Spring应用](docs/spring/Spring常�注解.md)
+
+* [Springæº�ç �剖æž�:Spring概述](docs/spring/Springæº�ç �分æž�/Springæº�ç �剖æž�:Spring概述.md)
+* [Springæº�ç �剖æž�:åˆ�探SpringIOCæ ¸å¿ƒæµ�程](docs/spring/Springæº�ç �分æž�/Springæº�ç �剖æž�:åˆ�探SpringIOCæ ¸å¿ƒæµ�程.md)
+* [Springæº�ç �剖æž�:SpringIOCå®¹å™¨çš„åŠ è½½è¿‡ç¨‹ ](docs/spring/Springæº�ç �分æž�/Springæº�ç �剖æž�:SpringIOCå®¹å™¨çš„åŠ è½½è¿‡ç¨‹.md)
+* [Springæº�ç �剖æž�ï¼šæ‡’åŠ è½½çš„å�•例Bean获å�–过程分æž�](docs/spring/Springæº�ç �分æž�/Springæº�ç �剖æž�ï¼šæ‡’åŠ è½½çš„å�•例Bean获å�–过程分æž�.md)
+* [Springæº�ç �剖æž�:JDKå’Œcglib动æ€�代ç�†åŽŸç�†è¯¦è§£ ](docs/spring/Springæº�ç �分æž�/Springæº�ç �剖æž�:JDKå’Œcglib动æ€�代ç�†åŽŸç�†è¯¦è§£.md)
+* [Springæº�ç �剖æž�:SpringAOP概述](docs/spring/Springæº�ç �分æž�/Springæº�ç �剖æž�:SpringAOP概述.md)
+* [Springæº�ç �剖æž�:AOP实现原ç�†è¯¦è§£ ](docs/spring/Springæº�ç �分æž�/Springæº�ç �剖æž�:AOP实现原ç�†è¯¦è§£.md)
+* [Springæº�ç �剖æž�:Spring事务概述](docs/spring/Springæº�ç �分æž�/Springæº�ç �剖æž�:Spring事务概述.md)
+* [Springæº�ç �剖æž�:Spring事务æº�ç �剖æž�](docs/spring/Springæº�ç �分æž�/Springæº�ç �剖æž�:Spring事务æº�ç �剖æž�.md)
+### SpringMVC
-* [Springæº�ç �剖æž�:Spring概述](docs/spring/Springæº�ç �剖æž�:Spring概述.md)
-* [Springæº�ç �剖æž�:åˆ�探SpringIOCæ ¸å¿ƒæµ�程](docs/spring/Springæº�ç �剖æž�:åˆ�探SpringIOCæ ¸å¿ƒæµ�程.md)
-* [Springæº�ç �剖æž�:SpringIOCå®¹å™¨çš„åŠ è½½è¿‡ç¨‹ ](docs/spring/Springæº�ç �剖æž�:SpringIOCå®¹å™¨çš„åŠ è½½è¿‡ç¨‹.md)
-* [Springæº�ç �剖æž�ï¼šæ‡’åŠ è½½çš„å�•例Bean获å�–过程分æž�](docs/spring/Springæº�ç �剖æž�ï¼šæ‡’åŠ è½½çš„å�•例Bean获å�–过程分æž�.md)
-* [Springæº�ç �剖æž�:JDKå’Œcglib动æ€�代ç�†åŽŸç�†è¯¦è§£ ](docs/spring/Springæº�ç �剖æž�:JDKå’Œcglib动æ€�代ç�†åŽŸç�†è¯¦è§£.md)
-* [Springæº�ç �剖æž�:SpringAOP概述](docs/spring/Springæº�ç �剖æž�:SpringAOP概述.md)
-* [Springæº�ç �剖æž�:AOP实现原ç�†è¯¦è§£ ](docs/spring/Springæº�ç �剖æž�:AOP实现原ç�†è¯¦è§£.md)
-* [Springæº�ç �剖æž�:Spring事务概述](docs/spring/Springæº�ç �剖æž�:Spring事务概述.md)
-* [Springæº�ç �剖æž�:Spring事务æº�ç �剖æž�](docs/spring/Springæº�ç �剖æž�:Spring事务æº�ç �剖æž�.md)
+* [SpringMVCä¸çš„国际化功能](docs/spring/SpringMVC/SpringMVCä¸çš„国际化功能.md)
+* [SpringMVCä¸çš„异常处ç�†å™¨](docs/spring/SpringMVC/SpringMVCä¸çš„异常处ç�†å™¨.md)
+* [SpringMVCä¸çš„æ‹¦æˆªå™¨](docs/spring/SpringMVC/SpringMVCä¸çš„æ‹¦æˆªå™¨.md)
+* [SpringMVCä¸çš„视图解æž�器](docs/spring/SpringMVC/SpringMVCä¸çš„视图解æž�器.md)
+* [SpringMVCä¸çš„过滤器Filter](docs/spring/SpringMVC/SpringMVCä¸çš„过滤器Filter.md)
+* [SpringMVC基本介�与快速入门](docs/spring/SpringMVC/SpringMVC基本介�与快速入门.md)
+* [SpringMVCå¦‚ä½•å®žçŽ°æ–‡ä»¶ä¸Šä¼ ](docs/spring/SpringMVC/SpringMVCå¦‚ä½•å®žçŽ°æ–‡ä»¶ä¸Šä¼ .md)
+* [SpringMVCä¸çš„常用功能](docs/spring/SpringMVC/SpringMVCä¸çš„常用功能.md)
-### SpringMVC
-* [SpringMVCæº�ç �分æž�:SpringMVC概述](docs/spring/springMVC/SpringMVCæº�ç �分æž�:SpringMVC概述.md)
-* [SpringMVCæº�ç �分æž�:SpringMVC设计ç�†å¿µä¸ŽDispatcherServlet](docs/spring/springMVC/SpringMVCæº�ç �分æž�:SpringMVC设计ç�†å¿µä¸ŽDispatcherServlet.md)
-* [SpringMVCæº�ç �分æž�:DispatcherServletçš„åˆ�始化与请求转å�‘ ](docs/spring/springMVC/SpringMVCæº�ç �分æž�:DispatcherServletçš„åˆ�始化与请求转å�‘.md)
-* [SpringMVCæº�ç �分æž�:DispatcherServlet如何找到æ£ç¡®çš„Controller ](docs/spring/springMVC/SpringMVCæº�ç �分æž�:DispatcherServlet如何找到æ£ç¡®çš„Controller.md)
-* [SpringMVCæº�ç �剖æž�:消æ�¯è½¬æ�¢å™¨HttpMessageConverter与@ResponseBody注解](docs/spring/springMVC/SpringMVCæº�ç �剖æž�:消æ�¯è½¬æ�¢å™¨HttpMessageConverter与@ResponseBody注解.md)
-* [SpringMVCæº�ç �分æž�:SpringMVC的视图解æž�原ç�† ](docs/spring/springMVC/SpringMVCæº�ç �分æž�:SpringMVC的视图解æž�原ç�†.md)
+* [SpringMVCæº�ç �分æž�:SpringMVC概述](docs/spring/SpringMVCæº�ç �分æž�/SpringMVCæº�ç �分æž�:SpringMVC概述.md)
+* [SpringMVCæº�ç �分æž�:SpringMVC设计ç�†å¿µä¸ŽDispatcherServlet](docs/spring/SpringMVCæº�ç �分æž�/SpringMVCæº�ç �分æž�:SpringMVC设计ç�†å¿µä¸ŽDispatcherServlet.md)
+* [SpringMVCæº�ç �分æž�:DispatcherServletçš„åˆ�始化与请求转å�‘ ](docs/spring/SpringMVCæº�ç �分æž�/SpringMVCæº�ç �分æž�:DispatcherServletçš„åˆ�始化与请求转å�‘.md)
+* [SpringMVCæº�ç �分æž�:DispatcherServlet如何找到æ£ç¡®çš„Controller ](docs/spring/SpringMVCæº�ç �分æž�/SpringMVCæº�ç �分æž�:DispatcherServlet如何找到æ£ç¡®çš„Controller.md)
+* [SpringMVCæº�ç �剖æž�:消æ�¯è½¬æ�¢å™¨HttpMessageConverter与@ResponseBody注解](docs/spring/SpringMVC/SpringMVCæº�ç �剖æž�:消æ�¯è½¬æ�¢å™¨HttpMessageConverter与@ResponseBody注解.md)
+* [SpringMVCæº�ç �分æž�:SpringMVC的视图解æž�原ç�† ](docs/spring/SpringMVCæº�ç �分æž�/SpringMVCæº�ç �分æž�:SpringMVC的视图解æž�原ç�†.md)
### SpringBoot
* [SpringBoot系列:SpringBoot的�世今生](docs/spring/SpringBoot/SpringBoot的�世今生.md)
+* [ç»™ä½ ä¸€ä»½SpringBoot知识清å�•.md](docs/spring/SpringBoot/ç»™ä½ ä¸€ä»½SpringBoot知识清å�•.md)
+* [Spring常�注解使用指�(包�Spring+SpringMVC+SpringBoot)](docs/spring/SpringBoot/Spring常�注解使用指�(包�Spring+SpringMVC+SpringBoot).md)
+* [SpringBootä¸çš„æ—¥å¿—管ç�†](docs/spring/SpringBoot/SpringBootä¸çš„æ—¥å¿—管ç�†.md)
+* [SpringBoot常�注解](docs/spring/SpringBoot/SpringBoot常�注解.md)
+* [SpringBoot应用也�以部署到外部Tomcat](docs/spring/SpringBoot/SpringBoot应用也�以部署到外部Tomcat.md)
+* [SpringBoot生产环境工具Actuator](docs/spring/SpringBoot/SpringBoot生产环境工具Actuator.md)
+* [SpringBoot的Starter机制](docs/spring/SpringBoot/SpringBoot的Starter机制.md)
+* [SpringBoot的�世今生](docs/spring/SpringBoot/SpringBoot的�世今生.md)
+* [SpringBoot的基本使用](docs/spring/SpringBoot/SpringBoot的基本使用.md)
+* [SpringBoot的�置文件管�](docs/spring/SpringBoot/SpringBoot的�置文件管�.md)
+* [SpringBoot自带的çƒéƒ¨ç½²å·¥å…·](docs/spring/SpringBoot/SpringBoot自带的çƒéƒ¨ç½²å·¥å…·.md)
+* [SpringBootä¸çš„任务调度与@Async](docs/spring/SpringBoot/SpringBootä¸çš„任务调度与@Async.md)
+* [基于SpringBootä¸çš„å¼€æº�监控工具SpringBootAdmin](docs/spring/SpringBoot/基于SpringBootä¸çš„å¼€æº�监控工具SpringBootAdmin.md)
### SpringCloud
diff --git "a/docs/spring/SpringBean\347\232\204\345\256\232\344\271\211\344\270\216\347\256\241\347\220\206\357\274\210\346\240\270\345\277\203\357\274\211.md" "b/docs/spring/SpringBean\347\232\204\345\256\232\344\271\211\344\270\216\347\256\241\347\220\206\357\274\210\346\240\270\345\277\203\357\274\211.md"
index a684554..c4de431 100644
--- "a/docs/spring/SpringBean\347\232\204\345\256\232\344\271\211\344\270\216\347\256\241\347\220\206\357\274\210\346\240\270\345\277\203\357\274\211.md"
+++ "b/docs/spring/SpringBean\347\232\204\345\256\232\344\271\211\344\270\216\347\256\241\347\220\206\357\274\210\346\240\270\345\277\203\357\274\211.md"
@@ -133,11 +133,11 @@ Bean
ÈÝÆ÷ÖÐÒ»µ©×¢²áÁËBeanºó´¦ÀíÆ÷£¬Beanºó´¦ÀíÆ÷¾Í»á×Ô¶¯Æô¶¯£¬ÔÚÈÝÆ÷ÖÐÿ¸öBean´´½¨Ê±×Ô¶¯¹¤×÷£¬Beanºó´¦ÀíÆ÷Á½¸ö·½·¨µÄ»Øµ÷ʱ»úÈçÏÂͼ£º
-
+
×¢ÒâÒ»µã£¬Èç¹ûʹÓÃ`BeanFactory`×÷ΪSpringÈÝÆ÷£¬Ôò±ØÐëÊÖ¶¯×¢²áBeanºó´¦ÀíÆ÷£¬³ÌÐò±ØÐë»ñÈ¡Beanºó´¦ÀíÆ÷ʵÀý£¬È»ºóÊÖ¶¯×¢²á¡£
- BeanPostProcessor bp = (BeanPostProcessor)beanFactory.getBean("bp"); beanFactory.addBeanPostProcessor(bp); Person p = (Person)beanFactory.getBean("person");
+BeanPostProcessor bp = (BeanPostProcessor)beanFactory.getBean("bp"); beanFactory.addBeanPostProcessor(bp); Person p = (Person)beanFactory.getBean("person");
### ÈÝÆ÷ºó´¦ÀíÆ÷
@@ -158,7 +158,7 @@ Spring
ÔÚSpringÅäÖÃÎļþÖÐ×öÈçÏÂÅäÖã¬Ö¸¶¨×Ô¶¯É¨ÃèµÄ°ü£º
-
+
### ʹÓÃ@ResourceÅäÖÃÒÀÀµ
@@ -174,6 +174,7 @@ Spring
SpringÌṩÁË`@Autowired`×¢½âÀ´Ö¸¶¨×Ô¶¯×°Å䣬`@Autowired`¿ÉÒÔÐÞÊÎsetter·½·¨¡¢ÆÕͨ·½·¨¡¢ÊµÀý±äÁ¿ºÍ¹¹ÔìÆ÷µÈ¡£µ±Ê¹ÓÃ`@Autowired`±ê×¢setter·½·¨Ê±£¬Ä¬ÈϲÉÓÃbyType×Ô¶¯×°Åä²ßÂÔ¡£ÔÚÕâÖÖ²ßÂÔÏ£¬·ûºÏ×Ô¶¯×°ÅäÀàÐ͵ĺòÑ¡BeanʵÀý³£³£Óжà¸ö£¬Õâ¸öʱºò¾Í¿ÉÄÜÒýÆðÒì³££¬ÎªÁËʵÏÖ¾«È·µÄ×Ô¶¯×°Å䣬SpringÌṩÁË`@Qualifier`×¢½â£¬Í¨¹ýʹÓÃ`@Qualifier`£¬ÔÊÐí¸ù¾ÝBeanµÄidÀ´Ö´ÐÐ×Ô¶¯×°Åä¡£
# ²Î¿¼ÎÄÕÂ
+
https://www.w3cschool.cn/wkspring
https://www.runoob.com/w3cnote/basic-knowledge-summary-of-spring.html
http://codepub.cn/2015/06/21/Basic-knowledge-summary-of-Spring
diff --git "a/docs/spring/SpringBoot/SpringBoot\344\270\255\347\232\204\344\273\273\345\212\241\350\260\203\345\272\246\344\270\216@Async.md" "b/docs/spring/SpringBoot/SpringBoot\344\270\255\347\232\204\344\273\273\345\212\241\350\260\203\345\272\246\344\270\216@Async.md"
new file mode 100644
index 0000000..c3bce06
--- /dev/null
+++ "b/docs/spring/SpringBoot/SpringBoot\344\270\255\347\232\204\344\273\273\345\212\241\350\260\203\345\272\246\344\270\216@Async.md"
@@ -0,0 +1,240 @@
+
+
+
+
+# Spring Bootµ÷¶È
+
+ÒÔÏÂÄÚÈݽöÊÇÕ¾³¤»òÍøÓѸöÈËѧϰ±Ê¼Ç¡¢×ܽáºÍÑо¿Êղء£²»±£Ö¤ÕýÈ·ÐÔ£¬ÒòʹÓöø´øÀ´µÄ·çÏÕÓë±¾Õ¾Î޹أ¡
+
+
+
+
+
+
+
+
+
+µ÷¶ÈÊÇÖ´ÐÐÌØ¶¨Ê±¼ä¶ÎµÄÈÎÎñµÄ¹ý³Ì¡£Spring BootΪÔÚSpringÓ¦ÓóÌÐòÉϱàдµ÷¶È³ÌÐòÌṩÁ˺ܺõÄÖ§³Ö¡£
+
+## Java Cron±í´ïʽ
+
+Java Cron±í´ïʽÓÃÓÚÅäÖÃCronTriggerµÄʵÀý£¬ËüÊÇ`org.quartz.Trigger`µÄ×ÓÀà¡£ ÓйØJava cron±í´ïʽµÄ¸ü¶àÐÅÏ¢£¬Çë²ÎÔÄ´ËÁ´½Ó -
+
+* [https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.html](https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.html)
+
+`[@EnableScheduling](https://github.com/EnableScheduling "@EnableScheduling")`×¢½âÓÃÓÚΪӦÓóÌÐòÆôÓõ÷¶È³ÌÐò¡£½«´ËÅú×¢Ìí¼Óµ½Ö÷Spring BootÓ¦ÓóÌÐòÀàÎļþÖС£
+
+```
+@SpringBootApplication
+@EnableScheduling
+
+public class DemoApplication {
+ public static void main(String[] args) {
+ SpringApplication.run(DemoApplication.class, args);
+ }
+}
+
+```
+
+`[@Scheduled](https://github.com/Scheduled "@Scheduled")`×¢½âÓÃÓÚÔÚÌØ¶¨Ê±¼ä¶ÎÄÚ´¥·¢µ÷¶È³ÌÐò¡£
+
+```
+@Scheduled(cron = "0 * 9 * * ?")
+public void cronJobSch() throws Exception {
+}
+
+```
+
+ÒÔÏÂÊÇÒ»¸öʾÀý´úÂ룬ÑÝʾÈçºÎÔÚÿÌìÉÏÎç9:00¿ªÊ¼µ½Ã¿ÌìÉÏÎç9:59½áÊøÖ´ÐÐÈÎÎñ¡£
+
+```
+package com.yiibai.demo.scheduler;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+@Component
+public class Scheduler {
+ @Scheduled(cron = "0 * 9 * * ?")
+ public void cronJobSch() {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+ Date now = new Date();
+ String strDate = sdf.format(now);
+ System.out.println("Java cron job expression:: " + strDate);
+ }
+}
+
+```
+
+ÒÔÏÂÆÁÄ»½ØÍ¼ÏÔʾÁËÓ¦ÓóÌÐòÈçºÎÔÚ`09:03:23`Æô¶¯£¬²¢ÇÒ´ÓÄÇʱÆðÿ¸ôÒ»·ÖÖÓÖ´ÐÐÒ»´Îcron×÷Òµµ÷¶È³ÌÐòÈÎÎñ¡£
+
+
+
+## ¹Ì¶¨ËÙÂÊ
+
+¹Ì¶¨ËÙÂʵ÷¶È³ÌÐòÓÃÓÚÔÚÌØ¶¨Ê±¼äÖ´ÐÐÈÎÎñ¡£Ëü²»µÈ´ýǰһ¸öÈÎÎñµÄÍê³É¡£ ÖµÊÇÒÔºÁÃëΪµ¥Î»¡£ ʾÀý´úÂëÏÔʾÔÚ´Ë´¦ -
+
+```
+@Scheduled(fixedRate = 1000)
+public void fixedRateSch() {
+}
+
+```
+
+´Ë´¦ÏÔʾÁËÓ¦ÓóÌÐòÆô¶¯Ê±Ã¿ÃëÖ´ÐÐÈÎÎñµÄʾÀý´úÂë -
+
+```
+package com.yiibai.demo.scheduler;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+@Component
+public class Scheduler {
+ @Scheduled(fixedRate = 1000)
+ public void fixedRateSch() {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+
+ Date now = new Date();
+ String strDate = sdf.format(now);
+ System.out.println("Fixed Rate scheduler:: " + strDate);
+ }
+}
+
+```
+
+Çë×¢ÒâÒÔÏÂÆÁÄ»½ØÍ¼£¬ÆäÖÐÏÔʾÁËÔÚ`09:12:00`Æô¶¯µÄÓ¦ÓóÌÐò£¬Ö®ºóÿ¸ôÒ»¸ö¹Ì¶¨ËÙÂʵ÷¶È³ÌÐòÖ´ÐÐÈÎÎñ¡£
+
+
+
+## ¹Ì¶¨ÑÓ³Ù
+
+¹Ì¶¨ÑÓ³Ùµ÷¶È³ÌÐòÓÃÓÚÔÚÌØ¶¨Ê±¼äÖ´ÐÐÈÎÎñ¡£ ËüÓ¦¸ÃµÈ´ýÉÏÒ»¸öÈÎÎñÍê³É¡£ ÖµÓ¦ÒÔºÁÃëΪµ¥Î»¡£ ´Ë´¦ÏÔʾʾÀý´úÂë -
+
+```
+@Scheduled(fixedDelay = 1000, initialDelay = 1000)
+public void fixedDelaySch() {
+}
+
+```
+
+ÕâÀ`initialDelay`ÊÇÔÚ³õʼÑÓ³ÙÖµÖ®ºóµÚÒ»´ÎÖ´ÐÐÈÎÎñµÄʱ¼ä¡£
+
+´ÓÓ¦ÓóÌÐòÆô¶¯Íê³É`3`ÃëºóÿÃëÖ´ÐÐÒ»´ÎÈÎÎñµÄʾÀýÈçÏÂËùʾ -
+
+```
+package com.yiibai.demo.scheduler;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+@Component
+public class Scheduler {
+ @Scheduled(fixedDelay = 1000, initialDelay = 3000)
+ public void fixedDelaySch() {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+ Date now = new Date();
+ String strDate = sdf.format(now);
+ System.out.println("Fixed Delay scheduler:: " + strDate);
+ }
+}
+
+```
+
+Ö´ÐÐÉÏÃæ´úÂëºó£¬Ëü»áÏÔʾÔÚ`09:18:39`¿ªÊ¼µÄÓ¦ÓóÌÐò£¬Ã¿`3`Ãëºó£¬¹Ì¶¨Ñӳټƻ®³ÌÐòÈÎÎñ(ÿÃëÖ´ÐÐÒ»´Î)¡£
+
+
+
+
+
+//¸ü¶àÇëÔĶÁ£ºhttps://www.yiibai.com/spring-boot/spring_boot_scheduling.html
+
+@EnableAsync ×¢½â
+ҪʹÓà @Async£¬Ê×ÏÈÐèҪʹÓà @EnableAsync ×¢½â¿ªÆô Spring Boot ÖеÄÒì²½ÌØÐÔ¡£
+
+@Configuration
+@EnableAsync
+public class AppConfig {
+}
+¸üÏêϸµÄÅäÖÃ˵Ã÷£¬¿ÉÒԲο¼£ºAsyncConfigurer(opens new window)
+
+#@Async ×¢½â
+#Ö§³ÖµÄÓ÷¨
+£¨1£©ÎÞÈë²ÎÎÞ·µ»ØÖµ·½·¨
+
+Äú¿ÉÒÔÓà @Async ×¢½âÐÞÊη½·¨£¬Õâ±íÃ÷Õâ¸ö·½·¨ÊÇÒì²½·½Ê½µ÷Ó᣻»¾ä»°Ëµ£¬³ÌÐòÔÚµ÷Óô˷½·¨Ê±»áÁ¢¼´·µ»Ø£¬¶ø·½·¨µÄʵ¼ÊÖ´Ðз¢ÉúÔÚÒÑÌá½»¸ø Spring TaskExecutor µÄÈÎÎñÖС£ÔÚ×î¼òµ¥µÄÇé¿öÏ£¬Äú¿ÉÒÔ½«×¢½âÓ¦ÓÃÓÚ·µ»Ø void µÄ·½·¨£¬ÈçÒÔÏÂʾÀýËùʾ£º
+
+@Async
+void doSomething() {
+// this will be executed asynchronously
+}
+£¨2£©ÓÐÈë²ÎÎÞ·µ»ØÖµ·½·¨
+
+ÓëʹÓà @Scheduled ×¢ÊÍ×¢Ê͵ķ½·¨²»Í¬£¬ÕâЩ·½·¨¿ÉÒÔÖ¸¶¨²ÎÊý£¬ÒòΪËüÃÇÔÚÔËÐÐʱÓɵ÷ÓÃÕßÒÔ¡°Õý³£¡±·½Ê½µ÷Ó㬶ø²»ÊÇÓÉÈÝÆ÷¹ÜÀíµÄµ÷¶ÈÈÎÎñµ÷Óá£ÀýÈ磬ÒÔÏ´úÂëÊÇ @Async ×¢½âµÄºÏ·¨Ó¦Óãº
+
+@Async
+void doSomething(String s) {
+// this will be executed asynchronously
+}
+£¨3£©ÓÐÈë²ÎÓзµ»ØÖµ·½·¨
+
+ÉõÖÁ¿ÉÒÔÒì²½µ÷Ó÷µ»ØÖµµÄ·½·¨¡£µ«ÊÇ£¬ÕâЩ·½·¨ÐèÒª¾ßÓÐ Future ÀàÐ͵ķµ»ØÖµ¡£ÕâÈÔÈ»ÌṩÁËÒì²½Ö´Ðеĺô¦£¬ÒÔ±ãµ÷ÓÃÕß¿ÉÒÔÔÚµ÷Óà Future É쵀 get() ֮ǰִÐÐÆäËûÈÎÎñ¡£ÒÔÏÂʾÀýÏÔʾÈçºÎÔÚ·µ»ØÖµµÄ·½·¨ÉÏʹÓÃ@Async£º
+
+@Async
+Future returnSomething(int i) {
+// this will be executed asynchronously
+}
+#²»Ö§³ÖµÄÓ÷¨
+@Async ²»ÄÜÓëÉúÃüÖÜÆÚ»Øµ÷Ò»ÆðʹÓã¬ÀýÈç @PostConstruct¡£
+
+ÒªÒì²½³õʼ»¯ Spring bean£¬±ØÐëʹÓõ¥¶ÀµÄ³õʼ»¯ Spring bean£¬È»ºóÔÚÄ¿±êÉϵ÷Óà @Async ´ø×¢Ê͵ķ½·¨£¬ÈçÒÔÏÂʾÀýËùʾ£º
+
+public class SampleBeanImpl implements SampleBean {
+
+ @Async
+ void doSomething() {
+ // ...
+ }
+
+}
+
+public class SampleBeanInitializer {
+
+ private final SampleBean bean;
+
+ public SampleBeanInitializer(SampleBean bean) {
+ this.bean = bean;
+ }
+
+ @PostConstruct
+ public void initialize() {
+ bean.doSomething();
+ }
+
+}
+#Ã÷È·Ö¸¶¨Ö´ÐÐÆ÷
+ĬÈÏÇé¿öÏ£¬ÔÚ·½·¨ÉÏÖ¸¶¨ @Async ʱ£¬Ê¹ÓõÄÖ´ÐÐÆ÷ÊÇÔÚÆôÓÃÒì²½Ö§³ÖʱÅäÖõÄÖ´ÐÐÆ÷£¬¼´Èç¹ûʹÓà XML »ò AsyncConfigurer ʵÏÖ£¨Èç¹ûÓУ©£¬ÔòΪ annotation-driven ÔªËØ¡£µ«ÊÇ£¬Èç¹ûÐèҪָʾÔÚÖ´Ðиø¶¨·½·¨Ê±Ó¦Ê¹ÓÃĬÈÏÖµÒÔÍâµÄÖ´ÐÐÆ÷£¬Ôò¿ÉÒÔʹÓà @Async ×¢½âµÄ value ÊôÐÔ¡£ÒÔÏÂʾÀýÏÔʾÁËÈçºÎÖ´Ðд˲Ù×÷£º
+
+@Async("otherExecutor")
+void doSomething(String s) {
+// this will be executed asynchronously by "otherExecutor"
+}
+ÔÚÕâÖÖÇé¿öÏ£¬¡°otherExecutor¡±¿ÉÒÔÊÇ Spring ÈÝÆ÷ÖÐÈκΠExecutor bean µÄÃû³Æ£¬Ò²¿ÉÒÔÊÇÓëÈκΠExecutor ¹ØÁªµÄÏÞ¶¨·ûµÄÃû³Æ£¨ÀýÈ磬ʹÓÃ ÔªËØ»ò Spring µÄ @Qualifier ×¢ÊÍÖ¸¶¨£© £©¡£
+
+#¹ÜÀí @Async µÄÒì³£
+µ± @Async ·½·¨µÄ·µ»ØÖµÀàÐÍΪ Future ÐÍʱ£¬ºÜÈÝÒ×¹ÜÀíÔÚ·½·¨Ö´ÐÐÆÚ¼äÅ׳öµÄÒì³££¬ÒòΪÔÚµ÷Óà get ½á¹ûʱ»áÅ׳ö´ËÒì³£¡£µ«ÊÇ£¬¶ÔÓÚ·µ»ØÖµÀàÐÍΪ void Ð͵ķ½·¨£¬Òì³£²»»á±»²¶»ñÇÒÎÞ·¨´«Êä¡£Äú¿ÉÒÔÌṩ AsyncUncaughtExceptionHandler À´´¦Àí´ËÀàÒì³£¡£ÒÔÏÂʾÀýÏÔʾÁËÈçºÎÖ´Ðд˲Ù×÷£º
+
+public class MyAsyncUncaughtExceptionHandler implements AsyncUncaughtExceptionHandler {
+
+ @Override
+ public void handleUncaughtException(Throwable ex, Method method, Object... params) {
+ // handle exception
+ }
+}
+ĬÈÏÇé¿öÏ£¬½ö¼Ç¼Òì³£¡£Äú¿ÉÒÔʹÓà AsyncConfigurer »ò XML ÔªËØ¶¨Òå×Ô¶¨Òå AsyncUncaughtExceptionHandler¡£
\ No newline at end of file
diff --git "a/docs/spring/SpringBoot/SpringBoot\344\270\255\347\232\204\346\227\245\345\277\227\347\256\241\347\220\206.md" "b/docs/spring/SpringBoot/SpringBoot\344\270\255\347\232\204\346\227\245\345\277\227\347\256\241\347\220\206.md"
new file mode 100644
index 0000000..009576d
--- /dev/null
+++ "b/docs/spring/SpringBoot/SpringBoot\344\270\255\347\232\204\346\227\245\345\277\227\347\256\241\347\220\206.md"
@@ -0,0 +1,806 @@
+## 4\. ÈÕÖ¾
+
+
+
+
+
+Spring BootÔÚËùÓÐÄÚ²¿ÈÕÖ¾ÖÐʹÓà [Commons Logging](https://commons.apache.org/logging) £¬µ«¶Ôµ×²ãÈÕÖ¾µÄʵÏÖ±£³Ö¿ª·Å¡£ Ϊ [Java Util Logging](https://docs.oracle.com/javase/17/docs/api/java/util/logging/package-summary.html) ¡¢ [Log4j2](https://logging.apache.org/log4j/2.x/) ¡¢ [Logback](https://logback.qos.ch/) ÌṩÁËĬÈÏÅäÖᣠÔÚÿһÖÖÇé¿öÏ£¬¼Ç¼Æ÷£¨logger£©¶¼±»Ô¤ÉèΪʹÓÿØÖÆÌ¨Êä³ö£¬Ò²¿ÉÒÔÑ¡ÔñÊä³öµ½Îļþ¡£
+
+
+
+
+
+ĬÈÏÇé¿öÏ£¬Èç¹ûÄãʹÓà ¡°Starter¡±£¬ÔòĬÈÏʹÓÃLogback¡£ Êʵ±µÄLogback·ÓÉÒ²°üÀ¨ÔÚÄÚ£¬ÒÔÈ·±£Ê¹ÓÃJava Util Logging¡¢Commons Logging¡¢Log4J»òSLF4JµÄÒÀÀµ¿â¶¼ÄÜÕýÈ·¹¤×÷¡£
+
+
+
+
+
+| | ÓкܶàÊÊÓÃÓÚJavaµÄÈÕÖ¾¿ò¼Ü¡£ Èç¹ûÉÏÃæµÄÁÐ±í¿´ÆðÀ´ºÜ»ìÂÒ£¬Çë²»Òªµ£ÐÄ¡£ Ò»°ãÀ´Ëµ£¬Äã²»ÐèÒª¸Ä±äÄãµÄÈÕÖ¾ÒÀÀµ£¬Spring BootµÄĬÈÏÖµ¾ÍºÜºÃÓᣠ|
+| --- | --- |
+
+
+
+
+
+| | µ±Äã°ÑÄãµÄÓ¦ÓóÌÐò²¿Êðµ½Ò»¸öservletÈÝÆ÷»òÓ¦Ó÷þÎñÆ÷ʱ£¬ÓÃJava Util Logging APIÖ´ÐеÄÈÕÖ¾²»»á±»´«Ë͵½ÄãµÄÓ¦ÓóÌÐòµÄÈÕÖ¾ÖС£ Õâ¿ÉÒÔ·ÀÖ¹ÓÉÈÝÆ÷»òÆäËûÒѾ²¿Êðµ½ËüµÄÓ¦ÓóÌÐòÖ´ÐеÄÈÕÖ¾³öÏÖÔÚÄãµÄÓ¦ÓóÌÐòµÄÈÕÖ¾ÖС£ |
+| --- | --- |
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/features.html#features.logging.log-format)4.1\. ÈÕÖ¾¸ñʽ
+
+
+
+Spring BootµÄĬÈϵÄÈÕÖ¾Êä³ö¸ñʽÀàËÆÓÚÏÂÃæµÄÀý×Ó¡£
+
+
+
+
+
+
+
+ 2023-03-03T21:18:18.827+08:00 INFO 19388 --- [ main] o.s.b.d.f.s.MyApplication : Starting MyApplication using Java 17 with PID 19388 (/opt/apps/myapp.jar started by myuser in /opt/apps/)
+2023-03-03T21:18:18.834+08:00 INFO 19388 --- [ main] o.s.b.d.f.s.MyApplication : No active profile set, falling back to 1 default profile: "default"
+2023-03-03T21:18:20.439+08:00 INFO 19388 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
+2023-03-03T21:18:20.461+08:00 INFO 19388 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
+2023-03-03T21:18:20.461+08:00 INFO 19388 --- [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.5]
+2023-03-03T21:18:20.600+08:00 INFO 19388 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
+2023-03-03T21:18:20.602+08:00 INFO 19388 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1685 ms
+2023-03-03T21:18:21.078+08:00 INFO 19388 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
+2023-03-03T21:18:21.093+08:00 INFO 19388 --- [ main] o.s.b.d.f.s.MyApplication : Started MyApplication in 2.998 seconds (process running for 3.601)
+
+
+
+
+
+
+
+Êä³öµÄÏîÄ¿ÈçÏ¡£
+
+
+
+
+
+* DateºÍʱTime£º¾«È·µ½ºÁÃ룬Ò×ÓÚÅÅÐò¡£
+
+* ÈÕÖ¾¼¶±ð: `ERROR`, `WARN`, `INFO`, `DEBUG`, »ò `TRACE`.
+
+* ½ø³ÌID¡£
+
+* Ò»¸ö `---` ·Ö¸ô·û£¬ÒÔÇø·Öʵ¼ÊÈÕÖ¾ÐÅÏ¢µÄ¿ªÊ¼¡£
+
+* Ïß³ÌÃû³Æ£º°üº¬ÔÚ·½À¨ºÅÖУ¨¶ÔÓÚ¿ØÖÆÌ¨Êä³ö¿ÉÄܻᱻ½Ø¶Ï£©¡£
+
+* ¼Ç¼Æ÷Ãû³Æ£ºÕâͨ³£ÊÇÔ´ÀàµÄÃû³Æ£¨Í¨³£ÊÇËõд£©¡£
+
+* ÈÕÖ¾ÏûÏ¢¡£
+
+
+
+
+
+| | LogbackûÓÐ `FATAL` ¼¶±ð¡£ Ëü±»Ó³Éäµ½ `ERROR`¡£ |
+| --- | --- |
+
+
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/features.html#features.logging.console-output)4.2\. ¿ØÖÆÌ¨Êä³ö
+
+
+
+ĬÈÏÇé¿öÏ£¬ÈÕÖ¾»áÊä³ö `ERROR`¡¢`WARN` ºÍ `INFO` ¼¶±ðµÄÏûÏ¢µ½¿ØÖÆÌ¨¡£ ÄãÒ²¿ÉÒÔͨ¹ýÓà `--debug` ±êÖ¾Æô¶¯ÄãµÄÓ¦ÓóÌÐò£¬À´ÆôÓà `debug` ģʽ¡£
+
+
+
+
+
+
+
+```
+$ java -jar myapp.jar --debug
+```
+
+
+
+
+
+
+
+| | ÄãÒ²¿ÉÒÔÔÚÄãµÄ `application.properties` ÖÐÖ¸¶¨ `debug=true`¡£ |
+| --- | --- |
+
+
+
+
+
+µ±debugģʽ±»ÆôÓÃʱ£¬Ò»Ð©ºËÐļǼÆ÷£¨Ç¶ÈëʽÈÝÆ÷¡¢HibernateºÍSpring Boot£©±»ÅäÖÃΪÊä³ö¸ü¶àÐÅÏ¢¡£ ÆôÓÃdebugģʽ²¢²»Òâζ׎«ÄãµÄÓ¦ÓóÌÐòÅäÖÃΪÒÔ `DEBUG` ¼¶±ð¼Ç¼ËùÓÐÐÅÏ¢¡£
+
+
+
+
+
+ÁíÍ⣬Äã¿ÉÒÔͨ¹ýÔÚÆô¶¯Ó¦ÓóÌÐòʱʹÓà `--trace` ±êÖ¾£¨»òÔÚ `application.properties` ÖÐʹÓà `trace=true` £©À´ÆôÓà ¡°trace¡± ģʽ¡£ ÕâÑù×ö¿ÉÒÔ¶ÔһЩºËÐļǼÆ÷£¨Ç¶ÈëʽÈÝÆ÷¡¢Hibernate schemaÉú³ÉºÍÕû¸öSpring×éºÏ£©½øÐиú×ټǼ¡£
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/features.html#features.logging.console-output.color-coded)4.2.1\. ²ÊÉ«±àÂëµÄÊä³ö
+
+
+
+Èç¹ûÄãµÄÖÕ¶ËÖ§³ÖANSI£¬¾Í»áʹÓòÊÉ«Êä³öÀ´°ïÖúÔĶÁ¡£ Äã¿ÉÒÔ½« `spring.output.ansi.enabled` ÉèÖÃΪ [Ö§³ÖµÄÖµ](https://docs.spring.io/spring-boot/docs/3.1.0-SNAPSHOT/api/org/springframework/boot/ansi/AnsiOutput.Enabled.html)£¬ÒÔ¸²¸Ç×Ô¶¯¼ì²â¡£
+
+
+
+
+
+ÑÕÉ«±àÂëÊÇͨ¹ýʹÓà `%clr` ת»»¹Ø¼ü×ÖÀ´ÅäÖõġ£ ÔÚÆä×î¼òµ¥µÄÐÎʽÖУ¬×ª»»Æ÷¸ù¾ÝÈÕÖ¾¼¶±ð¶ÔÊä³ö½øÐÐ×ÅÉ«£¬ÈçÏÂÃæµÄÀý×ÓÖÐËùʾ¡£
+
+
+
+
+
+
+
+```
+%clr(%5p)
+```
+
+
+
+
+
+
+
+ϱíÃèÊöÁËÈÕÖ¾¼¶±ðÓëÑÕÉ«µÄÓ³Éä¹ØÏµ¡£
+
+
+
+
+| ÈÕÖ¾¼¶±ð | ÑÕÉ« |
+| --- | --- |
+| `FATAL` | ºì |
+| `ERROR` | ºì |
+| `WARN` | Ȯ |
+| `INFO` | ÂÌ |
+| `DEBUG` | ÂÌ |
+| `TRACE` | ÂÌ |
+
+
+
+ÁíÍ⣬ÄãÒ²¿ÉÒÔͨ¹ýΪת»»Ìṩһ¸öÑ¡ÏîÀ´Ö¸¶¨Ó¦¸ÃʹÓõÄÑÕÉ«»òÑùʽ¡£ ÀýÈ磬ҪʹÎı¾Îª»ÆÉ«£¬ÇëʹÓÃÒÔÏÂÉèÖá£
+
+
+
+
+
+
+
+```
+%clr(%d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX}){yellow}
+```
+
+
+
+
+
+
+
+Ö§³ÖÒÔÏÂÑÕÉ«ºÍÑùʽ¡£
+
+
+
+
+
+* `blue`
+
+* `cyan`
+
+* `faint`
+
+* `green`
+
+* `magenta`
+
+* `red`
+
+* `yellow`
+
+
+
+
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/features.html#features.logging.file-output)4.3\. Êä³öµ½Îļþ
+
+
+
+ĬÈÏÇé¿öÏ£¬Spring BootÖ»Ïò¿ØÖÆÌ¨¼Ç¼ÈÕÖ¾£¬²»Ð´ÈÕÖ¾Îļþ¡£ Èç¹ûÄãÏëÔÚ¿ØÖÆÌ¨Êä³öÖ®ÍâдÈÕÖ¾Îļþ£¬ÄãÐèÒªÉèÖà `logging.file.name` »ò `logging.file.path` ÊôÐÔ£¨ÀýÈ磬ÔÚÄãµÄ `application.properties` ÖУ©¡£
+
+
+
+
+
+ϱíÏÔʾÁË `logging.*` ÊôÐÔÈçºÎ±»Ò»ÆðʹÓá£
+
+
+
+Table 5\. Logging properties
+| `logging.file.name` | `logging.file.path` | Example | Description |
+| --- | --- | --- | --- |
+| _(none)_ | _(none)_ | | Ö»ÔÚ¿ØÖÆÌ¨½øÐмǼ¡£ |
+| Ö¸¶¨Îļþ | _(none)_ | `my.log` | дÈëÖ¸¶¨µÄÈÕÖ¾Îļþ¡£ Ãû³Æ¿ÉÒÔÊÇÒ»¸öÈ·ÇеÄλÖã¬Ò²¿ÉÒÔÊÇÓ뵱ǰĿ¼µÄÏà¶ÔλÖᣠ|
+| _(none)_ | Ö¸¶¨Ä¿Â¼ | `/var/log` | ½« `spring.log` дµ½Ö¸¶¨Ä¿Â¼¡£ Ãû³Æ¿ÉÒÔÊÇÒ»¸öÈ·ÇеÄλÖã¬Ò²¿ÉÒÔÊÇÓ뵱ǰĿ¼µÄÏà¶ÔλÖᣠ|
+
+
+
+ÈÕÖ¾ÎļþÔÚ´ïµ½10MBʱ¾Í»áÂÖ»»£¬Óë¿ØÖÆÌ¨Êä³öÒ»Ñù£¬Ä¬ÈÏÇé¿öÏ»á¼Ç¼ `ERROR` ¡¢`WARN` ¼¶ºÍ `INFO` ¼¶±ðµÄÐÅÏ¢¡£
+
+
+
+
+
+| | ÈÕÖ¾ÊôÐÔ¶ÀÁ¢ÓÚʵ¼ÊµÄÈÕÖ¾»ù´¡ÉèÊ©¡£ Òò´Ë£¬Ìض¨µÄÅäÖÃÊôÐÔ£¨ÈçLogbackµÄ `logback.configurationFile` £©²»ÓÉspring Boot¹ÜÀí¡£ |
+| --- | --- |
+
+
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/features.html#features.logging.file-rotation)4.4\. ÎļþÂÖ»»£¨¹ö¶¯ÈÕÖ¾£©
+
+
+
+Èç¹ûÄãʹÓÃLogback£¬¿ÉÒÔʹÓÃÄãµÄ `application.properties` »ò `application.yaml` ÎļþÀ´Î¢µ÷ÈÕÖ¾ÂÖ»»ÉèÖᣠ¶ÔÓÚËùÓÐÆäËûµÄÈÕ־ϵͳ£¬Ä㽫ÐèÒª×Ô¼ºÖ±½ÓÅäÖÃÂÖ»»ÉèÖã¨ÀýÈ磬Èç¹ûÄãʹÓÃLog4J2£¬ÄÇôÄã¿ÉÒÔÌí¼ÓÒ»¸ö `log4j2.xml` »ò `log4j2-spring.xml` Îļþ£©¡£
+
+
+
+
+
+Ö§³ÖÒÔÏÂÂÖ»»²ßÂÔÊôÐÔ¡£
+
+
+
+
+| ÊôÐÔ | ˵Ã÷ |
+| --- | --- |
+| `logging.logback.rollingpolicy.file-name-pattern` | ÓÃÓÚ´´½¨ÈÕÖ¾¹éµµµÄÎļþÃûģʽ¡£ |
+| `logging.logback.rollingpolicy.clean-history-on-start` | Ó¦ÓóÌÐòÆô¶¯Ê±£¬ÊÇ·ñÐÐÈÕÖ¾¹éµµÇåÀí¡£ |
+| `logging.logback.rollingpolicy.max-file-size` | ÈÕÖ¾Îļþ¹éµµÇ°µÄ×î´ó³ß´ç£¨Îļþ×î´óÌå»ý£¬´ïµ½Õâ¸öÌå»ý¾Í»á¹éµµ£©¡£ |
+| `logging.logback.rollingpolicy.total-size-cap` | ÈÕÖ¾µµ°¸ÔÚ±»É¾³ýǰµÄ×î´ó³ß´ç£¨¹éµµÎļþ×î´óÕ¼ÓôóС£¬³¬¹ýÕâ¸ö´óСºó»á±»É¾³ý£©¡£ |
+| `logging.logback.rollingpolicy.max-history` | Òª±£ÁôµÄ¹éµµÈÕÖ¾ÎļþµÄ×î´óÊýÁ¿£¨Ä¬ÈÏΪ7£©¡£ |
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/features.html#features.logging.log-levels)4.5\. ÈÕÖ¾¼¶±ð
+
+
+
+ËùÓÐÖ§³ÖµÄÈÕ־ϵͳ¶¼¿ÉÒÔͨ¹ýʹÓà `logging.level.=` ÔÚSpringµÄ `Environment`£¨ÀýÈ磬ÔÚ `application.properties`£©ÖÐÉèÖÃÈÕÖ¾¼¶±ð£¬ÆäÖÐ `level` ÊÇ `TRACE`, `DEBUG`, `INFO`, `WARN`, `ERROR`, `FATAL`, »ò `OFF` Ö®Ò»¡£ `root` ¼Ç¼Æ÷£¨logger£©µÄ¼¶±ð¿ÉÒÔͨ¹ý `logging.level.root` À´ÅäÖá£
+
+
+
+
+
+ÏÂÃæµÄÀý×ÓÏÔʾÁË `application.properties` ÖÐDZÔÚµÄÈÕÖ¾ÉèÖá£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+logging.level.root=warn
+logging.level.org.springframework.web=debug
+logging.level.org.hibernate=error
+```
+
+
+
+
+
+
+
+Ò²¿ÉÒÔʹÓû·¾³±äÁ¿À´ÉèÖÃÈÕÖ¾¼¶±ð¡£ ÀýÈ磬`LOGGING_LEVEL_ORG_SPRINGFRAMEWORK_WEB=DEBUG` ½«ÉèÖà `org.springframework.web` Ϊ `DEBUG` ¡£
+
+
+
+
+
+| | ÉÏÊö·½·¨Ö»ÊÊÓÃÓÚ°ü¼¶ÈÕÖ¾¡£ ÓÉÓÚ¿íËɰó¶¨×ÜÊǽ«»·¾³±äÁ¿×ª»»ÎªÐ¡Ð´×Öĸ£¬ËùÒÔ²»¿ÉÄÜÓÃÕâÖÖ·½Ê½Îªµ¥¸öÀàÅäÖÃÈÕÖ¾¡£ Èç¹ûÄãÐèҪΪһ¸öÀàÅäÖÃÈÕÖ¾£¬Äã¿ÉÒÔʹÓÃ[`SPRING_APPLICATION_JSON`](https://springdoc.cn/spring-boot/features.html#features.external-config.application-json)±äÁ¿¡£ |
+| --- | --- |
+
+
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/features.html#features.logging.log-groups)4.6\. ÈÕÖ¾×飨Log Groups£©
+
+
+
+Äܹ»½«Ïà¹ØµÄÈÕÖ¾¼Ç¼Æ÷·Ö×飬ÒÔ±ãͬʱ¶ÔËüÃǽøÐÐÅäÖã¬Õâͨ³£ºÜÓÐÓᣠÀýÈ磬Äã¿ÉÄܾ³£¸Ä±ä _ËùÓÐ_ ÓëTomcatÏà¹ØµÄ¼Ç¼Æ÷µÄ¼Ç¼¼¶±ð£¬µ«Äã²»ÈÝÒ×¼Çס×î¸ß¼¶±ðµÄ°ü¡£
+
+
+
+
+
+ΪÁ˰ïÖú½â¾öÕâ¸öÎÊÌ⣬Spring BootÔÊÐíÄãÔÚSpring `Environment` Öж¨ÒåÈÕÖ¾×é¡£ ÀýÈ磬Äã¿ÉÒÔͨ¹ýÔÚ `application.properties` ÖмÓÈë ¡°tomcat¡± group À´¶¨ÒåËü¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+logging.group.tomcat=org.apache.catalina,org.apache.coyote,org.apache.tomcat
+
+```
+
+
+
+
+
+
+
+Ò»µ©¶¨ÒåºÃºó£¬¾Í¿ÉÒÔÓÃÒ»ÐдúÂëÀ´¸Ä±ä×éÖÐËùÓÐloggerµÄ¼¶±ð¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+logging.level.tomcat=trace
+
+```
+
+
+
+
+
+
+
+Spring Boot°üÀ¨ÒÔÏÂÔ¤¶¨ÒåµÄÈÕÖ¾×飬¿ÉÒÔ¿ªÏä¼´Óá£
+
+
+
+
+| ×éÃû | ×éÖеÄlogger |
+| --- | --- |
+| web | `org.springframework.core.codec`, `org.springframework.http`, `org.springframework.web`, `org.springframework.boot.actuate.endpoint.web`, `org.springframework.boot.web.servlet.ServletContextInitializerBeans` |
+| sql | `org.springframework.jdbc.core`, `org.hibernate.SQL`, `org.jooq.tools.LoggerListener` |
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/features.html#features.logging.shutdown-hook)4.7\. ʹÓÃÈÕÖ¾ Shutdown Hook
+
+
+
+ΪÁËÔÚÄãµÄÓ¦ÓóÌÐòÖÕֹʱÊÍ·ÅÈÕÖ¾×ÊÔ´£¬ÎÒÃÇÌṩÁËÒ»¸öShutdown Hook£¬Ëü½«ÔÚJVMÍ˳öʱ´¥·¢ÈÕ־ϵͳÇåÀí¡£ ³ý·ÇÄãµÄÓ¦ÓóÌÐòÊÇÒÔwarÎļþµÄÐÎʽ²¿ÊðµÄ£¬·ñÔòÕâ¸öShutdown Hook»á×Ô¶¯×¢²á¡£ Èç¹ûÄãµÄÓ¦ÓóÌÐòÓи´ÔÓµÄÉÏÏÂÎIJã´Î½á¹¹£¬Shutdown Hook¿ÉÄÜÎÞ·¨Âú×ãÄãµÄÐèÇó¡£ Èç¹û²»ÄÜ£¬Çë½ûÓùػú¹³×Ó£¬²¢Ñо¿µ×²ãÈÕ־ϵͳֱ½ÓÌṩµÄÑ¡Ïî¡£ ÀýÈ磬LogbackÌṩÁË [context selectors](https://logback.qos.ch/manual/loggingSeparation.html)£¬ÔÊÐíÿ¸ö¼Ç¼Æ÷ÔÚËü×Ô¼ºµÄÉÏÏÂÎÄÖб»´´½¨¡£ Äã¿ÉÒÔʹÓà `logging.register-shutdown-hook` ÊôÐÔÀ´½ûÓÃShutdown Hook¡£ ½«ÆäÉèÖÃΪ `false` ½«½ûÓÃ×¢²á¡£ Äã¿ÉÒÔÔÚÄãµÄ `application.properties` »ò `application.yaml` ÎļþÖÐÉèÖøÃÊôÐÔ¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+logging.register-shutdown-hook=false
+
+```
+
+
+
+
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/features.html#features.logging.custom-log-configuration)4.8\. ×Ô¶¨ÒåÈÕÖ¾ÅäÖÃ
+
+
+
+¸÷ÖÖÈÕ־ϵͳ¿ÉÒÔͨ¹ýÔÚclasspathÉϰüº¬Êʵ±µÄ¿âÀ´¼¤»î£¬²¢ÇÒ¿ÉÒÔͨ¹ýÔÚclasspathµÄ¸ùĿ¼Ï»òÔÚ Spring `Environment` ÊôÐÔÖ¸¶¨µÄλÖÃÌṩһ¸öºÏÊʵÄÅäÖÃÎļþÀ´½øÒ»²½¶¨ÖÆ£º `logging.config`¡£
+
+
+
+
+
+Äú¿ÉÒÔͨ¹ýʹÓà `org.springframework.boot.logging.LoggingSystem` ϵͳÊôÐÔ£¬Ç¿ÖÆSpring BootʹÓÃÌØ¶¨µÄÈÕ־ϵͳ¡£ ¸ÃÖµÓ¦¸ÃÊÇ `LoggingSystem` ʵÏÖµÄÈ«ÀàÃû¡£ ÄãÒ²¿ÉÒÔͨ¹ýʹÓà `none` µÄÖµÀ´ÍêÈ«½ûÓÃSpring BootµÄÈÕÖ¾ÅäÖá£
+
+
+
+
+
+| | SÓÉÓÚÈÕÖ¾ÊÇÔÚ´´½¨ `ApplicationContext` ֮ǰ³õʼ»¯µÄ£¬ËùÒÔ²»¿ÉÄÜ´ÓSpring `@Configuration` ÎļþÖÐµÄ `@PropertySources` ¿ØÖÆÈÕÖ¾¡£ ¸Ä±äÈÕ־ϵͳ»òÍêȫͣÓÃËüµÄΨһ·½·¨ÊÇͨ¹ýSystem properties¡£ |
+| --- | --- |
+
+
+
+
+
+¸ù¾ÝÄãµÄÈÕ־ϵͳ£¬»á¼ÓÔØÒÔÏÂÎļþ¡£
+
+
+
+
+| ÈÕ־ϵͳ | ÅäÖÃÎļþ |
+| --- | --- |
+| Logback | `logback-spring.xml`, `logback-spring.groovy`, `logback.xml` »òÕß `logback.groovy` |
+| Log4j2 | `log4j2-spring.xml` »òÕß `log4j2.xml` |
+| JDK (Java Util Logging) | `logging.properties` |
+
+
+
+| | ÔÚ¿ÉÄܵÄÇé¿öÏ£¬ÎÒÃǽ¨ÒéÄãʹÓà `-spring` ±äÌåÀ´½øÐÐÈÕÖ¾ÅäÖã¨ÀýÈ磬 `logback-spring.xml` ¶ø²»ÊÇ `logback.xml` £©¡£ Èç¹ûÄãʹÓñê×¼ÅäÖÃλÖã¬Spring²»ÄÜÍêÈ«¿ØÖÆÈÕÖ¾³õʼ»¯¡£ |
+| --- | --- |
+
+
+
+
+
+| | µ±´Ó "¿ÉÖ´ÐеÄjar "ÖÐÔËÐÐʱ£¬Java Util LoggingÓÐһЩÒÑÖªµÄÀà¼ÓÔØÎÊÌ⣬»áµ¼ÖÂÎÊÌâ¡£ Èç¹û¿ÉÄܵϰ£¬ÎÒÃǽ¨ÒéÄãÔÚ´Ó "¿ÉÖ´ÐеÄjar" ÖÐÔËÐÐʱ±ÜÃâʹÓÃËü¡£ |
+| --- | --- |
+
+
+
+
+
+ΪÁ˰ïÖú¶¨ÖÆ£¬ÆäËûһЩÊôÐÔ´ÓSpringµÄ `Environment` ×ªÒÆµ½System properties£¬ÈçϱíËùʾ¡£
+
+
+
+| Spring Environment | System Property | ±¸×¢ |
+| --- | --- | --- |
+| `logging.exception-conversion-word` | `LOG_EXCEPTION_CONVERSION_WORD` | ¼Ç¼Ò쳣ʱʹÓõÄת»»´Ê¡£ |
+| `logging.file.name` | `LOG_FILE` | Èç¹û¶¨ÒåÁË£¬Ëü½«ÓÃÓÚĬÈϵÄÈÕÖ¾ÅäÖÃÖС£ |
+| `logging.file.path` | `LOG_PATH` | Èç¹û¶¨ÒåÁË£¬Ëü½«ÓÃÓÚĬÈϵÄÈÕÖ¾ÅäÖÃÖС£ |
+| `logging.pattern.console` | `CONSOLE_LOG_PATTERN` | ÔÚ¿ØÖÆÌ¨£¨stdout£©Ê¹ÓõÄÈÕÖ¾Êä³öģʽ¡£ |
+| `logging.pattern.dateformat` | `LOG_DATEFORMAT_PATTERN` | date ¸ñʽ»¯. |
+| `logging.charset.console` | `CONSOLE_LOG_CHARSET` | ¿ØÖÆÌ¨Êä³öÈÕÖ¾µÄ×Ö·û±àÂë¡£ |
+| `logging.threshold.console` | `CONSOLE_LOG_THRESHOLD` | ÓÃÓÚ¿ØÖÆÌ¨ÈÕÖ¾¼Ç¼µÄÈÕÖ¾¼¶±ð¡£ |
+| `logging.pattern.file` | `FILE_LOG_PATTERN` | ÒªÔÚÎļþÖÐʹÓõÄÈÕ־ģʽ£¨Èç¹û `LOG_FILE` ±»ÆôÓã©¡£ |
+| `logging.charset.file` | `FILE_LOG_CHARSET` | ÎļþÈÕÖ¾µÄ×Ö·û±àÂ루Èç¹û `LOG_FILE` ±»ÆôÓã©¡£ |
+| `logging.threshold.file` | `FILE_LOG_THRESHOLD` | ÓÃÓÚÎļþÈÕÖ¾¼Ç¼µÄÈÕÖ¾¼¶±ð¡£ |
+| `logging.pattern.level` | `LOG_LEVEL_PATTERN` | äÖȾÈÕÖ¾¼¶±ðʱʹÓõĸñʽ£¨Ä¬ÈÏΪ `%5p` £©¡£ |
+| `PID` | `PID` | µ±Ç°µÄ½ø³ÌID |
+
+
+
+Èç¹ûÄãʹÓÃLogback£¬ÒÔÏÂÊôÐÔÒ²»á±»×ªÒÆ¡£
+
+
+
+| Spring Environment | System Property | ±¸×¢ |
+| --- | --- | --- |
+| `logging.logback.rollingpolicy.file-name-pattern` | `LOGBACK_ROLLINGPOLICY_FILE_NAME_PATTERN` | ¹ö¶¯ÈÕÖ¾ÎļþÃûµÄģʽ£¨Ä¬ÈÏΪ `${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz` £©¡£ |
+| `logging.logback.rollingpolicy.clean-history-on-start` | `LOGBACK_ROLLINGPOLICY_CLEAN_HISTORY_ON_START` | ÊÇ·ñÔÚÆô¶¯Ê±ÇåÀí¹éµµÈÕÖ¾Îļþ¡£ |
+| `logging.logback.rollingpolicy.max-file-size` | `LOGBACK_ROLLINGPOLICY_MAX_FILE_SIZE` | ×î´óÈÕÖ¾Îļþ´óС¡£ |
+| `logging.logback.rollingpolicy.total-size-cap` | `LOGBACK_ROLLINGPOLICY_TOTAL_SIZE_CAP` | Òª±£ÁôµÄÈÕÖ¾±¸·ÝµÄ×Ü´óС¡£ |
+| `logging.logback.rollingpolicy.max-history` | `LOGBACK_ROLLINGPOLICY_MAX_HISTORY` | Òª±£ÁôµÄ×î´ó¹éµµÈÕÖ¾ÎļþÊýÁ¿¡£ |
+
+
+
+ËùÓÐÖ§³ÖµÄÈÕ־ϵͳÔÚ½âÎöÆäÅäÖÃÎļþʱ¶¼¿ÉÒÔ´Ó System properties ÖлñÈ¡ÊôÐÔ¡£ Àý×Ó¼û `spring-boot.jar` ÖеÄĬÈÏÅäÖá£
+
+
+
+
+
+* [Logback](https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot/src/main/resources/org/springframework/boot/logging/logback/defaults.xml)
+
+* [Log4j 2](https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot/src/main/resources/org/springframework/boot/logging/log4j2/log4j2.xml)
+
+* [Java Util logging](https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot/src/main/resources/org/springframework/boot/logging/java/logging-file.properties)
+
+
+
+
+
+| | Èç¹ûÄãÏëÔÚÈÕÖ¾ÊôÐÔÖÐʹÓÃռλ·û£¬ÄãÓ¦¸ÃʹÓÃ[Spring BootµÄÓï·¨](https://springdoc.cn/spring-boot/features.html#features.external-config.files.property-placeholders)¶ø²»Êǵײã¿ò¼ÜµÄÓï·¨¡£ ÖµµÃ×¢ÒâµÄÊÇ£¬Èç¹ûÄãʹÓÃLogback£¬ÄãÓ¦¸ÃʹÓà `:` ×÷ΪÊôÐÔÃûºÍÆäĬÈÏÖµÖ®¼äµÄ·Ö¸ô·û£¬¶ø²»ÊÇʹÓà `:-` ¡£ |
+| --- | --- |
+
+
+
+
+
+| | Äã¿ÉÒÔͨ¹ýÖ»¸²¸Ç `LOG_LEVEL_PATTERN` £¨»òʹÓÃLogbackµÄ `logging.pattern.level` £©À´ÏòÈÕÖ¾ÐÐÌí¼ÓMDCºÍÆäËûÁÙʱÄÚÈÝ¡£ ÀýÈ磬Èç¹ûÄãʹÓà `logging.pattern.level=user:%X{user} %5p` £¬ÄÇôĬÈϵÄÈÕÖ¾¸ñʽ°üº¬Ò»¸ö "user" µÄMDCÌõÄ¿£¬Èç¹ûËü´æÔڵϰ£¬ÈçÏÂÀýËùʾ¡£ 2019-08-30 12:30:04.031 user:someone INFO 22174 --- [ nio-8080-exec-0] demo.ControllerHandling authenticated request |
+| --- | --- |
+
+
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/features.html#features.logging.logback-extensions)4.9\. Logback À©Õ¹
+
+
+
+Spring Boot°üÀ¨Ò»Ð©¶ÔLogbackµÄÀ©Õ¹£¬¿ÉÒÔ°ïÖú½øÐи߼¶ÅäÖᣠÄã¿ÉÒÔÔÚÄãµÄ `logback-spring.xml` ÅäÖÃÎļþÖÐʹÓÃÕâЩÀ©Õ¹¡£
+
+
+
+
+
+| | ÒòΪ±ê×¼µÄ `logback.xml` ÅäÖÃÎļþ±»¹ýÔç¼ÓÔØ£¬Äã²»ÄÜÔÚÆäÖÐʹÓÃÀ©Õ¹¡£ ÄãÐèҪʹÓà `logback-spring.xml` »òÕß¶¨ÒåÒ»¸ö `logging.config` ÊôÐÔ¡£ |
+| --- | --- |
+
+
+
+
+
+| | À©Õ¹³ÌÐò²»ÄÜÓë [LogbackµÄÅäÖÃɨÃè](https://logback.qos.ch/manual/configuration.html#autoScan) Ò»ÆðʹÓᣠÈç¹ûÄãÊÔͼÕâÑù×ö£¬¶ÔÅäÖÃÎļþ½øÐÐÐ޸ĻᵼÖÂÀàËÆÓÚÒÔϵĴíÎ󱻼ǼÏÂÀ´¡£ |
+| --- | --- |
+
+
+
+
+
+
+
+ ERROR in ch.qos.logback.core.joran.spi.Interpreter@4:71 - no applicable action for [springProperty], current ElementPath is [[configuration][springProperty]]
+ERROR in ch.qos.logback.core.joran.spi.Interpreter@4:71 - no applicable action for [springProfile], current ElementPath is [[configuration][springProfile]]
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/features.html#features.logging.logback-extensions.profile-specific)4.9.1\. ÌØ¶¨µÄÅäÖÃÎļþ
+
+
+
+`` ±êÇ©ÈÃÄã¿ÉÒÔ¸ù¾Ý»î¶¯µÄSpringÅäÖÃÎļþÑ¡ÔñÐԵذüÀ¨»òÅųýÅäÖõIJ¿·Ö£¬ Ö§³ÖÔÚ `` ÔªËØµÄÈκεط½¶¨ÒåËü¡£ ʹÓà `name` ÊôÐÔÀ´Ö¸¶¨½ÓÊÜÅäÖõÄÅäÖÃÎļþ¡£ `` ±êÇ©¿ÉÒÔ°üº¬Ò»¸öÅäÖÃÎļþÃû³Æ£¨ÀýÈç `staging` £©»òÒ»¸öÅäÖÃÎļþ±í´ïʽ¡£ ÅäÖÃÎļþ±í´ïʽÔÊÐí±í´ï¸ü¸´ÔÓµÄÅäÖÃÎļþÂß¼£¬ÀýÈç `production & (eu-central | eu-west)` ¡£ ²é¿´ [Spring ¿ò¼Ü²Î¿¼Ö¸ÄÏ](https://docs.spring.io/spring-framework/docs/6.0.5/reference/html/core.html#beans-definition-profiles-java) ÒÔÁ˽â¸ü¶àϸ½Ú¡£ ÏÂÃæµÄÁбíÏÔʾÁËÈý¸öÑù±¾ÅäÖÃÎļþ¡£
+
+
+
+
+
+
+
+```
+
+
+
+
+
+
+
+
+
+
+
+```
+
+
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/features.html#features.logging.logback-extensions.environment-properties)4.9.2\. £¨»·¾³ÊôÐÔ£©Environment Properties
+
+
+
+`` ±êÇ©¿ÉÒÔ·ÃÎÊ Spring `Environment` ÖеÄÊôÐÔ£¬ÒÔ±ãÔÚLogbackÖÐʹÓᣠÈç¹ûÄãÏëÔÚLogbackÅäÖÃÖзÃÎÊ `application.properties` ÎļþÖеÄÖµ£¬ÕâÑù×ö»áºÜÓÐÓᣠ¸Ã±êÇ©µÄ¹¤×÷·½Ê½ÓëLogbackµÄ±ê×¼ `` ±êÇ©ÀàËÆ¡£ È»¶ø£¬Äã²»ÊÇÖ±½ÓÖ¸¶¨Ò»¸ö `value` £¬¶øÊÇÖ¸¶¨ÊôÐ﵀ `source` £¨À´×Ô `Environment` £©¡£ Èç¹ûÄãÐèÒªÔÚ `local` ·¶Î§ÒÔÍâµÄµØ·½´æ´¢¸ÃÊôÐÔ£¬Äã¿ÉÒÔʹÓà `scope` ÊôÐÔ¡£ Èç¹ûÄãÐèÒªÒ»¸öºó±¸Öµ£¨Ä¬ÈÏÖµ£©£¨ÍòÒ»¸ÃÊôÐÔûÓÐÔÚ `Environment` ÖÐÉèÖã©£¬Äã¿ÉÒÔʹÓà `defaultValue` ÊôÐÔ¡£ ÏÂÃæµÄÀý×ÓÏÔʾÁËÈçºÎ¹«¿ªÊôÐÔÒÔ±ãÔÚLogbackÖÐʹÓá£
+
+
+
+
+
+
+
+```
+
+
+ ${fluentHost}
+ ...
+
+```
+
+
+
+
+
+
+
+| | `source` ±ØÐëÒÔkebab·ç¸ñÖ¸¶¨£¨Èç `my.property-name` £©¡£ È»¶ø£¬ÊôÐÔ¿ÉÒÔͨ¹ýʹÓÿíËɵĹæÔòÌí¼Óµ½ `Environment` ÖС£ |
+| --- | --- |
+
+
+
+
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/features.html#features.logging.log4j2-extensions)4.10\. Log4j2 À©Õ¹
+
+
+
+Spring Boot°üÀ¨Ò»Ð©¶ÔLog4j2µÄÀ©Õ¹£¬¿ÉÒÔ°ïÖú½øÐи߼¶ÅäÖá£Äã¿ÉÒÔÔÚÈκΠ`log4j2-spring.xml` ÅäÖÃÎļþÖÐʹÓÃÕâЩÀ©Õ¹¡£
+
+
+
+
+
+| | ÒòΪ±ê×¼µÄ `log4j2.xml` ÅäÖÃÎļþ±»¹ýÔç¼ÓÔØ£¬Äã²»ÄÜÔÚÆäÖÐʹÓÃÀ©Õ¹¡£ÄãÐèҪʹÓà `log4j2-spring.xml` »òÕß¶¨ÒåÒ»¸ö ``logging.config`` ÊôÐÔ¡£ |
+| --- | --- |
+
+
+
+
+
+| | ÕâЩÀ©Õ¹È¡´úÁËLog4JÌṩµÄ [Spring BootÖ§³Ö](https://logging.apache.org/log4j/2.x/log4j-spring-boot/index.html)¡£ ÄãÓ¦¸ÃÈ·±£ÔÚÄãµÄ¹¹½¨Öв»°üÀ¨ `org.apache.logging.log4j:log4j-spring-boot` Ä£¿é¡£ |
+| --- | --- |
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/features.html#features.logging.log4j2-extensions.profile-specific)4.10.1\. ÌØ¶¨ÅäÖÃÎļþÅäÖÃ
+
+
+
+`` ±êÇ©ÈÃÄã¿ÉÒÔ¸ù¾Ý»î¶¯µÄSpringÅäÖÃÎļþÑ¡ÔñÐԵذüÀ¨»òÅųýÅäÖõIJ¿·Ö¡£ÅäÖÃÎļþ²¿·Ö±»Ö§³ÖÔÚ `` ÔªËØµÄÈκεط½¡£Ê¹Óà `name` ÊôÐÔÀ´Ö¸¶¨ÄĸöÅäÖÃÎļþ½ÓÊÜÅäÖᣠ`` ±êÇ©¿ÉÒÔ°üº¬Ò»¸öÅäÖÃÎļþÃû³Æ£¨ÀýÈç `staging`£©»òÒ»¸öÅäÖÃÎļþ±í´ïʽ¡£ ÅäÖÃÎļþ±í´ïʽÔÊÐí±í´ï¸ü¸´ÔÓµÄÅäÖÃÎļþÂß¼£¬ÀýÈç `production & (eu-central | eu-west)`¡£²é¿´ [Spring¿ò¼Ü²Î¿¼Ö¸ÄÏ](https://docs.spring.io/spring-framework/docs/6.0.5/reference/html/core.html#beans-definition-profiles-java) ÒÔÁ˽â¸ü¶àϸ½Ú¡£ ÏÂÃæµÄÁбíÏÔʾÁËÈý¸öÑù±¾ÅäÖÃÎļþ¡£
+
+
+
+
+
+
+
+```
+
+
+
+
+
+
+
+
+
+
+
+```
+
+
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/features.html#features.logging.log4j2-extensions.environment-properties-lookup)4.10.2\. »·¾³£¨Environment£©ÊôÐÔ²éÕÒ
+
+
+
+Èç¹ûÄãÏëÔÚLog4j2ÅäÖÃÖÐÒýÓÃSpring `Environment` ÖеÄÊôÐÔ£¬Äã¿ÉÒÔʹÓà `spring:` ǰ׺ [²éÕÒ](https://logging.apache.org/log4j/2.x/manual/lookups.html)¡£Èç¹ûÄãÏëÔÚLog4j2ÅäÖÃÖзÃÎÊ `application.properties` ÎļþÖеÄÖµ£¬ÕâÑù×ö»áºÜÓÐÓá£
+
+
+
+
+
+ÏÂÃæµÄÀý×ÓÏÔʾÁËÈçºÎÉèÖÃÒ»¸öÃûΪ `applicationName` µÄLog4j2ÊôÐÔ£¬Ëü´ÓSpring `Environment` ÖжÁÈ¡ `spring.application.name`¡£
+
+
+
+
+
+
+
+```
+
+ ${spring:spring.application.name}
+
+```
+
+
+
+
+
+
+
+| | ²éѯkeyÓ¦ÒÔkebabf·ç¸ñÖ¸¶¨£¨Èç `my.property-name`£©¡£ |
+| --- | --- |
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/features.html#features.logging.log4j2-extensions.environment-property-source)4.10.3\. Log4j2 ϵͳÊôÐÔ£¨System Properties£©
+
+
+
+Log4j2Ö§³ÖһЩ [System Properties](https://logging.apache.org/log4j/2.x/manual/configuration.html#SystemProperties)£¬¿ÉÒÔÓÃÀ´ÅäÖø÷ÖÖÏîÄ¿¡£ÀýÈ磬`log4j2.skipJansi` ϵͳÊôÐÔ¿ÉÒÔÓÃÀ´ÅäÖà `ConsoleAppender` ÊÇ·ñ»áÔÚWindowsÉϳ¢ÊÔʹÓà [Jansi](https://github.com/fusesource/jansi) Êä³öÁ÷¡£
+
+
+
+
+
+Log4j2 ³õʼ»¯ºó¼ÓÔØµÄËùÓÐϵͳÊôÐÔ¶¼¿ÉÒÔ´ÓSpring `Environment` ÖлñµÃ¡£ÀýÈ磬Äã¿ÉÒÔÔÚ `application.properties` ÎļþÖÐÌí¼Ó `log4j2.skipJansi=false`£¬Èà `ConsoleAppender` ÔÚWindowsÉÏʹÓÃJansi¡£
+
+
+
+
+
+| | Ö»Óе±ÏµÍ³ÊôÐÔ£¨system properties£©ºÍ²Ù×÷ϵͳ»·¾³±äÁ¿²»°üº¬ÕýÔÚ¼ÓÔØµÄֵʱ£¬²Å»á¿¼ÂÇSpring `Environment`¡£ |
+| --- | --- |
+
+
+
+
+
+| | ÔÚÔçÆÚLog4j2³õʼ»¯ÆÚ¼ä¼ÓÔØµÄϵͳÊôÐÔ²»ÄÜÒýÓÃSpring `Environment`¡£ÀýÈ磬Log4j2ÓÃÓÚÔÊÐíÑ¡ÔñĬÈÏLog4j2ʵÏÖµÄÊôÐÔÊÇÔÚ Spring Environment ¿ÉÓÃ֮ǰʹÓõġ£ |
+| --- | --- |
+
+
+
+
+
+
+
diff --git "a/docs/spring/SpringBoot/SpringBoot\345\272\224\347\224\250\344\271\237\345\217\257\344\273\245\351\203\250\347\275\262\345\210\260\345\244\226\351\203\250Tomcat.md" "b/docs/spring/SpringBoot/SpringBoot\345\272\224\347\224\250\344\271\237\345\217\257\344\273\245\351\203\250\347\275\262\345\210\260\345\244\226\351\203\250Tomcat.md"
new file mode 100644
index 0000000..e22fa00
--- /dev/null
+++ "b/docs/spring/SpringBoot/SpringBoot\345\272\224\347\224\250\344\271\237\345\217\257\344\273\245\351\203\250\347\275\262\345\210\260\345\244\226\351\203\250Tomcat.md"
@@ -0,0 +1,302 @@
+
+
+
+
+# Spring Boot Tomcat²¿Êð
+
+ÒÔÏÂÄÚÈݽöÊÇÕ¾³¤»òÍøÓѸöÈËѧϰ±Ê¼Ç¡¢×ܽáºÍÑо¿Êղء£²»±£Ö¤ÕýÈ·ÐÔ£¬ÒòʹÓöø´øÀ´µÄ·çÏÕÓë±¾Õ¾Î޹أ¡
+
+
+
+
+
+
+
+
+
+ͨ¹ýʹÓÃSpring BootÓ¦ÓóÌÐò£¬¿ÉÒÔ´´½¨Ò»¸öwarÎļþÒÔ²¿Êðµ½Web·þÎñÆ÷ÖС£ÔÚ±¾ÕÂÖУ¬½«Ñ§Ï°ÈçºÎ´´½¨WARÎļþ²¢ÔÚTomcat Web·þÎñÆ÷Öв¿ÊðSpring BootÓ¦ÓóÌÐò¡£
+
+## Spring Boot Servlet³õʼ»¯³ÌÐò
+
+´«Í³µÄ²¿Êð·½Ê½ÊÇʹSpring BootÓ¦ÓóÌÐò`[@SpringBootApplication](https://github.com/SpringBootApplication "@SpringBootApplication")`ÀàÀ©Õ¹`SpringBootServletInitializer`Àà¡£ `SpringBootServletInitializer`ÀàÎļþÔÊÐíÔÚʹÓÃServletÈÝÆ÷Æô¶¯Ê±ÅäÖÃÓ¦ÓóÌÐò¡£
+
+ÏÂÃæ¸ø³öÁËÓÃÓÚJARÎļþ²¿ÊðµÄSpring BootÓ¦ÓóÌÐòÀàÎļþµÄ´úÂë -
+
+```
+package com.yiibai.demo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class DemoApplication {
+ public static void main(String[] args) {
+ SpringApplication.run(DemoApplication.class, args);
+ }
+}
+
+```
+
+ÐèÒªÀ©Õ¹Àà`SpringBootServletInitializer`ÒÔÖ§³ÖWARÎļþ²¿Êð¡£ Spring BootÓ¦ÓóÌÐòÀàÎļþµÄ´úÂëÈçÏ -
+
+```
+package com.yiibai.demo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.support.SpringBootServletInitializer;
+
+@SpringBootApplication
+public class DemoApplication extends SpringBootServletInitializer {
+ @Override
+ protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
+ return application.sources(DemoApplication.class);
+ }
+ public static void main(String[] args) {
+ SpringApplication.run(DemoApplication.class, args);
+ }
+}
+
+```
+
+## ÉèÖÃMainÀà
+
+ÔÚSpring BootÖУ¬ÐèÒªÔÚ¹¹½¨ÎļþÖÐÖ¸¶¨Æô¶¯µÄÖ÷Àà¡£
+¶ÔÓÚMaven£¬ÔÚ`pom.xml`ÊôÐÔÖÐÌí¼Ó`start`À࣬ÈçÏÂËùʾ -
+
+```
+com.yiibai.demo.DemoApplication
+
+```
+
+¶ÔÓÚGradle£¬ÔÚ`build.gradle`ÖÐÌí¼ÓÖ÷ÀàÃû£¬ÈçÏÂËùʾ -
+
+```
+mainClassName="com.yiibai.demo.DemoApplication"
+
+```
+
+## ½«´ò°üJAR¸üÐÂΪWAR
+
+ʹÓÃÒÔÏ´úÂ뽫°ü×°JAR¸üÐÂΪWAR¡£
+
+¶ÔÓÚMaven£¬ÔÚ_pom.xml_ Öн«°ü×°Ìí¼ÓΪWAR£¬ÈçÏÂËùʾ -
+
+```
+war
+
+```
+
+¶ÔÓÚGradle£¬ÔÚ_build.gradle_ ÖÐÌí¼ÓÓ¦ÓóÌÐò²å¼þºÍwar²å¼þ£¬ÈçÏÂËùʾ -
+
+```
+apply plugin: 'war'
+apply plugin: 'application'
+
+```
+
+¶ÔÓÚGradlNow£¬±àдһ¸ö¼òµ¥µÄRest¶ËµãÀ´·µ»Ø×Ö·û´®:`"Hello World from Tomcat"`¡£ Òª±àдRest¶Ëµã£¬ÐèÒª½«Spring Boot Web starterÒÀÀµÏîÌí¼Óµ½¹¹½¨ÎļþÖС£
+
+¶ÔÓÚMaven£¬Ê¹ÓÃÈçÏÂËùʾµÄ´úÂëÔÚ_pom.xml_ ÖÐÌí¼ÓSpring BootÆô¶¯³ÌÐòÒÀÀµÏî -
+
+```
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+```
+
+¶ÔÓÚGradle£¬Ê¹ÓÃÈçÏÂËùʾµÄ´úÂëÔÚ_build.gradle_ ÖÐÌí¼ÓSpring Boot starterÒÀÀµÏî -
+
+```
+dependencies {
+ compile('org.springframework.boot:spring-boot-starter-web')
+}
+
+```
+
+ÏÖÔÚ£¬Ê¹ÓÃÈçÏÂËùʾµÄ´úÂëÔÚSpring Boot ApplicationÀàÎļþÖбàдһ¸ö¼òµ¥µÄRest¶Ëµã -
+
+```
+package com.yiibai.demo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.support.SpringBootServletInitializer;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@SpringBootApplication
+@RestController
+public class DemoApplication extends SpringBootServletInitializer {
+ @Override
+ protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
+ return application.sources(DemoApplication.class);
+ }
+ public static void main(String[] args) {
+ SpringApplication.run(DemoApplication.class, args);
+ }
+
+ @RequestMapping(value = "/")
+ public String hello() {
+ return "Hello World from Tomcat";
+ }
+}
+
+```
+
+## ´ò°üÓ¦ÓóÌÐò
+
+ÏÖÔÚ£¬Ê¹ÓÃMavenºÍGradleÃüÁî´´½¨Ò»¸öWARÎļþÒÔ²¿Êðµ½Tomcat·þÎñÆ÷ÖУ¬ÒÔ´ò°üÓ¦ÓóÌÐò£¬ÈçÏÂËùʾ¡£
+
+¶ÔÓÚMaven£¬Ê¹ÓÃÃüÁî`mvn package`´ò°üÓ¦ÓóÌÐò¡£ È»ºó´´½¨WARÎļþ£¬¿ÉÒÔÔÚÄ¿±êĿ¼ÖÐÕÒµ½Ëü£¬ÈçÏÂÃæ¸ø³öµÄÆÁÄ»½ØÍ¼Ëùʾ -
+
+
+
+¶ÔÓÚGradle£¬Ê¹ÓÃÃüÁî`gradle clean build`´ò°üÓ¦ÓóÌÐò¡£ È»ºó£¬½«´´½¨WARÎļþ£¬¿ÉÒÔÔÚ`build/libs`Ŀ¼ÏÂÕÒµ½Ëü¡£¹Û²ì´Ë´¦¸ø³öµÄÆÁÄ»½ØÍ¼ÒÔ±ã¸üºÃµØÀí½â -
+
+
+
+## ²¿Êðµ½Tomcat
+
+ÏÖÔÚ£¬ÔËÐÐTomcat·þÎñÆ÷£¬²¢ÔÚwebappsĿ¼Ï²¿ÊðWARÎļþ¡£¹Û²ì´Ë´¦ÏÔʾµÄÆÁÄ»½ØÍ¼ÒÔ±ã¸üºÃµØÀí½â -
+
+
+
+³É¹¦²¿Êðºó£¬µã»÷ÍøÒ³ä¯ÀÀÆ÷ÖеÄURL => `http://localhost:8080/demo-0.0.1-SNAPSHOT/`£¬¹Û²ìÊä³ö½á¹ûÈçÏÂͼËùʾ -
+
+
+
+ÍêÕû´úÂëÈçÏ£º
+
+Îļþ£º_pom.xml_ -
+
+```
+
+
+4.0.0
+
+ com.yiibai
+ demo
+ 0.0.1-SNAPSHOT
+ war
+ demo
+ Demo project for Spring Boot
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 1.5.8.RELEASE
+
+
+
+
+ UTF-8
+ UTF-8
+ 1.8
+ com.yiibai.demo.DemoApplication
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
+```
+
+Îļþ£º_build.gradle_
+
+```
+buildscript {
+ ext {
+ springBootVersion = '1.5.8.RELEASE'
+ }
+ repositories {
+ mavenCentral()
+ }
+dependencies {
+ classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
+ }
+}
+
+apply plugin: 'java'
+apply plugin: 'eclipse'
+apply plugin: 'org.springframework.boot'
+apply plugin: 'war'
+apply plugin: 'application'
+
+group = 'com.yiibai'
+version = '0.0.1-SNAPSHOT'
+sourceCompatibility = 1.8
+mainClassName = "com.yiibai.demo.DemoApplication"
+
+repositories {
+ mavenCentral()
+}
+dependencies {
+ compile('org.springframework.boot:spring-boot-starter-web')
+ testCompile('org.springframework.boot:spring-boot-starter-test')
+}
+
+```
+
+Spring BootÓ¦ÓóÌÐòÀàÎļþµÄ´úÂëÈçÏ -
+
+```
+package com.yiibai.demo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.support.SpringBootServletInitializer;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@SpringBootApplication
+@RestController
+public class DemoApplication extends SpringBootServletInitializer {
+ @Override
+ protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
+ return application.sources(DemoApplication.class);
+ }
+ public static void main(String[] args) {
+ SpringApplication.run(DemoApplication.class, args);
+ }
+
+ @RequestMapping(value = "/")
+ public String hello() {
+ return "Hello World from Tomcat";
+ }
+}
+```
+
+
+
+
+
+//¸ü¶àÇëÔĶÁ£ºhttps://www.yiibai.com/spring-boot/spring_boot_tomcat_deployment.html
+
diff --git "a/docs/spring/SpringBoot/SpringBoot\347\224\237\344\272\247\347\216\257\345\242\203\345\267\245\345\205\267Actuator.md" "b/docs/spring/SpringBoot/SpringBoot\347\224\237\344\272\247\347\216\257\345\242\203\345\267\245\345\205\267Actuator.md"
new file mode 100644
index 0000000..e0eeb3e
--- /dev/null
+++ "b/docs/spring/SpringBoot/SpringBoot\347\224\237\344\272\247\347\216\257\345\242\203\345\267\245\345\205\267Actuator.md"
@@ -0,0 +1,5832 @@
+
+
+# Éú²ú¾ÍÐ÷¹¦ÄÜ
+
+[Back to index](https://springdoc.cn/spring-boot/index.html)
+
+* [1\. ÆôÓÃÉú²ú¾ÍÐ÷µÄ¹¦ÄÜ](https://springdoc.cn/spring-boot/actuator.html#actuator.enabling)
+* [2\. ¶Ëµã£¨Endpoint£©](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints)
+* [3\. ͨ¹ýHTTP½øÐÐ¼à¿ØºÍ¹ÜÀí](https://springdoc.cn/spring-boot/actuator.html#actuator.monitoring)
+* [4\. ͨ¹ýJMX½øÐÐ¼à¿ØºÍ¹ÜÀí](https://springdoc.cn/spring-boot/actuator.html#actuator.jmx)
+* [5\. ¿É¹Û²âÐÔ£¨Observability£©](https://springdoc.cn/spring-boot/actuator.html#actuator.observability)
+* [6\. ÈÕÖ¾¼Ç¼Æ÷£¨Logger£©](https://springdoc.cn/spring-boot/actuator.html#actuator.loggers)
+* [7\. Ö¸±ê£¨Metrics£©](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics)
+* [8\. ×·×Ù£¨Tracing£©](https://springdoc.cn/spring-boot/actuator.html#actuator.micrometer-tracing)
+* [9\. Éó¼Æ](https://springdoc.cn/spring-boot/actuator.html#actuator.auditing)
+* [10\. ¼Ç¼ HTTP Exchange](https://springdoc.cn/spring-boot/actuator.html#actuator.http-exchanges)
+* [11\. ½ø³Ì¼à¿Ø](https://springdoc.cn/spring-boot/actuator.html#actuator.process-monitoring)
+* [12\. Cloud Foundry µÄÖ§³Ö](https://springdoc.cn/spring-boot/actuator.html#actuator.cloud-foundry)
+* [13\. ½ÓÏÂÀ´¶Áʲô](https://springdoc.cn/spring-boot/actuator.html#actuator.whats-next)
+
+
+
+
+
+
+
+
+
+
+
+
+
+| | ±¾Õ¾([springdoc.cn](https://springdoc.cn/))ÖеÄÄÚÈÝÀ´Ô´ÓÚ [spring.io](https://spring.io/) £¬Ôʼ°æÈ¨¹éÊôÓÚ [spring.io](https://spring.io/)¡£ÓÉ [springboot.io - Spring BootÖÐÎÄÉçÇø](https://springboot.io/) ½øÐзÒ룬ÕûÀí¡£¿É¹©¸öÈËѧϰ¡¢Ñо¿£¬Î´¾Ðí¿É£¬²»µÃ½øÐÐÈκÎ×ªÔØ¡¢ÉÌÓûòÓëÖ®Ïà¹ØµÄÐÐΪ¡£ É̱êÉùÃ÷£ºSpring ÊÇ Pivotal Software, Inc. ÔÚÃÀ¹úÒÔ¼°ÆäËû¹ú¼ÒµÄÉ̱ꡣ |
+| --- | --- |
+
+
+
+
+
+Spring Boot°üÀ¨Ò»Ð©¶îÍâµÄ¹¦ÄÜ£¬ÒÔ°ïÖúÄãÔÚ½«Ó¦ÓóÌÐò·¢²¼µ½Éú²úʱ¼à¿ØºÍ¹ÜÀíÄãµÄÓ¦ÓóÌÐò¡£ Äã¿ÉÒÔÑ¡Ôñͨ¹ýʹÓÃHTTP¶Ëµã»òʹÓÃJMXÀ´¹ÜÀíºÍ¼à¿ØÄãµÄÓ¦ÓóÌÐò¡£ É󼯡¢½¡¿µºÍÖ¸±êÊÕ¼¯Ò²¿ÉÒÔ×Ô¶¯Ó¦ÓÃÓÚÄãµÄÓ¦ÓóÌÐò¡£
+
+
+
+
+
+
+
+
+
+## [](https://springdoc.cn/spring-boot/actuator.html#actuator.enabling)1\. ÆôÓÃÉú²ú¾ÍÐ÷µÄ¹¦ÄÜ
+
+
+
+
+
+[`spring-boot-actuator`](https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot-actuator) Ä£¿éÌṩÁËËùÓÐSpring BootµÄÉú²ú¾ÍÐ÷¹¦ÄÜ¡£ ÆôÓÃÕâЩ¹¦ÄܵÄÍÆ¼ö·½·¨ÊÇÌí¼Ó¶Ô `spring-boot-starter-actuator` ¡°Starter¡± µÄÒÀÀµ¡£
+
+
+
+
+
+
+
+ActuatorµÄ¶¨Òå
+
+
+
+actuator£¨Ö´ÐÐÆ÷£© ÊÇÒ»¸öÖÆÔìÊõÓָµÄÊÇÓÃÓÚÒÆ¶¯»ò¿ØÖÆÄ³ÎïµÄ»úеװÖá£actuator ¿ÉÒÔ´ÓÒ»¸öСµÄ±ä»¯ÖвúÉú´óÁ¿µÄÔ˶¯¡£
+
+
+
+
+
+
+
+
+
+ÒªÔÚ»ùÓÚMavenµÄÏîÄ¿ÖÐÌí¼Óactuator£¬ÇëÌí¼ÓÒÔÏ ¡°Starter¡± ÒÀÀµ¡£
+
+
+
+
+
+
+
+```
+
+
+ org.springframework.boot
+ spring-boot-starter-actuator
+
+
+```
+
+
+
+
+
+
+
+¶ÔÓÚGradle£¬Ê¹ÓÃÒÔÏÂÉùÃ÷¡£
+
+
+
+
+
+
+
+```
+dependencies {
+ implementation 'org.springframework.boot:spring-boot-starter-actuator'
+}
+```
+
+
+
+
+
+
+
+
+
+
+
+## [](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints)2\. ¶Ëµã£¨Endpoint£©
+
+
+
+
+
+Actuator ¶Ëµã£¨endpoint£©ÈÃÄã¿ÉÒÔ¼à¿Ø²¢ÓëÄãµÄÓ¦ÓóÌÐò»¥¶¯¡£ Spring Boot°üÀ¨Ò»Ð©ÄÚÖõĶ˵㣬²¢ÔÊÐíÄãÌí¼Ó×Ô¼ºµÄ¶Ëµã¡£ ÀýÈ磬`health` ¶ËµãÌṩ»ù±¾µÄÓ¦ÓóÌÐò½¡¿µÐÅÏ¢¡£
+
+
+
+
+
+Äã¿ÉÒÔ[ÆôÓûò½ûÓÃ](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.enabling)ÿ¸öµ¥¶ÀµÄ¶Ëµã£¬²¢[ͨ¹ýHTTP»òJMX¹«¿ªËüÃÇ£¨Ê¹ËüÃÇ¿ÉÒÔÔ¶³Ì·ÃÎÊ£©](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.exposing)¡£µ±Ò»¸ö¶Ëµã±»ÆôÓúͱ©Â¶Ê±£¬Ëü±»ÈÏΪÊÇ¿ÉÓõġ£ÄÚÖõĶ˵ãÖ»ÓÐÔÚËüÃÇ¿ÉÓÃʱ²Å»á±»×Ô¶¯ÅäÖᣴó¶àÊýÓ¦ÓóÌÐòÑ¡Ôñͨ¹ýHTTP±©Â¶£¬ÆäÖж˵ãµÄIDºÍ `/actuator` µÄǰ׺±»Ó³Éäµ½Ò»¸öURL¡£ÀýÈ磬ĬÈÏÇé¿öÏ£¬`health` ¶Ëµã±»Ó³Éäµ½ `/actuator/health`¡£
+
+
+
+
+
+| | ÒªÁ˽â¸ü¶à¹ØÓÚactuatorµÄ¶ËµãÒÔ¼°ËüÃǵÄÇëÇóºÍÏìÓ¦¸ñʽ£¬Çë¿´µ¥¶ÀµÄAPIÎĵµ£¨ [HTML](https://docs.spring.io/spring-boot/docs/3.1.0-SNAPSHOT/actuator-api/htmlsingle) »ò [PDF](https://docs.spring.io/spring-boot/docs/3.1.0-SNAPSHOT/actuator-api/pdf/spring-boot-actuator-web-api.pdf)£©¡£ |
+| --- | --- |
+
+
+
+
+
+ÒÔÏÂÊǼ¼ÊõÎ޹صÄÖÕ¶Ë¡£
+
+
+
+
+| ID | ˵Ã÷ |
+| --- | --- |
+| `auditevents` | ¹«¿ªµ±Ç°Ó¦ÓóÌÐòµÄÉó¼ÆÊ¼þÐÅÏ¢¡£ ÐèÒªÒ»¸ö `AuditEventRepository` bean¡£ |
+| `beans` | ÏÔʾÄãµÄÓ¦ÓóÌÐòÖÐËùÓÐSpring BeanµÄÍêÕûÁÐ±í¡£ |
+| `caches` | ÏÔʾ¿ÉÓõĻº´æ¡£ |
+| `conditions` | ÏÔʾ¶ÔÅäÖúÍ×Ô¶¯ÅäÖÃÀà½øÐÐÆÀ¹ÀµÄÌõ¼þ£¬ÒÔ¼°ËüÃÇ·ûºÏ»ò²»·ûºÏµÄÔÒò¡£ |
+| `configprops` | ÏÔʾËùÓÐ `@ConfigurationProperties` µÄÕûÀíÁÐ±í¡£ |
+| `env` | ±©Â¶SpringµÄ `ConfigurableEnvironment` ÖеÄÊôÐÔ¡£ |
+| `flyway` | ÏÔʾÈκÎÒѾӦÓõÄFlywayÊý¾Ý¿âÇ¨ÒÆ¡£ ÐèÒªÒ»¸ö»ò¶à¸ö `Flyway` bean¡£ |
+| `health` | ÏÔʾӦÓóÌÐòµÄ½¡¿µÐÅÏ¢¡£ |
+| `httpexchanges` | ÏÔʾ HTTP exchange ÐÅÏ¢£¨Ä¬ÈÏÇé¿öÏ£¬×îºó 100 ¸ö HTTP request/response exchange£©¡£ ÐèÒªÒ»¸ö `HttpExchangeRepository` bean¡£ |
+| `info` | ÏÔʾÈÎÒâµÄÓ¦ÓóÌÐòÐÅÏ¢¡£ |
+| `integrationgraph` | ÏÔʾSpring¼¯³Éͼ¡£ ÐèÒªÒÀÀµ `spring-integration-core`¡£ |
+| `loggers` | ÏÔʾºÍÐÞ¸ÄÓ¦ÓóÌÐòÖÐloggerµÄÅäÖᣠ|
+| `liquibase` | ÏÔʾÈκÎÒѾӦÓõÄLiquibaseÊý¾Ý¿âÇ¨ÒÆ¡£ ÐèÒªÒ»¸ö»ò¶à¸ö `Liquibase` Bean¡£ |
+| `metrics` | ÏÔʾµ±Ç°Ó¦ÓóÌÐòµÄ ¡°metrics¡± ÐÅÏ¢¡£ |
+| `mappings` | ÏÔʾËùÓÐ `@RequestMapping` ·¾¶µÄÕûÀíÁÐ±í¡£ |
+| `quartz` | ÏÔʾÓйØQuartz Scheduler JobµÄÐÅÏ¢¡£ |
+| `scheduledtasks` | ÏÔʾÄãµÄÓ¦ÓóÌÐòÖеļƻ®ÈÎÎñ¡£ |
+| `sessions` | ÔÊÐí´ÓSpring SessionÖ§³ÖµÄ»á»°´æ´¢ÖмìË÷ºÍɾ³ýÓû§»á»°¡£ ÐèÒªÒ»¸öʹÓÃSpring SessionµÄ»ùÓÚServletµÄWebÓ¦ÓóÌÐò¡£ |
+| `shutdown` | ÈÃÓ¦ÓóÌÐòÓÅÑŵعرա£Ö»ÔÚʹÓÃjar´ò°üʱÓÐЧ¡£Ä¬ÈÏÇé¿öÏÂÊǽûÓõġ£ |
+| `startup` | ÏÔʾÓÉ `ApplicationStartup` ÊÕ¼¯µÄ[Æô¶¯²½ÖèÊý¾Ý](https://springdoc.cn/spring-boot/features.html#features.spring-application.startup-tracking)¡£ÒªÇó `SpringApplication` ±»ÅäÖÃΪ `BufferingApplicationStartup`¡£ |
+| `threaddump` | Performs a thread dump. |
+
+
+
+Èç¹ûÄãµÄÓ¦ÓóÌÐòÊÇÒ»¸öWebÓ¦ÓóÌÐò£¨Spring MVC¡¢Spring WebFlux»òJersey£©£¬Äã¿ÉÒÔʹÓÃÒÔ϶îÍâµÄ¶Ëµã¡£
+
+
+
+
+| ID | ˵Ã÷ |
+| --- | --- |
+| `heapdump` | ·µ»ØÒ»¸ö¶ÑdumpÎļþ¡£ ÔÚHotSpot JVMÉÏ£¬·µ»ØÒ»¸ö `HPROF` ¸ñʽµÄÎļþ¡£ ÔÚOpenJ9 JVMÉÏ£¬·µ»ØÒ»¸ö `PHD` ¸ñʽµÄÎļþ¡£ |
+| `logfile` | ·µ»ØÈÕÖ¾ÎļþµÄÄÚÈÝ£¨Èç¹û `logging.file.name` »ò `logging.file.path` ÊôÐÔÒѱ»ÉèÖã©¡£ Ö§³ÖʹÓÃHTTP `Range` Í·À´¼ìË÷ÈÕÖ¾ÎļþµÄ²¿·ÖÄÚÈÝ¡£ |
+| `prometheus` | ÒԿɱ» Prometheus ·þÎñÆ÷ץȡµÄ¸ñʽչʾ¶ÈÁ¿£¨metric£©¡£ ÒÀÀµÓÚ `micrometer-registry-prometheus`¡£ |
+
+
+
+### [](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.enabling)2.1\. ÆôÓö˵ã
+
+
+
+ĬÈÏÇé¿öÏ£¬³ý `shutdown` ÍâµÄËùÓж˵㶼±»ÆôÓᣠҪÅäÖÃÒ»¸ö¶ËµãµÄÆôÓã¬ÇëʹÓÃÆä `management.endpoint..enabled` ÊôÐÔ¡£ ÏÂÃæµÄÀý×ÓÆôÓÃÁË `shutdown` ¶Ëµã¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.endpoint.shutdown.enabled=true
+
+```
+
+
+
+
+
+
+
+Èç¹ûÄãÏ£Íû¶ËµãÆôÓÃÊÇ¡°Ñ¡ÔñÆôÓá±¶ø²»ÊÇ¡°Ñ¡Ôñ½ûÓá±£¬Ç뽫 `management.endpoints.enabled-by-default` ÊôÐÔÉèÖÃΪ `false`£¬²¢Ê¹Óõ¥¸ö¶ËµãµÄ `enabled` ÊôÐÔÀ´Ñ¡ÔñÖØÐÂÆôÓᣠÏÂÃæµÄÀý×ÓÆôÓÃÁË `info` ¶Ëµã£¬²¢½ûÓÃÁËËùÓÐÆäËû¶Ëµã¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.endpoints.enabled-by-default=false
+management.endpoint.info.enabled=true
+
+```
+
+
+
+
+
+
+
+| | ±»½ûÓõĶ˵ã»á´ÓÓ¦ÓóÌÐòÉÏÏÂÎÄÖÐÍêȫɾ³ý¡£Èç¹ûÄãÏëÖ»¸Ä±ä±©Â¶¶ËµãµÄ¼¼Êõ£¬ÇëʹÓà [`include` ºÍ `exclude` ÊôÐÔ](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.exposing)À´´úÌæ¡£ |
+| --- | --- |
+
+
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.exposing)2.2\. ±©Â¶¶Ëµã
+
+
+
+ĬÈÏÇé¿öÏ£¬Ö»ÓÐhealth¶ËµãÊÇͨ¹ýHTTPºÍJMX±©Â¶µÄ¡£ ÓÉÓڶ˵ã¿ÉÄܰüº¬Ãô¸ÐÐÅÏ¢£¬ÄãÓ¦¸Ã×Ðϸ¿¼ÂǺÎʱ±©Â¶ËüÃÇ¡£
+
+
+
+
+
+Òª¸Ä±äÄÄЩ¶Ëµã±»±©Â¶£¬ÇëʹÓÃÒÔÏÂÌØ¶¨¼¼ÊõµÄ `include` ºÍ `exclude` ÊôÐÔ¡£
+
+
+
+
+| ÊôÐÔ | ĬÈÏ |
+| --- | --- |
+| `management.endpoints.jmx.exposure.exclude` | |
+| `management.endpoints.jmx.exposure.include` | `health` |
+| `management.endpoints.web.exposure.exclude` | |
+| `management.endpoints.web.exposure.include` | `health` |
+
+
+
+`include` ÊôÐÔÁгöÁ˱»±©Â¶µÄ¶ËµãµÄID¡£ `exclude` ÊôÐÔÁгöÁ˲»Ó¦¸Ã±»¹«¿ªµÄ¶ËµãµÄID¡£ `exclude` ÊôÐÔÓÅÏÈÓÚ `include` ÊôÐÔ¡£ Äã¿ÉÒÔÓÃÒ»¸ö¶ËµãIDÁбíÀ´ÅäÖà `include` ºÍ `exclude` ÊôÐÔ¡£
+
+
+
+
+
+ÀýÈ磬Ҫͨ¹ýJMXÖ»¹«¿ª `health` ºÍ `info` ¶Ëµã£¬ÇëʹÓÃÒÔÏÂÊôÐÔ¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.endpoints.jmx.exposure.include=health,info
+
+```
+
+
+
+
+
+
+
+`*` ¿ÉÒÔÓÃÀ´Ñ¡ÔñËùÓж˵㡣 ÀýÈ磬Ҫͨ¹ýHTTP¹«¿ªËùÓеĶ«Î÷£¬³ýÁË `env` ºÍ `beans` ¶Ëµã£¬Ê¹ÓÃÒÔÏÂÊôÐÔ¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.endpoints.web.exposure.include=*
+management.endpoints.web.exposure.exclude=env,beans
+
+```
+
+
+
+
+
+
+
+| | `*` ÔÚYAMLÖоßÓÐÌØÊ⺬Ò壬ËùÒÔÈç¹ûÄãÏë°üÀ¨£¨»òÅųý£©ËùÓеĶ˵㣬һ¶¨Òª¼ÓÒýºÅ¡£ |
+| --- | --- |
+
+
+
+
+
+| | Èç¹ûÄãµÄÓ¦ÓóÌÐòÊǹ«¿ª±©Â¶µÄ£¬ÎÒÃÇÇ¿ÁÒ½¨ÒéÄãÒ²[±£»¤ÄãµÄ¶Ëµã](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.security)¡£ |
+| --- | --- |
+
+
+
+
+
+| | Èç¹ûÄãÏëÔڶ˵㱩¶ʱʵʩ×Ô¼ºµÄ²ßÂÔ£¬Äã¿ÉÒÔ×¢²áÒ»¸ö `EndpointFilter` bean¡£ |
+| --- | --- |
+
+
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.security)2.3\. °²È«£¨Security£©
+
+
+
+ΪÁ˰²È«Æð¼û£¬Ä¬ÈÏÇé¿öÏÂÖ»ÓÐ `/health` ¶Ëµãͨ¹ýHTTP¹«¿ª¡£ Äã¿ÉÒÔʹÓà `management.endpoints.web.exposure.include` ÊôÐÔÀ´ÅäÖñ»±©Â¶µÄ¶Ëµã¡£
+
+
+
+
+
+| | ÔÚÉèÖà `management.endpoints.web.exposure.include` ֮ǰ£¬ÇëÈ·±£±©Â¶µÄÖ´ÐÐÆ÷²»°üº¬Ãô¸ÐÐÅÏ¢£¬½«ÆäÖÃÓÚ·À»ðǽ֮ºó£¬»òÓÉSpring SecurityÖ®ÀàµÄ¶«Î÷À´±£Ö¤°²È«¡£ |
+| --- | --- |
+
+
+
+
+
+Èç¹ûSpring SecurityÔÚclasspathÉÏ£¬²¢ÇÒûÓÐÆäËû `SecurityFilterChain` bean£¬ÄÇô³ýÁË `/health` Ö®ÍâµÄËùÓÐÖ´ÐÐÆ÷£¨actuator£©¶¼ÓÉSpring Boot×Ô¶¯ÅäÖÃÀ´±£Ö¤°²È«¡£ Èç¹ûÄ㶨ÒåÁËÒ»¸ö×Ô¶¨ÒåµÄ `SecurityFilterChain` bean£¬Spring Boot×Ô¶¯ÅäÖþͻáÍËËõ£¬ÈÃÄãÍêÈ«¿ØÖÆÖ´ÐÐÆ÷µÄ·ÃÎʹæÔò¡£
+
+
+
+
+
+Èç¹ûÄãÏëΪHTTP¶ËµãÅäÖÃ×Ô¶¨Ò尲ȫ£¨ÀýÈ磬ֻÔÊÐí¾ßÓÐijÖÖ½ÇÉ«µÄÓû§·ÃÎÊ£©£¬Spring BootÌṩÁËһЩ·½±ãµÄ `RequestMatcher` ¶ÔÏó£¬Äã¿ÉÒÔÓëSpring Security½áºÏʹÓá£
+
+
+
+
+
+Ò»¸öµäÐ͵ÄSpring SecurityÅäÖÿÉÄÜ¿´ÆðÀ´ÏñÏÂÃæµÄÀý×Ó¡£
+
+
+
+
+
+
+
+Java
+
+Kotlin
+
+
+
+
+
+```
+@Configuration(proxyBeanMethods = false)
+public class MySecurityConfiguration {
+
+ @Bean
+ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
+ http.securityMatcher(EndpointRequest.toAnyEndpoint());
+ http.authorizeHttpRequests((requests) -> requests.anyRequest().hasRole("ENDPOINT_ADMIN"));
+ http.httpBasic(withDefaults());
+ return http.build();
+ }
+
+}
+
+```
+
+
+
+
+
+
+
+Ç°ÃæµÄÀý×ÓʹÓà `EndpointRequest.toAnyEndpoint()` À´Æ¥ÅäÒ»¸öÇëÇóµ½Èκζ˵㣬ȻºóÈ·±£ËùÓеĶ˵㶼ÓÐ `ENDPOINT_ADMIN` µÄ½ÇÉ«¡£ `EndpointRequest` ÉÏ»¹ÓÐÆäËû¼¸¸öÆ¥ÅäÆ÷·½·¨¡£ ÏêÇé¼ûAPIÎĵµ£¨ [HTML](https://docs.spring.io/spring-boot/docs/3.1.0-SNAPSHOT/actuator-api/htmlsingle) »ò [PDF](https://docs.spring.io/spring-boot/docs/3.1.0-SNAPSHOT/actuator-api/pdf/spring-boot-actuator-web-api.pdf)£©¡£
+
+
+
+
+
+Èç¹ûÄãÔÚ·À»ðǽºóÃæ²¿ÊðÓ¦ÓóÌÐò£¬Äã¿ÉÄÜÏ£ÍûÄãµÄËùÓÐÖ´ÐÐÆ÷¶Ëµã¶¼Äܱ»·ÃÎÊ£¬¶ø²»ÐèÒªÈÏÖ¤¡£ Äã¿ÉÒÔͨ¹ý¸Ä±ä `management.endpoints.web.exposure.include` ÊôÐÔÀ´×öµ½ÕâÒ»µã£¬ÈçÏÂËùʾ¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.endpoints.web.exposure.include=*
+
+```
+
+
+
+
+
+
+
+´ËÍ⣬Èç¹û´æÔÚSpring Security£¬ÄãÐèÒªÌí¼Ó×Ô¶¨Ò尲ȫÅäÖã¬ÔÊÐíδ¾ÈÏÖ¤µÄ·ÃÎʶ˵㣬ÈçÏÂÀýËùʾ¡£
+
+
+
+
+
+
+
+Java
+
+Kotlin
+
+
+
+
+
+```
+@Configuration(proxyBeanMethods = false)
+public class MySecurityConfiguration {
+
+ @Bean
+ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
+ http.securityMatcher(EndpointRequest.toAnyEndpoint());
+ http.authorizeHttpRequests((requests) -> requests.anyRequest().permitAll());
+ return http.build();
+ }
+
+}
+
+```
+
+
+
+
+
+
+
+| | ÔÚÇ°ÃæµÄÁ½¸öÀý×ÓÖУ¬ÅäÖÃÖ»ÊÊÓÃÓÚactuator¶Ëµã¡£ ÓÉÓÚSpring BootµÄ°²È«ÅäÖÃÔÚÓÐÈκΠ`SecurityFilterChain` beanµÄÇé¿ö϶¼»áÍêÈ«Í˳ö£¬ËùÒÔÄãÐèÒªÅäÖÃÒ»¸ö¶îÍâµÄ `SecurityFilterChain` bean£¬Æä¹æÔòÊÊÓÃÓÚÓ¦ÓóÌÐòµÄÆäËû²¿·Ö¡£ |
+| --- | --- |
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.security.csrf)2.3.1\. ¿çÍøÕ¾ÇëÇóαÔì±£»¤£¨CSRF£©
+
+
+
+ÓÉÓÚSpring BootÒÀÀµSpring SecurityµÄĬÈÏÖµ£¬CSRF±£»¤ÔÚĬÈÏÇé¿öϱ»´ò¿ª¡£ ÕâÒâζ×ÅÔÚʹÓÃĬÈϰ²È«ÅäÖÃʱ£¬ÐèÒª `POST`£¨shutdownºÍloggers¶Ëµã£©¡¢`PUT` »ò `DELETE` µÄactuator¶Ëµã»á³öÏÖ403£¨½ûÖ¹£©µÄ´íÎó¡£
+
+
+
+
+
+| | ÎÒÃǽ¨ÒéÖ»ÓÐÔÚÄã´´½¨µÄ·þÎñ±»·Çä¯ÀÀÆ÷¿Í»§¶ËʹÓÃʱ²ÅÍêÈ«½ûÓÃCSRF±£»¤¡£ |
+| --- | --- |
+
+
+
+
+
+Äã¿ÉÒÔÔÚ [Spring°²È«²Î¿¼Ö¸ÄÏ](https://docs.spring.io/spring-security/reference/6.1.0-M1/features/exploits/csrf.html) ÖÐÕÒµ½¹ØÓÚCSRF±£»¤µÄÆäËûÐÅÏ¢¡£
+
+
+
+
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.caching)2.4\. ÅäÖö˵ã
+
+
+
+¶Ëµã»á×Ô¶¯»º´æ²»ÐèÒªÈκβÎÊýµÄ¶ÁÈ¡²Ù×÷µÄÏìÓ¦¡£ ÒªÅäÖö˵㻺´æÏìÓ¦µÄʱ¼ä£¬ÇëʹÓÃÆä `cache.time-to-live` ÊôÐÔ¡£ ÏÂÃæµÄÀý×Ó½« `beans` ¶ËµãµÄ»º´æÉú´æÊ±¼äÉèÖÃΪ10Ãë¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.endpoint.beans.cache.time-to-live=10s
+
+```
+
+
+
+
+
+
+
+| | `management.endpoint.` ǰ׺ΨһµØ±êʶÁËÕýÔÚÅäÖõĶ˵㡣 |
+| --- | --- |
+
+
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.hypermedia)2.5\. ÓÃÓÚ Actuator Web ¶ËµãµÄ³¬Ã½Ì壨Hypermedia£©
+
+
+
+Ò»¸ö ¡°discovery page¡± ±»Ìí¼Óµ½ËùÓж˵ãµÄÁ´½ÓÖС£ ĬÈÏÇé¿öÏ£¬¡°discovery page¡± ÔÚ `/actuator` ÉÏÊÇ¿ÉÓõġ£
+
+
+
+
+
+Òª½ûÓà ¡°discovery page¡±£¬ÇëÔÚÄãµÄÓ¦ÓóÌÐòÊôÐÔÖÐÌí¼ÓÒÔÏÂÊôÐÔ¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.endpoints.web.discovery.enabled=false
+
+```
+
+
+
+
+
+
+
+µ±ÅäÖÃÁËÒ»¸ö×Ô¶¨ÒåµÄ¹ÜÀíÉÏÏÂÎÄ·¾¶Ê±£¬¡°discovery page¡± »á×Ô¶¯´Ó `/actuator` ÒÆµ½¹ÜÀíÉÏÏÂÎĵĸù²¿¡£ ÀýÈ磬Èç¹û¹ÜÀíÉÏÏÂÎÄ·¾¶ÊÇ `/management`£¬discovery page¿ÉÒÔ´Ó `/management` »ñµÃ¡£ µ±¹ÜÀíÉÏÏÂÎÄ·¾¶±»ÉèÖÃΪ `/` ʱ£¬·¢ÏÖÒ³±»½ûÓã¬ÒÔ·ÀÖ¹ÓëÆäËûmapping·¢Éú³åÍ»µÄ¿ÉÄÜÐÔ¡£
+
+
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.cors)2.6\. CORSµÄÖ§³Ö
+
+
+
+[¿çÔ´×ÊÔ´¹²Ïí](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing)£¨CORS£©ÊÇ [W3CµÄÒ»¸ö¹æ·¶](https://www.w3.org/TR/cors/)£¬¿ÉÒÔÈÃÄãÒÔÁé»îµÄ·½Ê½Ö¸¶¨ÄÄÖÖ¿çÓòÇëÇó±»ÊÚȨ¡£Èç¹ûÄãʹÓÃSpring MVC»òSpring WebFlux£¬Äã¿ÉÒÔÅäÖÃActuatorµÄWeb¶ËµãÀ´Ö§³ÖÕâÖÖÇé¿ö¡£
+
+
+
+
+
+CORSÖ§³ÖÔÚĬÈÏÇé¿öÏÂÊǽûÓõģ¬Ö»ÓÐÔÚÄãÉèÖÃÁË `management.endpoints.web.cors.allowed-origins` ÊôÐÔºó²Å»áÆôÓᣠÏÂÃæµÄÅäÖÃÔÊÐí´Ó `example.com` ÓòÃûÖе÷Óà `GET` ºÍ `POST`¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.endpoints.web.cors.allowed-origins=https://example.com
+management.endpoints.web.cors.allowed-methods=GET,POST
+
+```
+
+
+
+
+
+
+
+| | ²Î¼û [`CorsEndpointProperties`](https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/CorsEndpointProperties.java) ÒÔ»ñµÃÍêÕûµÄÑ¡ÏîÁÐ±í¡£ |
+| --- | --- |
+
+
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.implementing-custom)2.7\. ʵÏÖ×Ô¶¨Òå¶Ëµã
+
+
+
+Èç¹ûÄãÌí¼ÓÁËÒ»¸ö´øÓÐ `@Endpoint` ×¢½âµÄ `@Bean`£¬ÈκδøÓÐ `@ReadOperation`¡¢`@WriteOperation` »ò `@DeleteOperation` ×¢Ê͵ķ½·¨¶¼»á×Ô¶¯Í¨¹ýJMX¹«¿ª£¬ÔÚWebÓ¦ÓóÌÐòÖÐÒ²»áͨ¹ýHTTP¹«¿ª¡£ ͨ¹ýʹÓÃJersey¡¢Spring MVC»òSpring WebFlux£¬¶Ëµã¿ÉÒÔͨ¹ýHTTP±©Â¶¡£ Èç¹ûJerseyºÍSpring MVC¶¼¿ÉÓã¬ÔòʹÓÃSpring MVC¡£
+
+
+
+
+
+ÏÂÃæµÄÀý×Ó±©Â¶ÁËÒ»¸ö¶Á²Ù×÷£¬Ëü·µ»ØÒ»¸ö×Ô¶¨Òå¶ÔÏó¡£
+
+
+
+
+
+
+
+Java
+
+Kotlin
+
+
+
+
+
+```
+@ReadOperation
+public CustomData getData() {
+ return new CustomData("test", 5);
+}
+
+```
+
+
+
+
+
+
+
+ÄãÒ²¿ÉÒÔͨ¹ýʹÓà `@JmxEndpoint` »ò `@WebEndpoint` À´±àÐ´ÌØ¶¨¼¼ÊõµÄ¶Ëµã¡£ ÕâЩ¶Ëµã±»ÏÞÖÆÔÚËüÃǸ÷×Եļ¼ÊõÉÏ¡£ ÀýÈ磬`@WebEndpoint` ֻͨ¹ýHTTP±©Â¶£¬¶ø²»ÊÇͨ¹ýJMX¡£
+
+
+
+
+
+Äã¿ÉÒÔͨ¹ýʹÓà `@EndpointWebExtension` ºÍ `@EndpointJmxExtension` À´±àÐ´ÌØ¶¨µÄ¼¼ÊõÀ©Õ¹¡£ ÕâЩע½âÈÃÄãÌá¹©ÌØ¶¨¼¼ÊõµÄ²Ù×÷£¬ÒÔÔöÇ¿ÏÖÓеĶ˵㡣
+
+
+
+
+
+×îºó£¬Èç¹ûÄãÐèÒª·ÃÎÊWeb¿ò¼ÜµÄÌØ¶¨¹¦ÄÜ£¬Äã¿ÉÒÔʵÏÖservlet»òSpringµÄ `@Controller` ºÍ `@RestController` ¶Ëµã£¬´ú¼ÛÊÇËüÃDz»ÄÜͨ¹ýJMX»òʹÓò»Í¬µÄWeb¿ò¼Üʱ¿ÉÓá£
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.implementing-custom.input)2.7.1\. ½ÓÊÕÊäÈë
+
+
+
+¶ËµãÉϵIJÙ×÷ͨ¹ýÆä²ÎÊý½ÓÊÕÊäÈë¡£ µ±Í¨¹ýweb¹«¿ªÊ±£¬ÕâЩ²ÎÊýµÄÖµÀ´×ÔURLµÄ²éѯ²ÎÊýºÍJSONÇëÇóÌå¡£ µ±Í¨¹ýJMX¹«¿ªÊ±£¬²ÎÊý±»Ó³Éäµ½MBean²Ù×÷µÄ²ÎÊýÖС£ ĬÈÏÇé¿öÏ£¬²ÎÊýÊDZØÐèµÄ¡£ ËüÃÇ¿ÉÒÔͨ¹ýʹÓà `@javax.annotation.Nullable` »ò `@org.springframework.lang.Nullable` ½øÐÐ×¢½â¶ø³ÉΪ¿ÉÑ¡Ïî¡£
+
+
+
+
+
+Äã¿ÉÒÔ½«JSONÇëÇóÌåÖеÄÿ¸ö¸ùÊôÐÔÓ³Éäµ½¶ËµãµÄÒ»¸ö²ÎÊý¡£ ¿¼ÂÇÒ»ÏÂÏÂÃæµÄJSONÇëÇóÌå¡£
+
+
+
+
+
+
+
+```
+{
+ "name": "test",
+ "counter": 42
+}
+```
+
+
+
+
+
+
+
+Äã¿ÉÒÔÓÃËüÀ´µ÷ÓÃÒ»¸öд²Ù×÷£¬¸Ã²Ù×÷ÐèÒª `String name` ºÍ `int counter` ²ÎÊý£¬ÈçÏÂÃæµÄÀý×ÓËùʾ¡£
+
+
+
+
+
+
+
+Java
+
+Kotlin
+
+
+
+
+
+```
+@WriteOperation
+public void updateData(String name, int counter) {
+ // injects "test" and 42
+}
+
+```
+
+
+
+
+
+
+
+| | ÒòΪ¶ËµãÊǼ¼Êõ²»¿ÉÖªµÄ£¬ÔÚ·½·¨Ç©ÃûÖÐÖ»ÄÜÖ¸¶¨¼òµ¥µÄÀàÐÍ¡£ ÌØ±ðÊÇ£¬²»Ö§³ÖÓà `CustomData` ÀàÐÍÉùÃ÷Ò»¸ö¶¨ÒåÁË `name` ºÍ `counter` ÊôÐԵĵ¥Ò»²ÎÊý¡£ |
+| --- | --- |
+
+
+
+
+
+| | ΪÁËÈÃÊäÈëÓ³Éäµ½²Ù×÷·½·¨µÄ²ÎÊý£¬ÊµÏֶ˵ãµÄJava´úÂëÓ¦¸ÃÓà `-parameters` ±àÒ룬¶øÊµÏֶ˵ãµÄKotlin´úÂëÓ¦¸ÃÓà `-java-parameters` ±àÒë¡£ Èç¹ûÄãʹÓÃSpring BootµÄGradle²å¼þ»òʹÓÃMavenºÍ `spring-boot-starter-parent`£¬Õ⽫×Ô¶¯·¢Éú¡£ |
+| --- | --- |
+
+
+
+
+
+##### [](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.implementing-custom.input.conversion)ÊäÈëÀàÐÍת»»
+
+
+
+Èç¹ûÓбØÒª£¬´«µÝ¸ø¶Ëµã²Ù×÷·½·¨µÄ²ÎÊý»á×Ô¶¯×ª»»ÎªËùÐèÀàÐÍ¡£ ÔÚµ÷ÓòÙ×÷·½·¨Ö®Ç°£¬Í¨¹ýJMX»òHTTPÊÕµ½µÄÊäÈ뱻ת»»ÎªËùÐèµÄÀàÐÍ£¬·½·¨ÊÇʹÓà `ApplicationConversionService` µÄʵÀýÒÔ¼°ÈκΠ`Converter` »ò `GenericConverter` Bean£¬²¢ÒÔ `@EndpointConverter` ÏÞ¶¨¡£
+
+
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.implementing-custom.web)2.7.2\. ×Ô¶¨ÒåWEB¶Ëµã
+
+
+
+¶Ô `@Endpoint`¡¢`@WebEndpoint` »ò `@EndpointWebExtension` ²Ù×÷»á×Ô¶¯Ê¹ÓÃJersey¡¢Spring MVC»òSpring WebFluxͨ¹ýHTTP¹«¿ª¡£ Èç¹ûJerseyºÍSpring MVC¶¼¿ÉÓã¬ÔòʹÓÃSpring MVC¡£
+
+
+
+
+
+##### [](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.implementing-custom.web.request-predicates)WEB¶ËµãÇëÇóν´Ê£¨Predicates£©
+
+
+
+Ò»¸öÇëÇóν´Ê»áΪweb±©Â¶µÄ¶ËµãÉϵÄÿ¸ö²Ù×÷£¨operation£©×Ô¶¯Éú³É¡£
+
+
+
+
+
+
+
+##### [](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.implementing-custom.web.path-predicates)Path
+
+
+
+pathν´ÊÓɶ˵ãµÄIDºÍÍøÂ籩¶µÄ¶ËµãµÄ»ù±¾Â·¾¶¾ö¶¨¡£ ĬÈϵĻù±¾Â·¾¶ÊÇ `/actuator`¡£ ÀýÈ磬һ¸öIDΪ `sessions` µÄ¶ËµãÔÚν´ÊÖÐʹÓà `/actuator/sessions` ×÷ΪÆä·¾¶¡£
+
+
+
+
+
+Äã¿ÉÒÔͨ¹ýÓà `@Selector` ×¢½â²Ù×÷·½·¨µÄÒ»¸ö»ò¶à¸ö²ÎÊýÀ´½øÒ»²½¶¨ÖÆÂ·¾¶¡£ ÕâÑùµÄ²ÎÊý»á×÷Ϊһ¸ö·¾¶±äÁ¿Ìí¼Óµ½Â·¾¶Î½´ÊÖС£ ÔÚµ÷Óö˵ã²Ù×÷ʱ£¬¸Ã±äÁ¿µÄÖµ»á±»´«Èë²Ù×÷·½·¨¡£ Èç¹ûÄãÏë²¶»ñËùÓÐÊ£ÓàµÄ·¾¶ÔªËØ£¬Äã¿ÉÒÔÔÚ×îºóÒ»¸ö²ÎÊýÉÏÌí¼Ó `@Selector(Match=ALL_REMAINING)`£¬²¢Ê¹Æä³ÉΪһ¸öÓë `String[]` ת»»¼æÈݵÄÀàÐÍ¡£
+
+
+
+
+
+
+
+##### [](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.implementing-custom.web.method-predicates)HTTP method£¨·½·¨£©
+
+
+
+HTTP methodν´ÊÊÇÓɲÙ×÷ÀàÐ;ö¶¨µÄ£¬ÈçϱíËùʾ¡£
+
+
+
+
+| Operation | HTTP method |
+| --- | --- |
+| `@ReadOperation` | `GET` |
+| `@WriteOperation` | `POST` |
+| `@DeleteOperation` | `DELETE` |
+
+
+
+
+
+##### [](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.implementing-custom.web.consumes-predicates)Consumes
+
+
+
+¶ÔÓÚʹÓÃrequest bodyµÄ `@WriteOperation`£¨HTTP `POST`£©£¬Î½´ÊµÄ `consumes` ×Ó¾äÊÇ `application/vnd.spring-boot.actuator.v2+json, application/json`¡£ ¶ÔÓÚËùÓÐÆäËû²Ù×÷£¬`consumes` ×Ó¾äÊǿյġ£
+
+
+
+
+
+
+
+##### [](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.implementing-custom.web.produces-predicates)Produces
+
+
+
+ν´ÊµÄ `produces` ×Ó¾ä¿ÉÒÔÓÉ `@DeleteOperation`¡¢`@ReadOperation` ºÍ `@WriteOperation` ×¢Ê굀 `produces` ÊôÐÔ¾ö¶¨¡£ ¸ÃÊôÐÔÊÇ¿ÉÑ¡µÄ¡£ Èç¹û²»Ê¹ÓÃËü£¬`produces` ×Ó¾ä»á×Ô¶¯È·¶¨¡£
+
+
+
+
+
+Èç¹û²Ù×÷·½·¨·µ»Ø `void` »ò `Void`£¬Ôò `produces` ×Ó¾äΪ¿Õ¡£ Èç¹û²Ù×÷·½·¨·µ»Ø `org.springframework.core.io.Resource`£¬`produces` ×Ó¾äÊÇ `application/octet-stream`¡£ ¶ÔÓÚËùÓÐÆäËû²Ù×÷£¬`produces` ×Ó¾äÊÇ `application/vnd.spring-boot.actuator.v2+json, application/json`¡£
+
+
+
+
+
+
+
+##### [](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.implementing-custom.web.response-status)WEB¶ËµãÏìӦ״̬
+
+
+
+¶Ëµã²Ù×÷µÄĬÈÏÏìӦ״̬ȡ¾öÓÚ²Ù×÷ÀàÐÍ£¨¶Á¡¢Ð´»òɾ³ý£©ºÍ²Ù×÷·µ»ØµÄÄÚÈÝ£¨Èç¹ûÓеϰ£©¡£
+
+
+
+
+
+Èç¹û `@ReadOperation` ·µ»ØÒ»¸öÖµ£¬ÏìӦ״̬½«ÊÇ200(Ok)¡£ Èç¹ûËüûÓзµ»ØÒ»¸öÖµ£¬ÏìӦ״̬½«ÊÇ404(Not Found)¡£
+
+
+
+
+
+Èç¹û `@WriteOperation` »ò `@DeleteOperation` ·µ»ØÒ»¸öÖµ£¬ÏìӦ״̬½«ÊÇ200£¨OK£©¡£ Èç¹ûËüûÓзµ»ØÒ»¸öÖµ£¬ÏìӦ״̬½«ÊÇ204£¨No Content£©¡£
+
+
+
+
+
+Èç¹ûÒ»¸ö²Ù×÷ÔÚµ÷ÓÃʱûÓÐËùÐèµÄ²ÎÊý£¬»òÕß²ÎÊý²»Äܱ»×ª»»ÎªËùÐèµÄÀàÐÍ£¬²Ù×÷·½·¨¾Í²»»á±»µ÷Óã¬ÏìӦ״̬½«ÊÇ400£¨Bad Request£©¡£
+
+
+
+
+
+
+
+##### [](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.implementing-custom.web.range-requests)WEB¶Ëµã Range ÇëÇó
+
+
+
+Äã¿ÉÒÔʹÓÃHTTP rangeÇëÇóÀ´ÇëÇóÒ»¸öHTTP×ÊÔ´µÄÒ»²¿·Ö¡£ µ±Ê¹ÓÃSpring MVC»òSpring Web Fluxʱ£¬·µ»Ø `org.springframework.core.io.Resource` µÄ²Ù×÷×Ô¶¯Ö§³Ö·¶Î§ÇëÇó¡£
+
+
+
+
+
+| | ʹÓÃJerseyʱ²»Ö§³Ö Range ÇëÇó¡£ |
+| --- | --- |
+
+
+
+
+
+
+
+##### [](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.implementing-custom.web.security)Web¶ËµãµÄ°²È«
+
+
+
+ÔÚweb¶Ëµã»òwebÌØ¶¨¶ËµãÀ©Õ¹ÉϵIJÙ×÷¿ÉÒÔ½ÓÊÕµ±Ç°µÄ `java.security.Principal` »ò `org.springframework.boot.actuate.endpoint.SecurityContext` ×÷Ϊ·½·¨²ÎÊý¡£ ǰÕßͨ³£Óë `@Nullable` Ò»ÆðʹÓã¬ÎªÒÑÈÏÖ¤ºÍδÈÏÖ¤µÄÓû§Ìṩ²»Í¬µÄÐÐΪ¡£ ºóÕßͨ³£ÓÃÓÚͨ¹ýʹÓÃÆä `isUserInRole(String)` ·½·¨À´Ö´ÐÐÊÚȨ¼ì²é¡£
+
+
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.implementing-custom.servlet)2.7.3\. Servlet ¶Ëµã
+
+
+
+Ò»¸öServlet¿ÉÒÔ×÷Ϊһ¸ö¶Ëµã±©Â¶³öÀ´£¬·½·¨ÊÇʵÏÖÒ»¸öÓà `@ServletEndpoint` ×¢½âµÄÀ࣬ͬʱʵÏÖ `Supplier`¡£ Servlet¶ËµãÌṩÁËÓëservletÈÝÆ÷µÄ¸üÉî²ã´ÎµÄÕûºÏ£¬µ«È´ÎþÉüÁË¿ÉÒÆÖ²ÐÔ¡£ ËüÃǵÄÄ¿µÄÊÇÓÃÀ´½«ÏÖÓеÄServlet×÷Ϊһ¸ö¶ËµãÀ´¹«¿ª¡£ ¶ÔÓÚеĶ˵㣬Ӧ¾¡¿ÉÄÜÑ¡Ôñ `@Endpoint` ºÍ `@WebEndpoint` ×¢½â¡£
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.implementing-custom.controller)2.7.4\. Controller ¶Ëµã
+
+
+
+Äã¿ÉÒÔʹÓà `@ControllerEndpoint` ºÍ `@RestControllerEndpoint` À´ÊµÏÖÒ»¸ö½öÓÉSpring MVC»òSpring WebFlux¹«¿ªµÄ¶Ëµã¡£ ·½·¨Í¨¹ýʹÓÃSpring MVCºÍSpring WebFluxµÄ±ê×¼×¢½â½øÐÐÓ³É䣬Èç `@RequestMapping` ºÍ `@GetMapping`£¬¶ËµãµÄID±»ÓÃ×÷·¾¶µÄǰ׺¡£ ¿ØÖÆÆ÷¶ËµãÌṩÁËÓëSpringµÄWeb¿ò¼Ü¸üÉîÈëµÄ¼¯³É£¬µ«È´ÎþÉüÁË¿ÉÒÆÖ²ÐÔ¡£ Ó¦¾¡¿ÉÄÜÑ¡Ôñ `@Endpoint` ºÍ `@WebEndpoint` ×¢½â¡£
+
+
+
+
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.health)2.8\. ½¡¿µÐÅÏ¢
+
+
+
+Äã¿ÉÒÔʹÓý¡¿µÐÅÏ¢À´¼ì²éÄãÔËÐеÄÓ¦ÓóÌÐòµÄ״̬¡£ Ëü¾³£±»¼à¿ØÈí¼þÓÃÀ´ÔÚÉú²úϵͳ·¢Éú¹ÊÕÏʱÌáÐѱðÈË¡£ `health` ¶Ëµã±©Â¶µÄÐÅϢȡ¾öÓÚ `management.endpoint.health.show-details` ºÍ `management.endpoint.health.show-components` ÊôÐÔ£¬ËüÃÇ¿ÉÒÔÅäÖÃΪÒÔÏÂÖµÖ®Ò»¡£
+
+
+
+
+| Öµ | ˵Ã÷ |
+| --- | --- |
+| `never` | ϸ½Ú´Ó²»ÏÔʾ¡£ |
+| `when-authorized` | ϸ½ÚÖ»ÏÔʾ¸øÊÚȨÓû§¡£ ÊÚȨµÄ½ÇÉ«¿ÉÒÔͨ¹ýʹÓà `management.endpoint.health.roles` ½øÐÐÅäÖᣠ|
+| `always` | ÏêÇéÏÔʾ¸øËùÓÐÓû§¡£ |
+
+
+
+ĬÈÏÖµÊÇ `never`¡£ µ±Óû§´¦Óڶ˵ãµÄÒ»¸ö»ò¶à¸ö½ÇÉ«ÖÐʱ£¬ËûÃDZ»ÈÏΪÊDZ»ÊÚȨµÄ¡£ Èç¹û¶ËµãûÓÐÅäÖýÇÉ«£¨Ä¬ÈÏÖµ£©£¬ËùÓÐÈÏÖ¤µÄÓû§¶¼±»ÈÏΪÊÇÊÚȨµÄ¡£ Äã¿ÉÒÔͨ¹ýʹÓà `management.endpoint.health.roles` ÊôÐÔÀ´ÅäÖýÇÉ«¡£
+
+
+
+
+
+| | Èç¹ûÄãÒѾ±£»¤ÁËÄãµÄÓ¦ÓóÌÐò²¢Ï£ÍûʹÓà `always`£¬ÄãµÄ°²È«ÅäÖã¨security configuration£©±ØÐëÔÊÐíÈÏÖ¤ºÍ·ÇÈÏÖ¤Óû§·ÃÎÊhealth¶Ëµã¡£ |
+| --- | --- |
+
+
+
+
+
+½¡¿µÐÅÏ¢ÊÇ´Ó [`HealthContributorRegistry`](https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthContributorRegistry.java) µÄÄÚÈÝÖÐÊÕ¼¯µÄ£¨Ä¬ÈÏÇé¿öÏ£¬ËùÓÐ [`HealthContributor`](https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthContributor.java) ʵÀý¶¼¶¨ÒåÔÚÄãµÄ `ApplicationContext` ÖУ©¡£ Spring Boot°üÀ¨Ò»Ð©×Ô¶¯ÅäÖÃµÄ `HealthContributor`£¬ÄãÒ²¿ÉÒÔ±àд×Ô¼ºµÄ¡£
+
+
+
+
+
+Ò»¸ö `HealthContributor` ¿ÉÒÔÊÇÒ»¸ö `HealthIndicator` »òÒ»¸ö `CompositeHealthContributor`¡£ Ò»¸ö `HealthIndicator` Ìṩʵ¼ÊµÄ½¡¿µÐÅÏ¢£¬°üÀ¨ `Status`¡£ Ò»¸ö `CompositeHealthContributor` ÌṩÆäËû `HealthContributors` µÄ×éºÏ¡£ ×ÛºÏÆðÀ´£¬contributorÐγÉÒ»¸öÊ÷×´½á¹¹À´±íʾÕû¸öϵͳµÄ½¡¿µ×´¿ö¡£
+
+
+
+
+
+ĬÈÏÇé¿öÏ£¬×îÖÕµÄϵͳ½¡¿µ×´¿öÊÇÓÉÒ»¸ö `StatusAggregator` µÃ³öµÄ£¬Ëü¸ù¾ÝÒ»¸öÓÐÐòµÄ״̬Áбí¶Ôÿ¸ö `HealthIndicator` µÄ״̬½øÐÐÅÅÐò¡£ ÅÅÐòÁбíÖеĵÚÒ»¸ö״̬±»ÓÃ×÷ÕûÌ彡¿µ×´Ì¬¡£ Èç¹ûûÓÐ `HealthIndicator` ·µ»ØµÄ״̬ÊÇ `StatusAggregator` ËùÖªµÀµÄ£¬¾Í»áʹÓà `UNKNOWN` ״̬¡£
+
+
+
+
+
+| | Äã¿ÉÒÔʹÓà `HealthContributorRegistry` À´ÔÚÔËÐÐʱע²áºÍÈ¡Ïû×¢²á½¡¿µÖ¸±ê¡£ |
+| --- | --- |
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.health.auto-configured-health-indicators)2.8.1\. ×Ô¶¯ÅäÖõÄHealthIndicators
+
+
+
+ÔÚÊʵ±µÄʱºò£¬Spring Boot»á×Ô¶¯ÅäÖÃϱíÖÐÁгöµÄ `HealthIndicators`¡£ ÄãÒ²¿ÉÒÔͨ¹ýÅäÖà `management.health.key.enabled` À´ÆôÓûòÍ£ÓÃËùѡָ±ê¡£ ºÍϱíÖÐÁгöµÄ `key`¡£
+
+
+
+
+| Key | Name | ˵Ã÷ |
+| --- | --- | --- |
+| `cassandra` | [`CassandraDriverHealthIndicator`](https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/cassandra/CassandraDriverHealthIndicator.java) | ¼ì²éCassandraÊý¾Ý¿âÊÇ·ñÒѾÆô¶¯¡£ |
+| `couchbase` | [`CouchbaseHealthIndicator`](https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/couchbase/CouchbaseHealthIndicator.java) | ¼ì²éCouchbase¼¯ÈºÊÇ·ñÒѾÆô¶¯¡£ |
+| `db` | [`DataSourceHealthIndicator`](https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/jdbc/DataSourceHealthIndicator.java) | ¼ì²éÊÇ·ñ¿ÉÒÔ»ñµÃÓë`DataSource`µÄÁ¬½Ó¡£ |
+| `diskspace` | [`DiskSpaceHealthIndicator`](https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/system/DiskSpaceHealthIndicator.java) | ¼ì²é´ÅÅ̿ռäÊÇ·ñ²»×ã¡£ |
+| `elasticsearch` | [`ElasticsearchRestHealthIndicator`](https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestHealthIndicator.java) | ¼ì²éElasticsearch¼¯ÈºÊÇ·ñÒѾÆô¶¯¡£ |
+| `hazelcast` | [`HazelcastHealthIndicator`](https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/hazelcast/HazelcastHealthIndicator.java) | ¼ì²éHazelcast·þÎñÆ÷ÊÇ·ñÒѾÆô¶¯¡£ |
+| `influxdb` | [`InfluxDbHealthIndicator`](https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/influx/InfluxDbHealthIndicator.java) | ¼ì²éInfluxDB·þÎñÆ÷ÊÇ·ñÒѾÆô¶¯¡£ |
+| `jms` | [`JmsHealthIndicator`](https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/jms/JmsHealthIndicator.java) | ¼ì²éÒ»¸öJMS´úÀíÊÇ·ñÒѾÆô¶¯¡£ |
+| `ldap` | [`LdapHealthIndicator`](https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/ldap/LdapHealthIndicator.java) | ¼ì²éÒ»¸öLDAP·þÎñÆ÷ÊÇ·ñÕý³£¡£ |
+| `mail` | [`MailHealthIndicator`](https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/mail/MailHealthIndicator.java) | ¼ì²éÒ»¸öÓʼþ·þÎñÆ÷ÊÇ·ñÕý³£¡£ |
+| `mongo` | [`MongoHealthIndicator`](https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/data/mongo/MongoHealthIndicator.java) | ¼ì²éMongoÊý¾Ý¿âÊÇ·ñÒѾÆô¶¯¡£ |
+| `neo4j` | [`Neo4jHealthIndicator`](https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/neo4j/Neo4jHealthIndicator.java) | ¼ì²éNeo4jÊý¾Ý¿âÊÇ·ñÒѾÆô¶¯¡£ |
+| `ping` | [`PingHealthIndicator`](https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/PingHealthIndicator.java) | ×ÜÊÇÏìÓ¦ `UP` ¡£ |
+| `rabbit` | [`RabbitHealthIndicator`](https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/amqp/RabbitHealthIndicator.java) | ¼ì²éÒ»¸öRabbit·þÎñÆ÷ÊÇ·ñÒѾÆô¶¯¡£ |
+| `redis` | [`RedisHealthIndicator`](https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/data/redis/RedisHealthIndicator.java) | ¼ì²éRedis·þÎñÆ÷ÊÇ·ñÒѾÆô¶¯¡£ |
+
+
+
+| | Äã¿ÉÒÔͨ¹ýÉèÖà `management.health.defaults.enabled` ÊôÐÔÀ´½ûÓÃËüÃÇ¡£ |
+| --- | --- |
+
+
+
+
+
+¶îÍâµÄ `HealthIndicators` ÊÇ¿ÉÓõ쬵«ÔÚĬÈÏÇé¿öϲ»ÆôÓá£
+
+
+
+
+| Key | Name | ˵Ã÷ |
+| --- | --- | --- |
+| `livenessstate` | [`LivenessStateHealthIndicator`](https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/availability/LivenessStateHealthIndicator.java) | ÏÔʾ ¡°Liveness¡± Ó¦ÓóÌÐòµÄ¿ÉÓÃÐÔ״̬¡£ |
+| `readinessstate` | [`ReadinessStateHealthIndicator`](https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/availability/ReadinessStateHealthIndicator.java) | ±©Â¶ ¡°Readiness¡± Ó¦ÓóÌÐòµÄ¿ÉÓÃÐÔ״̬¡£ |
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.health.writing-custom-health-indicators)2.8.2\. ±àд×Ô¶¨ÒåHealthIndicators
+
+
+
+ΪÁËÌṩ×Ô¶¨ÒåµÄ½¡¿µÐÅÏ¢£¬Äã¿ÉÒÔ×¢²áʵÏÖ [`HealthIndicator`](https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthIndicator.java) ½Ó¿ÚµÄSpring Bean¡£ ÄãÐèÒªÌṩһ¸ö `health()` ·½·¨µÄʵÏÖ£¬²¢·µ»ØÒ»¸ö `Health` ÏìÓ¦¡£ `Health` ÏìÓ¦Ó¦¸Ã°üÀ¨Ò»¸östatus£¬²¢¿ÉÒÔÑ¡Ôñ°üÀ¨ÒªÏÔʾµÄÆäËûϸ½Ú¡£ ÏÂÃæµÄ´úÂëÏÔʾÁËÒ»¸ö `HealthIndicator` µÄʵÏÖÑù±¾¡£
+
+
+
+
+
+
+
+Java
+
+Kotlin
+
+
+
+
+
+```
+@Component
+public class MyHealthIndicator implements HealthIndicator {
+
+ @Override
+ public Health health() {
+ int errorCode = check();
+ if (errorCode != 0) {
+ return Health.down().withDetail("Error Code", errorCode).build();
+ }
+ return Health.up().build();
+ }
+
+ private int check() {
+ // perform some specific health check
+ return ...
+ }
+
+}
+
+```
+
+
+
+
+
+
+
+| | Ò»¸ö¸ø¶¨µÄ `HealthIndicator` µÄ±êʶ·û£¨ID£©ÊÇûÓÐ `HealthIndicator` ºó׺µÄBeanµÄÃû×Ö£¬Èç¹ûËü´æÔڵϰ¡£ ÔÚÇ°ÃæµÄÀý×ÓÖУ¬½¡¿µÐÅÏ¢¿ÉÒÔÔÚÒ»¸öÃûΪ `my` µÄÌõÄ¿ÖÐÕÒµ½¡£ |
+| --- | --- |
+
+
+
+
+
+| | ½¡¿µÖ¸±êͨ³£ÊÇͨ¹ýHTTPµ÷Óõģ¬ÐèÒªÔÚÈκÎÁ¬½Ó³¬Ê±Ö®Ç°×ö³öÏìÓ¦¡£ Èç¹ûÈκν¡¿µÖ¸±êµÄÏìӦʱ¼ä³¬¹ý10Ã룬Spring Boot½«¼Ç¼һÌõ¾¯¸æÐÅÏ¢¡£ Èç¹ûÄãÏëÅäÖÃÕâ¸öãÐÖµ£¬Äã¿ÉÒÔʹÓà `management.endpoint.health.logging.slow-indicator-threshold` ÊôÐÔ¡£ |
+| --- | --- |
+
+
+
+
+
+³ýÁËSpring BootÔ¤¶¨ÒåµÄ [`Status`](https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/Status.java) ÀàÐÍÍ⣬`Health` ¿ÉÒÔ·µ»Ø´ú±íÐÂϵͳ״̬µÄ×Ô¶¨Òå `Status`¡£ ÔÚÕâÖÖÇé¿öÏ£¬Ä㻹ÐèÒªÌṩ `StatusAggregator` ½Ó¿ÚµÄ×Ô¶¨ÒåʵÏÖ£¬»òÕßÄã±ØÐëͨ¹ýʹÓà `management.endpoint.health.status.order` ÅäÖÃÊôÐÔÀ´ÅäÖÃĬÈÏʵÏÖ¡£
+
+
+
+
+
+ÀýÈ磬¼ÙÉèÔÚÄãµÄÒ»¸ö `HealthIndicator` ʵÏÖÖÐʹÓÃÁËÒ»¸ö´úÂëΪ `FATAL` µÄР`Status`¡£ ΪÁËÅäÖÃÑÏÖØÐÔ˳Ðò£¬ÔÚÄãµÄÓ¦ÓóÌÐòÊôÐÔÖÐÌí¼ÓÒÔÏÂÊôÐÔ¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.endpoint.health.status.order=fatal,down,out-of-service,unknown,up
+
+```
+
+
+
+
+
+
+
+ÏìÓ¦ÖеÄHTTP״̬´úÂë·´Ó³ÁËÕûÌ彡¿µ×´Ì¬¡£ ĬÈÏÇé¿öÏ£¬`OUT_OF_SERVICE` ºÍ `DOWN` Ó³Éäµ½503¡£ ÈκÎδӳÉäµÄ½¡¿µ×´Ì¬£¬°üÀ¨ `UP`£¬¶¼Ó³ÉäΪ200¡£ Èç¹ûÄãͨ¹ýHTTP·ÃÎʽ¡¿µ¶Ëµã£¬Äã¿ÉÄÜ»¹Ïë×¢²á×Ô¶¨Òå״̬ӳÉä¡£ ÅäÖÃ×Ô¶¨ÒåÓ³Éä»á½ûÓà `DOWN` ºÍ `OUT_OF_SERVICE` µÄĬÈÏÓ³Éä¡£ Èç¹ûÄãÏë±£ÁôĬÈÏÓ³É䣬Äã±ØÐëÃ÷È·µØÅäÖÃËüÃÇ£¬ÒÔ¼°ÈκÎ×Ô¶¨ÒåÓ³Éä¡£ ÀýÈ磬ÏÂÃæµÄÊôÐÔ½« `FATAL` Ó³ÉäΪ503£¨·þÎñ²»¿ÉÓã©£¬²¢±£ÁôÁË `DOWN` ºÍ `OUT_OF_SERVICE` µÄĬÈÏÓ³Éä¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.endpoint.health.status.http-mapping.down=503
+management.endpoint.health.status.http-mapping.fatal=503
+management.endpoint.health.status.http-mapping.out-of-service=503
+
+```
+
+
+
+
+
+
+
+| | Èç¹ûÄãÐèÒª¸ü¶àµÄ¿ØÖÆ£¬Äã¿ÉÒÔ¶¨ÒåÄã×Ô¼ºµÄ `HttpCodeStatusMapper` bean¡£ |
+| --- | --- |
+
+
+
+
+
+ϱíÏÔʾÁËÄÚÖÃ״̬µÄĬÈÏ״̬ӳÉä¡£
+
+
+
+
+| Status | Mapping |
+| --- | --- |
+| `DOWN` | `SERVICE_UNAVAILABLE` (`503`) |
+| `OUT_OF_SERVICE` | `SERVICE_UNAVAILABLE` (`503`) |
+| `UP` | ĬÈÏÇé¿öÏÂûÓÐÓ³É䣬ËùÒÔHTTP״̬Ϊ `200`¡£ |
+| `UNKNOWN` | ĬÈÏÇé¿öÏÂûÓÐÓ³É䣬ËùÒÔHTTP״̬Ϊ `200`¡£ |
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.health.reactive-health-indicators)2.8.3\. ÏìӦʽ½¡¿µÖ¸±ê
+
+
+
+¶ÔÓÚÏìӦʽӦÓóÌÐò£¬ÀýÈçÄÇЩʹÓÃSpring WebFluxµÄÓ¦ÓóÌÐò£¬`ReactiveHealthContributor` ÌṩÁËÒ»¸ö·Ç×èÈûµÄÆõÔ¼À´»ñȡӦÓóÌÐòµÄ½¡¿µ×´¿ö¡£ Ó봫ͳµÄ `HealthContributor` ÀàËÆ£¬½¡¿µÐÅÏ¢´Ó [`ReactiveHealthContributorRegistry`](https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/ReactiveHealthContributorRegistry.java) µÄÄÚÈÝÖÐÊÕ¼¯£¨Ä¬ÈÏÇé¿öÏ£¬ËùÓÐ [`HealthContributor`](https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthContributor.java) ºÍ [`ReactiveHealthContributor`](https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/ReactiveHealthContributor.java) µÄʵÀý¶¨ÒåÔÚÄãµÄ `ApplicationContext` À¡£
+
+
+
+
+
+²»¶ÔÏìӦʽAPI½øÐмì²éµÄ³£¹æ `HealthContributors` ÔÚµ¯ÐÔµ÷¶ÈÆ÷ÉÏÖ´ÐС£
+
+
+
+
+
+| | ÔÚÒ»¸öÏìӦʽӦÓóÌÐòÖУ¬ÄãÓ¦¸ÃʹÓà `ReactiveHealthContributorRegistry` À´ÔÚÔËÐÐʱע²áºÍÈ¡Ïû×¢²á½¡¿µÖ¸±ê¡£ Èç¹ûÄãÐèҪע²áÒ»¸öÆÕͨµÄ `HealthContributor`£¬ÄãÓ¦¸ÃÓà `ReactiveHealthContributor#adapt` À´°ü×°Ëü¡£ |
+| --- | --- |
+
+
+
+
+
+ΪÁË´ÓÏìӦʽAPIÖÐÌṩ×Ô¶¨ÒåµÄ½¡¿µÐÅÏ¢£¬Äã¿ÉÒÔ×¢²áʵÏÖ [`ReactiveHealthIndicator`](https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/ReactiveHealthIndicator.java) ½Ó¿ÚµÄSpring Bean¡£ ÏÂÃæµÄ´úÂëÏÔʾÁËÒ»¸ö `ReactiveHealthIndicator` µÄʾÀýʵÏÖ¡£
+
+
+
+
+
+
+
+Java
+
+Kotlin
+
+
+
+
+
+```
+@Component
+public class MyReactiveHealthIndicator implements ReactiveHealthIndicator {
+
+ @Override
+ public Mono health() {
+ return doHealthCheck().onErrorResume((exception) ->
+ Mono.just(new Health.Builder().down(exception).build()));
+ }
+
+ private Mono doHealthCheck() {
+ // perform some specific health check
+ return ...
+ }
+
+}
+
+```
+
+
+
+
+
+
+
+| | ΪÁË×Ô¶¯´¦Àí´íÎ󣬿ÉÒÔ¿¼ÂÇ´Ó `AbstractReactiveHealthIndicator` ÖÐÀ©Õ¹¡£ |
+| --- | --- |
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.health.auto-configured-reactive-health-indicators)2.8.4\. ×Ô¶¯ÅäÖÃµÄ ReactiveHealthIndicators
+
+
+
+ÔÚÊʵ±µÄʱºò£¬Spring Boot»á×Ô¶¯ÅäÖÃÒÔÏ嵀 `ReactiveHealthIndicators`¡£
+
+
+
+
+| Key | Name | ˵Ã÷ |
+| --- | --- | --- |
+| `cassandra` | [`CassandraDriverReactiveHealthIndicator`](https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/cassandra/CassandraDriverReactiveHealthIndicator.java) | ¼ì²éCassandraÊý¾Ý¿âÊÇ·ñÒѾÆô¶¯¡£ |
+| `couchbase` | [`CouchbaseReactiveHealthIndicator`](https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/couchbase/CouchbaseReactiveHealthIndicator.java) | ¼ì²éCouchbase¼¯ÈºÊÇ·ñÒѾÆô¶¯¡£ |
+| `elasticsearch` | [`ElasticsearchReactiveHealthIndicator`](https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/data/elasticsearch/ElasticsearchReactiveHealthIndicator.java) | ¼ì²éElasticsearch¼¯ÈºÊÇ·ñÒѾÆô¶¯¡£ |
+| `mongo` | [`MongoReactiveHealthIndicator`](https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/data/mongo/MongoReactiveHealthIndicator.java) | ¼ì²éMongoÊý¾Ý¿âÊÇ·ñÒѾÆô¶¯¡£ |
+| `neo4j` | [`Neo4jReactiveHealthIndicator`](https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/neo4j/Neo4jReactiveHealthIndicator.java) | ¼ì²éNeo4jÊý¾Ý¿âÊÇ·ñÒѾÆô¶¯¡£ |
+| `redis` | [`RedisReactiveHealthIndicator`](https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/data/redis/RedisReactiveHealthIndicator.java) | ¼ì²éRedis·þÎñÆ÷ÊÇ·ñÒѾÆô¶¯¡£ |
+
+
+
+| | Èç¹ûÓбØÒª£¬ÏìӦʽָ±ê»áÈ¡´ú³£¹æÖ¸±ê¡£ ÁíÍ⣬ÈκÎûÓб»Ã÷È·´¦ÀíµÄ `HealthIndicator` ¶¼»á±»×Ô¶¯°ü×°ÆðÀ´¡£ |
+| --- | --- |
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.health.groups)2.8.5\. Health·Ö×飨Health Groups£©
+
+
+
+ÓÐʱ£¬½«½¡¿µÖ¸±ê×éÖ¯³É¿ÉÒÔÓÃÓÚ²»Í¬Ä¿µÄµÄ×éÊǺÜÓÐÓõġ£
+
+
+
+
+
+Òª´´½¨Ò»¸ö½¡¿µÖ¸±ê×飬Äã¿ÉÒÔʹÓà `management.endpoint.health.group.` ÊôÐÔ£¬²¢Ö¸¶¨Ò»¸ö½¡¿µÖ¸±êIDÁбíÀ´ `include` »ò `exclude`¡£ ÀýÈ磬Ҫ´´½¨Ò»¸öÖ»°üÀ¨Êý¾Ý¿âÖ¸±êµÄ×飬Äã¿ÉÒÔ¶¨ÒåÈçÏ¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.endpoint.health.group.custom.include=db
+
+```
+
+
+
+
+
+
+
+È»ºóÄã¿ÉÒÔͨ¹ýµã»÷ `[localhost:8080/actuator/health/custom](http://localhost:8080/actuator/health/custom)` À´¼ì²é½á¹û¡£
+
+
+
+
+
+ͬÑù£¬Òª´´½¨Ò»¸ö×飬½«Êý¾Ý¿âÖ¸±êÅųýÔÚ¸Ã×éÖ®Í⣬²¢°üÀ¨ËùÓÐÆäËûÖ¸±ê£¬Äã¿ÉÒÔ¶¨ÒåÈçÏ¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.endpoint.health.group.custom.exclude=db
+
+```
+
+
+
+
+
+
+
+ĬÈÏÇé¿öÏ£¬×é¼Ì³ÐÁËÓëϵͳ½¡¿µÏàͬµÄ `StatusAggregator` ºÍ `HttpCodeStatusMapper` ÉèÖᣠȻ¶ø£¬ÄãÒ²¿ÉÒÔÔÚÿ¸ö×éµÄ»ù´¡É϶¨ÒåÕâЩ¡£ Èç¹ûÐèÒª£¬ÄãÒ²¿ÉÒÔ¸²¸Ç `show-details` ºÍ `roles` ÊôÐÔ¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.endpoint.health.group.custom.show-details=when-authorized
+management.endpoint.health.group.custom.roles=admin
+management.endpoint.health.group.custom.status.order=fatal,up
+management.endpoint.health.group.custom.status.http-mapping.fatal=500
+management.endpoint.health.group.custom.status.http-mapping.out-of-service=500
+
+```
+
+
+
+
+
+
+
+| | Èç¹ûÄãÐèҪע²á×Ô¶¨ÒåµÄ `StatusAggregator` »ò `HttpCodeStatusMapper` BeanÒÔÓÃÓÚ×飬Äã¿ÉÒÔʹÓà `@Qualifier("groupname")`¡£ |
+| --- | --- |
+
+
+
+
+
+Ò»¸ö½¡¿µ×éÒ²¿ÉÒÔ°üÀ¨/ÅųýÒ»¸ö `CompositeHealthContributor`¡£ ÄúÒ²¿ÉÒÔÖ»°üÀ¨/ÅųýÒ»¸ö `CompositeHealthContributor` µÄij¸ö×é¼þ¡£ Õâ¿ÉÒÔʹÓÃ×é¼þµÄÍêÈ«Ãû³ÆÀ´Íê³É£¬ÈçÏÂËùʾ¡£
+
+
+
+
+
+
+
+```
+management.endpoint.health.group.custom.include="test/primary"
+management.endpoint.health.group.custom.exclude="test/primary/b"
+```
+
+
+
+
+
+
+
+ÔÚÉÏÃæµÄÀý×ÓÖУ¬`custom` ×齫°üÀ¨Ãû³ÆÎª `primary` µÄ `HealthContributor`£¬ËüÊǸ´ºÏ `test` µÄÒ»¸ö×é³É²¿·Ö¡£ ÔÚÕâÀ`primary` ±¾Éí¾ÍÊÇÒ»¸ö¸´ºÏÌ壬Ãû×ÖΪ `b` µÄ `HealthContributor` ½«±»ÅųýÔÚ `custom` ×éÖ®Íâ¡£
+
+
+
+
+
+½¡¿µ×é¿ÉÒÔÔÚÖ÷¶Ë¿Ú»ò¹ÜÀí¶Ë¿ÚµÄ¶îÍâ·¾¶ÉÏÌṩ¡£ ÕâÔÚKubernetesµÈÔÆ»·¾³ÖкÜÓÐÓã¬ÔÚÕâЩ»·¾³ÖУ¬³öÓÚ°²È«¿¼ÂÇ£¬ÎªÖ´ÐÐÆ÷¶ËµãʹÓÃÒ»¸öµ¥¶ÀµÄ¹ÜÀí¶Ë¿ÚÊǺܳ£¼ûµÄ¡£ ÓÐÒ»¸öµ¥¶ÀµÄ¶Ë¿Ú¿ÉÄܵ¼Ö²»¿É¿¿µÄ½¡¿µ¼ì²é£¬ÒòΪ¼´Ê¹½¡¿µ¼ì²é³É¹¦£¬Ö÷Ó¦ÓóÌÐòÒ²¿ÉÄÜÎÞ·¨Õý³£¹¤×÷¡£ ½¡¿µ×é¿ÉÒÔÓÃÒ»¸ö¶îÍâµÄ·¾¶½øÐÐÅäÖã¬ÈçÏÂËùʾ¡£
+
+
+
+
+
+
+
+```
+management.endpoint.health.group.live.additional-path="server:/healthz"
+```
+
+
+
+
+
+
+
+Õ⽫ʹ `live` ½¡¿µ×éÔÚÖ÷·þÎñÆ÷¶Ë¿Ú `/healthz` ÉÏ¿ÉÓᣠǰ׺ÊÇÇ¿ÖÆÐԵ쬱ØÐëÊÇ `server:`£¨´ú±íÖ÷·þÎñÆ÷¶Ë¿Ú£©»ò `management:`£¨´ú±í¹ÜÀí¶Ë¿Ú£¬Èç¹ûÒÑÅäÖã©¡£ ·¾¶±ØÐëÊÇÒ»¸öµ¥Ò»µÄ·¾¶¶Î¡£
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.health.datasource)2.8.6\. Êý¾ÝÔ´½¡¿µ
+
+
+
+`DataSource` ½¡¿µÖ¸±êÏÔʾ±ê×¼Êý¾ÝÔ´ºÍ·ÓÉÊý¾ÝÔ´BeanµÄ½¡¿µ×´¿ö¡£ ·ÓÉÊý¾ÝÔ´µÄ½¡¿µ×´¿ö°üÀ¨Æäÿ¸öÄ¿±êÊý¾ÝÔ´µÄ½¡¿µ×´¿ö¡£ ÔÚ½¡¿µ¶ËµãµÄÏìÓ¦ÖУ¬Â·ÓÉÊý¾ÝÔ´µÄÿ¸öÄ¿±ê¶¼ÊÇͨ¹ýʹÓÃÆä·ÓɼüÀ´ÃüÃûµÄ¡£ Èç¹ûÄ㲻ϣÍûÔÚÖ¸±êµÄÊä³öÖаüÀ¨Â·ÓÉÊý¾ÝÔ´£¬Ç뽫 `management.health.db.ignore-routing-data-sources` ÉèÖÃΪ `true`¡£
+
+
+
+
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.kubernetes-probes)2.9\. Kubernetes ̽Õë
+
+
+
+²¿ÊðÔÚKubernetesÉϵÄÓ¦ÓóÌÐò¿ÉÒÔͨ¹ý [ÈÝÆ÷̽Õë](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes) ÌṩÓÐ¹ØÆäÄÚ²¿×´Ì¬µÄÐÅÏ¢¡£¸ù¾Ý [ÄãµÄKubernetesÅäÖÃ](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/)£¬kubelet»áµ÷ÓÃÕâЩ̽Õë²¢¶Ô½á¹û×ö³ö·´Ó¦¡£
+
+
+
+
+
+ĬÈÏÇé¿öÏ£¬Spring Boot»á¹ÜÀíÄãµÄ[Ó¦ÓÿÉÓÃÐÔ״̬](https://springdoc.cn/spring-boot/features.html#features.spring-application.application-availability)¡£ Èç¹û²¿ÊðÔÚKubernetes»·¾³ÖУ¬actuator´Ó `ApplicationAvailability` ½Ó¿ÚÖÐÊÕ¼¯ ¡°Liveness¡± ºÍ ¡°Readiness¡± ÐÅÏ¢£¬²¢ÔÚרÓÃ[½¡¿µÖ¸±ê](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.health.auto-configured-health-indicators)ÖÐʹÓÃÕâЩÐÅÏ¢¡£`LivenessStateHealthIndicator` ºÍ `ReadinessStateHealthIndicator`¡£ ÕâЩָ±êÏÔʾÔÚÈ«¾Ö½¡¿µ¶Ëµã£¨`"/actuator/health"`£©¡£ ËüÃÇÒ²¿ÉÒÔͨ¹ýʹÓÃ[½¡¿µ×é](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.health.groups)×÷Ϊµ¥¶ÀµÄHTTP̽Õ룺`"/actuator/health/liveness"` ºÍ `"/actuator/health/readiness"`¡£
+
+
+
+
+
+È»ºó£¬Äã¿ÉÒÔÓÃÒÔ϶˵ãÐÅÏ¢ÅäÖÃÄãµÄKubernetes»ù´¡ÉèÊ©¡£
+
+
+
+
+
+
+
+```
+livenessProbe:
+ httpGet:
+ path: "/actuator/health/liveness"
+ port:
+ failureThreshold: ...
+ periodSeconds: ...
+
+readinessProbe:
+ httpGet:
+ path: "/actuator/health/readiness"
+ port:
+ failureThreshold: ...
+ periodSeconds: ...
+```
+
+
+
+
+
+
+
+| | `` Ó¦¸Ã±»ÉèÖÃΪִÐÐÆ÷¶Ëµã¿ÉÓõĶ˿ڡ£ Ëü¿ÉÒÔÊÇÖ÷Web·þÎñÆ÷µÄ¶Ë¿Ú£¬Ò²¿ÉÒÔÊÇÒ»¸öµ¥¶ÀµÄ¹ÜÀí¶Ë¿Ú£¬Èç¹û `"management.server.port"` ÊôÐÔÒѾ±»ÉèÖᣠ|
+| --- | --- |
+
+
+
+
+
+Ö»Óе±Ó¦ÓóÌÐò[ÔÚKubernetes»·¾³ÖÐÔËÐÐʱ](https://springdoc.cn/spring-boot/deployment.html#deployment.cloud.kubernetes)£¬ÕâЩ½¡¿µ×é²Å»á×Ô¶¯ÆôÓᣠÄã¿ÉÒÔͨ¹ýʹÓà `management.endpoint.health.probes.enabled` ÅäÖÃÊôÐÔÔÚÈκλ·¾³ÖÐÆôÓÃËüÃÇ¡£
+
+
+
+
+
+| | Èç¹ûÒ»¸öÓ¦ÓóÌÐòµÄÆô¶¯Ê±¼ä³¬¹ýÁËÅäÖõÄÓÐЧÆÚ£¬Kubernetes »áÌáµ½ `"startupProbe"` ×÷Ϊһ¸ö¿ÉÄܵĽâ¾ö·½°¸¡£Ò»°ãÀ´Ëµ£¬ÕâÀï²»Ò»¶¨ÐèÒª `"startupProbe"`£¬ÒòΪ `"readinessProbe"` »áÔÚËùÓÐÆô¶¯ÈÎÎñÍê³É֮ǰʧЧ¡£ÕâÒâζ×ÅÄãµÄÓ¦ÓóÌÐòÔÚ×¼±¸ºÃ֮ǰ²»»áÊÕµ½Á÷Á¿¡£È»¶ø£¬Èç¹ûÄãµÄÓ¦ÓóÌÐòÐèÒªºÜ³¤Ê±¼ä²ÅÄÜÆô¶¯£¬¿ÉÒÔ¿¼ÂÇʹÓà `"startupProbe"` À´È·±£Kubernetes²»»áÔÚÄãµÄÓ¦ÓóÌÐòÆô¶¯¹ý³ÌÖÐɱËÀËü¡£Çë²ÎÔÄÃèÊö[̽ÕëÔÚÓ¦ÓóÌÐòÉúÃüÖÜÆÚÖеÄÐÐΪ](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.kubernetes-probes.lifecycle)µÄ²¿·Ö¡£ |
+| --- | --- |
+
+
+
+
+
+Èç¹ûÄãµÄActuator¶Ëµã±»²¿ÊðÔÚÒ»¸öµ¥¶ÀµÄ¹ÜÀíÉÏÏÂÎÄÖУ¬ÄÇôÕâЩ¶Ëµã¾Í²»»áÏñÖ÷³ÌÐòÄÇÑùʹÓÃÏàͬµÄÍøÂç»ù´¡ÉèÊ©£¨¶Ë¿Ú¡¢Á¬½Ó³Ø¡¢¿ò¼Ü×é¼þ£©¡£ ÔÚÕâÖÖÇé¿öÏ£¬¼´Ê¹Ö÷³ÌÐò²»ÄÜÕý³£¹¤×÷£¨ÀýÈ磬Ëü²»ÄܽÓÊÜеÄÁ¬½Ó£©£¬Ì½²â¼ì²éÒ²¿ÉÄܳɹ¦¡£ ÓÉÓÚÕâ¸öÔÒò£¬ÔÚÖ÷·þÎñÆ÷¶Ë¿ÚÉÏÉèÖà `liveness` ºÍ `readiness` ½¡¿µ×éÊǸöºÃÖ÷Òâ¡£ Õâ¿ÉÒÔͨ¹ýÉèÖÃÒÔÏÂÊôÐÔÀ´ÊµÏÖ¡£
+
+
+
+
+
+
+
+```
+management.endpoint.health.probes.add-additional-paths=true
+```
+
+
+
+
+
+
+
+Õ⽫ʹ `liveness` ÔÚ `/livez` ¿ÉÓã¬`readiness` ÔÚ `readyz` µÄÖ÷·þÎñÆ÷¶Ë¿Ú¿ÉÓá£
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.kubernetes-probes.external-state)2.9.1\. ÓÃKubernetes̽Õë¼ì²éÍⲿ״̬
+
+
+
+Ö´ÐÐÆ÷½« ¡°liveness¡± ºÍ ¡°readiness¡± ̽ÕëÅäÖÃΪ½¡¿µ×é¡£ÕâÒâζ×ÅËùÓеÄ[½¡¿µ×éµÄ¹¦ÄÜ](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.health.groups)¶ÔËüÃǶ¼ÊÇ¿ÉÓõġ£ÀýÈ磬Äã¿ÉÒÔÅäÖöîÍâµÄ½¡¿µÖ¸±ê¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.endpoint.health.group.readiness.include=readinessState,customCheck
+
+```
+
+
+
+
+
+
+
+ĬÈÏÇé¿öÏ£¬Spring Boot²»»áÏòÕâЩ×éÌí¼ÓÆäËû½¡¿µÖ¸±ê¡£
+
+
+
+
+
+¡°liveness¡± ̽Õë²»Ó¦¸ÃÒÀÀµÓÚÍⲿϵͳµÄ½¡¿µ¼ì²é¡£Èç¹û[Ó¦ÓóÌÐòµÄÓÐЧÐÔ״̬](https://springdoc.cn/spring-boot/features.html#features.spring-application.application-availability.liveness)±»ÆÆ»µ£¬Kubernetes»á³¢ÊÔͨ¹ýÖØÐÂÆô¶¯Ó¦ÓóÌÐòʵÀýÀ´½â¾öÕâ¸öÎÊÌâ¡£ÕâÒâζ×Å£¬Èç¹ûÒ»¸öÍⲿϵͳ£¨ÈçÊý¾Ý¿â¡¢Web API»òÍⲿ»º´æ£©³öÏÖ¹ÊÕÏ£¬Kubernetes¿ÉÄÜ»áÖØÐÂÆô¶¯ËùÓÐÓ¦ÓóÌÐòʵÀý£¬²¢²úÉú¼¶Áª¹ÊÕÏ¡£
+
+
+
+
+
+ÖÁÓÚ ¡°readiness¡± ̽²â£¬¼ì²éÍⲿϵͳµÄÑ¡Ôñ±ØÐëÓÉÓ¦ÓóÌÐò¿ª·¢ÈËÔ±½÷É÷×÷³ö¡£³öÓÚÕâ¸öÔÒò£¬Spring BootÔÚ×¼±¸×´Ì¬Ì½²âÖв»°üÀ¨ÈκζîÍâµÄ½¡¿µ¼ì²é¡£Èç¹û[Ó¦ÓóÌÐòʵÀýµÄreadiness stateÊÇunready](https://springdoc.cn/spring-boot/features.html#features.spring-application.application-availability.readiness)£¬Kubernetes¾Í²»»á½«Á÷Á¿Â·Óɵ½¸ÃʵÀý¡£Ò»Ð©Íⲿϵͳ¿ÉÄܲ»±»Ó¦ÓÃʵÀýËù¹²Ïí£¬ÔÚÕâÖÖÇé¿öÏ£¬ËüÃÇ¿ÉÒÔ±»°üÀ¨ÔÚ×¼±¸×´Ì¬Ì½²âÖС£ÆäËûÍⲿϵͳ¿ÉÄܲ»ÊÇÓ¦ÓóÌÐòµÄ¹Ø¼ü£¨Ó¦ÓóÌÐò¿ÉÄÜÓжÏ·Æ÷ºÍ»ØÍË£©£¬ÔÚÕâÖÖÇé¿öÏ£¬ËüÃǾø¶Ô²»Ó¦¸Ã±»°üÀ¨ÔÚÄÚ¡£²»ÐÒµÄÊÇ£¬Ò»¸ö±»ËùÓÐÓ¦ÓÃʵÀý¹²ÏíµÄÍⲿϵͳºÜ³£¼û£¬Äã±ØÐë×ö³öÅжϡ£°ÑËü°üÀ¨ÔÚ×¼±¸¾ÍÐ÷̽ÕëÖУ¬²¢ÆÚÍûµ±Íⲿ·þÎñ·¢Éú¹ÊÕÏʱ£¬Ó¦ÓóÌÐò»á±»Í£Ö¹·þÎñ£¬»òÕß²»°üÀ¨Ëü£¬²¢´¦Àí¶ÑÕ»Öиü¸ß²ã´ÎµÄ¹ÊÕÏ£¬Ò²Ðíͨ¹ýÔÚµ÷ÓÃÕßÖÐʹÓöÏ·Æ÷¡£
+
+
+
+
+
+| | Èç¹ûÒ»¸öÓ¦ÓóÌÐòµÄËùÓÐʵÀý¶¼Ã»ÓÐ×¼±¸ºÃ£¬`type=ClusterIP` »ò `NodePort` µÄKubernetes·þÎñ²»½ÓÊÜÈκδ«ÈëÁ¬½Ó¡£Ã»ÓÐHTTP´íÎóÏìÓ¦£¨503µÈ£©£¬ÒòΪûÓÐÁ¬½Ó¡£`type=LoadBalancer` µÄ·þÎñ¿ÉÄܽÓÊÜÒ²¿ÉÄܲ»½ÓÊÜÁ¬½Ó£¬ÕâÈ¡¾öÓÚÌṩÕß¡£Ò»¸öÓÐÃ÷È· [ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/) µÄ·þÎñÒ²»áÒÔÒ»ÖÖÈ¡¾öÓÚʵÏֵķ½Ê½½øÐÐÏìÓ¦¡ª?Èë¿Ú·þÎñ±¾Éí±ØÐë¾ö¶¨ÈçºÎ´¦ÀíÀ´×ÔÏÂÓ뵀 ¡°connection refused¡±¡£ÔÚ¸ºÔؾùºâÆ÷ºÍÈë¿ÚµÄÇé¿öÏ£¬HTTP 503ÊǺÜÓпÉÄܵġ£ |
+| --- | --- |
+
+
+
+
+
+ÁíÍ⣬Èç¹ûÒ»¸öÓ¦ÓóÌÐòʹÓà Kubernetes [autoscaling](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/)£¬Ëü¿ÉÄÜ»á¶ÔÓ¦ÓóÌÐò±»´Ó¸ºÔØÆ½ºâÆ÷ÖÐÈ¡³ö×ö³ö²»Í¬µÄ·´Ó¦£¬ÕâÈ¡¾öÓÚÆäautoscalerµÄÅäÖá£
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.kubernetes-probes.lifecycle)2.9.2\. Ó¦ÓóÌÐòÉúÃüÖÜÆÚºÍ̽Õë״̬
+
+
+
+Kubernetes ProbesÖ§³ÖµÄÒ»¸öÖØÒª·½ÃæÊÇËüÓëÓ¦ÓóÌÐòÉúÃüÖÜÆÚµÄÒ»ÖÂÐÔ¡£ `AvailabilityState`£¨¼´Ó¦ÓóÌÐòµÄÄÚ´æÄÚ²¿×´Ì¬£©ºÍʵ¼ÊµÄ̽Õ루±©Â¶¸Ã״̬£©Ö®¼ä´æÔÚ×ÅÏÔÖøµÄÇø±ð¡£ ºÍʵ¼ÊµÄ̽Õ루±©Â¶Á˸Ã״̬£©Ö®¼äÓкܴóµÄÇø±ð¡£ ¸ù¾ÝÓ¦ÓóÌÐòÉúÃüÖÜÆÚµÄ²»Í¬½×¶Î£¬Ì½Õë¿ÉÄÜÎÞ·¨Ê¹Óá£
+
+
+
+
+
+Spring BootÔÚ[Æô¶¯ºÍ¹Ø±ÕÆÚ¼ä·¢²¼application event](https://springdoc.cn/spring-boot/features.html#features.spring-application.application-events-and-listeners)£¬Ì½Õë¿ÉÒÔ¼àÌýÕâЩʼþ²¢±©Â¶³ö `AvailabilityState` ÐÅÏ¢¡£
+
+
+
+
+
+ϱíÏÔʾÁ˲»Í¬½×¶ÎµÄ `AvailabilityState` ºÍHTTP connectorµÄ״̬¡£
+
+
+
+
+
+µ±Ò»¸öSpring BootÓ¦ÓóÌÐòÆô¶¯Ê±¡£
+
+
+
+
+| Æô¶¯½×¶Î | LivenessState | ReadinessState | HTTP server | ±¸×¢ |
+| --- | --- | --- | --- | --- |
+| Starting | `BROKEN` | `REFUSING_TRAFFIC` | δÆô¶¯ | Kubernetes¼ì²é "liveness" ̽Õ룬Èç¹ûʱ¼ä¹ý³¤£¬¾ÍÖØÐÂÆô¶¯Ó¦ÓóÌÐò¡£ |
+| Started | `CORRECT` | `REFUSING_TRAFFIC` | ¾Ü¾øÇëÇó | Ó¦ÓóÌÐòÉÏÏÂÎı»Ë¢Ð¡£Ó¦ÓóÌÐòÖ´ÐÐÆô¶¯ÈÎÎñ£¬»¹Ã»ÓÐÊÕµ½Á÷Á¿¡£ |
+| Ready | `CORRECT` | `ACCEPTING_TRAFFIC` | ½ÓÊÜÇëÇó | Æô¶¯ÈÎÎñÒѾÍê³É¡£¸ÃÓ¦ÓóÌÐòÕýÔÚ½ÓÊÕÁ÷Á¿¡£ |
+
+
+
+µ±Ò»¸öSpring BootÓ¦ÓóÌÐò¹Ø±Õʱ¡£
+
+
+
+
+| Í£»ú½×¶Î | Liveness State | Readiness State | HTTP server | ±¸×¢ |
+| --- | --- | --- | --- | --- |
+| Running | `CORRECT` | `ACCEPTING_TRAFFIC` | ½ÓÊÜÇëÇó | ÒÑÒªÇ󹨱ա£ |
+| Graceful shutdown | `CORRECT` | `REFUSING_TRAFFIC` | еÄÇëÇ󱻾ܾø | Èç¹ûÆôÓ㬠[ÓÅÑŹػú»á´¦Àí¡°´¦ÀíÖС±µÄÇëÇó](https://springdoc.cn/spring-boot/web.html#web.graceful-shutdown)¡£ |
+| Shutdown complete | N/A | N/A | ·þÎñÆ÷±»¹Ø±Õ | Ó¦ÓóÌÐòÉÏÏÂÎı»¹Ø±Õ£¬Ó¦ÓóÌÐò±»¹Ø±Õ¡£ |
+
+
+
+| | ¹ØÓÚKubernetes²¿ÊðµÄ¸ü¶àÐÅÏ¢£¬Çë²Î¼û[KubernetesÈÝÆ÷ÉúÃüÖÜÆÚ](https://springdoc.cn/spring-boot/deployment.html#deployment.cloud.kubernetes.container-lifecycle)²¿·Ö¡£ |
+| --- | --- |
+
+
+
+
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.info)2.10\. Ó¦ÓÃÐÅÏ¢
+
+
+
+Ó¦ÓóÌÐòÐÅÏ¢¹«¿ªÁË´ÓÄãµÄ `ApplicationContext` Öж¨ÒåµÄËùÓÐ [`InfoContributor`](https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/InfoContributor.java) BeanÊÕ¼¯µÄ¸÷ÖÖÐÅÏ¢¡£ Spring Boot°üÀ¨Ò»Ð©×Ô¶¯ÅäÖÃµÄ `InfoContributor` Bean£¬ÄãÒ²¿ÉÒÔ±àд×Ô¼ºµÄ¡£
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.info.auto-configured-info-contributors)2.10.1\. ×Ô¶¯ÅäÖÃµÄ InfoContributor
+
+
+
+ÔÚÊʵ±µÄʱºò£¬Spring»á×Ô¶¯ÅäÖÃÒÔÏ `InfoContributor` Bean¡£
+
+
+
+
+| ID | Name | ˵Ã÷ | ǰÌáÌõ¼þ |
+| --- | --- | --- | --- |
+| `build` | [`BuildInfoContributor`](https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/BuildInfoContributor.java) | ±©Â¶Á˹¹½¨ÐÅÏ¢¡£ | Ò»¸ö `META-INF/build-info.properties` ×ÊÔ´¡£ |
+| `env` | [`EnvironmentInfoContributor`](https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/EnvironmentInfoContributor.java) | ±©Â¶ `Environment` ÖÐÃû³ÆÒÔ `info.` ¿ªÍ·µÄÈκÎÊôÐÔ¡£ | None. |
+| `git` | [`GitInfoContributor`](https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/GitInfoContributor.java) | ±©Â¶ÁËgitÐÅÏ¢¡£ | Ò»¸ö `git.properties` ×ÊÔ´¡£ |
+| `java` | [`JavaInfoContributor`](https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/JavaInfoContributor.java) | ±©Â¶JavaÔËÐÐʱ£¨Runtime£©ÐÅÏ¢¡£ | None. |
+| `os` | [`OsInfoContributor`](https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/OsInfoContributor.java) | ±©Â¶²Ù×÷ϵͳÐÅÏ¢¡£ | None. |
+
+
+
+¸öÈ˹±Ï×Õߣ¨contributor£©ÊÇ·ñ±»ÆôÓÃÊÇÓÉÆä `management.info..enabled` ÊôÐÔ¿ØÖÆ¡£ ²»Í¬µÄcontributor¶ÔÕâ¸öÊôÐÔÓв»Í¬µÄĬÈÏÖµ£¬ÕâÈ¡¾öÓÚËûÃǵÄÏȾöÌõ¼þºÍËûÃÇËù±©Â¶µÄÐÅÏ¢µÄÐÔÖÊ¡£
+
+
+
+
+
+ÓÉÓÚûÓÐÏȾöÌõ¼þ±íÃ÷ËüÃÇÓ¦¸Ã±»ÆôÓã¬`env`¡¢`java` ºÍ `os` contributor ĬÈÏÊǽûÓõġ£ ¿ÉÒÔͨ¹ýÉèÖà `management.info..enabled` ÊôÐÔΪ `true` À´ÆôÓÃËüÃÇ¡£
+
+
+
+
+
+`build` ºÍ `git` ÐÅÏ¢contributorĬÈÏÊÇÆôÓõġ£ ¿ÉÒÔͨ¹ý½«Æä `management.info..enabled` ÊôÐÔÉèÖÃΪ `false` À´½ûÓᣠÁíÍ⣬Ҫ½ûÓÃÿһ¸öĬÈÏÆôÓõÄcontributor£¬Ç뽫 `management.info.defaults.enabled` ÊôÐÔÉèΪ `false`¡£
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.info.custom-application-information)2.10.2\. ×Ô¶¨ÒåÓ¦ÓÃÐÅÏ¢£¨Application Information£©
+
+
+
+µ± `env` contributor ±»ÆôÓÃʱ£¬Äã¿ÉÒÔͨ¹ýÉèÖà `info.*` SpringÊôÐÔÀ´¶¨ÖÆ `info` ¶ËµãËù±©Â¶µÄÊý¾Ý¡£ `info` keyϵÄËùÓÐ `Environment` ÊôÐÔ¶¼»á×Ô¶¯±©Â¶¡£ ÀýÈ磬Äã¿ÉÒÔÔÚÄãµÄ `application.properties` ÎļþÖÐÌí¼ÓÒÔÏÂÉèÖá£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+info.app.encoding=UTF-8
+info.app.java.source=17
+info.app.java.target=17
+
+```
+
+
+
+
+
+
+
+| | ÓëÆäÓ²±àÂëÕâЩֵ£¬Ä㻹¿ÉÒÔ [ÔÚ¹¹½¨Ê±À©Õ¹ÐÅÏ¢ÊôÐÔ](https://springdoc.cn/spring-boot/howto.html#howto.properties-and-configuration.expand-properties)¡£¼ÙÉèÄãʹÓÃMaven£¬Äã¿ÉÒÔ½«Ç°ÃæµÄÀý×Ó¸ÄдÈçÏ¡£PropertiesYaml```info.app.encoding=@project.build.sourceEncoding@info.app.java.source=@java.version@info.app.java.target=@java.version@``` |
+| --- | --- |
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.info.git-commit-information)2.10.3\. Git Commit ÐÅÏ¢
+
+
+
+`info` ¶ËµãµÄÁíÒ»¸öÓÐÓõŦÄÜÊÇËüÄܹ»·¢²¼¹ØÓÚÄãµÄ `git` Ô´´úÂë¿âÔÚÏîÄ¿½¨Á¢Ê±µÄ״̬µÄÐÅÏ¢¡£ Èç¹ûÓÐÒ»¸ö `GitProperties` bean£¬Äã¿ÉÒÔʹÓà `info` ¶ËµãÀ´¹«²¼ÕâЩÊôÐÔ¡£
+
+
+
+
+
+| | Èç¹ûclasspathµÄ¸ù²¿ÓÐ `git.properties` Îļþ£¬`GitProperties` Bean¾Í»á±»×Ô¶¯ÅäÖ᣸ü¶àϸ½Ú¼û "[ÈçºÎÉú³ÉgitÐÅÏ¢](https://springdoc.cn/spring-boot/howto.html#howto.build.generate-git-info)"¡£ |
+| --- | --- |
+
+
+
+
+
+ĬÈÏÇé¿öÏ£¬¶Ëµã»á±©Â¶ `git.branch`¡¢`git.commit.id` ºÍ `git.commit.time` ÊôÐÔ£¨Èç¹û´æÔÚ£©¡£ Èç¹ûÄã²»ÏëÈÃÕâЩÊôÐÔ³öÏÖÔڶ˵ãÏìÓ¦ÖУ¬ÐèÒª´Ó `git.properties` ÎļþÖÐÅųýËüÃÇ¡£ Èç¹ûÄãÏëÏÔʾÍêÕûµÄgitÐÅÏ¢£¨¼´ `git.properties` µÄÈ«²¿ÄÚÈÝ£©£¬Ê¹Óà `management.info.git.mode` ÊôÐÔ£¬ÈçÏÂËùʾ¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.info.git.mode=full
+
+```
+
+
+
+
+
+
+
+Òª´Ó `info` ¶ËµãÍêÈ«½ûÓÃgitÌá½»ÐÅÏ¢£¬Çë `management.info.git.enabled` ÊôÐÔÉèΪ `false`£¬ÈçÏÂËùʾ¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.info.git.enabled=false
+
+```
+
+
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.info.build-information)2.10.4\. ¹¹½¨ÐÅÏ¢
+
+
+
+Èç¹û `BuildProperties` BeanÊÇ¿ÉÓõģ¬`info` ¶ËµãÒ²¿ÉÒÔ·¢²¼¹ØÓÚÄãµÄ¹¹½¨ÐÅÏ¢¡£Èç¹ûclasspathÖÐµÄ `META-INF/build-info.properties` Îļþ¿ÉÓ㬾ͻᷢÉúÕâÖÖÇé¿ö¡£
+
+
+
+
+
+| | MavenºÍGradle²å¼þ¶¼¿ÉÒÔÉú³É¸ÃÎļþ¡£Ïê¼û "[ÈçºÎÉú³É¹¹½¨ÐÅÏ¢](https://springdoc.cn/spring-boot/howto.html#howto.build.generate-info)"¡£ |
+| --- | --- |
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.info.java-information)2.10.5\. JavaÐÅÏ¢
+
+
+
+`info` ¶Ëµã·¢²¼Á˹ØÓÚÄãµÄJavaÔËÐл·¾³µÄÐÅÏ¢£¬¸ü¶àϸ½Ú¼û [`JavaInfo`](https://docs.spring.io/spring-boot/docs/3.1.0-SNAPSHOT/api/org/springframework/boot/info/JavaInfo.html)¡£
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.info.os-information)2.10.6\. ²Ù×÷ϵͳ£¨OS£©ÐÅÏ¢
+
+
+
+`info` ¶Ëµã·¢²¼¹ØÓÚÄãµÄ²Ù×÷ϵͳµÄÐÅÏ¢£¬¸ü¶àϸ½Ú¼û [`OsInfo`](https://docs.spring.io/spring-boot/docs/3.1.0-SNAPSHOT/api/org/springframework/boot/info/OsInfo.html)`¡£
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.info.writing-custom-info-contributors)2.10.7\. ±àд×Ô¶¨Òå InfoContributor
+
+
+
+ΪÁËÌṩ×Ô¶¨ÒåµÄÓ¦ÓóÌÐòÐÅÏ¢£¬Äã¿ÉÒÔ×¢²áʵÏÖ [`InfoContributor`](https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/InfoContributor.java) ½Ó¿ÚµÄSpring Bean¡£
+
+
+
+
+
+ÏÂÃæµÄÀý×Ó¹±Ï×ÁËÒ»¸öÖ»ÓÐÒ»¸öÖµµÄ `example` ÌõÄ¿¡£
+
+
+
+
+
+
+
+Java
+
+Kotlin
+
+
+
+
+
+```
+@Component
+public class MyInfoContributor implements InfoContributor {
+
+ @Override
+ public void contribute(Info.Builder builder) {
+ builder.withDetail("example", Collections.singletonMap("key", "value"));
+ }
+
+}
+
+```
+
+
+
+
+
+
+
+Èç¹ûÄãÇëÇó `info` ¶Ëµã£¬ÄãÓ¦¸Ã¿´µ½Ò»¸ö°üº¬ÒÔ϶îÍâÌõÄ¿µÄÏìÓ¦¡£
+
+
+
+
+
+
+
+```
+{
+ "example": {
+ "key" : "value"
+ }
+}
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+## [](https://springdoc.cn/spring-boot/actuator.html#actuator.monitoring)3\. ͨ¹ýHTTP½øÐÐ¼à¿ØºÍ¹ÜÀí
+
+
+
+
+
+Èç¹ûÄãÕýÔÚ¿ª·¢Ò»¸öWebÓ¦ÓóÌÐò£¬Spring Boot Actuator»á×Ô¶¯ÅäÖÃËùÓÐÆôÓõĶ˵㣬ʹÆäͨ¹ýHTTP¹«¿ª¡£ ĬÈϵĹßÀýÊÇʹÓö˵ãµÄ `id` ºÍ `/actuator` µÄǰ׺×÷ΪURL·¾¶¡£ ÀýÈ磬`health` ÒÔ `/actuator/health` µÄÐÎʽ¹«¿ª¡£
+
+
+
+
+
+| | Actuator Ö§³Ö Spring MVC¡¢Spring WebFluxºÍJersey¡£ Èç¹ûJerseyºÍSpring MVC¶¼¿ÉÓã¬Ôò»áʹÓÃSpring MVC¡£ |
+| --- | --- |
+
+
+
+
+
+| | ΪÁË»ñµÃAPIÎĵµ£¨ [HTML](https://docs.spring.io/spring-boot/docs/3.1.0-SNAPSHOT/actuator-api/htmlsingle) »ò [PDF](https://docs.spring.io/spring-boot/docs/3.1.0-SNAPSHOT/actuator-api/pdf/spring-boot-actuator-web-api.pdf) £©ÖмÇÔØµÄÕýÈ·µÄJSONÏìÓ¦£¬JacksonÊÇÒ»¸ö±ØÒªµÄÒÀÀµ¡£ |
+| --- | --- |
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/actuator.html#actuator.monitoring.customizing-management-server-context-path)3.1\. ¶¨ÖƹÜÀí¶Ëµã·¾¶
+
+
+
+ÓÐʱ£¬Îª¹ÜÀí¶Ëµã¶¨ÖÆÇ°×ºÊǺÜÓÐÓõġ£ ÀýÈ磬ÄãµÄÓ¦ÓóÌÐò¿ÉÄÜÒѾ½« `/actuator` ÓÃÓÚÆäËûÄ¿µÄ¡£ Äã¿ÉÒÔʹÓà `management.endpoints.web.base-path` ÊôÐÔÀ´¸Ä±ä¹ÜÀí¶ËµãµÄǰ׺£¬ÈçÏÂÃæµÄÀý×ÓËùʾ¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.endpoints.web.base-path=/manage
+
+```
+
+
+
+
+
+
+
+Ç°ÃæµÄ `application.properties` Àý×Ó½«¶Ëµã´Ó `/actuator/{id}` ¸ÄΪ `/manage/{id}` £¨ÀýÈ磬`/manage/info`£©¡£
+
+
+
+
+
+| | ³ý·Ç¹ÜÀí¶Ë¿Ú±»ÅäÖÃΪ[ʹÓò»Í¬µÄHTTP¶Ë¿Ú](https://springdoc.cn/spring-boot/actuator.html#actuator.monitoring.customizing-management-server-port)À´±©Â¶¶Ëµã£¬·ñÔò `management.endpoints.web.base-path` ÊÇÏà¶ÔÓÚ `server.servlet.context-path` £¨ÓÃÓÚServlet WebÓ¦Óã©»ò `spring.webflux.base-path` £¨ÓÃÓÚreactive WebÓ¦Óã©¡£Èç¹ûÅäÖÃÁË `management.server.port`£¬ `management.endpoints.web.base-path` ÊÇÏà¶ÔÓÚ `management.server.base-path` µÄ¡£ |
+| --- | --- |
+
+
+
+
+
+Èç¹ûÄãÏë°Ñ¶ËµãÓ³Éäµ½²»Í¬µÄ·¾¶£¬Äã¿ÉÒÔʹÓà `management.endpoints.web.path-mapping` ÊôÐÔ¡£
+
+
+
+
+
+ÏÂÃæµÄÀý×Ó½« `/actuator/health` ÖØÐÂÓ³ÉäΪ `/healthcheck`¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.endpoints.web.base-path=/
+management.endpoints.web.path-mapping.health=healthcheck
+
+```
+
+
+
+
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/actuator.html#actuator.monitoring.customizing-management-server-port)3.2\. ¶¨ÖƹÜÀí·þÎñÆ÷¶Ë¿Ú
+
+
+
+¶ÔÓÚ»ùÓÚÔÆµÄ²¿ÊðÀ´Ëµ£¬Í¨¹ýʹÓÃĬÈϵÄHTTP¶Ë¿ÚÀ´±©Â¶¹ÜÀí¶ËµãÊÇÒ»¸öÃ÷ÖǵÄÑ¡Ôñ¡£ È»¶ø£¬Èç¹ûÄãµÄÓ¦ÓóÌÐòÔÚÄã×Ô¼ºµÄÊý¾ÝÖÐÐÄÄÚÔËÐУ¬Äã¿ÉÄܸüϲ»¶Ê¹Óò»Í¬µÄHTTP¶Ë¿ÚÀ´±©Â¶¶Ëµã¡£
+
+
+
+
+
+Äã¿ÉÒÔÉèÖà `management.server.port` ÊôÐÔÀ´¸Ä±äHTTP¶Ë¿Ú£¬ÈçÏÂÃæµÄÀý×ÓËùʾ¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.server.port=8081
+
+```
+
+
+
+
+
+
+
+| | ÔÚ Cloud Foundry ÉÏ£¬Ä¬ÈÏÇé¿öÏ£¬Ó¦ÓóÌÐò½öÔÚ¶Ë¿Ú 8080 ÉϽÓÊÕ HTTP ºÍ TCP ·ÓɵÄÇëÇó¡£ Èç¹ûÄúÏëÔÚ Cloud Foundry ÉÏʹÓÃ×Ô¶¨Òå¹ÜÀí¶Ë¿Ú£¬ÄúÐèÒªÃ÷È·ÉèÖÃÓ¦ÓóÌÐòµÄ·ÓÉÒÔ½«Á÷Á¿×ª·¢µ½×Ô¶¨Òå¶Ë¿Ú¡£ |
+| --- | --- |
+
+
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/actuator.html#actuator.monitoring.management-specific-ssl)3.3\. ÅäÖÃÕë¶ÔManagement£¨¹ÜÀí£©²ãµÄSSL
+
+
+
+µ±ÅäÖÃΪʹÓÃ×Ô¶¨Òå¶Ë¿Úʱ£¬ÄãÒ²¿ÉÒÔͨ¹ýʹÓø÷ÖÖ `management.server.ssl.*` ÊôÐÔÀ´ÅäÖùÜÀí·þÎñÆ÷µÄSSL¡£ ÀýÈ磬ÕâÑù×ö¿ÉÒÔÈùÜÀí·þÎñÆ÷ͨ¹ýHTTPÌṩ·þÎñ£¬¶øÖ÷Ó¦ÓóÌÐòʹÓÃHTTPS£¬ÈçÒÔÏÂÊôÐÔÉèÖÃËùʾ¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+server.port=8443
+server.ssl.enabled=true
+server.ssl.key-store=classpath:store.jks
+server.ssl.key-password=secret
+management.server.port=8080
+management.server.ssl.enabled=false
+
+```
+
+
+
+
+
+
+
+»òÕߣ¬Ö÷·þÎñÆ÷ºÍ¹ÜÀí·þÎñÆ÷¶¼¿ÉÒÔʹÓÃSSL£¬µ«Ê¹Óò»Í¬µÄÃÜÔ¿´æ´¢£¬ÈçÏÂËùʾ¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+server.port=8443
+server.ssl.enabled=true
+server.ssl.key-store=classpath:main.jks
+server.ssl.key-password=secret
+management.server.port=8080
+management.server.ssl.enabled=true
+management.server.ssl.key-store=classpath:management.jks
+management.server.ssl.key-password=secret
+
+```
+
+
+
+
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/actuator.html#actuator.monitoring.customizing-management-server-address)3.4\. ¶¨ÖÆManagement£¨¹ÜÀí£©·þÎñÆ÷µØÖ·
+
+
+
+Äã¿ÉÒÔͨ¹ýÉèÖà `management.server.address` ÐÔÀ´¶¨ÖƹÜÀí¶ËµãµÄ¿ÉÓõØÖ·¡£ Èç¹ûÄãÏëÖ»ÔÚÄÚ²¿»òÃæÏòÔËάµÄÍøÂçÉϼàÌý£¬»òÕßÖ»¼àÌýÀ´×Ô `localhost` µÄÁ¬½Ó£¬ÕâÑù×ö»áºÜÓÐÓá£
+
+
+
+
+
+| | Ö»Óе±¶Ë¿ÚÓëÖ÷·þÎñÆ÷¶Ë¿Ú²»Í¬Ê±£¬Äã²ÅÄÜÔÚ²»Í¬µÄµØÖ·ÉϽøÐмàÌý¡£ |
+| --- | --- |
+
+
+
+
+
+ÏÂÃæµÄÀý×Ó `application.properties` ²»ÔÊÐíÔ¶³Ì¹ÜÀíÁ¬½Ó¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.server.port=8081
+management.server.address=127.0.0.1
+
+```
+
+
+
+
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/actuator.html#actuator.monitoring.disabling-http-endpoints)3.5\. ½ûÓÃHTTP¶Ëµã
+
+
+
+Èç¹ûÄã²»Ïëͨ¹ýHTTP±©Â¶¶Ëµã£¬Äã¿ÉÒ԰ѹÜÀí¶Ë¿ÚÉèÖÃΪ `-1`£¬ÈçÏÂÀýËùʾ¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.server.port=-1
+
+```
+
+
+
+
+
+
+
+ÄãÒ²¿ÉÒÔͨ¹ýʹÓà `management.endpoints.web.exposure.exclude` ÊôÐÔÀ´ÊµÏÖ£¬ÈçÏÂÀýËùʾ¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.endpoints.web.exposure.exclude=*
+
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+## [](https://springdoc.cn/spring-boot/actuator.html#actuator.jmx)4\. ͨ¹ýJMX½øÐÐ¼à¿ØºÍ¹ÜÀí
+
+
+
+
+
+Java¹ÜÀíÀ©Õ¹£¨JMX£©ÌṩÁËÒ»¸ö±ê×¼µÄ»úÖÆÀ´¼à¿ØºÍ¹ÜÀíÓ¦ÓóÌÐò¡£ ĬÈÏÇé¿öÏ£¬¸Ã¹¦ÄÜδ±»ÆôÓᣠÄã¿ÉÒÔͨ¹ýÉèÖà `spring.jmx.enabled` ÅäÖÃÊôÐÔΪ `true` À´´ò¿ªËü¡£ Spring Boot½«×îºÏÊ浀 `MBeanServer` ×÷ΪIDΪ `mbeanServer` µÄBean¹«¿ª¡£ ÄãµÄÈκδøÓÐSpring JMX×¢½âµÄBean£¨`@ManagedResource`¡¢`@ManagedAttribute` »ò `@ManagedOperation`£©¶¼»á±©Â¶¸øËü¡£
+
+
+
+
+
+Èç¹ûÄãµÄƽ̨ÌṩÁËÒ»¸ö±ê×¼µÄ `MBeanServer` £¬Spring Boot»áʹÓÃËü£¬²¢ÔÚ±ØÒªÊ±Ä¬ÈÏΪVM `MBeanServer`¡£ Èç¹ûËùÓÐÕâЩ¶¼Ê§°ÜÁË£¬¾Í»á´´½¨Ò»¸öÐ嵀 `MBeanServer`¡£
+
+
+
+
+
+¸ü¶àϸ½Ú¼û [`JmxAutoConfiguration`](https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jmx/JmxAutoConfiguration.java) Àà¡£
+
+
+
+
+
+ĬÈÏÇé¿öÏ£¬Spring BootÒ²½«¹ÜÀí¶Ëµã×÷ΪJMX MBeansÔÚ `org.springframework.boot` ÓòϹ«¿ª¡£ ÒªÍêÈ«¿ØÖÆJMXÓòÖеĶ˵ã×¢²á£¬¿ÉÒÔ¿¼ÂÇ×¢²áÄã×Ô¼ºµÄ `EndpointObjectNameFactory` ʵÏÖ¡£
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/actuator.html#actuator.jmx.custom-mbean-names)4.1\. ×Ô¶¨ÒåMBeanÃû³Æ
+
+
+
+MBeanµÄÃû×Öͨ³£Óɶ˵ãµÄ `id` Éú³É¡£ ÀýÈ磬 `health` ¶Ëµã±»±©Â¶Îª `org.springframework.boot:type=Endpoint,name=Health`¡£
+
+
+
+
+
+Èç¹ûÄãµÄÓ¦ÓóÌÐò°üº¬Ò»¸öÒÔÉϵÄSpring `ApplicationContext`£¬Äã¿ÉÄܻᷢÏÖÃû×Ö·¢Éú³åÍ»¡£ ΪÁ˽â¾öÕâ¸öÎÊÌ⣬Äã¿ÉÒÔ½« `spring.jmx.unique-names` ÊôÐÔÉèÖÃΪ `true`£¬ÕâÑùMBeanµÄÃû×Ö¾Í×ÜÊÇΨһµÄ¡£
+
+
+
+
+
+Ä㻹¿ÉÒÔ×Ô¶¨Ò屩¶¶ËµãµÄJMXÓò¡£ ÏÂÃæµÄÉèÖÃÏÔʾÁËÔÚ `application.properties` ÖÐÕâÑù×öµÄÒ»¸öÀý×Ó¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+spring.jmx.unique-names=true
+management.endpoints.jmx.domain=com.example.myapp
+
+```
+
+
+
+
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/actuator.html#actuator.jmx.disable-jmx-endpoints)4.2\. ½ûÓÃJMX¶Ëµã
+
+
+
+Èç¹ûÄã²»Ïëͨ¹ýJMX±©Â¶¶Ëµã£¬Äã¿ÉÒÔ°Ñ `management.endpoints.jmx.exposure.exclude` ÊôÐÔÉèÖÃΪ `*`£¬ÈçÏÂÀýËùʾ¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.endpoints.jmx.exposure.exclude=*
+
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+## [](https://springdoc.cn/spring-boot/actuator.html#actuator.observability)5\. ¿É¹Û²âÐÔ£¨Observability£©
+
+
+
+
+
+¿É¹Û²ìÐÔÊÇÖ¸´ÓÍⲿ¹Û²ìÒ»¸öÔËÐÐÖеÄϵͳµÄÄÚ²¿×´Ì¬µÄÄÜÁ¦¡£ËüÓÉÈý¸öÖ§Öù×é³É£ºÈÕÖ¾¡¢¶ÈÁ¿ºÍ¸ú×Ù¡£
+
+
+
+
+
+¶ÔÓÚ¶ÈÁ¿ºÍ¸ú×Ù£¬Spring BootʹÓà [Micrometer Observation](https://micrometer.io/docs/observation)¡£Òª´´½¨Äã×Ô¼ºµÄ¹Û²ì£¨Õ⽫µ¼Ö¶ÈÁ¿ºÍ¸ú×Ù£©£¬Äã¿ÉÒÔ×¢ÈëÒ»¸ö `ObservationRegistry`¡£
+
+
+
+
+
+
+
+```
+@Component
+public class MyCustomObservation {
+
+ private final ObservationRegistry observationRegistry;
+
+ public MyCustomObservation(ObservationRegistry observationRegistry) {
+ this.observationRegistry = observationRegistry;
+ }
+
+ public void doSomething() {
+ Observation.createNotStarted("doSomething", this.observationRegistry)
+ .lowCardinalityKeyValue("locale", "en-US")
+ .highCardinalityKeyValue("userId", "42")
+ .observe(() -> {
+ // Execute business logic here
+ });
+ }
+
+}
+
+```
+
+
+
+
+
+
+
+| | µÍ¿¨¶ÈµÄ±êÇ©½«±»Ìí¼Óµ½Ö¸±êºÍ×·×ÙÖУ¬¶ø¸ß¿¨¶ÈµÄ±êÇ©½«Ö»±»Ìí¼Óµ½×·×ÙÖС£ |
+| --- | --- |
+
+
+
+
+
+`ObservationPredicate`¡¢`GlobalObservationConvention` ºÍ `ObservationHandler` ÀàÐ굀 Bean ½«±»×Ô¶¯×¢²áµ½ `ObservationRegistry` ÉÏ¡£Äã¿ÉÒÔÁíÍâ×¢²áÈÎÒâÊýÁ¿µÄ `ObservationRegistryCustomizer` BeanÀ´½øÒ»²½ÅäÖÃ×¢²á±í¡£
+
+
+
+
+
+¸ü¶àϸ½ÚÇë¼û [Micrometer Observation Îĵµ](https://micrometer.io/docs/observation)¡£
+
+
+
+
+
+| | JDBCºÍR2DBCµÄ¿É¹Û²ìÐÔ£¨Observability£©¿ÉÒÔʹÓõ¥¶ÀµÄÏîÄ¿½øÐÐÅäÖ᣶ÔÓÚ JDBC£¬ [Datasource Micrometer ÏîÄ¿](https://github.com/jdbc-observations/datasource-micrometer) ÌṩÁËÒ»¸ö Spring Boot Starter£¬ÔÚµ÷ÓÃJDBC²Ù×÷ʱ×Ô¶¯´´½¨¹Û²ì¡£ÔÚ [²Î¿¼Îĵµ](https://jdbc-observations.github.io/datasource-micrometer/docs/current/docs/html/)ÖÐÔĶÁ¸ü¶à¹ØÓÚËüµÄÐÅÏ¢¡£¶ÔÓÚR2DBC£¬ [R2DBC¹Û²ìµÄSpring Boot×Ô¶¯ÅäÖÃ](https://github.com/spring-projects-experimental/r2dbc-micrometer-spring-boot) ¿ÉÒÔΪR2DBC²éѯµ÷Óô´½¨¹Û²ì¡£ |
+| --- | --- |
+
+
+
+
+
+½ÓÏÂÀ´µÄÕ½ڽ«Ìṩ¹ØÓÚÈÕÖ¾¡¢Ö¸±êºÍ×·×ٵĸü¶àϸ½Ú¡£
+
+
+
+
+
+
+
+
+
+## [](https://springdoc.cn/spring-boot/actuator.html#actuator.loggers)6\. ÈÕÖ¾¼Ç¼Æ÷£¨Logger£©
+
+
+
+
+
+Spring Boot Actuator°üÀ¨ÔÚÔËÐÐʱ²é¿´ºÍÅäÖÃÓ¦ÓóÌÐòµÄÈÕÖ¾¼¶±ðµÄ¹¦ÄÜ¡£ Äã¿ÉÒԲ鿴Õû¸öÁбí»òµ¥¸öÈÕÖ¾¼Ç¼Æ÷µÄÅäÖã¬ËüÓÉÃ÷È·ÅäÖõÄÈÕÖ¾¼¶±ðÒÔ¼°ÈÕÖ¾¿ò¼Ü¸³ÓèËüµÄÓÐЧÈÕÖ¾¼¶±ð×é³É¡£ ÕâЩ¼¶±ð¿ÉÒÔÊÇÒÔÏÂÖ®Ò»¡£
+
+
+
+
+
+* `TRACE`
+
+* `DEBUG`
+
+* `INFO`
+
+* `WARN`
+
+* `ERROR`
+
+* `FATAL`
+
+* `OFF`
+
+* `null`
+
+
+
+
+
+`null` ±íʾûÓÐÃ÷È·µÄÅäÖá£
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/actuator.html#actuator.loggers.configure)6.1\. ÅäÖÃÒ»¸ö Logger
+
+
+
+ÒªÅäÖÃÒ»¸ö¸ø¶¨µÄ¼Ç¼Æ÷£¬`POST` Ò»¸ö²¿·ÖʵÌåµ½×ÊÔ´µÄURI£¬ÈçÏÂÃæµÄÀý×ÓËùʾ¡£
+
+
+
+
+
+
+
+```
+{
+ "configuredLevel": "DEBUG"
+}
+```
+
+
+
+
+
+
+
+| | Òª ¡°reset¡± £¨ÖØÖ㩼ǼÆ÷µÄÌØ¶¨¼¶±ð£¨²¢Ê¹ÓÃĬÈÏÅäÖã©£¬Äã¿ÉÒÔ´«µÝÒ»¸ö `null` µÄÖµ×÷Ϊ `configuredLevel`¡£ |
+| --- | --- |
+
+
+
+
+
+
+
+
+
+
+
+## [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics)7\. Ö¸±ê£¨Metrics£©
+
+
+
+
+
+Spring Boot ActuatorΪ [Micrometer](https://micrometer.io/) ÌṩÁËÒÀÀµ¹ÜÀíºÍ×Ô¶¯ÅäÖã¬MicrometerÊÇÒ»¸öÖ§³Ö [ÖÚ¶à¼à¿ØÏµÍ³](https://micrometer.io/docs) µÄÓ¦ÓóÌÐòÖ¸±ê½Ó¿Ú£¬°üÀ¨¡£
+
+
+
+
+
+* [AppOptics](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.export.appoptics)
+
+* [Atlas](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.export.atlas)
+
+* [Datadog](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.export.datadog)
+
+* [Dynatrace](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.export.dynatrace)
+
+* [Elastic](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.export.elastic)
+
+* [Ganglia](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.export.ganglia)
+
+* [Graphite](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.export.graphite)
+
+* [Humio](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.export.humio)
+
+* [Influx](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.export.influx)
+
+* [JMX](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.export.jmx)
+
+* [KairosDB](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.export.kairos)
+
+* [New Relic](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.export.newrelic)
+
+* [OpenTelemetry](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.export.otlp)
+
+* [Prometheus](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.export.prometheus)
+
+* [SignalFx](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.export.signalfx)
+
+* [Simple (in-memory)](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.export.simple)
+
+* [Stackdriver](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.export.stackdriver)
+
+* [StatsD](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.export.statsd)
+
+* [Wavefront](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.export.wavefront)
+
+
+
+
+
+| | ÒªÁ˽â¸ü¶à¹ØÓÚMicrometerµÄ¹¦ÄÜ£¬Çë²Î¼ûÆä [²Î¿¼Îĵµ](https://micrometer.io/docs)£¬ÌرðÊÇ [¸ÅÄ·Ö](https://micrometer.io/docs/concepts)¡£ |
+| --- | --- |
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.getting-started)7.1\. ÈëÃÅ
+
+
+
+Spring Boot»á×Ô¶¯ÅäÖÃÒ»¸ö¸´ºÏµÄ `MeterRegistry`£¬²¢ÎªËüÔÚclasspathÉÏ·¢ÏÖµÄÿ¸öÖ§³ÖµÄʵÏÖÌí¼ÓÒ»¸ö×¢²á±í¡£ ÔÚÄãµÄÔËÐÐʱclasspathÖÐÓÐ¶Ô `micrometer-registry-{system}` µÄÒÀÀµ¾Í×ãÒÔÈÃSpring BootÅäÖÃ×¢²á±íÁË¡£
+
+
+
+
+
+´ó¶àÊý×¢²á±íÓй²Í¬µÄÌØµã¡£ ÀýÈ磬¼´Ê¹ Micrometer ×¢²á±íµÄʵÏÖÔÚclasspathÉÏ£¬ÄãÒ²¿ÉÒÔ½ûÓÃÒ»¸öÌØ¶¨µÄ×¢²á±í¡£ ÏÂÃæµÄÀý×Ó½ûÓÃÁËDatadog¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.datadog.metrics.export.enabled=false
+
+```
+
+
+
+
+
+
+
+ÄãÒ²¿ÉÒÔ½ûÓÃËùÓеÄ×¢²á±í£¬³ý·Ç×¢²á±íÌØ¶¨ÊôÐÔÁíÓÐ˵Ã÷£¬ÈçÏÂÀýËùʾ¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.defaults.metrics.export.enabled=false
+
+```
+
+
+
+
+
+
+
+Spring Boot»¹½«ÈκÎ×Ô¶¯ÅäÖõÄ×¢²á±íÌí¼Óµ½ `Metrics` ÀàÉϵÄÈ«¾Ö¾²Ì¬¸´ºÏ×¢²á±í£¬³ý·ÇÄãÃ÷È·¸æËßËü²»ÒªÕâÑù×ö¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.metrics.use-global-registry=false
+
+```
+
+
+
+
+
+
+
+Äã¿ÉÒÔ×¢²áÈÎÒâÊýÁ¿µÄ `MeterRegistryCustomizer` BeanÀ´½øÒ»²½ÅäÖÃ×¢²á±í£¬±ÈÈçÔÚÈÎºÎ±í±»×¢²á֮ǰӦÓÃÆÕͨ±êÇ©¡£
+
+
+
+
+
+
+
+Java
+
+Kotlin
+
+
+
+
+
+```
+@Configuration(proxyBeanMethods = false)
+public class MyMeterRegistryConfiguration {
+
+ @Bean
+ public MeterRegistryCustomizer metricsCommonTags() {
+ return (registry) -> registry.config().commonTags("region", "us-east-1");
+ }
+
+}
+
+```
+
+
+
+
+
+
+
+Äã¿ÉÒÔͨ¹ý¸ü¾ßÌåµÄ·ºÐͽ«¶¨ÖÆÓ¦ÓÃÓÚÌØ¶¨µÄ×¢²á±íʵÏÖ¡£
+
+
+
+
+
+
+
+Java
+
+Kotlin
+
+
+
+
+
+```
+@Configuration(proxyBeanMethods = false)
+public class MyMeterRegistryConfiguration {
+
+ @Bean
+ public MeterRegistryCustomizer graphiteMetricsNamingConvention() {
+ return (registry) -> registry.config().namingConvention(this::name);
+ }
+
+ private String name(String name, Meter.Type type, String baseUnit) {
+ return ...
+ }
+
+}
+
+```
+
+
+
+
+
+
+
+Spring Boot»¹ [ÅäÖÃÁËÄÚÖà instrumentation](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.supported)£¬Äã¿ÉÒÔͨ¹ýÅäÖûòרÓÃ×¢½â±ê¼ÇÀ´¿ØÖÆ¡£
+
+
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.export)7.2\. Ö§³ÖµÄ¼à¿ØÏµÍ³
+
+
+
+±¾½Ú¼òÒª½éÉÜÿ¸öÖ§³ÖµÄ¼à¿ØÏµÍ³¡£
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.export.appoptics)7.2.1\. AppOptics
+
+
+
+ĬÈÏÇé¿öÏ£¬AppOptics×¢²áÖÐÐĻᶨÆÚ½«Ö¸±êÍÆË͵½ `[api.appoptics.com/v1/measurements](https://api.appoptics.com/v1/measurements)`¡£Òª½«Ö¸±êµ¼³öµ½ SaaS [AppOptics](https://micrometer.io/docs/registry/appOptics)£¬±ØÐëÌṩÄãµÄAPIÁîÅÆ¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.appoptics.metrics.export.api-token=YOUR_TOKEN
+
+```
+
+
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.export.atlas)7.2.2\. Atlas
+
+
+
+ĬÈÏÇé¿öÏ£¬Ö¸±ê»á±»µ¼³öµ½ÔËÐÐÔÚÄã±¾µØ»úÆ÷É쵀 [Atlas](https://micrometer.io/docs/registry/atlas)¡£Äã¿ÉÒÔÌṩ [Atlas server](https://github.com/Netflix/atlas) µÄλÖá£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.atlas.metrics.export.uri=https://atlas.example.com:7101/api/v1/publish
+
+```
+
+
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.export.datadog)7.2.3\. Datadog
+
+
+
+Ò»¸öDatadog×¢²áÖÐÐĻᶨÆÚ½«Ö¸±êÍÆË͵½ [datadoghq](https://www.datadoghq.com/)¡£ Òªµ¼³öÖ¸±êµ½ [Datadog](https://micrometer.io/docs/registry/datadog)£¬Äã±ØÐëÌṩÄãµÄAPIÃÜÔ¿¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.datadog.metrics.export.api-key=YOUR_KEY
+
+```
+
+
+
+
+
+
+
+Èç¹ûÄãÁíÍâÌṩһ¸öÓ¦ÓÃÃÜÔ¿£¨¿ÉÑ¡£©£¬ÄÇôԪÊý¾Ý£¬ÈçÒDZíÃèÊö¡¢ÀàÐͺͻù±¾µ¥Î»Ò²½«±»µ¼³ö¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.datadog.metrics.export.api-key=YOUR_API_KEY
+management.datadog.metrics.export.application-key=YOUR_APPLICATION_KEY
+
+```
+
+
+
+
+
+
+
+ĬÈÏÇé¿öÏ£¬Ö¸±ê±»·¢Ë͵½DatadogÃÀ¹ú [site](https://docs.datadoghq.com/getting_started/site) £¨`[api.datadoghq.com](https://api.datadoghq.com/)`£©¡£ Èç¹ûÄãµÄDatadogÏîÄ¿ÍйÜÔÚÆäËûÍøÕ¾ÉÏ£¬»òÕßÄãÐèҪͨ¹ý´úÀí·¢ËÍÖ¸±ê£¬ÇëÏàÓ¦ÅäÖÃURI¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.datadog.metrics.export.uri=https://api.datadoghq.eu
+
+```
+
+
+
+
+
+
+
+Ä㻹¿ÉÒԸıäÏòDatadog·¢ËÍÖ¸±êµÄʱ¼ä¼ä¸ô¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.datadog.metrics.export.step=30s
+
+```
+
+
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.export.dynatrace)7.2.4\. Dynatrace
+
+
+
+DynatraceÌṩÁËÁ½¸öÖ¸±êÉãÈ¡API£¬¶¼ÊÇΪ [Micrometer](https://micrometer.io/docs/registry/dynatrace) ʵÏֵġ£Äã¿ÉÒÔÔÚ [ÕâÀï](https://www.dynatrace.com/support/help/how-to-use-dynatrace/metrics/metric-ingestion/ingestion-methods/micrometer) ÕÒµ½Dynatrace¹ØÓÚMicrometerÖ¸±êÉãÈëµÄÎĵµ¡£`v1` ÃüÃû¿Õ¼äÖеÄÅäÖÃÊôÐÔÖ»ÊÊÓÃÓÚµ¼³öµ½ [Timeseries v1 API](https://www.dynatrace.com/support/help/dynatrace-api/environment-api/metric-v1/) ʱ¡£`v2` ÃüÃû¿Õ¼äÖеÄÅäÖÃÊôÐÔÖ»ÊÊÓÃÓÚµ¼³öµ½ [Metrics v2 API](https://www.dynatrace.com/support/help/dynatrace-api/environment-api/metric-v2/post-ingest-metrics/) ʱ¡£Çë×¢Ò⣬¸Ã¼¯³Éÿ´ÎÖ»Äܵ¼³öµ½APIµÄ `v1` »ò `v2` °æ±¾£¬`v2` °æ±¾ÊÇÊ×Ñ¡¡£Èç¹û `device-id`£¨v1°æÐèÒª£¬µ«ÔÚv2°æÖв»Ê¹Óã©ÔÚ `v1` °æÃüÃû¿Õ¼äÖб»ÉèÖã¬ÄÇômetric½«±»µ¼³öµ½ `v1` °æ¶Ëµã¡£·ñÔò£¬¾Í¼Ù¶¨ÊÇ `v2` °æ±¾¡£
+
+
+
+
+
+##### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.export.dynatrace.v2-api)v2 API
+
+
+
+Äã¿ÉÒÔͨ¹ýÁ½ÖÖ·½Ê½Ê¹ÓÃv2 API¡£
+
+
+
+
+
+###### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.export.dynatrace.v2-api.auto-config)×Ô¶¯ÅäÖÃ
+
+
+
+Dynatrace×Ô¶¯ÅäÖÃÊÊÓÃÓÚÓÉOneAgent»òDynatrace Operator for Kubernetes¼à¿ØµÄÖ÷»ú¡£
+
+
+
+
+
+**±¾µØOneAgent£º**Èç¹ûÖ÷»úÉÏÔËÐÐOneAgent£¬Ö¸±ê»á×Ô¶¯Êä³öµ½ [local OneAgent ingest endpoint](https://www.dynatrace.com/support/help/how-to-use-dynatrace/metrics/metric-ingestion/ingestion-methods/local-api/) ¡£ ÉãÈ¡¶Ëµã½«Ö¸±êת·¢µ½Dynatraceºó¶Ë¡£
+
+
+
+
+
+**Dynatrace Kubernetes Operator£º**ÔÚ°²×°ÁËDynatrace OperatorµÄKubernetesÖÐÔËÐÐʱ£¬×¢²á±í½«×Ô¶¯´Ó²Ù×÷Ô±ÄÇÀï»ñÈ¡ÄãµÄ¶ËµãURIºÍAPIÁîÅÆ¡£
+
+
+
+
+
+ÕâÊÇĬÈÏÐÐΪ£¬³ýÁËÒÀÀµ `io.micrometer:micrometer-registry-dynatrace` Ö®Í⣬²»ÐèÒªÌØ±ðµÄÉèÖá£
+
+
+
+
+
+
+
+###### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.export.dynatrace.v2-api.manual-config)ÊÖ¶¯ÅäÖÃ
+
+
+
+Èç¹ûûÓÐ×Ô¶¯ÅäÖã¬ÔòÐèÒª [Metrics v2 API](https://www.dynatrace.com/support/help/dynatrace-api/environment-api/metric-v2/post-ingest-metrics/) µÄ¶ËµãºÍÒ»¸ö API ÁîÅÆ¡£APIÁîÅÆ±ØÐëÓÐ ¡°Ingest metrics¡± £¨`metrics.ingest`£©µÄȨÏÞÉèÖá£ÎÒÃǽ¨Ò齫ÁîÅÆµÄ·¶Î§ÏÞÖÆÔÚÕâÒ»¸öȨÏÞÉÏ¡£Äã±ØÐëÈ·±£¶ËµãURI°üº¬Â·¾¶£¨ÀýÈ磬`/api/v2/metrics/ingest`£©¡£
+
+
+
+
+
+Metrics API v2ÉãÈ¡¶ËµãµÄURL¸ù¾ÝÄãµÄ²¿ÊðÑ¡Ïî¶ø²»Í¬¡£
+
+
+
+
+
+* SaaS: `https://{your-environment-id}.live.dynatrace.com/api/v2/metrics/ingest`
+
+* Managed deployments: `https://{your-domain}/e/{your-environment-id}/api/v2/metrics/ingest`
+
+
+
+
+
+ÏÂÃæµÄÀý×ÓÊÇÓà `example` environment id ÅäÖöÈÁ¿Öµµ¼³ö¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.dynatrace.metrics.export.uri=https://example.live.dynatrace.com/api/v2/metrics/ingest
+management.dynatrace.metrics.export.api-token=YOUR_TOKEN
+
+```
+
+
+
+
+
+
+
+ÔÚʹÓÃDynatrace v2 APIʱ£¬¿ÉÒÔʹÓÃÒÔÏ¿ÉÑ¡¹¦ÄÜ£¨¸ü¶àϸ½Ú¿ÉÔÚ [DynatraceÎĵµ](https://www.dynatrace.com/support/help/how-to-use-dynatrace/metrics/metric-ingestion/ingestion-methods/micrometer#dt-configuration-properties) ÖÐÕÒµ½£©¡£
+
+
+
+
+
+* Metric key µÄǰ׺¡£ÉèÖÃÒ»¸öǰ׺£¬¸Ãǰ׺½«±»Ìí¼Óµ½ËùÓе¼³öµÄmetric keyÖС£
+
+* ÓÃDynatraceÔªÊý¾ÝÀ´³äʵ¡£Èç¹ûOneAgent»òDynatrace²Ù×÷Ô±ÕýÔÚÔËÐУ¬ÓöîÍâµÄÔªÊý¾Ý£¨ÀýÈ磬¹ØÓÚÖ÷»ú¡¢½ø³Ì»òPod£©À´·á¸»Ö¸±ê¡£
+
+* ĬÈÏά¶È¡£Ö¸¶¨Ìí¼Óµ½ËùÓе¼³ö¶ÈÁ¿µÄ¼üÖµ¶Ô¡£ Èç¹ûÓÃMicrometerÖ¸¶¨Á˾ßÓÐÏàͬ¼üµÄ±êÇ©£¬ËüÃǽ«¸²¸ÇĬÈÏdimension¡£
+
+* ʹÓÃDynatrace Summary instrument¡£ÔÚijЩÇé¿öÏ£¬Micrometer Dynatrace×¢²á±í´´½¨µÄÖ¸±ê±»¾Ü¾ø¡£ ÔÚMicrometer 1.9.xÖУ¬Í¨¹ýÒýÈëDynatraceÌØ¶¨µÄÕªÒª¹¤¾ßÀ´½â¾öÕâ¸öÎÊÌâ¡£ °ÑÕâ¸ö¿ª¹ØÉèÖÃΪ `false` »áÆÈʹMicrometer»Øµ½1.9.x֮ǰµÄĬÈÏÐÐΪ¡£ Ö»ÓÐÔÚ´ÓMicrometer 1.8.xÇ¨ÒÆµ½1.9.xʱÓöµ½ÎÊÌâʱ²Å¿ÉÒÔʹÓá£
+
+
+
+
+
+¿ÉÒÔ²»Ö¸¶¨URIºÍAPIÁîÅÆ£¬ÈçÒÔÏÂÀý×ÓËùʾ¡£ ÔÚÕâÖÖÇé¿öÏ£¬»áʹÓÃ×Ô¶¯ÅäÖõĶ˵㡣
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.dynatrace.metrics.export.v2.metric-key-prefix=your.key.prefix
+management.dynatrace.metrics.export.v2.enrich-with-dynatrace-metadata=true
+management.dynatrace.metrics.export.v2.default-dimensions.key1=value1
+management.dynatrace.metrics.export.v2.default-dimensions.key2=value2
+management.dynatrace.metrics.export.v2.use-dynatrace-summary-instruments=true
+
+```
+
+
+
+
+
+
+
+
+
+
+
+##### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.export.dynatrace.v1-api)v1 API (Legacy)
+
+
+
+Dynatrace v1 APIÖ¸±ê×¢²á±íͨ¹ýʹÓà [Timeseries v1 API](https://www.dynatrace.com/support/help/dynatrace-api/environment-api/metric-v1/) ¶¨ÆÚ½«Ö¸±êÍÆË͵½ÅäÖõÄURI¡£ ΪÁËÏòºó¼æÈÝÏÖÓеÄÉèÖ㬵± `device-id` ±»ÉèÖÃʱ£¨v1ÐèÒª£¬µ«ÔÚv2Öв»Ê¹Óã©£¬Ö¸±ê±»µ¼³öµ½Timeseries v1¶Ëµã¡£ ÒªÏò [Dynatrace](https://micrometer.io/docs/registry/dynatrace) µ¼³öÖ¸±ê£¬±ØÐëÌṩÄãµÄAPIÁîÅÆ¡¢É豸IDºÍURI¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.dynatrace.metrics.export.uri=https://{your-environment-id}.live.dynatrace.com
+management.dynatrace.metrics.export.api-token=YOUR_TOKEN
+management.dynatrace.metrics.export.v1.device-id=YOUR_DEVICE_ID
+
+```
+
+
+
+
+
+
+
+¶ÔÓÚv1°æAPI£¬Äã±ØÐëÖ¸¶¨»ù±¾»·¾³URI£¬¶ø²»Ö¸¶¨Â·¾¶£¬ÒòΪv1°æµÄ¶Ëµã·¾¶»á×Ô¶¯Ìí¼Ó¡£
+
+
+
+
+
+
+
+##### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.export.dynatrace.version-independent-settings)Óë°æ±¾Î޹صÄÉèÖÃ
+
+
+
+³ýÁËAPI¶ËµãºÍÁîÅÆÍ⣬Ä㻹¿ÉÒԸıäÏòDynatrace·¢ËÍÖ¸±êµÄ¼ä¸ôʱ¼ä¡£ ĬÈϵĵ¼³öʱ¼ä¼ä¸ôÊÇ `60s`¡£ ÏÂÃæµÄÀý×Ó½«µ¼³öʱ¼ä¼ä¸ôÉèÖÃΪ30Ãë¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.dynatrace.metrics.export.step=30s
+
+```
+
+
+
+
+
+
+
+Äã¿ÉÒÔÔÚ [MicrometerÎĵµ](https://micrometer.io/docs/registry/dynatrace) ºÍ [DynatraceÎĵµ](https://www.dynatrace.com/support/help/how-to-use-dynatrace/metrics/metric-ingestion/ingestion-methods/micrometer) ÖÐÕÒµ½¹ØÓÚÈçºÎΪMicrometerÉèÖÃDynatrace exporter£¨µ¼³öÆ÷£©µÄ¸ü¶àÐÅÏ¢¡£
+
+
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.export.elastic)7.2.5\. Elastic
+
+
+
+ĬÈÏÇé¿öÏ£¬Ö¸±ê±»µ¼³öµ½ÔËÐÐÔÚÄã±¾µØ»úÆ÷É쵀 [Elastic](https://micrometer.io/docs/registry/elastic) ¡£ Äã¿ÉÒÔͨ¹ýʹÓÃÒÔÏÂÊôÐÔÌṩҪʹÓõÄElastic·þÎñÆ÷µÄλÖá£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.elastic.metrics.export.host=https://elastic.example.com:8086
+
+```
+
+
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.export.ganglia)7.2.6\. Ganglia
+
+
+
+ĬÈÏÇé¿öÏ£¬Ö¸±ê±»µ¼³öµ½ÔËÐÐÔÚÄã±¾µØ»úÆ÷É쵀 [Ganglia](https://micrometer.io/docs/registry/ganglia) ¡£Äã¿ÉÒÔÌṩ [Ganglia server](http://ganglia.sourceforge.net/) µÄÖ÷»úºÍ¶Ë¿Ú£¬ÈçÏÂÀýËùʾ¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.ganglia.metrics.export.host=ganglia.example.com
+management.ganglia.metrics.export.port=9649
+
+```
+
+
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.export.graphite)7.2.7\. Graphite
+
+
+
+ĬÈÏÇé¿öÏ£¬Ö¸±ê»á±»µ¼³öµ½ÔËÐÐÔÚÄã±¾µØ»úÆ÷É쵀 [Graphite](https://micrometer.io/docs/registry/graphite) ¡£Äã¿ÉÒÔÌṩ [Graphite server](https://graphiteapp.org/) µÄÖ÷»úºÍ¶Ë¿Ú£¬ÈçÏÂÀýËùʾ¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.graphite.metrics.export.host=graphite.example.com
+management.graphite.metrics.export.port=9004
+
+```
+
+
+
+
+
+
+
+MicrometerÌṩÁËÒ»¸öĬÈ쵀 `HierarchicalNameMapper`£¬¹ÜÀídimensional meter IDÈçºÎhttps://micrometer.io/docs/registry/graphite#_hierarchical_name_mapping[Ó³Éäµ½ flat hierarchical name]¡£
+
+
+
+
+
+| | Òª¿ØÖÆÕâÖÖÐÐΪ£¬Ç붨ÒåÄãµÄ `GraphiteMeterRegistry` ²¢ÌṩÄã×Ô¼ºµÄ `HierarchicalNameMapper`¡£ ³ý·ÇÄã×Ô¼º¶¨Ò壬·ñÔò»áÌṩһ¸ö×Ô¶¯ÅäÖÃµÄ `GraphiteConfig` ºÍ `Clock` Bean¡£JavaKotlin```@Configuration(proxyBeanMethods = false)public class MyGraphiteConfiguration { @Bean public GraphiteMeterRegistry graphiteMeterRegistry(GraphiteConfig config, Clock clock) { return new GraphiteMeterRegistry(config, clock, this::toHierarchicalName); } private String toHierarchicalName(Meter.Id id, NamingConvention convention) { return ... }}``` |
+| --- | --- |
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.export.humio)7.2.8\. Humio
+
+
+
+ĬÈÏÇé¿öÏ£¬Humio×¢²áÖÐÐĻᶨÆÚ½«Ö¸±êÍÆË͵½ [cloud.humio.com](https://cloud.humio.com/) ¡£ Òª½«Ö¸±êµ¼³öµ½SaaS [Humio](https://micrometer.io/docs/registry/humio)£¬Äã±ØÐëÌṩÄãµÄAPIÁîÅÆ¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.humio.metrics.export.api-token=YOUR_TOKEN
+
+```
+
+
+
+
+
+
+
+Ä㻹Ӧ¸ÃÅäÖÃÒ»¸ö»ò¶à¸ö±êÇ©£¬ÒÔÈ·¶¨ÍÆËÍÖ¸±êµÄÊý¾ÝÔ´¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.humio.metrics.export.tags.alpha=a
+management.humio.metrics.export.tags.bravo=b
+
+```
+
+
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.export.influx)7.2.9\. Influx
+
+
+
+ĬÈÏÇé¿öÏ£¬Ö¸±ê»á±»µ¼³öµ½ÔËÐÐÔÚ±¾µØ»úÆ÷É쵀 [Influx](https://micrometer.io/docs/registry/influx) v1ʵÀý£¬²¢²ÉÓÃĬÈÏÅäÖá£Òªµ¼³öÖ¸±êµ½InfluxDB v2£¬ÇëÅäÖà `org`¡¢`bucket` ºÍÓÃÓÚдÈëÖ¸±êµÄauthentication `token`¡£Äã¿ÉÒÔͨ¹ýÒÔÏ·½Ê½ÌṩҪʹÓÃµÄ [Influx server](https://www.influxdata.com/) µÄλÖá£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.influx.metrics.export.uri=https://influx.example.com:8086
+
+```
+
+
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.export.jmx)7.2.10\. JMX
+
+
+
+MicrometerÌṩÁË¶Ô [JMX](https://micrometer.io/docs/registry/jmx) µÄ·Ö²ãÓ³É䣬Ö÷ÒªÊÇ×÷ΪһÖÖÁ®¼ÛºÍ¿ÉÒÆÖ²µÄ·½Ê½À´²é¿´±¾µØµÄ¶ÈÁ¿¡£ ĬÈÏÇé¿öÏ£¬Ö¸±ê±»µ¼³öµ½ `metrics` JMXÓò¡£ Äã¿ÉÒÔͨ¹ýÒÔÏ·½Ê½ÌṩҪʹÓõÄÓò¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.jmx.metrics.export.domain=com.example.app.metrics
+
+```
+
+
+
+
+
+
+
+MicrometerÌṩÁËÒ»¸öĬÈ쵀 `HierarchicalNameMapper`£¬¹ÜÀídimensional meter ID ÈçºÎ [Ó³Éäµ½ flat hierarchical name](https://micrometer.io/docs/registry/jmx#_hierarchical_name_mapping)¡£
+
+
+
+
+
+| | Òª¿ØÖÆÕâÖÖÐÐΪ£¬Ç붨ÒåÄãµÄ `JmxMeterRegistry` ²¢ÌṩÄã×Ô¼ºµÄ `HierarchicalNameMapper`¡£ ³ý·ÇÄã×Ô¼º¶¨Ò壬·ñÔò»áÌṩһ¸ö×Ô¶¯ÅäÖÃµÄ `JmxConfig` ºÍ `Clock` Bean¡£JavaKotlin```@Configuration(proxyBeanMethods = false)public class MyJmxConfiguration { @Bean public JmxMeterRegistry jmxMeterRegistry(JmxConfig config, Clock clock) { return new JmxMeterRegistry(config, clock, this::toHierarchicalName); } private String toHierarchicalName(Meter.Id id, NamingConvention convention) { return ... }}``` |
+| --- | --- |
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.export.kairos)7.2.11\. KairosDB
+
+
+
+ĬÈÏÇé¿öÏ£¬Ö¸±ê±»µ¼³öµ½ÔËÐÐÔÚÄã±¾µØ»úÆ÷É쵀 [KairosDB](https://micrometer.io/docs/registry/kairos) ¡£Äã¿ÉÒÔͨ¹ýÒÔÏ·½Ê½ÌṩҪʹÓÃµÄ [KairosDB server](https://kairosdb.github.io/) µÄλÖá£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.kairos.metrics.export.uri=https://kairosdb.example.com:8080/api/v1/datapoints
+
+```
+
+
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.export.newrelic)7.2.12\. New Relic
+
+
+
+New Relic×¢²áÖÐÐĻᶨÆÚ½«Ö¸±êÍÆË͵½ [New Relic](https://micrometer.io/docs/registry/new-relic)¡£Òªµ¼³öÖ¸±êµ½ [New Relic](https://newrelic.com/)£¬Äã±ØÐëÌṩÄãµÄAPIÃÜÔ¿ºÍÕË»§ID¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.newrelic.metrics.export.api-key=YOUR_KEY
+management.newrelic.metrics.export.account-id=YOUR_ACCOUNT_ID
+
+```
+
+
+
+
+
+
+
+Ä㻹¿ÉÒԸıäÏòNew Relic·¢ËÍÖ¸±êµÄʱ¼ä¼ä¸ô¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.newrelic.metrics.export.step=30s
+
+```
+
+
+
+
+
+
+
+ĬÈÏÇé¿öÏ£¬Ö¸±êÊÇͨ¹ýRESTµ÷Ó÷¢²¼µÄ£¬µ«Èç¹ûÄãÔÚclasspathÉÏÓÐJava Agent API£¬ÄãÒ²¿ÉÒÔʹÓÃËü¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.newrelic.metrics.export.client-provider-type=insights-agent
+
+```
+
+
+
+
+
+
+
+×îºó£¬Äã¿ÉÒÔͨ¹ý¶¨ÒåÄã×Ô¼ºµÄ `NewRelicClientProvider` ¶¹À´ÍêÈ«¿ØÖÆ¡£
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.export.otlp)7.2.13\. OpenTelemetry
+
+
+
+ĬÈÏÇé¿öÏ£¬Ö¸±ê±»µ¼³öµ½ÔËÐÐÔÚÄã±¾µØ»úÆ÷É쵀 [OpenTelemetry](https://micrometer.io/docs/registry/otlp) ¡£Äã¿ÉÒÔͨ¹ýÒÔÏ·½Ê½ÌṩҪʹÓÃµÄ [OpenTelemtry metric endpoint](https://opentelemetry.io/) µÄλÖá£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.otlp.metrics.export.url=https://otlp.example.com:4318/v1/metrics
+
+```
+
+
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.export.prometheus)7.2.14\. Prometheus
+
+
+
+[Prometheus](https://micrometer.io/docs/registry/prometheus) Ï£Íûscrape»òÂÖѯµ¥¸öÓ¦ÓóÌÐòʵÀýµÄÖ¸±ê¡£Spring BootÔÚ `/actuator/prometheus` ÌṩÁËÒ»¸öactuator¶Ëµã£¬ÒÔ±ãÒÔÊʵ±µÄ¸ñʽ³ÊÏÖ [Prometheus scrape](https://prometheus.io/)¡£
+
+
+
+
+
+| | ĬÈÏÇé¿öÏ£¬¸Ã¶ËµãÊDz»¿ÉÓõ쬱ØÐë±»±©Â¶¡£¸ü¶àϸ½ÚÇë²Î¼û[±©Â¶¶Ëµã](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.exposing)¡£ |
+| --- | --- |
+
+
+
+
+
+ÏÂÃæµÄÀý×Ó `scrape_config` Ìí¼Óµ½ `prometheus.yml`¡£
+
+
+
+
+
+
+
+```
+scrape_configs:
+ - job_name: "spring"
+ metrics_path: "/actuator/prometheus"
+ static_configs:
+ - targets: ["HOST:PORT"]
+```
+
+
+
+
+
+
+
+Ò²Ö§³Ö [Prometheus Exemplars](https://prometheus.io/docs/prometheus/latest/feature_flags/#exemplars-storage)¡£ÒªÆôÓÃÕâ¸ö¹¦ÄÜ£¬Ó¦¸ÃÓÐÒ»¸ö `SpanContextSupplier` Bean¡£Èç¹ûÄãʹÓà [Micrometer Tracing](https://micrometer.io/docs/tracing)£¬Õ⽫ΪÄã×Ô¶¯ÅäÖ㬵«Èç¹ûÄãÏ룬Äã×ÜÊÇ¿ÉÒÔ´´½¨×Ô¼ºµÄ¡£Çë²é¿´ [Prometheus Îĵµ](https://prometheus.io/docs/prometheus/latest/feature_flags/#exemplars-storage) £¬ÒòΪÕâ¸ö¹¦ÄÜÐèÒªÔÚPrometheusÕâ±ßÃ÷È·ÆôÓ㬶øÇÒÖ»Ö§³ÖʹÓà [OpenMetrics](https://github.com/OpenObservability/OpenMetrics/blob/v1.0.0/specification/OpenMetrics.md#exemplars) ¸ñʽ¡£
+
+
+
+
+
+¶ÔÓÚ¶ÌÔݵĻòÅú´¦ÀíµÄ×÷Òµ£¬¿ÉÄÜ´æÔÚµÄʱ¼ä²»¹»³¤£¬ÎÞ·¨±»¹ÎÈ¡£¬Äã¿ÉÒÔʹÓà [Prometheus Pushgateway](https://github.com/prometheus/pushgateway) Ö§³Ö£¬½«Ö¸±ê±©Â¶¸øPrometheus¡£ÒªÆôÓÃPrometheus PushgatewayÖ§³Ö£¬ÇëÔÚÄãµÄÏîÄ¿ÖÐÌí¼ÓÒÔÏÂÒÀÀµ¡£
+
+
+
+
+
+
+
+```
+
+ io.prometheus
+ simpleclient_pushgateway
+
+```
+
+
+
+
+
+
+
+µ±Prometheus PushgatewayµÄÒÀÀµ³öÏÖÔÚclasspathÉÏ£¬²¢ÇÒ `management.prometheus.metrics.export.pushgateway.enabled` ÊôÐÔ±»ÉèÖÃΪ `true` ʱ£¬Ò»¸ö `PrometheusPushGatewayManager` bean¾Í±»×Ô¶¯ÅäÖÃÁË¡£ Ëü¸ºÔð¹ÜÀíÏòPrometheus PushgatewayÍÆËÍÖ¸±êµÄ¹¤×÷¡£
+
+
+
+
+
+Äã¿ÉÒÔͨ¹ýʹÓà `management.prometheus.metrics.export.pushgateway` ϵÄÊôÐÔÀ´µ÷Õû `PrometheusPushGatewayManager`¡£ ¶ÔÓڸ߼¶ÅäÖã¬ÄãÒ²¿ÉÒÔÌṩÄã×Ô¼ºµÄ `PrometheusPushGatewayManager` bean¡£
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.export.signalfx)7.2.15\. SignalFx
+
+
+
+SignalFx×¢²áÖÐÐĻᶨÆÚ½«Ö¸±êÍÆË͵½ [SignalFx](https://micrometer.io/docs/registry/signalFx)¡£Òªµ¼³öÖ¸±êµ½ [SignalFx](https://www.signalfx.com/)£¬Äã±ØÐëÌṩÄãµÄaccess token¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.signalfx.metrics.export.access-token=YOUR_ACCESS_TOKEN
+
+```
+
+
+
+
+
+
+
+ÄãÒ²¿ÉÒԸıäÏòSignalFx·¢ËÍÖ¸±êµÄʱ¼ä¼ä¸ô¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.signalfx.metrics.export.step=30s
+
+```
+
+
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.export.simple)7.2.16\. Simple
+
+
+
+MicrometerÌṩÁËÒ»¸ö¼òµ¥µÄ¡¢ÄÚ´æÖеĺó¶Ë£¬Èç¹ûûÓÐÅäÖÃÆäËû×¢²á±í£¬¸Ãºó¶Ë»á×Ô¶¯×÷Ϊ±¸Óá£Õâ¿ÉÒÔÈÃÄã¿´µ½ÔÚ [metrics endpoint](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.endpoint) ÖÐÊÕ¼¯ÁËÄÄЩ¶ÈÁ¿¡£
+
+
+
+
+
+Ò»µ©ÄãʹÓÃÈÎºÎÆäËû¿ÉÓõĺó¶Ë£¬ÄÚ´æÖеĺó¶Ë¾Í»á×Ô¶¯¹Ø±Õ¡£ÄãÒ²¿ÉÒÔÃ÷È·µØ½ûÓÃËü¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.simple.metrics.export.enabled=false
+
+```
+
+
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.export.stackdriver)7.2.17\. Stackdriver
+
+
+
+Stackdriver×¢²áÖÐÐĻᶨÆÚÏò [Stackdriver](https://cloud.google.com/stackdriver/) ÍÆËÍÖ¸±ê¡£Òªµ¼³öÖ¸±êµ½SaaS [Stackdriver](https://micrometer.io/docs/registry/stackdriver)£¬Äã±ØÐëÌṩÄãµÄGoogle Cloud project ID¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.stackdriver.metrics.export.project-id=my-project
+
+```
+
+
+
+
+
+
+
+Ä㻹¿ÉÒԸıäÏòStackdriver·¢ËÍÖ¸±êµÄʱ¼ä¼ä¸ô¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.stackdriver.metrics.export.step=30s
+
+```
+
+
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.export.statsd)7.2.18\. StatsD
+
+
+
+StatsD×¢²á±í¼±Çеؽ«Ö¸±êͨ¹ýUDPÍÆË͸øStatsD agent¡£Ä¬ÈÏÇé¿öÏ£¬Ö¸±ê±»µ¼³öµ½ÔËÐÐÔÚÄã±¾µØ»úÆ÷É쵀 [StatsD](https://micrometer.io/docs/registry/statsD) agent¡£Äã¿ÉÒÔͨ¹ýÒÔÏ·½Ê½ÌṩStatsD´úÀíµÄÖ÷»ú¡¢¶Ë¿ÚºÍÐÒ飬ÒÔ±ãʹÓá£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.statsd.metrics.export.host=statsd.example.com
+management.statsd.metrics.export.port=9125
+management.statsd.metrics.export.protocol=udp
+
+```
+
+
+
+
+
+
+
+Ä㻹¿ÉÒԸıäҪʹÓõÄStatsDÏß·ÐÒ飨ĬÈÏΪDatadog£©¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.statsd.metrics.export.flavor=etsy
+
+```
+
+
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.export.wavefront)7.2.19\. Wavefront
+
+
+
+Wavefront×¢²á±í¶¨ÆÚ½«Ö¸±êÍÆË͵½ [Wavefront](https://micrometer.io/docs/registry/wavefront)¡£Èç¹ûÄãÖ±½Ó½«Ö¸±êµ¼³öµ½ [Wavefront](https://www.wavefront.com/)£¬Äã±ØÐëÌṩÄãµÄAPI token¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.wavefront.api-token=YOUR_API_TOKEN
+
+```
+
+
+
+
+
+
+
+ÁíÍ⣬Äú¿ÉÒÔÔÚÄúµÄ»·¾³ÖÐʹÓÃWavefront sidecar»òÄÚ²¿´úÀíÀ´×ª·¢Ö¸±êÊý¾Ýµ½Wavefront APIÖ÷»ú¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.wavefront.uri=proxy://localhost:2878
+
+```
+
+
+
+
+
+
+
+Èç¹ûÄú½«Ö¸±ê·¢²¼µ½Wavefront´úÀí£¨Èç [WavefrontÎĵµ](https://docs.wavefront.com/proxies_installing.html) ÖÐËùÊö£©£¬Ö÷»ú±ØÐëÊÇ `proxy://HOST:PORT` ¸ñʽ¡£
+
+
+
+
+
+ÄãÒ²¿ÉÒԸıäÏòWavefront·¢ËÍÖ¸±êµÄʱ¼ä¼ä¸ô¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.wavefront.metrics.export.step=30s
+
+```
+
+
+
+
+
+
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.supported)7.3\. Ö§³ÖµÄÖ¸±ê £¨Metric£©ºÍ¶ÈÁ¿£¨Meter£©
+
+
+
+Spring BootΪ¸÷ÖÖ¸÷ÑùµÄ¼¼ÊõÌṩÁË×Ô¶¯¼ÆÁ¿Æ÷×¢²á¡£ ÔÚ´ó¶àÊýÇé¿öÏ£¬Ä¬ÈÏÖµÌṩÁ˺ÏÀíµÄÖ¸±ê£¬¿ÉÒÔ·¢²¼µ½ÈκÎÖ§³ÖµÄ¼à¿ØÏµÍ³ÖС£
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.supported.jvm)7.3.1\. JVMÖ¸±ê
+
+
+
+×Ô¶¯ÅäÖÃͨ¹ýʹÓúËÐÄ Micrometer ÀàÆôÓÃJVM¶ÈÁ¿¡£ JVMÖ¸±êÔÚ `jvm.` meter name Ï·¢²¼¡£
+
+
+
+
+
+ÌṩÒÔÏÂJVMÖ¸±ê¡£
+
+
+
+
+
+* ¸÷ÖÖÄÚ´æºÍ»º³å³ØÏ¸½Ú
+
+* ÓëÀ¬»øÊÕ¼¯ÓйصÄͳ¼ÆÊý¾Ý
+
+* Ïß³ÌÀûÓÃÂÊ
+
+* ¼ÓÔØºÍÐ¶ÔØµÄÀàµÄÊýÁ¿
+
+* JVMµÄ°æ±¾ÐÅÏ¢
+
+* JIT ±àÒëʱ¼ä
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.supported.system)7.3.2\. ϵͳָ±ê
+
+
+
+×Ô¶¯ÅäÖÃͨ¹ýʹÓúËÐÄMicrometerÀàÀ´ÊµÏÖϵͳ¶ÈÁ¿¡£ ϵͳָ±êÔÚ `system.`¡¢`process.` ºÍ `disk.` meter ÃûÏ·¢²¼¡£
+
+
+
+
+
+ÌṩÒÔÏÂϵͳָ±ê¡£
+
+
+
+
+
+* CPUÖ¸±ê
+
+* ÎļþÃèÊö·ûÖ¸±ê
+
+* Õý³£ÔËÐÐʱ¼äÖ¸±ê£¨°üÀ¨Ó¦ÓóÌÐòÒѾÔËÐеÄʱ¼äºÍ¾ø¶ÔÆô¶¯Ê±¼äµÄ¹Ì¶¨²âÁ¿£©¡£
+
+* ¿ÉÓõĴÅÅ̿ռä
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.supported.application-startup)7.3.3\. Ó¦ÓóÌÐòÆô¶¯Ö¸±ê
+
+
+
+×Ô¶¯ÅäÖñ©Â¶ÁËÓ¦ÓóÌÐòµÄÆô¶¯Ê±¼äÖ¸±ê¡£
+
+
+
+
+
+* `application.started.time`: Æô¶¯Ó¦ÓóÌÐòµÄʱ¼ä¡£
+
+* `application.ready.time`£ºÓ¦ÓóÌÐò×¼±¸ºÃΪÇëÇóÌṩ·þÎñËùÐèµÄʱ¼ä¡£
+
+
+
+
+
+Ö¸±êÊÇÓÉÓ¦ÓÃÀàµÄÍêÈ«Ãû³ÆÀ´±ê¼ÇµÄ¡£
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.supported.logger)7.3.4\. ÈÕÖ¾¼Ç¼Æ÷Ö¸±ê
+
+
+
+×Ô¶¯ÅäÖÃÆôÓÃÁËLogbackºÍLog4J2µÄʼþ¶ÈÁ¿¡£ ϸ½ÚÔÚ `log4j2.events.` »ò `logback.events.` meterÃûϹ«²¼¡£
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.supported.tasks)7.3.5\. ÈÎÎñÖ´Ðк͵÷¶ÈÖ¸±ê
+
+
+
+×Ô¶¯ÅäÖÃʹËùÓпÉÓÃµÄ `ThreadPoolTaskExecutor` ºÍ `ThreadPoolTaskScheduler` Bean¶¼Äܱ»²âÁ¿£¬Ö»Òªµ×²ãµÄ `ThreadPoolExecutor` ¿ÉÓᣠָ±êÓÉexecutorµÄÃû³ÆÀ´±ê¼Ç£¬executorµÄÃû³ÆÀ´×ÔÓÚBeanµÄÃû³Æ¡£
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.supported.spring-mvc)7.3.6\. Spring MVC Ö¸±ê
+
+
+
+×Ô¶¯ÅäÖÃÄܹ»¶Ô Spring MVC ControllerºÍ±à³Ìʽhandler´¦ÀíµÄËùÓÐÇëÇó½øÐжÈÁ¿¡£ ĬÈÏÇé¿öÏ£¬Ö¸±êÊÇÒÔ `http.server.requests` ΪÃû³ÆÉú³ÉµÄ¡£ Äã¿ÉÒÔͨ¹ýÉèÖà `management.observations.http.server.requests.name` ÊôÐÔÀ´¶¨ÖƸÃÃû³Æ¡£
+
+
+
+
+
+¹ØÓÚ²úÉúµÄ¹Û²ì½á¹û£¨observation£©µÄ¸ü¶àÐÅÏ¢£¬Çë²Î¼û [Spring Framework ²Î¿¼Îĵµ](https://docs.spring.io/spring-framework/docs/6.0.5/reference/html/integration.html#integration.observability.http-server.servlet)¡£
+
+
+
+
+
+ÒªÌí¼Óµ½Ä¬ÈϱêÇ©ÖУ¬ÇëÌṩһ¸ö¼Ì³ÐÁË `org.springframework.http.server.observation` °üÖÐµÄ `DefaultServerRequestObservationConvention` µÄ `@Bean`¡£ÒªÌ滻ĬÈϱêÇ©£¬ÇëÌṩһ¸öʵÏÖ `ServerRequestObservationConvention` µÄ `@Bean`¡£
+
+
+
+
+
+| | ÔÚijЩÇé¿öÏ£¬Web¿ØÖÆÆ÷Öд¦ÀíµÄÒì³£²»»á±»¼Ç¼ΪÇëÇó¶ÈÁ¿±êÇ©¡£Ó¦ÓóÌÐò¿ÉÒÔÑ¡Ôñ¼ÓÈ벢ͨ¹ý½«[handled exception ÉèÖÃΪ request attribute](https://springdoc.cn/spring-boot/web.html#web.servlet.spring-mvc.error-handling)À´¼Ç¼Òì³£¡£ |
+| --- | --- |
+
+
+
+
+
+ĬÈÏÇé¿öÏ£¬ËùÓÐÇëÇó¶¼±»´¦Àí¡£ Òª×Ô¶¨Òå¹ýÂËÆ÷£¬ÇëÌṩһ¸öʵÏÖ `FilterRegistrationBean` µÄ `@Bean`¡£
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.supported.spring-webflux)7.3.7\. Spring WebFlux Ö¸±ê
+
+
+
+×Ô¶¯ÅäÖÃÄܹ»¶ÔSpring WebFlux controllerºÍ±à³ÌʽhandlerµÄËùÓÐÇëÇó½øÐжÈÁ¿¡£ ĬÈÏÇé¿öÏ£¬Ö¸±êÊÇÒÔ `http.server.requests` ΪÃûÉú³ÉµÄ¡£ Äã¿ÉÒÔͨ¹ýÉèÖà `management.observations.http.server.requests.name` ÊôÐÔÀ´¶¨ÖƸÃÃû³Æ¡£
+
+
+
+
+
+¹ØÓÚ²úÉúµÄ¹Û²ì½á¹û£¨observation£©µÄ¸ü¶àÐÅÏ¢£¬Çë²Î¼û [Spring Framework ²Î¿¼Îĵµ](https://docs.spring.io/spring-framework/docs/6.0.5/reference/html/integration.html#integration.observability.http-server.reactive)¡£
+
+
+
+
+
+ÒªÌí¼Óµ½Ä¬ÈϱêÇ©ÖУ¬ÇëÌṩ¼Ì³ÐÁË `org.springframework.http.server.reactive.observation` °üÖÐµÄ `DefaultServerRequestObservationConvention` µÄ `@Bean`¡£ÒªÌ滻ĬÈϱêÇ©£¬ÇëÌṩһ¸öʵÏÖ `ServerRequestObservationConvention` µÄ `@Bean`¡£
+
+
+
+
+
+| | ÔÚijЩÇé¿öÏ£¬¿ØÖÆÆ÷ºÍ´¦Àíº¯ÊýÖд¦ÀíµÄÒì³£²»»á±»¼Ç¼ΪÇëÇó¶ÈÁ¿±êÇ©¡£Ó¦ÓóÌÐò¿ÉÒÔÑ¡Ôñ¼ÓÈ벢ͨ¹ý[½«handled exceptionÉèÖÃΪrequest attribute](https://springdoc.cn/spring-boot/web.html#web.reactive.webflux.error-handling)À´¼Ç¼Òì³£¡£ |
+| --- | --- |
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.supported.jersey)7.3.8\. Jersey Server Ö¸±ê
+
+
+
+×Ô¶¯ÅäÖÃʹJersey JAX-RSʵÏÖËù´¦ÀíµÄËùÓÐÇëÇó¶¼Äܱ»²âÁ¿¡£ ĬÈÏÇé¿öÏ£¬Ö¸±êÊÇÒÔ `http.server.requests` ΪÃû³ÆÉú³ÉµÄ¡£ Äã¿ÉÒÔͨ¹ýÉèÖà `management.observations.http.server.requests.name` ÊôÐÔÀ´¶¨ÖÆÃû³Æ¡£
+
+
+
+
+
+ĬÈÏÇé¿öÏ£¬Jersey·þÎñÆ÷Ö¸±ê±»±ê¼ÇΪÒÔÏÂÐÅÏ¢¡£
+
+
+
+
+| Tag | ˵Ã÷ |
+| --- | --- |
+| `exception` | ´¦ÀíÇëÇóʱÅ׳öµÄÈκÎÒì³£µÄ¼òµ¥ÀàÃû¡£ |
+| `method` | ÇëÇóµÄ·½·¨£¨ÀýÈ磬`GET` »ò `POST`£©¡£ |
+| `outcome` | ÇëÇóµÄ½á¹û£¬»ùÓÚÏìÓ¦µÄ״̬´úÂë¡£ 1xxÊÇ `INFORMATIONAL`£¬2xxÊÇ `SUCCESS`£¬3xxÊÇ `REDIRECTION`£¬4xxÊÇ `CLIENT_ERROR`£¬5xxÊÇ `SERVER_ERROR`¡£ |
+| `status` | ÏìÓ¦µÄHTTP״̬´úÂ루ÀýÈ磬`200` »ò `500`£©¡£ |
+| `uri` | Èç¹û¿ÉÄܵϰ£¬ÔÚ½øÐбäÁ¿Ì滻֮ǰ£¬ÇëÇóµÄURIÄ£°å£¨ÀýÈ磺`/api/person/{id}`£©¡£ |
+
+
+
+Òª¶¨ÖƱêÇ©£¬ÇëÌṩһ¸öʵÏÖ `JerseyTagsProvider` µÄ `@Bean`¡£
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.supported.http-clients)7.3.9\. HTTP Client Ö¸±ê
+
+
+
+Spring Boot Actuator¸ºÔð¹ÜÀí `RestTemplate` ºÍ `WebClient` µÄ¹¤¾ß¡£Îª´Ë£¬Äã±ØÐë×¢Èë×Ô¶¯ÅäÖõĹ¹½¨Æ÷²¢Ê¹ÓÃËüÀ´´´½¨ÊµÀý¡£
+
+
+
+
+
+* `RestTemplateBuilder` ÓÃÓÚ `RestTemplate`
+
+* `WebClient.Builder` ÓÃÓÚ `WebClient`
+
+
+
+
+
+ÄãÒ²¿ÉÒÔÊÖ¶¯Ó¦ÓøºÔðÕâ¸ö¹¤¾ßµÄcustomizer£¬¼´ `ObservationRestTemplateCustomizer` ºÍ `ObservationWebClientCustomizer`¡£
+
+
+
+
+
+ĬÈÏÇé¿öÏ£¬Ö¸±êÊÇÒÔ `http.client.requests` Õâ¸öÃû×ÖÉú³ÉµÄ¡£
+
+
+
+
+
+Äã¿ÉÒÔͨ¹ýÉèÖà `management.observations.http.client.requests.name` ÊôÐÔÀ´¶¨ÖÆÕâ¸öÃû×Ö¡£
+
+
+
+
+
+¹ØÓÚ²úÉúµÄ¹Û²ì½á¹û£¨observation£©µÄ¸ü¶àÐÅÏ¢£¬Çë²Î¼û [Spring Framework ²Î¿¼Îĵµ](https://docs.spring.io/spring-framework/docs/6.0.5/reference/html/integration.html#integration.observability.http-client)¡£
+
+
+
+
+
+ÒªÔÚʹÓà `RestTemplate` ʱ¶¨ÖƱêÇ©£¬ÇëÌṩһ¸öʵÏÖÁË `org.springframework.http.client.observation` °üÖÐ `ClientRequestObservationConvention` µÄ `@Bean`¡£ÒªÔÚʹÓà `WebClient` ʱ×Ô¶¨Òå±êÇ©£¬ÇëÌṩһ¸öʵÏÖÁË `org.springframework.web.reactive.function.client` °üÖÐ `ClientRequestObservationConvention` µÄ `@Bean`¡£
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.supported.tomcat)7.3.10\. Tomcat Ö¸±ê
+
+
+
+×Ô¶¯ÅäÖýöÔÚ `MBeanRegistry` ±»ÆôÓÃʱ²Å»áÆôÓÃTomcatµÄÒÇÆ÷¡£ ĬÈÏÇé¿öÏ£¬`MBeanRegistry` ÊǽûÓõ쬵«Äã¿ÉÒÔͨ¹ýÉèÖà `server.tomcat.mbeanregistry.enabled` Ϊ `true` À´ÆôÓÃËü¡£
+
+
+
+
+
+TomcatµÄÖ¸±êÔÚ `tomcat.` meter ÃûÏ·¢²¼¡£
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.supported.cache)7.3.11\. Cache Ö¸±ê
+
+
+
+×Ô¶¯ÅäÖÿÉÒÔÔÚÆô¶¯Ê±¶ÔËùÓпÉÓÃµÄ `Cache` ʵÀý½øÐмì²â£¬ÆäÖ¸±êÒÔ `cache` Ϊǰ׺¡£
+
+
+
+
+
+»º´æÒDZíÊDZê×¼»¯µÄ»ù±¾Ö¸±ê¼¯¡£
+
+
+
+
+
+Ò²¿ÉÒÔʹÓöîÍâµÄ¡¢Õë¶Ô»º´æµÄÖ¸±ê¡£
+
+
+
+
+
+Ö§³ÖÒÔÏ»º´æ¿â¡£
+
+
+
+
+
+* Cache2k
+
+* Caffeine
+
+* Hazelcast
+
+* ÈκμæÈݵÄJCache£¨JSR-107£©ÊµÏÖ
+
+* Redis
+
+
+
+
+
+Ö¸±êÓÉ»º´æµÄÃû³ÆºÍ `CacheManager` µÄÃû³ÆÀ´±ê¼Ç£¬`CacheManager` µÄÃû³ÆÊÇÓÉBeanÃû³ÆÅÉÉúµÄ¡£
+
+
+
+
+
+| | Ö»ÓÐÔÚÆô¶¯Ê±ÅäÖõĻº´æ±»°ó¶¨µ½×¢²á±í¡£ ¶ÔÓÚûÓÐÔÚ»º´æÅäÖÃÖж¨ÒåµÄ»º´æ£¬ÀýÈçÔÚÆô¶¯½×¶ÎºóÁÙʱ´´½¨µÄ»º´æ»òÒÔ±à³Ì·½Ê½´´½¨µÄ»º´æ£¬ÐèÒªÃ÷È·×¢²á¡£ Ò»¸ö `CacheMetricsRegistrar` Bean¿ÉÒÔʹÕâ¸ö¹ý³Ì¸üÈÝÒס£ |
+| --- | --- |
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.supported.spring-graphql)7.3.12\. Spring GraphQL Ö¸±ê
+
+
+
+²Î¼û [Spring GraphQL ²Î¿¼Îĵµ](https://docs.spring.io/spring-graphql/docs/1.1.2/reference/html/)¡£
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.supported.jdbc)7.3.13\. DataSource Ö¸±ê
+
+
+
+×Ô¶¯ÅäÖÃʹËùÓпÉÓÃµÄ `DataSource` ¶ÔÏóµÄÒÇÆ÷»¯£¬Ö¸±êǰ׺Ϊ `jdbc.connections`¡£ Êý¾ÝÔ´¼ì²âµÄ½á¹ûÊDZíʾ³ØÖе±Ç°»î¶¯µÄ¡¢¿ÕÏеġ¢×î´óÔÊÐíµÄºÍ×îСÔÊÐíµÄÁ¬½ÓÊýµÄÒÇ±í¡£
+
+
+
+
+
+ºâÁ¿±ê×¼Ò²ÓÉ»ùÓÚbeanÃû³Æ¼ÆËãµÄ `DataSource` µÄÃû³ÆÀ´±ê¼Ç¡£
+
+
+
+
+
+| | ĬÈÏÇé¿öÏ£¬Spring BootΪËùÓÐÖ§³ÖµÄÊý¾ÝÔ´ÌṩԪÊý¾Ý¡£ Èç¹ûÄãϲ»¶µÄÊý¾ÝÔ´²»±»Ö§³Ö£¬Äã¿ÉÒÔÌí¼Ó¶îÍâµÄ `DataSourcePoolMetadataProvider` Bean¡£ Çë²ÎÔÄ `DataSourcePoolMetadataProvidersConfiguration` ÒÔÁ˽âʵÀý¡£ |
+| --- | --- |
+
+
+
+
+
+´ËÍ⣬HikariÌØ¶¨µÄÖ¸±êÒÔ `hikaricp` ǰ׺±©Â¶¡£ ÿ¸öÖ¸±ê¶¼±»poolµÄÃû×ÖËù±ê¼Ç£¨Äã¿ÉÒÔÓà `spring.datasource.name` À´¿ØÖÆ£©¡£
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.supported.hibernate)7.3.14\. Hibernate Ö¸±ê
+
+
+
+Èç¹û `org.hibernate.orm:hibernate-micrometer` ÔÚclasspathÉÏ£¬ËùÓÐÆôÓÃÁËͳ¼Æ¹¦ÄܵÄHibernate `EntityManagerFactory` ʵÀý¶¼»á±»Ò»¸öÃûΪ `hibernate` µÄÖ¸±êËù¼ì²â¡£
+
+
+
+
+
+ºâÁ¿±ê×¼Ò²ÓÉ `EntityManagerFactory` µÄÃû³ÆÀ´±ê¼Ç£¬¸ÃÃû³ÆÊÇÓÉBeanÃû³ÆÅÉÉúµÄ¡£
+
+
+
+
+
+ÒªÆôÓÃͳ¼Æ£¬±ê×¼JPAÊôÐÔ `hibernate.generate_statistics` ±ØÐëÉèÖÃΪ `true`¡£ Äã¿ÉÒÔÔÚ×Ô¶¯ÅäÖÃµÄ `EntityManagerFactory` ÉÏÆôÓá£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+spring.jpa.properties[hibernate.generate_statistics]=true
+
+```
+
+
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.supported.spring-data-repository)7.3.15\. Spring Data Repository Ö¸±ê
+
+
+
+×Ô¶¯ÅäÖÃÄܹ»¶ÔËùÓÐSpring Data `Repository` ·½·¨µÄµ÷ÓýøÐжÈÁ¿¡£ ĬÈÏÇé¿öÏ£¬Ö¸±êÒÔ `spring.data.repository.invocations` ΪÃûÉú³É¡£ Äã¿ÉÒÔͨ¹ýÉèÖà `management.metrics.data.repository.metric-name` ÊôÐÔÀ´×Ô¶¨ÒåÃû³Æ¡£
+
+
+
+
+
+`io.micrometer.core.annotation` °üÖÐµÄ `@Timed` ×¢½âÖ§³Ö `Repository` ½Ó¿ÚºÍ·½·¨¡£Èç¹ûÄã²»Ïë¼Ç¼ËùÓÐ `Repository` µ÷ÓõĶÈÁ¿£¨metric£©£¬Äã¿ÉÒÔ½« `management.metrics.data.repository.autotime.enabled` ÉèÖÃΪ `false`£¬¶ø×¨ÃÅʹÓà `@Timed` ×¢½â¡£
+
+
+
+
+
+| | Ò»¸ö´øÓÐ `longTask = true` µÄ `@Timed` ×¢½â¿ÉÒÔΪ¸Ã·½·¨ÆôÓÃÒ»¸ö³¤ÈÎÎñ¼ÆÊ±Æ÷¡£³¤ÈÎÎñ¶¨Ê±Æ÷ÐèÒªÒ»¸öµ¥¶ÀµÄ metric name£¬²¢ÇÒ¿ÉÒÔÓë¶ÌÈÎÎñ¶¨Ê±Æ÷£¨task timer£©µþ¼Ó¡£ |
+| --- | --- |
+
+
+
+
+
+ĬÈÏÇé¿öÏ£¬repositoryµ÷ÓÃÏà¹ØµÄ¶ÈÁ¿±ê×¼±»±ê¼ÇΪÒÔÏÂÐÅÏ¢¡£
+
+
+
+
+| Tag | ˵Ã÷ |
+| --- | --- |
+| `repository` | Ô´ `Repository` µÄ¼òµ¥ÀàÃû¡£ |
+| `method` | ±»µ÷ÓÃµÄ `Repository` ·½·¨µÄÃû³Æ¡£ |
+| `state` | ½á¹û״̬£¨`SUCCESS`, `ERROR`, `CANCELED`, `RUNNING`£©¡£ |
+| `exception` | µ÷ÓÃÖÐÅ׳öµÄÈκÎÒì³£µÄ¼òµ¥ÀàÃû¡£ |
+
+
+
+ÒªÌæ»»Ä¬ÈϱêÇ©£¬ÐèÒªÌṩһ¸öʵÏÖÁË `RepositoryTagsProvider` µÄ `@Bean`¡£
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.supported.rabbitmq)7.3.16\. RabbitMQ Ö¸±ê
+
+
+
+×Ô¶¯ÅäÖÃʹËùÓпÉÓÃµÄ RabbitMQ Á¬½Ó¹¤³§µÄÒÇÆ÷»¯£¬ÆäÖ¸±êÃûΪ `rabbitmq`¡£
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.supported.spring-integration)7.3.17\. Spring Integration Ö¸±ê
+
+
+
+Ö»ÒªÓÐ `MeterRegistry` bean£¬Spring Integration¾Í»á×Ô¶¯Ìṩ [Micrometer support](https://docs.spring.io/spring-integration/docs/6.1.0-M1/reference/html/system-management.html#micrometer-integration)¡£ ¶ÈÁ¿±ê×¼ÔÚ `spring.integration.` meter Ãû³ÆÏ·¢²¼¡£
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.supported.kafka)7.3.18\. Kafka Ö¸±ê
+
+
+
+×Ô¶¯ÅäÖÃΪ×Ô¶¯ÅäÖõÄÏû·ÑÕß¹¤³§ºÍÉú²úÕß¹¤³§·Ö±ð×¢²áÁËÒ»¸ö `MicrometerConsumerListener` ºÍ `MicrometerProducerListener`¡£ Ëü»¹Îª `StreamsBuilderFactoryBean` ×¢²áÁËÒ»¸ö `KafkaStreamsMicrometerListener`¡£ ¸ü¶àϸ½Ú£¬Çë²ÎÔÄSpring KafkaÎĵµÖÐµÄ [Micrometer Native Metrics](https://docs.spring.io/spring-kafka/docs/3.0.3/reference/html/#micrometer-native) ²¿·Ö¡£
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.supported.mongodb)7.3.19\. MongoDB Ö¸±ê
+
+
+
+±¾½Ú¼òÒª½éÉÜMongoDBµÄ¿ÉÓöÈÁ¿¡£
+
+
+
+
+
+##### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.supported.mongodb.command)MongoDBÃüÁîÖ¸±ê
+
+
+
+×Ô¶¯ÅäÖý« `MongoMetricsCommandListener` Óë×Ô¶¯ÅäÖÃµÄ `MongoClient` ×¢²á¡£
+
+
+
+
+
+Ò»¸öÃûΪ `mongodb.driver.commands` µÄtimerÖ¸±ê±»´´½¨£¬ÓÃÓÚÏòµ×²ãMongoDB driver·¢³öµÄÿÌõÃüÁî¡£ ĬÈÏÇé¿öÏ£¬Ã¿¸öÖ¸±ê¶¼±»±ê¼ÇΪÒÔÏÂÐÅÏ¢¡£
+
+
+
+
+| Tag | ˵Ã÷ |
+| --- | --- |
+| `command` | ·¢³öµÄÃüÁîµÄÃû³Æ¡£ |
+| `cluster.id` | ·¢Ë͸ÃÃüÁîµÄ¼¯ÈºµÄ±êʶ·û¡£ |
+| `server.address` | ·¢ËÍÃüÁîµÄ·þÎñÆ÷µÄµØÖ·¡£ |
+| `status` | ÃüÁîµÄ½á¹û£¨`SUCCESS` »ò `FAILED£©¡£ |
+
+
+
+ΪÁËÌæ»»Ä¬ÈϵĶÈÁ¿ºâ±êÇ©£¬¶¨ÒåÒ»¸ö `MongoCommandTagsProvider` bean£¬ÈçÏÂÀýËùʾ¡£
+
+
+
+
+
+
+
+Java
+
+Kotlin
+
+
+
+
+
+```
+@Configuration(proxyBeanMethods = false)
+public class MyCommandTagsProviderConfiguration {
+
+ @Bean
+ public MongoCommandTagsProvider customCommandTagsProvider() {
+ return new CustomCommandTagsProvider();
+ }
+
+}
+
+```
+
+
+
+
+
+
+
+Òª½ûÓÃ×Ô¶¯ÅäÖõÄÃüÁî¶ÈÁ¿£¬ÇëÉèÖÃÒÔÏÂÊôÐÔ¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.metrics.mongo.command.enabled=false
+
+```
+
+
+
+
+
+
+
+
+
+##### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.supported.mongodb.connection-pool)MongoDB Á¬½Ó³ØÖ¸±ê
+
+
+
+×Ô¶¯ÅäÖý« `MongoMetricsConnectionPoolListener` Óë×Ô¶¯ÅäÖÃµÄ `MongoClient` ×¢²á¡£
+
+
+
+
+
+ÒÔÏÂÊÇΪÁ¬½Ó³Ø´´½¨µÄ²âÁ¿Ö¸±ê¡£
+
+
+
+
+
+* `mongodb.driver.pool.size` ±¨¸æÁ¬½Ó³ØµÄµ±Ç°´óС£¬°üÀ¨¿ÕÏкÍÕýÔÚʹÓõijÉÔ±¡£
+
+* `mongodb.driver.pool.checkedout` ±¨¸æµ±Ç°Ê¹ÓÃÖеÄÁ¬½ÓÊý¡£
+
+* `mongodb.driver.pool.waitqueuesize` ±¨¸æ³ØÖÐÁ¬½ÓµÄµÈ´ý¶ÓÁеĵ±Ç°´óС¡£
+
+
+
+
+
+ĬÈÏÇé¿öÏ£¬Ã¿¸öÖ¸±ê¶¼±»±ê¼ÇΪÒÔÏÂÐÅÏ¢¡£
+
+
+
+
+| Tag | ˵Ã÷ |
+| --- | --- |
+| `cluster.id` | Á¬½Ó³ØËù¶ÔÓ¦µÄ¼¯ÈºµÄ±êʶ·û¡£ |
+| `server.address` | Á¬½Ó³ØËù¶ÔÓ¦µÄ·þÎñÆ÷µÄµØÖ·¡£ |
+
+
+
+Ҫȡ´úĬÈϵĶÈÁ¿ºâ±êÇ©£¬Ç붨ÒåÒ»¸ö `MongoConnectionPoolTagsProvider` bean¡£
+
+
+
+
+
+
+
+Java
+
+Kotlin
+
+
+
+
+
+```
+@Configuration(proxyBeanMethods = false)
+public class MyConnectionPoolTagsProviderConfiguration {
+
+ @Bean
+ public MongoConnectionPoolTagsProvider customConnectionPoolTagsProvider() {
+ return new CustomConnectionPoolTagsProvider();
+ }
+
+}
+
+```
+
+
+
+
+
+
+
+Òª½ûÓÃ×Ô¶¯ÅäÖõÄÁ¬½Ó³Ø¶ÈÁ¿£¬ÇëÉèÖÃÒÔÏÂÊôÐÔ¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.metrics.mongo.connectionpool.enabled=false
+
+```
+
+
+
+
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.supported.jetty)7.3.20\. Jetty Ö¸±ê
+
+
+
+×Ô¶¯ÅäÖÃͨ¹ýʹÓÃMicrometerµÄ `JettyServerThreadPoolMetrics` ΪJettyµÄ `ThreadPool` °ó¶¨Ö¸±ê¡£ JettyµÄ `Connector` ʵÀýµÄÖ¸±êͨ¹ýʹÓÃMicrometerµÄ `JettyConnectionMetrics` À´°ó¶¨£¬µ± `server.ssl.enabled` ±»ÉèÖÃΪ `true` ʱ£¬MicrometerµÄ `JettySslHandshakeMetrics`¡£
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.supported.timed-annotation)7.3.21\. @Timed ×¢½âµÄÖ§³Ö
+
+
+
+ÒªÔÚSpring Boot²»Ö±½ÓÖ§³ÖµÄµØ·½Ê¹Óà `@Timed`£¬Çë²Î¿¼ [Micrometer Îĵµ](https://micrometer.io/docs/concepts#_the_timed_annotation)¡£
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.supported.redis)7.3.22\. Redis Ö¸±ê
+
+
+
+×Ô¶¯ÅäÖÃΪ×Ô¶¯ÅäÖÃµÄ `LettuceConnectionFactory` ×¢²áÁËÒ»¸ö `MicrometerCommandLatencyRecorder`¡£ ¸ü¶àϸ½Ú£¬Çë²ÎÔÄLettuceÎĵµµÄ [Micrometer Metrics²¿·Ö](https://lettuce.io/core/6.2.3.RELEASE/reference/index.html#command.latency.metrics.micrometer)¡£
+
+
+
+
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.registering-custom)7.4\. ×¢²á×Ô¶¨ÒåÖ¸±ê
+
+
+
+Ҫע²á×Ô¶¨Òå¶ÈÁ¿£¬Ç뽫 `MeterRegistry` ×¢ÈëÄãµÄ×é¼þÖС£
+
+
+
+
+
+
+
+Java
+
+Kotlin
+
+
+
+
+
+```
+@Component
+public class MyBean {
+
+ private final Dictionary dictionary;
+
+ public MyBean(MeterRegistry registry) {
+ this.dictionary = Dictionary.load();
+ registry.gauge("dictionary.size", Tags.empty(), this.dictionary.getWords().size());
+ }
+
+}
+
+```
+
+
+
+
+
+
+
+Èç¹ûÄãµÄ¶ÈÁ¿±ê×¼ÒÀÀµÓÚÆäËûBean£¬ÎÒÃǽ¨ÒéÄãʹÓà `MeterBinder` À´×¢²áËüÃÇ¡£
+
+
+
+
+
+
+
+Java
+
+Kotlin
+
+
+
+
+
+```
+public class MyMeterBinderConfiguration {
+
+ @Bean
+ public MeterBinder queueSize(Queue queue) {
+ return (registry) -> Gauge.builder("queueSize", queue::size).register(registry);
+ }
+
+}
+
+```
+
+
+
+
+
+
+
+ʹÓà `MeterBinder` ¿ÉÒÔÈ·±£½¨Á¢ÕýÈ·µÄÒÀÀµ¹ØÏµ£¬²¢ÇÒÔÚ¼ìË÷¶ÈÁ¿ÖµµÄʱºò£¬BeanÊÇ¿ÉÓõġ£ Èç¹ûÄã·¢ÏÖÄãÔÚ×é¼þ»òÓ¦ÓóÌÐòÖÐÖØ¸´²âÁ¿Ò»Ì×Ö¸±ê£¬ÄÇô `MeterBinder` µÄʵÏÖÒ²»áºÜÓÐÓá£
+
+
+
+
+
+| | ĬÈÏÇé¿öÏ£¬ËùÓÐ `MeterBinder` BeanµÄÖ¸±ê¶¼»á×Ô¶¯°ó¶¨µ½Spring¹ÜÀíµÄ `MeterRegistry`¡£ |
+| --- | --- |
+
+
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.customizing)7.5\. ¶¨ÖƸö±ðÖ¸±ê
+
+
+
+Èç¹ûÄãÐèÒª¶ÔÌØ¶¨µÄ `Meter` ʵÀý½øÐÐ×Ô¶¨Ò壬Äã¿ÉÒÔʹÓà `io.micrometer.core.instrument.config.MeterFilter` ½Ó¿Ú¡£
+
+
+
+
+
+ÀýÈ磬Èç¹ûÄãÏë°ÑËùÓÐÒÔ `com.example` ¿ªÍ·µÄÒDZíIDµÄ `mytag.region` ±êÇ©ÖØÃüÃûΪ `mytag.area`£¬Äã¿ÉÒÔ×öÒÔϹ¤×÷¡£
+
+
+
+
+
+
+
+Java
+
+Kotlin
+
+
+
+
+
+```
+@Configuration(proxyBeanMethods = false)
+public class MyMetricsFilterConfiguration {
+
+ @Bean
+ public MeterFilter renameRegionTagMeterFilter() {
+ return MeterFilter.renameTag("com.example", "mytag.region", "mytag.area");
+ }
+
+}
+
+```
+
+
+
+
+
+
+
+| | ĬÈÏÇé¿öÏ£¬ËùÓÐµÄ `MeterFilter` Bean¶¼×Ô¶¯°ó¶¨µ½Spring¹ÜÀíµÄ `MeterRegistry`¡£ ÇëÈ·±£Ê¹ÓÃSpring¹ÜÀíµÄ `MeterRegistry` À´×¢²áÄãµÄÖ¸±ê£¬¶ø²»ÊÇʹÓà `Metrics` µÄÈκξ²Ì¬·½·¨¡£ ÕâЩ·½·¨Ê¹ÓõÄÊDz»±»Spring¹ÜÀíµÄÈ«¾Ö×¢²á±í¡£ |
+| --- | --- |
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.customizing.common-tags)7.5.1\. ³£¼û±êÇ©£¨Tag£©
+
+
+
+ͨÓñêǩһ°ãÓÃÓÚ¶ÔÔËÐл·¾³½øÐÐά¶ÈÏÂ×꣬ÈçÖ÷»ú¡¢ÊµÀý¡¢ÇøÓò¡¢¶ÑÕ»µÈ¡£ ¹²ÓñêÇ©ÊÊÓÃÓÚËùÓÐÒÇ±í£¬¿ÉÒÔ½øÐÐÅäÖã¬ÈçÏÂÀýËùʾ¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.metrics.tags.region=us-east-1
+management.metrics.tags.stack=prod
+
+```
+
+
+
+
+
+
+
+Ç°ÃæµÄÀý×ÓΪËùÓÐֵΪ `us-east-1` ºÍ `prod` µÄÒDZíÌí¼ÓÁË `region` ºÍ `stack` ±êÇ©¡£
+
+
+
+
+
+| | Èç¹ûÄãʹÓÃGraphite£¬ÆÕͨ±êÇ©µÄ˳ÐòÊǺÜÖØÒªµÄ¡£ ÓÉÓÚʹÓÃÕâÖÖ·½·¨²»Äܱ£Ö¤³£¼û±êÇ©µÄ˳Ðò£¬½¨ÒéGraphiteÓû§¶¨ÒåÒ»¸ö×Ô¶¨ÒåµÄ `MeterFilter` À´´úÌæ¡£ |
+| --- | --- |
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.customizing.per-meter-properties)7.5.2\. Per-meter Properties
+
+
+
+³ýÁË `MeterFilter` Bean£¬Ä㻹¿ÉÒÔʹÓÃÊôÐÔÔÚÿ¸ö±íµÄ»ù´¡ÉÏÓ¦ÓÃÒ»×éÓÐÏÞµÄ×Ô¶¨Ò幦ÄÜ¡£ ʹÓÃSpring BootµÄ `PropertiesMeterFilter`£¬Ã¿¸ö±íµÄ¶¨ÖƱ»Ó¦ÓÃÓÚÒÔ¸ø¶¨Ãû³Æ¿ªÍ·µÄÈκαíµÄID¡£ ÏÂÃæµÄÀý×Ó¹ýÂ˵ôÈκÎIDÒÔ `example.remote` ¿ªÍ·µÄÒÇ±í¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.metrics.enable.example.remote=false
+
+```
+
+
+
+
+
+
+
+ÏÂÃæµÄÊôÐÔÔÊÐíper-meterµÄ¶¨ÖÆ¡£
+
+
+
+Table 1\. Per-meter customizations
+| Property | ˵Ã÷ |
+| --- | --- |
+| `management.metrics.enable` | ÊÇ·ñ½ÓÊܾßÓÐÌØ¶¨IDµÄMeter¡£ ²»½ÓÊܵÄMeter½«´Ó `MeterRegistry` ÖйýÂ˵ô¡£ |
+| `management.metrics.distribution.percentiles-histogram` | ÊÇ·ñ·¢²¼ÊʺϼÆËã¿É¾Û¼¯£¨¿çά¶È£©µÄ°Ù·ÖλÊý½üËÆÖµµÄÖ±·½Í¼¡£ |
+| `management.metrics.distribution.minimum-expected-value`, `management.metrics.distribution.maximum-expected-value` | ͨ¹ýÇ¯ÖÆÔ¤ÆÚÖµµÄ·¶Î§£¬·¢²¼¸üÉÙµÄÖ±·½Í¼Í°¡£ |
+| `management.metrics.distribution.percentiles` | ·¢²¼ÔÚÄãµÄÓ¦ÓóÌÐòÖмÆËãµÄ°Ù·Öλֵ |
+| `management.metrics.distribution.expiry`, `management.metrics.distribution.buffer-length` | ͨ¹ýÔÚ»·Ðλº³åÇøÖлýÀÛ×î½üµÄÑù±¾£¬¸øËüÃǸü´óµÄÈ¨ÖØ£¬»·Ðλº³åÇøÔÚ¿ÉÅäÖõĹýÆÚºóÐýת£¬»º³åÇø³¤¶ÈΪ ¿ÉÅäÖõĻº³åÇø³¤¶È¡£ |
+| `management.metrics.distribution.slo` | ·¢²¼Ò»¸öÀÛ»ýÖ±·½Í¼£¬ÆäÖеÄͰÓÉÄãµÄ·þÎñˮƽĿ±ê¶¨Òå¡£ |
+
+
+
+¹ØÓÚ `percentiles-histogram` £¨°Ù·ÖÊý-Ö±·½Í¼£©¡¢`percentiles`£¨°Ù·ÖÊý£©ºÍ `slo` ±³ºóµÄ¸ÅÄîµÄ¸ü¶àϸ½Ú£¬Çë²Î¼ûMicrometerÎĵµÖÐµÄ [¡°Histograms and percentiles¡± £¨Ö±·½Í¼ºÍ°Ù·ÖÊý£©²¿·Ö](https://micrometer.io/docs/concepts#_histograms_and_percentiles)¡£
+
+
+
+
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.endpoint)7.6\. Ö¸±ê¶Ëµã
+
+
+
+Spring BootÌṩÁËÒ»¸ö `metrics` ¶Ëµã£¬Äã¿ÉÒÔÕï¶ÏÐÔµØÊ¹ÓÃËüÀ´¼ì²éÓ¦ÓóÌÐòÊÕ¼¯µÄÖ¸±ê¡£¸Ã¶ËµãĬÈÏÇé¿öÏÂÊDz»¿ÉÓõ쬱ØÐ빫¿ª¡£¸ü¶àϸ½ÚÇë²Î¼û [±©Â¶¶Ëµã](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints.exposing)¡£
+
+
+
+
+
+µ¼º½µ½ `/actuator/metrics` »áÏÔʾһ¸ö¿ÉÓõÄÒDZíÃû³ÆÁÐ±í¡£ Äã¿ÉÒÔͨ¹ýÌṩÃû³Æ×÷ΪѡÔñÆ÷À´ÉîÈë²é¿´Ä³¸öÌØ¶¨ÒDZíµÄÐÅÏ¢£¬ÀýÈ磬`/actuator/metrics/jvm.memory.max`¡£
+
+
+
+
+
+| | ÄãÔÚÕâÀïʹÓõÄÃû×ÖÓ¦¸ÃÓë´úÂëÖÐʹÓõÄÃû×ÖÒ»Ö£¬¶ø²»ÊÇÔÚËü±»ÔËÍùµÄ¼à¿ØÏµÍ³Öо¹ýÃüÃû¹ßÀý¹æ·¶»¯ºóµÄÃû×Ö¡£ »»¾ä»°Ëµ£¬Èç¹û `jvm.memory.max` ÔÚPrometheusÖÐÏÔʾΪ `jvm_memory_max`£¬ÒòΪËüµÄÉßÐÎÃüÃû¹ßÀý£¬ÄãÈÔȻӦ¸ÃʹÓà `jvm.memory.max` ×÷ΪѡÔñÆ÷£¬ÔÚ `metrics` ¶ËµãÖмì²éÒÇ±í¡£ |
+| --- | --- |
+
+
+
+
+
+ÄãÒ²¿ÉÒÔÔÚURLµÄĩβÌí¼ÓÈÎÒâÊýÁ¿µÄ `tag=KEY:VALUE` ²éѯ²ÎÊý£¬ÒÔ¶ÔÒÇ±í½øÐÐά¶ÈÏÂ×ê?¡ª?ÀýÈ磬`/actuator/metrics/jvm.memory.max?tag=area:nonheap`¡£
+
+
+
+
+
+| | ±¨¸æµÄ²âÁ¿ÖµÊÇËùÓÐÓëÒDZíÃû³ÆÏàÆ¥ÅäµÄÒDZíºÍÈκÎÒÑÓ¦ÓõıêÇ©µÄͳ¼ÆÁ¿µÄ _×ܺÍ_¡£ ÔÚÇ°ÃæµÄÀý×ÓÖУ¬·µ»ØµÄ `Value` ͳ¼ÆÊÇ¶ÑµÄ ¡°Code Cache¡±¡¢¡°Compressed Class Space¡± ºÍ ¡°Metaspace¡± ÇøÓòµÄ×î´óÄÚ´æ¡°×ã¼£¡±Ö®ºÍ¡£ Èç¹ûÄãÏëÖ»¿´µ½ ¡°Metaspace¡± µÄ×î´ó³ß´ç£¬Äã¿ÉÒÔÌí¼ÓÒ»¸ö¶îÍâµÄ `tag=id:Metaspace` --¼´ `/actuator/metrics/jvm.memory.max?tag=area:nonheap&tag=id:Metaspace`¡£ |
+| --- | --- |
+
+
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/actuator.html#actuator.metrics.micrometer-observation)7.7\. ÕûºÏ Micrometer Observation
+
+
+
+Ò»¸ö `DefaultMeterObservationHandler` ±»×Ô¶¯×¢²áÔÚ `ObservationRegistry` ÉÏ£¬ËüΪÿ¸öÍê³ÉµÄ¹Û²ì£¨completed observation£©´´½¨¶ÈÁ¿£¨metric£©¡£
+
+
+
+
+
+
+
+
+
+
+
+## [](https://springdoc.cn/spring-boot/actuator.html#actuator.micrometer-tracing)8\. ×·×Ù£¨Tracing£©
+
+
+
+
+
+Spring Boot Actuator Ϊ Micrometer Tracing ÌṩÁËÒÀÀµÐÔ¹ÜÀíºÍ×Ô¶¯ÅäÖ㬠[Micrometer Tracing](https://micrometer.io/docs/tracing) ÊÇÁ÷ÐеÄ×·×ÙÆ÷£¨tracer£©¿âµÄÒ»¸ö½Ó¿Ú£¨facade£©¡£
+
+
+
+
+
+| | ÒªÁ˽â¸ü¶à¹ØÓÚ Micrometer Tracing ¹¦ÄܵÄÐÅÏ¢£¬Çë²ÎÔÄÆä [²Î¿¼Îĵµ](https://micrometer.io/docs/tracing)¡£ |
+| --- | --- |
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/actuator.html#actuator.micrometer-tracing.tracers)8.1\. Ö§³ÖµÄ×·×ÙÆ÷
+
+
+
+Spring BootΪÒÔÏÂ×·×ÙÆ÷ÌṩÁË×Ô¶¯ÅäÖá£
+
+
+
+
+
+* ʹÓà [Zipkin](https://zipkin.io/) »ò [Wavefront](https://docs.wavefront.com/) µÄ [OpenTelemetry](https://opentelemetry.io/)
+
+* ʹÓà [Zipkin](https://zipkin.io/) »ò [Wavefront](https://docs.wavefront.com/) µÄ [OpenZipkin Brave](https://github.com/openzipkin/brave)
+
+
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/actuator.html#actuator.micrometer-tracing.getting-started)8.2\. ÈëÃÅ
+
+
+
+ÎÒÃÇÐèÒªÒ»¸ö¿ÉÒÔÓÃÀ´¿ªÊ¼×·×ÙµÄʾÀýÓ¦ÓóÌÐò¡£¾ÍÎÒÃǵÄÄ¿µÄ¶øÑÔ£¬¡°[getting-started.html](https://springdoc.cn/spring-boot/getting-started.html#getting-started.first-application)¡± ²¿·ÖËùÉæ¼°µÄ¼òµ¥µÄ ¡°Hello World!¡± web³ÌÐò¾Í×ã¹»ÁË¡£ÎÒÃǽ«Ê¹Óà `OpenTelemetry` ×·×ÙÆ÷ºÍ `Zipkin` ×÷Ϊ׷×Ùºó¶Ë¡£
+
+
+
+
+
+»Ø¹Ëһϣ¬ÎÒÃǵÄÖ÷ÒªÓ¦ÓôúÂë¿´ÆðÀ´ÊÇÕâÑùµÄ¡£
+
+
+
+
+
+
+
+```
+@RestController
+@SpringBootApplication
+public class MyApplication {
+
+ private static final Log logger = LogFactory.getLog(MyApplication.class);
+
+ @RequestMapping("/")
+ String home() {
+ logger.info("home() has been called");
+ return "Hello World!";
+ }
+
+ public static void main(String[] args) {
+ SpringApplication.run(MyApplication.class, args);
+ }
+
+}
+
+```
+
+
+
+
+
+
+
+| | ÔÚ `home()` ·½·¨ÖУ¬ÓÐÒ»¸ö¸½¼ÓµÄloggerÓï¾ä£¬ÕâÔÚºóÃæ»áºÜÖØÒª¡£ |
+| --- | --- |
+
+
+
+
+
+ÏÖÔÚ£¬ÎÒÃDZØÐëÌí¼ÓÒÔÏÂÒÀÀµÏî¡£
+
+
+
+
+
+* `org.springframework.boot:spring-boot-starter-actuator`
+
+* `io.micrometer:micrometer-tracing-bridge-otel` - ÕâÊÇÁ¬½Ó Micrometer Observation API ºÍ OpenTelemetry µÄ±ØÒªÌõ¼þ¡£
+
+* `io.opentelemetry:opentelemetry-exporter-zipkin` - ÕâÊÇÏòZipkin±¨¸æ [traces](https://micrometer.io/docs/tracing#_glossary) ËùÐèÒªµÄ¡£
+
+
+
+
+
+Ìí¼ÓÈçÏ嵀 application properties:
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.tracing.sampling.probability=1.0
+
+```
+
+
+
+
+
+
+
+ĬÈÏÇé¿öÏ£¬Spring BootÖ»¶Ô10%µÄÇëÇó½øÐвÉÑù£¬ÒÔ·ÀÖ¹×·×Ùºó¶Ë²»¿°Öظº¡£´ËÊôÐÔ½«ÆäÇл»Îª100%£¬ÕâÑùÿ¸öÇëÇ󶼻ᱻ·¢Ë͵½¸ú×Ùºó¶Ë¡£
+
+
+
+
+
+ΪÁËÊÕ¼¯ºÍ¿ÉÊÓ»¯¸ú×Ù£¬ÎÒÃÇÐèÒªÒ»¸öÔËÐиú×ٵĺó¶Ë¡£ÎÒÃÇÔÚÕâÀïʹÓÃZipkin×÷ΪÎÒÃǵĸú×Ùºó¶Ë¡£ [Zipkin¿ìËÙÈëÃÅÖ¸ÄÏ](https://zipkin.io/pages/quickstart) ÌṩÁËÈçºÎÔÚ±¾µØÆô¶¯ZipkinµÄ˵Ã÷¡£
+
+
+
+
+
+ZipkinÔËÐкó£¬Äã¿ÉÒÔÆô¶¯ÄãµÄÓ¦ÓóÌÐò¡£
+
+
+
+
+
+Èç¹ûÄã´ò¿ªwebä¯ÀÀÆ÷·ÃÎÊ `[localhost:8080](http://localhost:8080/)`£¬ÄãÓ¦¸Ã¿´µ½ÒÔÏÂÊä³ö¡£
+
+
+
+
+
+
+
+ Hello World!
+
+
+
+
+
+
+
+ÔÚÄ»ºó£¬ÒѾΪHTTPÇëÇó´´½¨ÁËÒ»¸ö observation£¬Ëü·´¹ýÀ´±»ÇŽӵ½ `OpenTelemetry`£¬ºóÕßÏòZipkin±¨¸æÒ»¸öеĸú×Ù£¨trace£©¡£
+
+
+
+
+
+ÏÖÔÚ£¬ÔÚ `[localhost:9411](http://localhost:9411/)` ´ò¿ªZipkinÓû§½çÃæ£¬µã»÷ "Run Query" °´Å¥£¬ÁгöËùÓÐÊÕ¼¯µ½µÄ¸ú×ÙÐÅÏ¢¡£ÄãÓ¦¸Ã¿´µ½Ò»¸ö×·×Ù¡£µã»÷ "Show" °´Å¥£¬²é¿´¸Ã×·×ÙµÄϸ½Ú¡£
+
+
+
+
+
+| | Äã¿ÉÒÔͨ¹ý½« `logging.pattern.level` ÊôÐÔÉèÖÃΪ `%5p [${spring.application.name:},%X{traceId:-},%X{spanId:-}]`£¬ÔÚÈÕÖ¾Öаüº¬µ±Ç°µÄ¸ú×Ù£¨trace£©ºÍ span id¡£ |
+| --- | --- |
+
+
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/actuator.html#actuator.micrometer-tracing.tracer-implementations)8.3\. ¸ú×ÙÆ÷£¨Tracer£©µÄʵÏÖ
+
+
+
+ÓÉÓÚMicrometer TracerÖ§³Ö¶àÖÖʾ×ÙÆ÷µÄʵÏÖ£¬Òò´ËSpring Boot¿ÉÄÜÓжàÖÖÒÀÀµ×éºÏ¡£
+
+
+
+
+
+ËùÓÐ×·×ÙÆ÷µÄʵÏÖ¶¼ÐèÒª `org.springframework.boot:spring-boot-starter-actuator` ÒÀÀµ¡£
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.micrometer-tracing.tracer-implementations.otel-zipkin)8.3.1\. ʹÓà Zipkin µÄ OpenTelemetry
+
+
+
+* `io.micrometer:micrometer-tracing-bridge-otel` - ÕâÊÇÁ¬½Ó Micrometer Observation API ºÍ OpenTelemetry µÄ±ØÒªÌõ¼þ¡£
+
+* `io.opentelemetry:opentelemetry-exporter-zipkin` - ÕâÊÇÏòZipkin±¨¸ætraceËùÐèÒªµÄ¡£
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.micrometer-tracing.tracer-implementations.otel-wavefront)8.3.2\. ʹÓà Wavefront µÄ OpenTelemetry
+
+
+
+* `io.micrometer:micrometer-tracing-bridge-otel` - ÕâÊÇÁ¬½Ó Micrometer Observation API ºÍ OpenTelemetry µÄ±ØÒªÌõ¼þ¡£
+
+* `io.micrometer:micrometer-tracing-reporter-wavefront` - ÕâÊÇÏòWavefront±¨¸ætraceËùÐèÒªµÄ¡£
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.micrometer-tracing.tracer-implementations.brave-zipkin)8.3.3\. ʹÓà Zipkin µÄ OpenZipkin Brave
+
+
+
+* `io.micrometer:micrometer-tracing-bridge-brave` - ÕâÊÇÁ¬½Ó Micrometer Observation API ºÍ Brave µÄ±ØÒªÌõ¼þ¡£
+
+* `io.zipkin.reporter2:zipkin-reporter-brave` - ÕâÊÇÏòZipkin±¨¸æ trace ËùÐèÒªµÄ¡£
+
+
+
+
+
+| | Èç¹ûÄãµÄÏîĿûÓÐʹÓÃSpring MVC»òSpring WebFlux£¬Ò²ÐèҪʹÓà `io.zipkin.reporter2:zipkin-sender-urlconnection` ÒÀÀµÏî¡£ |
+| --- | --- |
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/actuator.html#actuator.micrometer-tracing.tracer-implementations.brave-wavefront)8.3.4\. ʹÓÃWavefrontµÄOpenZipkin Brave
+
+
+
+* `io.micrometer:micrometer-tracing-bridge-brave` - ÕâÊÇÁ¬½Ó²âMicrometer Observation APIºÍBraveµÄ±ØÒªÌõ¼þ¡£
+
+* `io.micrometer:micrometer-tracing-reporter-wavefront` - ÕâÊÇÏòWavefront±¨¸ætraceËùÐèÒªµÄ¡£
+
+
+
+
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/actuator.html#actuator.micrometer-tracing.creating-spans)8.4\. ´´½¨×Ô¶¨Òå¿ç¶È£¨span£©
+
+
+
+Äã¿ÉÒÔͨ¹ýÆô¶¯Ò»¸ö observation À´´´½¨Äã×Ô¼ºµÄspan¡£Îª´Ë£¬½« `ObservationRegistry` ×¢Èëµ½ÄãµÄ×é¼þÖС£
+
+
+
+
+
+
+
+```
+@Component
+class CustomObservation {
+
+ private final ObservationRegistry observationRegistry;
+
+ CustomObservation(ObservationRegistry observationRegistry) {
+ this.observationRegistry = observationRegistry;
+ }
+
+ void someOperation() {
+ Observation observation = Observation.createNotStarted("some-operation", this.observationRegistry);
+ observation.lowCardinalityKeyValue("some-tag", "some-value");
+ observation.observe(() -> {
+ // Business logic ...
+ });
+ }
+
+}
+
+```
+
+
+
+
+
+
+
+Õ⽫´´½¨Ò»¸öÃûΪ "some-operation" µÄ observation£¬±êǩΪ£¬±êǩΪ "some-tag=some-value"¡£
+
+
+
+
+
+| | Èç¹ûÄãÏëÔÚ²»´´½¨metricµÄÇé¿öÏ´´½¨Ò»¸öspan£¬ÄãÐèҪʹÓà Micrometer µÄ [µÍ¼¶Tracer API](https://micrometer.io/docs/tracing#_using_micrometer_tracing_directly)¡£ |
+| --- | --- |
+
+
+
+
+
+
+
+
+
+
+
+## [](https://springdoc.cn/spring-boot/actuator.html#actuator.auditing)9\. Éó¼Æ
+
+
+
+
+
+Ò»µ©Spring Security·¢»Ó×÷Óã¬Spring Boot Actuator¾ÍÓÐÒ»¸öÁé»îµÄÉó¼Æ¿ò¼Ü£¬¿ÉÒÔ·¢²¼Ê¼þ£¨Ä¬ÈÏΪ ¡°authentication success¡±, ¡°failure¡± ºÍ ¡°access denied¡± µÄÒì³££©¡£ ÕâÒ»¹¦ÄܶÔÓÚ±¨¸æºÍʵʩ»ùÓÚÈÏ֤ʧ°ÜµÄËø¶¨²ßÂԷdz£ÓÐÓá£
+
+
+
+
+
+Äã¿ÉÒÔͨ¹ýÔÚÓ¦ÓóÌÐòµÄÅäÖÃÖÐÌṩһ¸ö `AuditEventRepository` ÀàÐ͵ÄbeanÀ´ÆôÓÃÉ󼯡£ ΪÁË·½±ã£¬Spring BootÌṩÁËÒ»¸ö `InMemoryAuditEventRepository`¡£ `InMemoryAuditEventRepository` µÄ¹¦ÄÜÓÐÏÞ£¬ÎÒÃǽ¨ÒéÖ»ÔÚ¿ª·¢»·¾³ÖÐʹÓÃËü¡£ ¶ÔÓÚÉú²ú»·¾³£¬Ç뿼ÂÇ´´½¨Äã×Ô¼ºµÄÌæ´ú `AuditEventRepository` ʵÏÖ¡£
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/actuator.html#actuator.auditing.custom)9.1\. ¶¨ÖÆÉó¼Æ
+
+
+
+ΪÁ˶¨ÖÆ·¢²¼µÄ°²È«Ê¼þ£¬Äã¿ÉÒÔÌṩÄã×Ô¼ºµÄ `AbstractAuthenticationAuditListener` ºÍ `AbstractAuthorizationAuditListener` µÄʵÏÖ¡£
+
+
+
+
+
+ÄãÒ²¿ÉÒÔΪÄã×Ô¼ºµÄÒµÎñʼþʹÓÃÉ󼯷þÎñ¡£ Òª×öµ½ÕâÒ»µã£¬ÒªÃ´½« `AuditEventRepository` bean×¢ÈëÄã×Ô¼ºµÄ×é¼þ²¢Ö±½ÓʹÓÃËü£¬ÒªÃ´ÓÃSpringµÄ `ApplicationEventPublisher` ·¢²¼ `AuditApplicationEvent`£¨Í¨¹ýʵÏÖ `ApplicationEventPublisherAware`£©¡£
+
+
+
+
+
+
+
+
+
+
+
+## [](https://springdoc.cn/spring-boot/actuator.html#actuator.http-exchanges)10\. ¼Ç¼ HTTP Exchange
+
+
+
+
+
+Äã¿ÉÒÔͨ¹ýÔÚÓ¦ÓóÌÐòµÄÅäÖÃÖÐÌṩһ¸ö `HttpExchangeRepository` ÀàÐ굀 bean À´ÆôÓà HTTP exchange µÄ¼Ç¼¡£ÎªÁË·½±ãÆð¼û£¬Spring Boot ÌṩÁË `InMemoryHttpExchangeRepository`£¬Ä¬ÈÏÇé¿öÏ£¬Ëü´æ´¢ÁË×îºó100¸ö request/response exchange¡£Óë×·×Ù½â¾ö·½°¸£¨tracing solutions£©Ïà±È£¬`InMemoryHttpExchangeRepository` ÊÇÓÐÏ޵ģ¬ÎÒÃǽ¨ÒéÖ»ÔÚ¿ª·¢»·¾³ÖÐʹÓÃËü¡£¶ÔÓÚÉú²ú»·¾³£¬ÎÒÃǽ¨ÒéʹÓÃÒ»¸öÉú²ú¾ÍÐ÷µÄ¸ú×Ù»ò¹Û²ì½â¾ö·½°¸£¬Èç `Zipkin` »ò `OpenTelemetry`¡£ÁíÍ⣬ÄãÒ²¿ÉÒÔ´´½¨Äã×Ô¼ºµÄ `HttpExchangeRepository`¡£
+
+
+
+
+
+Äã¿ÉÒÔʹÓà `httpexchanges` ¶ËµãÀ´»ñÈ¡´æ´¢ÔÚ `HttpExchangeRepository` ÖÐµÄ request/response exchange µÄÐÅÏ¢¡£
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/actuator.html#actuator.http-exchanges.custom)10.1\. ×Ô¶¨Òå HTTP Exchange ¼Ç¼
+
+
+
+Òª×Ô¶¨Òå°üÀ¨ÔÚÿ¸ö¼Ç¼µÄ exchange ÏîÄ¿£¬ÇëʹÓà `management.httpexchanges.recording.include` ÅäÖÃÊôÐÔ¡£
+
+
+
+
+
+ÒªÍêÈ«½ûÖ¹ÖØÐ±àÂ룬Ç뽫 `management.httpexchanges.recording.enabled` ÉèÖÃΪ `false`¡£
+
+
+
+
+
+
+
+
+
+
+
+## [](https://springdoc.cn/spring-boot/actuator.html#actuator.process-monitoring)11\. ½ø³Ì¼à¿Ø
+
+
+
+
+
+ÔÚ `spring-boot` Ä£¿éÖУ¬Äã¿ÉÒÔÕÒµ½Á½¸ö´´½¨ÎļþµÄÀ࣬ÕâЩÎļþÔÚ½ø³Ì¼à¿ØÖÐͨ³£ºÜÓÐÓá£
+
+
+
+
+
+* `ApplicationPidFileWriter` ´´½¨Ò»¸ö°üº¬Ó¦ÓóÌÐòPIDµÄÎļþ£¨Ä¬ÈÏÇé¿öÏ£¬ÔÚÓ¦ÓóÌÐòĿ¼Ï£¬ÎļþÃûΪ `application.pid`£©¡£
+
+* `WebServerPortFileWriter` ´´½¨Ò»¸ö£¨»ò¶à¸ö£©Îļþ£¬°üº¬ÔËÐÐÖеÄWeb·þÎñÆ÷µÄ¶Ë¿Ú£¨Ä¬ÈÏÇé¿öÏ£¬ÔÚÓ¦ÓóÌÐòĿ¼Ï£¬ÎļþÃûΪ `application.port`£©¡£
+
+
+
+
+
+ĬÈÏÇé¿öÏ£¬ÕâЩдÊÖûÓб»¼¤»î£¬µ«Äã¿ÉÒÔÆôÓÃËüÃÇ¡£
+
+
+
+
+
+* [ͨ¹ýÀ©Õ¹ÅäÖÃ](https://springdoc.cn/spring-boot/actuator.html#actuator.process-monitoring.configuration)
+
+* [ÒÔ±à³Ì·½Ê½ÊµÏÖ½ø³Ì¼à¿Ø](https://springdoc.cn/spring-boot/actuator.html#actuator.process-monitoring.programmatically)
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/actuator.html#actuator.process-monitoring.configuration)11.1\. À©Õ¹ÅäÖÃ
+
+
+
+ÔÚ `META-INF/spring.factories` ÎļþÖУ¬Äã¿ÉÒÔ¼¤»îдÈëPIDÎļþµÄlistener£¨Ò»¸ö»òÕß¶à¸ö£©¡£
+
+
+
+
+
+
+
+ org.springframework.context.ApplicationListener=\
+org.springframework.boot.context.ApplicationPidFileWriter,\
+org.springframework.boot.web.context.WebServerPortFileWriter
+
+
+
+
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/actuator.html#actuator.process-monitoring.programmatically)11.2\. ÒÔ±à³Ì·½Ê½ÊµÏÖ½ø³Ì¼à¿Ø
+
+
+
+ÄãÒ²¿ÉÒÔͨ¹ýµ÷Óà `SpringApplication.addListeners(¡?)` ·½·¨²¢´«µÝÊʵ±µÄ `Writer` ¶ÔÏóÀ´¼¤»îÒ»¸ö¼àÌýÆ÷¡£ Õâ¸ö·½·¨»¹¿ÉÒÔÈÃÄãÔÚ `Writer` ¹¹Ô캯ÊýÖÐ×Ô¶¨ÒåÎļþÃûºÍ·¾¶¡£
+
+
+
+
+
+
+
+
+
+
+
+## [](https://springdoc.cn/spring-boot/actuator.html#actuator.cloud-foundry)12\. Cloud Foundry µÄÖ§³Ö
+
+
+
+
+
+Spring Boot µÄactuatorÄ£¿é°üÀ¨¶îÍâµÄÖ§³Ö£¬µ±Äú²¿Êðµ½¼æÈÝµÄ Cloud Foundry ʵÀýʱ£¬¸ÃÖ§³Ö½«±»¼¤»î¡£ `/cloudfoundryapplication` ·¾¶ÎªËùÓÐ `@Endpoint` BeanÌṩÁËÁíÒ»Ìõ°²È«Â·Ïß¡£
+
+
+
+
+
+À©Õ¹Ö§³Öʹ Cloud Foundry ¹ÜÀí UI£¨ÀýÈçÄú¿ÉÒÔÓÃÀ´²é¿´ÒѲ¿ÊðµÄÓ¦ÓóÌÐòµÄ Web Ó¦ÓóÌÐò£©µÃµ½ Spring Boot Ö´ÐÐÆ÷ÐÅÏ¢µÄÔöÇ¿¡£ ÀýÈ磬ӦÓóÌÐò×´Ì¬Ò³Ãæ¿ÉÒÔ°üÀ¨ÍêÕûµÄ½¡¿µÐÅÏ¢£¬¶ø²»ÊǵäÐ굀 ¡°running¡± »ò ¡°stopped¡± ״̬¡£
+
+
+
+
+
+| | ÆÕͨÓû§ÎÞ·¨Ö±½Ó·ÃÎÊ `/cloudfoundryapplication` ·¾¶¡£ ҪʹÓøö˵㣬Äú±ØÐëÔÚÇëÇóÖд«µÝÒ»¸öÓÐЧµÄ UAA ÁîÅÆ¡£ |
+| --- | --- |
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/actuator.html#actuator.cloud-foundry.disable)12.1\. ½ûÓÃÀ©Õ¹µÄ Cloud Foundry Actuator Ö§³Ö
+
+
+
+Èç¹ûÄúÏëÍêÈ«½ûÓà `/cloudfoundryapplication` ¶Ëµã£¬Äú¿ÉÒÔÔÚÄúµÄ `application.properties` ÎļþÖÐÌí¼ÓÒÔÏÂÉèÖá£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.cloudfoundry.enabled=false
+
+```
+
+
+
+
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/actuator.html#actuator.cloud-foundry.ssl)12.2\. Cloud Foundry×ÔÇ©ÃûÖ¤Êé
+
+
+
+ĬÈÏÇé¿öÏ£¬`/cloudfoundryapplication` ¶ËµãµÄ°²È«ÑéÖ¤»á¶Ô¸÷ÖÖ Cloud Foundry ·þÎñ½øÐÐ SSL µ÷ÓᣠÈç¹ûÄúµÄ Cloud Foundry UAA »ò Cloud Controller ·þÎñʹÓÃ×ÔÇ©ÃûÖ¤Ê飬ÄúÐèÒªÉèÖÃÒÔÏÂÊôÐÔ¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+management.cloudfoundry.skip-ssl-validation=true
+
+```
+
+
+
+
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/actuator.html#actuator.cloud-foundry.custom-context-path)12.3\. ×Ô¶¨Òå Context Path
+
+
+
+Èç¹û·þÎñÆ÷µÄ context-path ±»ÅäÖÃΪ `/` ÒÔÍâµÄÈκÎÄÚÈÝ£¬Ôò Cloud Foundry ¶ËµãÔÚÓ¦ÓóÌÐòµÄ¸ù²¿²»¿ÉÓᣠÀýÈ磬Èç¹û `server.servlet.context-path=/app`£¬Ôò Cloud Foundry ¶ËµãÔÚ `/app/cloudfoundryapplication/*` ´¦¿ÉÓá£
+
+
+
+
+
+Èç¹ûÄúÏ£Íû Cloud Foundry ¶ËµãʼÖÕÔÚ `/cloudfoundryapplication/*` ´¦¿ÉÓã¬ÎÞÂÛ·þÎñÆ÷µÄÉÏÏÂÎÄ·¾¶ÈçºÎ£¬ÄúÐèÒªÔÚÄúµÄÓ¦ÓóÌÐòÖÐÃ÷È·ÅäÖᣠ¸ÃÅäÖÃÒòʹÓÃµÄ Web ·þÎñÆ÷²»Í¬¶ø²»Í¬¡£ ¶ÔÓÚ Tomcat£¬Äú¿ÉÒÔÌí¼ÓÒÔÏÂÅäÖá£
+
+
+
+
+
+
+
+Java
+
+Kotlin
+
+
+
+
+
+```
+@Configuration(proxyBeanMethods = false)
+public class MyCloudFoundryConfiguration {
+
+ @Bean
+ public TomcatServletWebServerFactory servletWebServerFactory() {
+ return new TomcatServletWebServerFactory() {
+
+ @Override
+ protected void prepareContext(Host host, ServletContextInitializer[] initializers) {
+ super.prepareContext(host, initializers);
+ StandardContext child = new StandardContext();
+ child.addLifecycleListener(new Tomcat.FixContextListener());
+ child.setPath("/cloudfoundryapplication");
+ ServletContainerInitializer initializer = getServletContextInitializer(getContextPath());
+ child.addServletContainerInitializer(initializer, Collections.emptySet());
+ child.setCrossContext(true);
+ host.addChild(child);
+ }
+
+ };
+ }
+
+ private ServletContainerInitializer getServletContextInitializer(String contextPath) {
+ return (classes, context) -> {
+ Servlet servlet = new GenericServlet() {
+
+ @Override
+ public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
+ ServletContext context = req.getServletContext().getContext(contextPath);
+ context.getRequestDispatcher("/cloudfoundryapplication").forward(req, res);
+ }
+
+ };
+ context.addServlet("cloudfoundry", servlet).addMapping("/*");
+ };
+ }
+
+}
+
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+## [](https://springdoc.cn/spring-boot/actuator.html#actuator.whats-next)13\. ½ÓÏÂÀ´¶Áʲô
+
+
+
+
+
+Äã¿ÉÄÜÏë¶ÁһϠ[Graphite](https://graphiteapp.org/) µÈͼÐι¤¾ß¡£
+
+
+
+
+
+·ñÔò£¬Äã¿ÉÒÔ¼ÌÐøÔĶÁ [¡°²¿ÊðÑ¡Ï](https://springdoc.cn/spring-boot/deployment.html#deployment) £¬»òÕßÌøµ½Ç°ÃæÈ¥Á˽âÓйØSpring Boot [¹¹½¨¹¤¾ß²å](https://springdoc.cn/spring-boot/build-tool-plugins.html#build-tool-plugins)¼þµÄһЩÉîÈëÐÅÏ¢¡£
+
+
+
+
+
+
+
diff --git "a/docs/spring/SpringBoot/SpringBoot\347\232\204Starter\346\234\272\345\210\266.md" "b/docs/spring/SpringBoot/SpringBoot\347\232\204Starter\346\234\272\345\210\266.md"
new file mode 100644
index 0000000..0318193
--- /dev/null
+++ "b/docs/spring/SpringBoot/SpringBoot\347\232\204Starter\346\234\272\345\210\266.md"
@@ -0,0 +1,262 @@
+starterÊÇSpringBootÖеÄÒ»¸öз¢Ã÷£¬ËüÓÐЧµÄ½µµÍÁËÏîÄ¿¿ª·¢¹ý³ÌµÄ¸´Ôӳ̶ȣ¬¶ÔÓÚ¼ò»¯¿ª·¢²Ù×÷ÓÐ×ŷdz£ºÃµÄЧ¹û¡£±¾ÎÄ×ªÔØÁËһƬÎÄÕ£¬Ïêϸ½éÉÜÁËspring boot staterÊÇʲô£¿ËüµÄ×÷ÓÃÊÇʲô£¿
+
+Spring Boot StarterÊÇÔÚSpringBoot×é¼þÖб»Ìá³öÀ´µÄÒ»ÖÖ¸ÅÄstackoverflowÉÏÃæÒѾÓÐÈ˸ÅÀ¨ÁËÕâ¸östarterÊÇʲô¶«Î÷£¬Ïë¿´ÍêÕûµÄ»Ø´ð´Á[ÕâÀï](https://stackoverflow.com/a/28273660)£¨https://stackoverflow.com/questions/28273543/what-are-spring-boot-starter-jars/28273660#28273660£©
+
+
+
+´ó¸ÅÒâ˼¾ÍÊÇ˵starterÊÇÒ»ÖÖ¶ÔÒÀÀµµÄsynthesize£¨ºÏ³É£©£¬ÕâÊÇʲôÒâË¼ÄØ£¿ÎÒ¿ÉÒÔ¾Ù¸öÀý×ÓÀ´ËµÃ÷¡£
+
+### ¡¡ ? ´«Í³µÄ×ö·¨
+
+ÔÚûÓÐstarter֮ǰ£¬¼ÙÈçÎÒÏëÒªÔÚSpringÖÐʹÓÃjpa£¬ÄÇÎÒ¿ÉÄÜÐèÒª×öÒÔϲÙ×÷£º
+
+1. ÔÚMavenÖÐÒýÈëʹÓõÄÊý¾Ý¿âµÄÒÀÀµ£¨¼´JDBCµÄjar£©
+2. ÒýÈëjpaµÄÒÀÀµ
+3. ÔÚxxx.xmlÖÐÅäÖÃһЩÊôÐÔÐÅÏ¢
+4. ·´¸´µÄµ÷ÊÔÖ±µ½¿ÉÒÔÕý³£ÔËÐÐ
+
+ÐèҪעÒâµÄÊÇ£¬ÕâÀï²Ù×÷ÔÚÎÒÃÇ**_ÿ´Îн¨Ò»¸öÐèÒªÓõ½jpaµÄÏîÄ¿µÄʱºò¶¼ÐèÒªÖØ¸´µÄ×öÒ»´Î_**¡£Ò²ÐíÄãÔÚµÚÒ»´Î×Ô¼º½¨Á¢ÏîÄ¿µÄʱºòÊÇÔÚGoogleÉÏ×Ô¼ºËÑË÷ÁËÒ»·¬£¬»¨Á˰ëÌìʱ¼ä½â¾öµôÁ˸÷ÖÖÆæ¹ÖµÄÎÊÌâÖ®ºó£¬jpaÖÕÓÚÄÜÕý³£ÔËÐÐÁË¡£ÓÐЩÓоÑéµÄÈË»áÔÚOneNoteÉÏÃæ°ÑÕâ´Î½¨Á¢ÏîÄ¿µÄ¹ý³Ì¸ø¼Ç¼ÏÂÀ´£¬°üÀ¨²Ù×÷µÄ²½ÖèÒÔ¼°ÐèÒªÓõ½µÄÅäÖÃÎļþµÄÄÚÈÝ£¬ÔÚÏÂÒ»´ÎÔÙ´´½¨jpaÏîÄ¿µÄʱºò£¬¾Í²»ÐèÒªÔÙ´ÎÈ¥GoogleÁË£¬Ö»ÐèÒªÕÕ×űʼÇÀ´£¬Ö®ºóÔÙ°ÑËùÓеÄÅäÖÃÎļþcopy&paste¾Í¿ÉÒÔÁË¡£
+
+ÏñÉÏÃæÕâÑùµÄ²Ù×÷Ò²²»Ëã²»ÐУ¬ÊÂʵÉÏÎÒÃÇÔÚûÓÐstarter֮ǰ¶¼ÊÇÕâô¸ÉµÄ£¬µ«ÊÇÕâÑù×öÓм¸¸öÎÊÌ⣺
+
+1. Èç¹û¹ý³Ì±È½Ï·±Ëö£¬ÕâÑùÒ»²½²½²Ù×÷»áÔö¼Ó³ö´íµÄ¿ÉÄÜÐÔ
+2. ²»Í£µØcopy&paste²»·ûºÏ[Don¡¯t repeat yourself](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself)¾«Éñ
+3. ÔÚµÚÒ»´ÎÅäÖõÄʱºò£¨ÓÈÆäÈç¹û¿ª·¢Õ߱ȽÏС°×£©£¬ÐèÒª»¨·Ñµô´óÁ¿µÄʱ¼ä
+
+### ¡¡¡¡Ê¹ÓÃSpring Boot StarterÌáÉýЧÂÊ
+
+starterµÄÖ÷ҪĿµÄ¾ÍÊÇΪÁ˽â¾öÉÏÃæµÄÕâЩÎÊÌâ¡£
+
+starterµÄÀíÄstarter»á°ÑËùÓÐÓõ½µÄÒÀÀµ¶¼¸ø°üº¬½øÀ´£¬±ÜÃâÁË¿ª·¢Õß×Ô¼ºÈ¥ÒýÈëÒÀÀµËù´øÀ´µÄÂé·³¡£ÐèҪעÒâµÄÊDz»Í¬µÄstarterÊÇΪÁ˽â¾ö²»Í¬µÄÒÀÀµ£¬ËùÒÔËüÃÇÄÚ²¿µÄʵÏÖ¿ÉÄÜ»áÓкܴóµÄ²îÒ죬ÀýÈçjpaµÄstarterºÍRedisµÄstarter¿ÉÄÜʵÏ־Ͳ»Ò»Ñù£¬ÕâÊÇÒòΪstarterµÄ±¾ÖÊÔÚÓÚsynthesize£¬ÕâÊÇÒ»²ãÔÚÂß¼²ãÃæµÄ³éÏó£¬Ò²ÐíÕâÖÖÀíÄîÓеãÀàËÆÓÚDocker£¬ÒòΪËüÃǶ¼ÊÇÔÚ×öÒ»¸ö¡°°ü×°¡±µÄ²Ù×÷£¬Èç¹ûÄãÖªµÀDockerÊÇΪÁ˽â¾öʲôÎÊÌâµÄ£¬Ò²ÐíÄã¿ÉÒÔÓÃDockerºÍstarter×öÒ»¸öÀà±È¡£
+
+starterµÄʵÏÖ£ºËäÈ»²»Í¬µÄstarterʵÏÖÆðÀ´¸÷ÓвîÒ죬µ«ÊÇËûÃÇ»ù±¾É϶¼»áʹÓõ½Á½¸öÏàͬµÄÄÚÈÝ£ºConfigurationPropertiesºÍAutoConfiguration¡£ÒòΪSpring Boot¼áÐÅ¡°Ô¼¶¨´óÓÚÅäÖá±ÕâÒ»ÀíÄËùÒÔÎÒÃÇʹÓÃConfigurationPropertiesÀ´±£´æÎÒÃǵÄÅäÖ㬲¢ÇÒÕâЩÅäÖö¼¿ÉÒÔÓÐÒ»¸öĬÈÏÖµ£¬¼´ÔÚÎÒÃÇûÓÐÖ÷¶¯¸²Ð´ÔʼÅäÖõÄÇé¿öÏ£¬Ä¬ÈÏÖµ¾Í»áÉúЧ£¬ÕâÔںܶàÇé¿öÏÂÊǷdz£ÓÐÓõġ£³ý´ËÖ®Í⣬starterµÄConfigurationProperties»¹Ê¹µÃËùÓеÄÅäÖÃÊôÐÔ±»¾Û¼¯µ½Ò»¸öÎļþÖУ¨Ò»°ãÔÚresourcesĿ¼ÏµÄapplication.properties£©£¬ÕâÑùÎÒÃǾ͸æ±ðÁËSpringÏîÄ¿ÖÐXMLµØÓü¡£
+
+starterµÄÕûÌåÂß¼£º
+
+
+
+ÉÏÃæµÄstarterÒÀÀµµÄjarºÍÎÒÃÇ×Ô¼ºÊÖ¶¯ÅäÖõÄʱºòÒÀÀµµÄjar²¢Ã»ÓÐʲô²»Í¬£¬ËùÒÔÎÒÃÇ¿ÉÒÔÈÏΪstarterÆäʵÊǰÑÕâһЩ·±ËöµÄÅäÖòÙ×÷½»¸øÁË×Ô¼º£¬¶ø°Ñ¼òµ¥½»¸øÁËÓû§¡£³ýÁ˰ïÖúÓû§È¥³ýÁË·±ËöµÄ¹¹½¨²Ù×÷£¬ÔÚ¡°Ô¼¶¨´óÓÚÅäÖá±µÄÀíÄîÏ£¬ConfigurationProperties»¹°ïÖúÓû§¼õÉÙÁËÎÞνµÄÅäÖòÙ×÷¡£²¢ÇÒÒòΪ?`application.properties`?ÎļþµÄ´æÔÚ£¬¼´Ê¹ÐèÒª×Ô¶¨ÒåÅäÖã¬ËùÓеÄÅäÖÃÒ²Ö»ÐèÒªÔÚÒ»¸öÎļþÖнøÐУ¬Ê¹ÓÃÆðÀ´·Ç³£·½±ã¡£
+
+Á˽âÁËstarterÆäʵ¾ÍÊǰïÖúÓû§¼ò»¯ÁËÅäÖõIJÙ×÷Ö®ºó£¬ÒªÀí½âstarterºÍ±»ÅäÖÃÁËstarterµÄ×é¼þÖ®¼ä²¢²»ÊǾºÕù¹ØÏµ£¬¶øÊǸ¨Öú¹ØÏµ£¬¼´ÎÒÃÇ¿ÉÒÔ¸øÒ»¸ö×é¼þ´´½¨Ò»¸östarterÀ´ÈÃ×îÖÕÓû§ÔÚʹÓÃÕâ¸ö×é¼þµÄʱºò¸ü¼ÓµÄ¼òµ¥·½±ã¡£»ùÓÚÕâÖÖÀíÄÎÒÃÇ¿ÉÒÔ¸øÈÎÒâÒ»¸öÏÖÓеÄ×é¼þ´´½¨Ò»¸östarterÀ´ÈñðÈËÔÚʹÓÃÕâ¸ö×é¼þµÄʱºò¸ü¼ÓµÄ¼òµ¥·½±ã£¬ÊÂʵÉÏSpring BootÍŶÓÒѾ°ïÖúÏÖÓд󲿷ֵÄÁ÷ÐеÄ×é¼þ´´½¨ºÃÁËËüÃǵÄstarter£¬Äã¿ÉÒÔÔÚ[ÕâÀï](https://github.com/spring-projects/spring-boot/tree/v1.5.7.RELEASE/spring-boot-starters)²é¿´ÕâЩstarterµÄÁÐ±í¡£
+
+ÓÃÁËspringboot ÄÇô¾ÃÁ˾ÓÈ»¶¼»¹Ã»×Ô¶¨Òå¹ýstarter£¬ÏëÏë¶¼¾õµÃÐßÀ¢£¬ËùÒÔ½ñÌìÀ´ÍæÒ»Ï¡£
+
+
+
+# SpringBoot starter
+
+SpringBootÖеÄstarterÊÇÒ»Öַdz£ÖØÒªµÄ»úÖÆ£¬Äܹ»ÅׯúÒÔǰ·±ÔÓµÄÅäÖ㬽«Æäͳһ¼¯³É½østarter£¬Ó¦ÓÃÕßÖ»ÐèÒªÔÚmavenÖÐÒýÈëstarterÒÀÀµ£¬SpringBoot¾ÍÄÜ×Ô¶¯É¨Ãèµ½Òª¼ÓÔØµÄÐÅÏ¢²¢Æô¶¯ÏàÓ¦µÄĬÈÏÅäÖá£starterÈÃÎÒÃǰÚÍÑÁ˸÷ÖÖÒÀÀµ¿âµÄ´¦Àí£¬ÐèÒªÅäÖø÷ÖÖÐÅÏ¢µÄÀ§ÈÅ¡£SpringBoot»á×Ô¶¯Í¨¹ýclasspath·¾¶ÏµÄÀà·¢ÏÖÐèÒªµÄBean£¬²¢×¢²á½øIOCÈÝÆ÷¡£SpringBootÌṩÁËÕë¶ÔÈÕ³£ÆóÒµÓ¦ÓÃÑз¢¸÷ÖÖ³¡¾°µÄspring-boot-starterÒÀÀµÄ£¿é¡£ËùÓÐÕâЩÒÀÀµÄ£¿é¶¼×ñÑ×ÅÔ¼¶¨³ÉË×µÄĬÈÏÅäÖ㬲¢ÔÊÐíÎÒÃǵ÷ÕûÕâЩÅäÖ㬼´×ñÑ¡°Ô¼¶¨´óÓÚÅäÖá±µÄÀíÄî¡£
+
+# ×Ô¶¨Òåstarter
+
+ÈÕ³£¹¤×÷ÖÐÓÐʱÓÐһЩ¶ÀÁ¢ÓÚÒµÎñÖ®ÍâµÄ¹¦ÄÜ»òÄ£¿é£¬¿ÉÄÜÕâ¸öÏîÄ¿ÔÚÓã¬ÁíÒ»¸öÏîĿҲҪÓã¬Èç¹ûÿ´Î¶¼ÖØÐ¼¯³ÉµÄ»°¾Í»áºÜÂé·³£¬ÕâʱÎÒÃÇÖ»Òª°ÑÕâЩ¹¦ÄÜ»òÄ£¿é·â×°³ÉÒ»¸ö¸östarterµÄ»°£¬ÔÚʹÓõÄʱºòÒýÈë½øÈ¥¾ÍºÜ·½±ãÁË¡£
+
+## ×Ô¶¨Òåstarter²½Öè
+
+Æäʵ×Ô¶¨ÒåstarterºÜ¼òµ¥£¬´óÖÂÐèÒªÒÔÏÂ5²½£º
+
+1. н¨Á½¸öÄ£¿é£¬ÃüÃû¹æ·¶£º springboot×Ô´øµÄstarterÃüÃû¹æ·¶Îªspring-boot-starter-xxx£¬ ×Ô¶¨ÒåµÄstarterÃüÃû¹æ·¶Îªxxx-spring-boot-starter
+
+¡ñ xxx-spring-boot-autoconfigure£º×Ô¶¯ÅäÖúËÐÄ´úÂë
+¡ñ xxx-spring-boot-starter£º¹ÜÀíÒÀÀµ
+Èç¹û²»ÐèÒª½«×Ô¶¯ÅäÖôúÂëºÍÒÀÀµÏî¹ÜÀí·ÖÀ뿪À´£¬Ôò¿ÉÒÔ½«ËüÃÇ×éºÏµ½Ò»¸öÄ£¿éÖС£Ö»²»¹ýspringboot¹Ù·½½¨Ò齫Á½¸öÄ£¿é·Ö¿ª¡£
+2\. ÒýÈëspring-boot-autoconfigureÒÀÀµ
+3\. ´´½¨×Ô¶¨ÒåµÄXXXProperties Àà: Õâ¸öÀàµÄÊôÐÔ¸ù¾ÝÐèÒªÊÇÒª³öÏÖÔÚÅäÖÃÎļþÖеġ£
+4\. ´´½¨×Ô¶¨ÒåµÄXXXAutoConfigurationÀࣺÕâ¸öÀàÒªÅäÖÃ×Ô¶¯ÅäÖÃʱµÄһЩÂß¼£¬Í¬Ê±Ò²ÒªÈÃXXXProperties ÀàÉúЧ¡£
+5\. ´´½¨×Ô¶¨ÒåµÄspring.factoriesÎļþ£ºÔÚresources/META-INF´´½¨Ò»¸öspring.factoriesÎļþºÍspring-configuration-metadata.json£¬spring-configuration-metadata.jsonÎļþÊÇÓÃÓÚÔÚÌîдÅäÖÃÎļþʱµÄÖÇÄÜÌáʾ£¬¿ÉÒª¿É²»Òª£¬ÓеϰÌáʾÆðÀ´¸üÓѺá£spring.factoriesÓÃÓÚµ¼Èë×Ô¶¯ÅäÖÃÀ࣬±ØÐëÒªÓÐ
+
+## ʵÏÖ
+
+ÎÒÕâÀïΪÁË·½±ã¾ÍÖ»´´½¨Ò»¸öÄ£¿éÁË£¬
+
+1. ´´½¨Ò»¸öÄ£¿é£¬ÃüÃûΪspring-boot-starter-my-starter£¬¶ÔÓ¦pomÎļþ
+
+```
+ com.example
+ spring-boot-starter-my-starter
+ 1.0
+ my-starter
+¸´ÖÆ´úÂë
+```
+
+1. ÒýÈëspring-boot-autoconfigureÒÀÀµ ÎÒÕâÀïʹÓõÄspring-boot-autoconfigure°æ±¾ÊÇ2.6.2
+
+```
+
+
+ org.springframework.boot
+ spring-boot-autoconfigure
+ 2.6.2
+
+
+¸´ÖÆ´úÂë
+```
+
+1. ´´½¨×Ô¶¨ÒåµÄXXXProperties Àà
+
+```
+@ConfigurationProperties(prefix = "com.arron")
+public class MyStarterProperties {
+
+ private String name;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
+¸´ÖÆ´úÂë
+```
+
+ÔÙ´´½¨Ò»¸öMyStarterConfigÓÃÓÚ¶ÁÈ¡MyStarterProperties ÀïµÄÊôÐÔ
+
+```
+public class MyStarterConfig {
+
+ private MyStarterProperties myStarterProperties;
+
+ private String name;
+
+ public MyStarterConfig(MyStarterProperties myStarterProperties) {
+ this.myStarterProperties = myStarterProperties;
+ }
+
+ public String getName() {
+ return myStarterProperties.getName();
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
+¸´ÖÆ´úÂë
+```
+
+1. ´´½¨×Ô¶¨ÒåµÄXXXAutoConfigurationÀà
+
+```
+@Configuration
+// EnableConfigurationProperties valueÊý×éÖеÄÅäÖÃÀàÆð×÷ÓÃ
+@EnableConfigurationProperties(value = {MyStarterProperties.class})
+public class MyStarterAutoConfiguration {
+
+ @Autowired
+ private MyStarterProperties myStarterProperties;
+
+ @Bean
+ @ConditionalOnMissingBean(MyStarterConfig.class)
+ public MyStarterConfig myStarterConfig(){
+ return new MyStarterConfig(myStarterProperties);
+ }
+
+}
+¸´ÖÆ´úÂë
+```
+
+1. ÔÚresources/META-INF´´½¨Ò»¸öspring.factoriesÎļþ
+
+spring.factories
+
+```
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.example.myStarter.MyStarterAutoConfiguration
+¸´ÖÆ´úÂë
+```
+
+spring-configuration-metadata.json
+
+```
+{
+ "group": [
+ {
+ "name": "com.arron",
+ "type": "com.example.myStarter.MyStarterProperties",
+ "sourceType": "com.example.myStarter.MyStarterProperties"
+ }
+ ],
+ "properties": [
+ {
+ "name": "com.arron.name",
+ "type": "java.lang.String",
+ "description": "my start name",
+ "sourceType": "com.example.myStarter.MyStarterProperties",
+ "defaultValue": "MyStarterProperties name"
+ }
+ ]
+}
+¸´ÖÆ´úÂë
+```
+
+## ´ò°ü²âÊÔ
+
+ÕÒµ½Èçͼmaven£¬µã»÷install£¬°²×°µ½±¾µØ 
+
+È»ºóн¨Ò»¸öÏîÄ¿µ¼°ü½øÐвâÊÔ£¬´´½¨ÏîÄ¿¹ý³Ì¾Í²»½éÉÜÁË¡£
+
+1. ÒýÈëÒÀÀµ
+
+```
+
+ com.example
+ spring-boot-starter-my-starter
+ 1.0
+
+¸´ÖÆ´úÂë
+```
+
+1. ÅäÖÃÎļþÌí¼ÓÊôÐÔ£º
+
+```
+com:
+ arron:
+ name: myname
+¸´ÖÆ´úÂë
+```
+
+1. µ¥Ôª²âÊÔ£º
+
+```
+@RunWith(SpringRunner.class)
+@SpringBootTest
+class RabbitmqApplicationTests {
+ @Autowired
+ private MyStarterConfig myStarterConfig;
+
+ @Test
+ public void testMyStarter(){
+ String name = myStarterConfig.getName();
+ System.out.println(name);
+ }
+}
+¸´ÖÆ´úÂë
+```
+
+¿ØÖÆÌ¨Êä³ö£º
+
+```
+myname
+¸´ÖÆ´úÂë
+```
+
+ÖÁ´Ë£¬Ò»¸ö¼òµ¥×Ô¶¨ÒåµÄspringboot starter¾ÍÍê³ÉÁË¡£
+
+# ×¢½â½âÊÍ
+
+ÏÂÃæÕâЩע½âÔÚ×Ô¶¨ÒåstarterÊÇ¿ÉÄÜ»áÓõ½¡£
+
+* @Conditional£º°´ÕÕÒ»¶¨µÄÌõ¼þ½øÐÐÅжϣ¬Âú×ãÌõ¼þ¸øÈÝÆ÷×¢²ábean
+* @ConditionalOnMissingBean£º¸ø¶¨µÄÔÚbean²»´æÔÚʱ,ÔòʵÀý»¯µ±Ç°Bean
+* @ConditionalOnProperty£ºÅäÖÃÎļþÖÐÂú×㶨ÒåµÄÊôÐÔÔò´´½¨bean£¬·ñÔò²»´´½¨
+* @ConditionalOnBean£º¸ø¶¨µÄÔÚbean´æÔÚʱ,ÔòʵÀý»¯µ±Ç°Bean
+* @ConditionalOnClass£º µ±¸ø¶¨µÄÀàÃûÔÚÀà·¾¶ÉÏ´æÔÚ£¬ÔòʵÀý»¯µ±Ç°Bean
+* @ConditionalOnMissingClass £ºµ±¸ø¶¨µÄÀàÃûÔÚÀà·¾¶Éϲ»´æÔÚ£¬ÔòʵÀý»¯µ±Ç°Bean
+
+
+
+×÷ÕߣºË÷ÂëÀí
+Á´½Ó£ºhttps://juejin.cn/post/7127468724046528525
+À´Ô´£ºÏ¡ÍÁ¾ò½ð
+Öø×÷Ȩ¹é×÷ÕßËùÓС£ÉÌÒµ×ªÔØÇëÁªÏµ×÷Õß»ñµÃÊÚȨ£¬·ÇÉÌÒµ×ªÔØÇë×¢Ã÷³ö´¦¡£
+
diff --git "a/docs/spring/SpringBoot/SpringBoot\347\232\204\345\237\272\346\234\254\344\275\277\347\224\250.md" "b/docs/spring/SpringBoot/SpringBoot\347\232\204\345\237\272\346\234\254\344\275\277\347\224\250.md"
index 36a2500..247e419 100644
--- "a/docs/spring/SpringBoot/SpringBoot\347\232\204\345\237\272\346\234\254\344\275\277\347\224\250.md"
+++ "b/docs/spring/SpringBoot/SpringBoot\347\232\204\345\237\272\346\234\254\344\275\277\347\224\250.md"
@@ -20,55 +20,20 @@
µã»÷¡°Éú³É¡±°´Å¥£¬ÏÂÔØ zip Îļþ£¬²¢½«Æä½âѹµ½Äú¼ÆËã»úÉϵÄÒ»¸öÎļþ¼ÐÖС£
-
+
[start.spring.io](http://start.spring.io/)´´½¨µÄÏîÄ¿°üº¬[Spring Boot](https://spring.io/projects/spring-boot)£¬Ò»¸öÈÃSpring×¼±¸ºÃÔÚÄúµÄÓ¦ÓóÌÐòÄÚ²¿¹¤×÷£¬µ«²»ÐèҪ̫¶à´úÂë»òÅäÖᣠSpring Boot ÊÇÆô¶¯ Spring ÏîÄ¿µÄ×î¿ìºÍ×îÁ÷Ðеķ½Ê½¡£
ÕâÀïÎÒÃÇÑ¡ÔñʹÓÃmaven×÷Ϊ°ü¹ÜÀí¹¤¾ß£¬ÏÂÔØÏÂÀ´µÄÏîÄ¿Àï»á°üº¬pomÎļþ£¬pomÎļþÀï°üº¬ÁËÄãµÄÌí¼ÓµÄÒÀÀµ¡£
-````
-
-
- 4.0.0
-
- org.springframework.boot
- spring-boot-starter-parent
- 3.0.5
-
-
- com.example
- demo
- 0.0.1-SNAPSHOT
- demo
- Demo project for Spring Boot
-
- 17
-
-
-
- org.springframework.boot
- spring-boot-starter-web
-
-
-
- org.springframework.boot
- spring-boot-starter-test
- test
-
-
-
-
-
-
- org.springframework.boot
- spring-boot-maven-plugin
-
-
-
-
-
-````
+````
+
+ 4.0.0 org.springframework.boot spring-boot-starter-parent 3.0.5 com.example demo 0.0.1-SNAPSHOT demo Demo project for Spring Boot 17 org.springframework.boot spring-boot-starter-web
+ org.springframework.boot spring-boot-starter-test test
+ org.springframework.boot spring-boot-maven-plugin
+
+````
## µÚ¶þ²½£ºÌí¼ÓÄãµÄ´úÂë
@@ -76,27 +41,20 @@
ÔÚÄúµÄ IDE Öдò¿ªÏîÄ¿²¢ÔÚ `src/main/java/com/example/demo` Îļþ¼ÐÖÐÕÒµ½ `DemoApplication.java` Îļþ¡£
ÏÖÔÚͨ¹ýÌí¼ÓÏÂÃæ´úÂëÖÐÏÔʾµÄ¶îÍâ·½·¨ºÍ×¢ÊÍÀ´¸ü¸ÄÎļþµÄÄÚÈÝ¡£Äú¿ÉÒÔ¸´ÖƲ¢Õ³Ìù´úÂë»òÖ±½Ó¼üÈë´úÂë¡£
-```
-package com.example.demo;
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
-
-@SpringBootApplication
-@RestController
-public class DemoApplication {
- public static void main(String[] args) {
- SpringApplication.run(DemoApplication.class, args);
- }
- @GetMapping("/hello")
- public String hello(@RequestParam(value = "name", defaultValue = "World") String name) {
- return String.format("Hello %s!", name);
- }
-}
-
-```
+```
+package com.example.demo;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+@SpringBootApplication
+@RestController
+public class DemoApplication {
+ public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } @GetMapping("/hello") public String hello(@RequestParam(value = "name", defaultValue = "World") String name) { return String.format("Hello %s!", name); }}
+
+```
ÕâÊÇÔÚ Spring Boot Öд´½¨Ò»¸ö¼òµ¥µÄ¡°Hello World¡± Web ·þÎñËùÐèµÄËùÓдúÂë¡£
@@ -104,8 +62,7 @@ public class DemoApplication {
ÕâÒâζ×ÅÈç¹ûÄúÔÚÇëÇóÖн«ÄúµÄÃû×ÖÉèÖÃΪ¡°Amy¡±£¬ÔòÏìÓ¦½«ÊÇ¡°Hello Amy¡±¡£
-`@RestController` ×¢Ê͸æËß Spring£¬´Ë´úÂëÃèÊöÁËÒ»¸ö¶Ëµã£¬¸Ã¶ËµãÓ¦ÔÚ Web ÉÏ¿ÉÓá£
-
+`@RestController` ×¢Ê͸æËß Spring£¬´Ë´úÂëÃèÊöÁËÒ»¸ö¶Ëµã£¬¸Ã¶ËµãÓ¦ÔÚ Web ÉÏ¿ÉÓá£
@GetMapping(¡°/hello¡±) ¸æËß Spring ʹÓÃÎÒÃÇµÄ hello() ·½·¨À´ÏìÓ¦·¢Ë͵½ http://localhost:8080/hello µØÖ·µÄÇëÇó¡£
×îºó£¬@RequestParam ¸æËß Spring ÔÚÇëÇóÖÐÆÚÍûÒ»¸öÃû³ÆÖµ£¬µ«Èç¹û²»´æÔÚ£¬Ëü½«Ä¬ÈÏʹÓõ¥´Ê¡°World¡±¡£
@@ -118,34 +75,33 @@ public class DemoApplication {
**MacOS/Linux:**
-```
-COPY./gradlew bootRun
-
-```
+```
+COPY./gradlew bootRun
+
+```
**Windows:**
-```
-COPY.\gradlew.bat bootRun
-
-```
+```
+COPY.\gradlew.bat bootRun
+
+```
-ÄúÓ¦¸Ã»á¿´µ½Ò»Ð©Óë´Ë·Ç³£ÏàËÆµÄÊä³ö£º
-
+ÄúÓ¦¸Ã»á¿´µ½Ò»Ð©Óë´Ë·Ç³£ÏàËÆµÄÊä³ö£º
+
-ÕâÀïµÄ×îºó¼¸ÐиæËßÎÒÃÇ£¬SpringÓ¦ÓÃÒѾ¿ªÊ¼ÔËÐÐÁË¡£
-Spring Boot µÄǶÈëʽ Apache Tomcat ·þÎñÆ÷³äµ±ÍøÂç·þÎñÆ÷£¬²¢ÕýÔÚ¼àÌý¡°localhost¡±¶Ë¿Ú¡°8080¡±ÉϵÄÇëÇó¡£
+ÕâÀïµÄ×îºó¼¸ÐиæËßÎÒÃÇ£¬SpringÓ¦ÓÃÒѾ¿ªÊ¼ÔËÐÐÁË¡£ Spring Boot µÄǶÈëʽ Apache Tomcat ·þÎñÆ÷³äµ±ÍøÂç·þÎñÆ÷£¬²¢ÕýÔÚ¼àÌý¡°localhost¡±¶Ë¿Ú¡°8080¡±ÉϵÄÇëÇó¡£
´ò¿ªä¯ÀÀÆ÷£¬ÔÚ¶¥²¿µÄµØÖ·À¸ÖÐÊäÈë`http://localhost:8080/hello`¡£
-ÄãÓ¦¸ÃµÃµ½ÕâÑùÒ»¸öÓѺõĻØÓ¦£º
-
+ÄãÓ¦¸ÃµÃµ½ÕâÑùÒ»¸öÓѺõĻØÓ¦£º
+
# ×ܽá
-¾ÍÊÇÈç´Ë¼òµ¥£¬µÚÒ»¸öSpringBootÓ¦ÓþÍÕâô¹¹½¨Íê³ÉÁË£¬Äã²»ÐèÒª¶îÍâµÄÅäÖÃÎļþ£¬¶îÍâµÄÒÀÀµ£¬ÉõÖÁÊǶîÍâµÄ·þÎñÆ÷¡£
+¾ÍÊÇÈç´Ë¼òµ¥£¬µÚÒ»¸öSpringBootÓ¦ÓþÍÕâô¹¹½¨Íê³ÉÁË£¬Äã²»ÐèÒª¶îÍâµÄÅäÖÃÎļþ£¬¶îÍâµÄÒÀÀµ£¬ÉõÖÁÊǶîÍâµÄ·þÎñÆ÷¡£
Ö»ÐèÒªÒ»¸öÆô¶¯À࣬¾Í¿ÉÒÔʵÏÖÒ»¸ö×î»ù±¾µÄSpringBootµÄÓ¦Óá£
-ÕâÒ²ÊÇΪʲôspringboot¿ÉÒÔÓÃÀ´¿ìËÙ¹¹½¨Ò»¸ö΢·þÎñ£¬ÒòΪËüʵÔÚÊÇÌ«·½±ãÁË¡£
+ÕâÒ²ÊÇΪʲôspringboot¿ÉÒÔÓÃÀ´¿ìËÙ¹¹½¨Ò»¸ö΢·þÎñ£¬ÒòΪËüʵÔÚÊÇÌ«·½±ãÁË¡£
µ±È»£¬Êµ¼Ê¿ª·¢ÖÐÎÒÃÇÐèÒªÓõ½¸ü¶àspringbootµÄ¹¦ÄܺÍÌØÐÔ£¬ÎÒÃǽ«»áÔÚ½ÓÏÂÀ´µÄÕ½ÚÖÐÖð½¥Õ¹¿ª½éÉÜ¡£
# ²Î¿¼ÎÄÕÂ
diff --git "a/docs/spring/SpringBoot/SpringBoot\347\232\204\351\205\215\347\275\256\346\226\207\344\273\266\347\256\241\347\220\206.md" "b/docs/spring/SpringBoot/SpringBoot\347\232\204\351\205\215\347\275\256\346\226\207\344\273\266\347\256\241\347\220\206.md"
new file mode 100644
index 0000000..46c6771
--- /dev/null
+++ "b/docs/spring/SpringBoot/SpringBoot\347\232\204\351\205\215\347\275\256\346\226\207\344\273\266\347\256\241\347\220\206.md"
@@ -0,0 +1,2989 @@
+## 1.SpringBootÅäÖùÜÀíµÄ±³¾°Óë»ù´¡
+
+ΪʵÏÖ¿ìËٴºÍ¿ª·¢£¬ÏîÄ¿ÒÔSpringboot¿ò¼Ü´î½¨£¬springboot´î½¨µÄÏîÄ¿¿ÉÒÔ½«ÏîĿֱ½Ó´ò³Éjar°ü²¢ÔËÐУ¬ÎÞÐè×Ô¼º°²×°ÅäÖÃTomcat»òÕ߯äËû·þÎñÆ÷£¬ÊÇÒ»ÖÖ·½±ã¿ì½ÝµÄ²¿Êð·½Ê½¡£
+
+¼ÙÉèÏîÄ¿ÒÔ×î³£¹æµÄ·½Ê½´ò°ü³ÉÒ»¸öÕûÌåµÄjar°ü²¿Ê𣬼´ÅäÖÃÎļþºÍµÚÈý·½ÒÀÀµ°ü¶¼°üº¬ÔÚjar°üÀ¾Í»áÓÐÈçÏÂÁ½¸öÎÊÌâ
+
+ÎÊÌâÒ»£ºÏîÄ¿ÔËÐйý³ÌÖУ¬Òª¸Ä¶¯ÅäÖÃÎļþµÄ»°ÐèÒªÖØÐ´ò°ü²¢²¿Êð¡£
+
+ÎÊÌâ¶þ£º¶à¸öµÚÈý·½ÒÀÀµ°ü¶¼Ïà½üµÄÏîĿҪ²¿ÊðÔÚͬһ̨·þÎñÆ÷ʱ£¬¸÷×ÔµÄjar°ü¶¼°üº¬ÁËÏàͬµÄµÚÈý·½ÒÀÀµ°ü£¨¼ÙÉèÏîÄ¿jar°üÓÐ100M£¬µÚÈý·½ÒÀÀµ°ü¿ÉÄܾÍÕ¼ÓÃÁË99M£©£¬ÕâÑùµÚÈý·½ÒÀÀµ°üÈßÓàÔì³ÉÁË·þÎñÆ÷×ÊÔ´µÄÀË·ÑÒÔ¼°½µµÍÁËÏîÄ¿²¿ÊðµÄЧÂÊ¡£
+
+Èç¹û½«¸÷ÏîÄ¿µÄÅäÖÃÎļþ¡¢µÚÈý·½ÒÀÀµ°ü¶¼ÌáÈ¡µ½jar°üÍâͳһ¹ÜÀí£¬ÕâÑù¼´ÌáÉýÁËÏîÄ¿´ò°üЧÂÊÓÖ½ÚÔ¼ÁË·þÎñÆ÷µÄ´ÅÅÌÏûºÄ£¬Í¬Ê±ÏîÄ¿µÄÔËάҲÊǷdz£·½±ãµÄ£¬¸Ä¶¯ÁËÅäÖÃÎļþÖØÆôÏ·þÎñ¾Í¿ÉÒÔÁË£¬ÎÞÐèÖØÐ¹¹½¨²¿Êð¡£
+
+ÏÂÃæÊǾßÌåµÄʵÏÖ·½°¸
+
+### 1.1 **ÅäÖÃÎļþͳһ¹ÜÀí**
+
+```
+ - springbootºËÐÄÅäÖÃÎļþ
+ - Springboot¶ÁÈ¡ºËÐÄÅäÖÃÎļþ£¨application.properties£©µÄÓÅÏȼ¶Îª
+ - Jar°üͬ¼¶Ä¿Â¼µÄconfigĿ¼
+ - Jar°üͬ¼¶Ä¿Â¼
+ - classPath(¼´resourcesĿ¼)µÄconfigĿ¼
+ - classpathĿ¼
+
+```
+
+ÉÏÃæÊÇspringbootĬÈÏÈ¥ÄÃ×Ô¼ºµÄºËÐÄÅäÖÃÎļþµÄÓÅÏȼ¶£¬»¹ÓÐÒ»ÖÖ×î¸ßÓÅÏȼ¶µÄ·½Ê½ÊÇÏîÄ¿Æô¶¯Ê±Í¨¹ýÃüÁîµÄ·½Ê½Ö¸¶¨ÏîÄ¿¼ÓÔØºËÐÄÅäÖÃÎļþ£¬ÃüÁîÈçÏÂ
+java ¨Cjar -Dspring.config.location=xxx/xxx/xxxx.properties xxxx.jar
+
+Èç¹ûSpring BootÔÚÓÅÏȼ¶¸ü¸ßµÄλÖÃÕÒµ½ÁËÅäÖã¬ÄÇôËü»áÎÞÊÓÓÅÏȼ¶¸üµÍµÄÅäÖÃ
+
+### 1.2 **ÆäËû×ÊÔ´ÅäÖÃÎļþ**
+
+ÉÏÃæÃèÊöµÄSpringbootºËÐÄÎļþÒѾÄܹ»ÌáÈ¡³öjar°üÍâ½øÐйÜÀíÁË£¬µ«ÊÇ»¹ÓÐÆäËûһЩҵÎñÉϵÄÅäÖÃÎļþ£¬ÈçÊý¾ÝÔ´ÅäÖÃÎļþ£¬¹«¹²×ÊÔ´¶¨ÒåÅäÖÃÎļþ£¨³£Á¿£¬FTPÐÅÏ¢µÈ£©£¬quartz¶¨Ê±Æ÷£¬ÈÕÖ¾µÈÅäÖÃÎļþÎÒÃÇÈçºÎÈ¥ÌáÈ¡³öÀ´²¢È·±£ÄÜÔÚ´úÂëÖÐÒýÓõ½ÄØ
+
+ÎÒÃÇÖªµÀSpringbootÏîÄ¿¿ÉÒÔͨ¹ý×¢½â·½Ê½À´»ñÈ¡Ïà¹ØÅäÖÃÎļþ£¬ËùÒÔÎÒÃÇÒ²ÊÇͨ¹ý×¢½â·½Ê½ÈÃÏîÄ¿Äܹ»ÒýÓõ½jar°üÍⲿµÄÅäÖÃÎļþµÄ£¬ÈçÏÂͼ£º
+
+
+@PropertySourceÀïÃæµÄvalueÓÐÁ½¸öÖµ£¬µÚÒ»¸öÊÇclasspathÏÂconfigĿ¼ÏµÄÊý¾ÝÔ´ÅäÖÃÎļþ£¬µÚ¶þ¸öÔòÊǸù¾Ýspring.profiles.path¶¯Ì¬»ñÈ¡µÄĿ¼£¬spring.profiles.pathÊÇÎÒÃÇÔÚºËÐÄÎļþ×Ô¶¨ÒåµÄÒ»¸öÅäÖÃÏËüµÄÖµÊÇÎÒÃÇÅäÖÃÎļþͳһ¹ÜÀíµÄÎļþ¼Ð·¾¶£¬ºóÃæµÄignoreResourceNotFound=trueÔòÊÇÉ趨¼ÙÈç¸ù¾ÝÇ°ÃæÒ»¸ö·¾¶Ã»ÓÐÕÒµ½Ïà¹ØÅäÖÃÎļþ£¬Ôò¸ù¾ÝµÚ¶þ¸ö·¾¶È¥ÕÒ¡£
+
+ÎÒÃÇ»¹¿ÉÒÔÖ±½Ó¸ù¾Ý·¾¶£¬ÓÃFileSystemResourceÀàÈ¥¼ÓÔØÒ»¸öÅäÖÃÎļþʵÀý³öÀ´£¬ÈçÏÂͼ
+
+
+ÔÀíÀàËÆ£¬¸ù¾ÝÔÚºËÐÄÎļþ×Ô¶¨ÒåµÄͳһÅäÖÃĿ¼µÄ·¾¶À´¼ÓÔØÅäÖÃÎļþ
+
+ÁíÍâlogbackÈÕÖ¾ÅäÖÃÎļþ¼ÓÔØ·½Ê½ÈçÏ£º
+
+
+×ÛÉÏËùÊö£¬ÎÒÃÇÊáÀíÒ»ÏÂʵÏÖ·½°¸µÄ˼·
+
+```
+ - ÔÚspringbootºËÐÄÎļþÀﶨÒåÒ»¸öspring.profiles.pathÅäÖÃÏËüµÄÖµÖ¸ÏòÎÒÃÇËùÓÐÅäÖÃÎļþͳһ·ÅÖõÄĿ¼£¬°üº¬ºËÐÄÎļþ×ÔÉíÒ²ÊÇ·ÅÖÃÔÚÀïÃæµÄ
+
+ - ´úÂë»òÕßÅäÖÃÎļþÀï¼ÓÔØÅäÖÃÎļþµÄµØ·½Ò²Ó¦¸Ã»ñÈ¡spring.profiles.pathÅäÖÃÏîÀ´¶¯Ì¬¼ÓÔØ¸Ã·¾¶ÏµÄÅäÖÃÎļþ
+
+ - Pom.xmlÎļþÐ޸Ĵò°üÏà¹ØÄ£¿é£¬½«ÅäÖÃÎļþÅųý£¬ÕâÑùÎÒÃÇ´ò³öµÄjar°üÊDz»º¬ÅäÖÃÎļþµÄ£¬´ò°üÅäÖÃÇë²Î¿¼Îĵµ½Úµã3
+
+ - Æô¶¯jar°üʱ£¬Í¨¹ýÃüÁîÖ¸¶¨¼ÓÔØµÄºËÐÄÎļþΪspring.profiles.pathϵĺËÐÄÎļþ
+
+```
+**µÚÈý·½ÒÀÀµ°üͳһ¹ÜÀí**
+
+ͨ³£µÚÈý·½jar°ü¿ÉÒÔ´ò½øjar°üÀҲ¿ÉÒÔ·ÅÔÚÏîÄ¿jar°üͬ¼¶Ä¿Â¼ÏµÄlibĿ¼£¬ÎÒÃÇ¿ÉÒÔ¸ù¾ÝÐÞ¸Äpom.xml´ò°üÅäÖÃÀ´ÊµÏÖ£¬Çë²Î¿¼Îĵµ½Úµã3´ò°üÅäÖÃ
+
+**´ò°üÅäÖÃ**
+
+```
+
+
+
+ src/main/java
+
+ **/*.properties
+ **/*.xml
+
+ true
+
+
+ src/main/resources
+
+
+ **/*.properties
+ **/*.xml
+ **/*.yml
+
+ false
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 1.8
+ 1.8
+ true
+ true
+
+ C:/Program Files/Java/jdk1.8.0_161/bin/javac.exe
+
+
+
+
+ maven-jar-plugin
+
+
+
+ true
+ lib/
+ false
+ com.xrq.demo.Application
+
+
+ ./
+
+
+
+ *.properties
+ *.yml
+ *.xml
+ config/**
+
+
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+
+
+ copy
+ package
+
+ copy-dependencies
+
+
+
+ ${project.build.directory}/lib
+
+
+
+
+
+
+
+
+```
+
+¸ÄºÃpom.xmlµÄbuildÄ£¿éºó£¬¾Í¿ÉÒÔͨ¹ýmvn package »òÕßmvn install´ò³öÎÒÃǵÄjar°üÁË
+
+1. **ÏîÄ¿¹ÜÀíshell½Å±¾±àд**
+ ×Ô¶¨Òåshell½Å±¾£¬ÊµÏÖÏîÄ¿µÄÆô¶¯£¬Í£Ö¹£¬×´Ì¬£¬ÖØÆô²Ù×÷£º
+
+```
+#!/bin/bash
+#ÕâÀï¿ÉÌæ»»ÎªÄã×Ô¼ºµÄÖ´ÐгÌÐò,ÆäËû´úÂëÎÞÐè¸ü¸Ä
+APP_NAME=demo1-0.0.1-SNAPSHOT.jar
+JVM="-server -Xms512m -Xmx512m -XX:PermSize=64M -XX:MaxNewSize=128m -XX:MaxPermSize=128m -Djava.awt.headless=true -XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled"
+APPFILE_PATH="-Dspring.config.location=/usr/local/demo/config/application-demo1.properties"
+#ʹÓÃ˵Ã÷,ÓÃÀ´ÌáʾÊäÈë²ÎÊý
+usage() {
+echo "Usage: sh Ö´Ðнű¾.sh [start|stop|restart|status]"
+exit 1
+}
+#¼ì²é³ÌÐòÊÇ·ñÔÚÔËÐÐ
+is_exist(){
+pid=`ps -ef|grep $APP_NAME|grep -v grep|awk '{print $2}' `
+#Èç¹û²»´æÔÚ·µ»Ø1,´æÔÚ·µ»Ø0
+if [ -z "${pid}" ]; then
+return 1
+else
+return 0
+fi
+}
+#Æô¶¯·½·¨
+start(){
+is_exist
+if [ $? -eq "0" ]; then
+echo "${APP_NAME} is already running. pid=${pid} ."
+else
+nohup java $JVM -jar $APPFILE_PATH $APP_NAME > /dev/null 2>&1
+fi
+}
+#Í£Ö¹·½·¨
+stop(){
+is_exist
+if [ $? -eq "0" ]; then
+kill -9 $pid
+else
+echo "${APP_NAME} is not running"
+fi
+}
+#Êä³öÔËÐÐ״̬
+status(){
+is_exist
+if [ $? -eq "0" ]; then
+echo "${APP_NAME} is running. Pid is ${pid}"
+else
+echo "${APP_NAME} is NOT running."
+fi
+}
+#ÖØÆô
+restart(){
+stop
+start
+}
+#¸ù¾ÝÊäÈë²ÎÊý,Ñ¡ÔñÖ´ÐжÔÓ¦·½·¨,²»ÊäÈëÔòÖ´ÐÐʹÓÃ˵Ã÷
+case "$1" in
+"start")
+start
+;;
+"stop")
+stop
+;;
+"status")
+status
+;;
+"restart")
+restart
+;;
+*)
+usage
+;;
+esac
+
+```
+
+**²¿Êð**
+
+linux·þÎñÆ÷ÉÏн¨¸öÎļþ¼Ð£¬½«ÎÒÃÇ´òºÃµÄÏîÄ¿jar°ü¶¼¶ª½øÈ¥£¬ÔÚjar°üµÄͬ¼¶Ä¿Â¼Ð½¨configºÍlibÎļþ¼Ð£¬·Ö±ð½«ÅäÖÃÎļþºÍµÚÈý·½ÒÀÀµ°ü¶ª½øÈ¥£¬Æä½á¹¹ÈçÏÂͼ£¬*.shΪ×Ô¼ºÐ´µÄÏîÄ¿Æô¶¯shell½Å±¾
+
+
+
+´ò¿ªconfigÄÚµÄspringbootºËÐÄÎļþ£¨Èçapplication-demo1.propertiesÎļþ£©£¬
+
+spring.profiles.pathÅäÖÃÏî¸Ä³Éµ±Ç°ÅäÖÃÎļþËùÔÚµÄĿ¼£¬¼ÙÉèΪ/usr/local/demo/config
+
+´ò¿ª*.sh½Å±¾£¬ÐÞ¸ÄAPPFILE_PATHµÄÖµ£¬ÈçÏÂ
+
+APPFILE_PATH="-Dspring.config.location=/usr/local/demo/config/application-demo1.properties"
+
+**ÏîÄ¿¹ÜÀí**
+
+½øÈëjar°üËùÔÚĿ¼ִÐÐÏÂÃæÃüÁî
+
+sh [demo1.sh](http://demo1.sh/) start Æô¶¯ÏîÄ¿
+
+sh [demo1.sh](http://demo1.sh/) stop Í£Ö¹ÏîÄ¿
+
+sh [demo1.sh](http://demo1.sh/) restartÖØÆôÏîÄ¿
+
+sh [demo1.sh](http://demo1.sh/) statusÏîĿ״̬
+
+## 2\. Íⲿ»¯µÄÅäÖÃ
+
+
+
+
+
+Spring Boot¿ÉÒÔÈÃÄ㽫ÅäÖÃÍⲿ»¯£¬ÕâÑùÄã¾Í¿ÉÒÔÔÚ²»Í¬µÄ»·¾³ÖÐʹÓÃÏàͬµÄÓ¦ÓóÌÐò´úÂë¡£ Äã¿ÉÒÔʹÓø÷ÖÖÍⲿÅäÖÃÔ´£¬°üÀ¨Java properties Îļþ¡¢YAMLÎļþ¡¢»·¾³±äÁ¿ºÍÃüÁîÐвÎÊý¡£
+
+
+
+
+
+ÊôÐÔÖµ¿ÉÒÔͨ¹ýʹÓà `@Value` ×¢½âÖ±½Ó×¢ÈëÄãµÄBean£¬Ò²¿ÉÒÔͨ¹ýSpring µÄ `Environment` ·ÃÎÊ£¬»òÕßͨ¹ý `@ConfigurationProperties` [°ó¶¨µ½¶ÔÏó](https://springdoc.cn/spring-boot/features.html#features.external-config.typesafe-configuration-properties)¡£
+
+
+
+
+
+Spring Boot ʹÓÃÒ»¸ö·Ç³£ÌرðµÄ `PropertySource` ˳Ðò£¬Ö¼ÔÚÔÊÐíºÏÀíµØÖØÐ´Öµ¡£ ºóÃæµÄ property source ¿ÉÒÔ¸²¸ÇÇ°ÃæÊôÐÔÔ´Öж¨ÒåµÄÖµ¡£ °´ÒÔÏÂ˳Ðò¿¼ÂÇ¡£
+
+
+
+
+
+1. ĬÈÏÊôÐÔ£¨Í¨¹ý `SpringApplication.setDefaultProperties` Ö¸¶¨£©¡£
+
+2. @Configuration ÀàÉ쵀 [`@PropertySource`](https://docs.spring.io/spring-framework/docs/6.0.5/javadoc-api/org/springframework/context/annotation/PropertySource.html) ×¢½â¡£Çë×¢Ò⣬ÕâÑùµÄÊôÐÔÔ´Ö±µ½application context±»Ë¢ÐÂʱ²Å»á±»Ìí¼Óµ½»·¾³ÖС£Õâ¶ÔÓÚÅäÖÃijЩÊôÐÔÀ´ËµÒѾ̫ÍíÁË£¬±ÈÈç `logging.*` ºÍ `spring.main.*` £¬ËüÃÇÔÚˢпªÊ¼Ç°¾ÍÒѾ±»¶ÁÈ¡ÁË¡£
+
+3. ÅäÖÃÊý¾Ý£¨Èç `application.properties` Îļþ£©¡£
+
+4. `RandomValuePropertySource`£¬ËüÖ»ÓÐ `random.*` ÊôÐÔ¡£
+
+5. ²Ù×÷ϵͳ»·¾³±äÁ¿
+
+6. Java System properties (`System.getProperties()`).
+
+7. `java:comp/env` ÖÐµÄ JNDI ÊôÐÔ¡£
+
+8. `ServletContext` init parameters.
+
+9. `ServletConfig` init parameters.
+
+10. À´×Ô `SPRING_APPLICATION_JSON` µÄÊôÐÔ£¨Ç¶Èë»·¾³±äÁ¿»òϵͳÊôÐÔÖеÄÄÚÁªJSON£©¡£
+
+11. ÃüÁîÐвÎÊý
+
+12. ÄãÔÚ²âÊÔÖÐµÄ `properties` ÊôÐÔ¡£ÔÚ [`@SpringBootTest`](https://docs.spring.io/spring-boot/docs/3.1.0-SNAPSHOT/api/org/springframework/boot/test/context/SpringBootTest.html) ºÍ²âÊÔ×¢½âÖпÉÓã¬[ÓÃÓÚ²âÊÔÄãµÄÓ¦ÓóÌÐòµÄÒ»¸öÌØ¶¨Æ¬¶Ï](https://springdoc.cn/spring-boot/features.html#features.testing.spring-boot-applications.autoconfigured-tests)¡£
+
+13. Äã²âÊÔÖеÄhttps://docs.spring.io/spring-framework/docs/6.0.5/javadoc-api/org/springframework/test/context/TestPropertySource.html[`@TestPropertySource`] ×¢½â.
+
+14. µ±devtools´¦Óڻ״̬ʱ£¬`$HOME/.config/spring-boot` Ŀ¼ÏµÄ[DevtoolsÈ«¾ÖÉèÖÃÊôÐÔ](https://springdoc.cn/spring-boot/using.html#using.devtools.globalsettings)¡£
+
+
+
+
+
+ÅäÖÃÊý¾ÝÎļþ°´ÒÔÏÂ˳Ðò¿¼ÂÇ¡£
+
+
+
+
+
+1. ÔÚÄãµÄjarÖдò°üµÄ[Application properties](https://springdoc.cn/spring-boot/features.html#features.external-config.files)£¨application.properties ºÍ YAML£©¡£
+
+2. ÔÚÄãµÄjarÖдò°üµÄ [ÌØ¶¨µÄ Profile application properties](https://springdoc.cn/spring-boot/features.html#features.external-config.files.profile-specific)£¨`application-{profile}.properties` ºÍ YAML£©¡£
+
+3. ÔÚÄã´ò°üµÄjarÖ®ÍâµÄ[Application properties](https://springdoc.cn/spring-boot/features.html#features.external-config.files)ÐÔ£¨application.propertiesºÍYAML£©¡£
+
+4. ÔÚÄã´ò°üµÄjarÖ®ÍâµÄ[ÌØ¶¨µÄ Profile application properties](https://springdoc.cn/spring-boot/features.html#features.external-config.files.profile-specific)£¨ `application-{profile}.properties` ºÍYAML£©¡£
+
+
+
+
+
+| | ½¨ÒéÄãÔÚÕû¸öÓ¦ÓóÌÐòÖмá³ÖʹÓÃÒ»ÖÖ¸ñʽ¡£ Èç¹ûÄãÔÚͬһ¸öµØ·½ÓÐ `.properties` ºÍ `.yml` ¸ñʽµÄÅäÖÃÎļþ£¬`.properties` ÓÅÏÈ¡£ |
+| --- | --- |
+
+
+
+
+
+ΪÁËÌṩһ¸ö¾ßÌåµÄÀý×Ó£¬¼ÙÉèÄ㿪·¢ÁËÒ»¸ö `@Component`£¬Ê¹ÓÃÁËÒ»¸ö `name` ÊôÐÔ£¬ÈçÏÂÃæµÄÀý×ÓËùʾ¡£
+
+
+
+
+
+
+
+Java
+
+Kotlin
+
+
+
+
+
+```
+@Component
+public class MyBean {
+
+ @Value("${name}")
+ private String name;
+
+ // ...
+
+}
+
+```
+
+
+
+
+
+
+
+ÔÚÄãµÄÓ¦ÓóÌÐòµÄclasspath£¨ÀýÈ磬ÔÚÄãµÄjarÖУ©£¬Äã¿ÉÒÔÓÐÒ»¸ö `application.properties` Îļþ£¬Îª `name` Ìṩһ¸öºÏÀíµÄĬÈÏÊôÐÔÖµ¡£µ±ÔÚÒ»¸öÐµĻ·¾³ÖÐÔËÐÐʱ£¬¿ÉÒÔÔÚÄãµÄjarÖ®ÍâÌṩһ¸ö `application.properties` ÎļþÀ´¸²¸Ç `name` ¡£¶ÔÓÚÒ»´ÎÐԵIJâÊÔ£¬Äã¿ÉÒÔÓÃÒ»¸öÌØ¶¨µÄÃüÁîÐвÎÊýÀ´Æô¶¯£¨ÀýÈ磬`java -jar app.jar --name="Spring"`£©¡£
+
+
+
+
+
+| | `env` ºÍ `configprops` ¶ËµãÔÚÈ·¶¨Ò»¸öÊôÐÔΪʲôÓÐÒ»¸öÌØ¶¨µÄֵʱ·Ç³£ÓÐÓá£Äã¿ÉÒÔʹÓÃÕâÁ½¸ö¶ËµãÀ´Õï¶ÏÒâÍâµÄÊôÐÔÖµ¡£Ïê¼û "[Éú²ú¾ÍÐ÷¹¦ÄÜ](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints)" ²¿·Ö¡£ |
+| --- | --- |
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/features.html#features.external-config.command-line-args)2.1\. ·ÃÎÊÃüÁîÐÐÊôÐÔ
+
+
+
+ĬÈÏÇé¿öÏ£¬`SpringApplication` »á½«ÈκÎÃüÁîÐÐÑ¡Ïî²ÎÊý£¨¼´ÒÔ `--` ¿ªÍ·µÄ²ÎÊý£¬Èç `--server.port=9000` £©×ª»»Îª `property` ²¢½«ÆäÌí¼Óµ½Spring `Environment` ÖС£ ÈçǰËùÊö£¬ÃüÁîÐÐÊôÐÔ×ÜÊÇÓÅÏÈÓÚ»ùÓÚÎļþµÄÊôÐÔÔ´¡£
+
+
+
+
+
+Èç¹ûÄ㲻ϣÍûÃüÁîÐÐÊôÐÔ±»Ìí¼Óµ½ `Environment` ÖУ¬Äã¿ÉÒÔͨ¹ý `SpringApplication.setAddCommandLineProperties(false)` ½ûÓÃËüÃÇ¡£
+
+
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/features.html#features.external-config.application-json)2.2\. JSON Application Properties
+
+
+
+»·¾³±äÁ¿ºÍϵͳÊôÐÔÍùÍùÓÐÏÞÖÆ£¬ÕâÒâζ×ÅÓÐЩÊôÐÔÃû³Æ²»ÄÜʹÓᣠΪÁ˰ïÖú½â¾öÕâ¸öÎÊÌ⣬Spring BootÔÊÐíÄ㽫һ¸öÊôÐÔ¿é±àÂëΪһ¸öµ¥Ò»µÄJSON½á¹¹¡£
+
+
+
+
+
+µ±ÄãµÄÓ¦ÓóÌÐòÆô¶¯Ê±£¬ÈκΠ`spring.application.json` »ò `SPRING_APPLICATION_JSON` ÊôÐÔ½«±»½âÎö²¢Ìí¼Óµ½ `Environment` ÖС£
+
+
+
+
+
+ÀýÈ磬`SPRING_APPLICATION_JSON` ÊôÐÔ¿ÉÒÔÔÚ UN*X shell µÄÃüÁîÐÐÖÐ×÷Ϊ»·¾³±äÁ¿Ìṩ¡£
+
+
+
+
+
+
+
+```
+$ SPRING_APPLICATION_JSON='{"my":{"name":"test"}}' java -jar myapp.jar
+```
+
+
+
+
+
+
+
+ÔÚÇ°ÃæµÄÀý×ÓÖУ¬ÄãÔÚSpringµÄ `Environment` ÖÐ×îÖյõ½ÁË `my.name=test`¡£
+
+
+
+
+
+ͬÑùµÄJSONÒ²¿ÉÒÔ×÷Ϊһ¸öϵͳÊôÐÔÌṩ¡£
+
+
+
+
+
+
+
+```
+$ java -Dspring.application.json='{"my":{"name":"test"}}' -jar myapp.jar
+```
+
+
+
+
+
+
+
+»òÕßÄã¿ÉÒÔͨ¹ýʹÓÃÒ»¸öÃüÁîÐвÎÊýÀ´ÌṩJSON¡£
+
+
+
+
+
+
+
+```
+$ java -jar myapp.jar --spring.application.json='{"my":{"name":"test"}}'
+```
+
+
+
+
+
+
+
+Èç¹ûÄãÒª²¿Êðµ½Ò»¸ö¾µäµÄÓ¦Ó÷þÎñÆ÷ÖУ¬ÄãÒ²¿ÉÒÔʹÓÃÒ»¸öÃûΪ `java:comp/env/spring.application.json` µÄJNDI±äÁ¿¡£
+
+
+
+
+
+| | ¾¡¹ÜJSONÖÐµÄ `null` Öµ½«±»Ìí¼Óµ½Éú³ÉµÄÊôÐÔÔ´ÖУ¬µ« `PropertySourcesPropertyResolver` ½« `null` ÊôÐÔÊÓΪȱʧֵ¡£ ÕâÒâζ×ÅJSON²»ÄÜÓà `null` Öµ¸²¸ÇÀ´×Եͽ×ÊôÐÔÔ´µÄÊôÐÔ¡£ |
+| --- | --- |
+
+
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/features.html#features.external-config.files)2.3\. ÍⲿµÄ Application Properties
+
+
+
+µ±ÄãµÄÓ¦ÓóÌÐòÆô¶¯Ê±£¬Spring Boot»á×Ô¶¯´ÓÒÔÏÂλÖÃÕÒµ½²¢¼ÓÔØ `application.properties` ºÍ `application.yaml` Îļþ¡£
+
+
+
+
+
+1. classpath
+
+
+
+ 1. classpath ¸ù·¾¶
+
+ 2. classpath Ï嵀 `/config` °ü
+
+
+
+2. µ±Ç°Ä¿Â¼
+
+
+
+ 1. µ±Ç°Ä¿Â¼ÏÂ
+
+ 2. µ±Ç°Ä¿Â¼Ï嵀 `config/` ×ÓĿ¼
+
+ 3. `config/` ×ÓĿ¼µÄÖ±½Ó×ÓĿ¼
+
+
+
+
+
+
+
+ÁÐ±í°´ÓÅÏȼ¶ÅÅÐò£¨½ÏµÍÏîÄ¿µÄÖµ¸²¸Ç½ÏÔçÏîÄ¿µÄÖµ£©¡£ ¼ÓÔØµÄÎļþ±»×÷Ϊ `PropertySources` Ìí¼Óµ½SpringµÄ `Environment` ÖС£
+
+
+
+
+
+Èç¹ûÄ㲻ϲ»¶ `application` ×÷ΪÅäÖÃÎļþÃû³Æ£¬Äã¿ÉÒÔͨ¹ýÖ¸¶¨ `spring.config.name` »·¾³ÊôÐÔÇл»µ½ÁíÒ»¸öÎļþÃû³Æ¡£ ÀýÈ磬ΪÁËѰÕÒ `myproject.properties` ºÍ `myproject.yaml` Îļþ£¬Äã¿ÉÒÔ°´ÒÔÏ·½Ê½ÔËÐÐÄãµÄÓ¦ÓóÌÐò¡£
+
+
+
+
+
+
+
+```
+$ java -jar myproject.jar --spring.config.name=myproject
+```
+
+
+
+
+
+
+
+ÄãÒ²¿ÉÒÔͨ¹ýʹÓà `spring.config.location` »·¾³ÊôÐÔÀ´ÒýÓÃÒ»¸öÃ÷È·µÄλÖᣠ¸ÃÊôÐÔ½ÓÊÜÒ»¸ö¶ººÅ·Ö¸ôµÄÁÐ±í£¬ÆäÖаüº¬Ò»¸ö»ò¶à¸öÒª¼ì²éµÄλÖá£
+
+
+
+
+
+ÏÂÃæµÄÀý×ÓÏÔʾÁËÈçºÎÖ¸¶¨Á½¸ö²»Í¬µÄÎļþ¡£
+
+
+
+
+
+
+
+```
+$ java -jar myproject.jar --spring.config.location=\
+ optional:classpath:/default.properties,\
+ optional:classpath:/override.properties
+```
+
+
+
+
+
+
+
+| | Èç¹û [ÅäÖÃÎļþÊÇ¿ÉÑ¡µÄ](https://springdoc.cn/spring-boot/features.html#features.external-config.files.optional-prefix)£¬²¢ÇÒ¿ÉÒÔÊDz»´æÔڵģ¬ÄÇôÇëʹÓà `optional:` ǰ׺¡£ |
+| --- | --- |
+
+
+
+
+
+| | `spring.config.name`, `spring.config.location`, ºÍ `spring.config.extra-location` ºÜÔç¾ÍÓÃÀ´È·¶¨ÄÄЩÎļþ±ØÐë±»¼ÓÔØ¡£ ËüÃDZØÐë±»¶¨ÒåΪ»·¾³ÊôÐÔ£¨Í¨³£ÊDzÙ×÷ϵͳ»·¾³±äÁ¿£¬ÏµÍ³ÊôÐÔ£¬»òÃüÁîÐвÎÊý£©¡£ |
+| --- | --- |
+
+
+
+
+
+Èç¹û `spring.config.location` °üº¬Ä¿Â¼£¨¶ø²»ÊÇÎļþ£©£¬ËüÃÇÓ¦¸ÃÒÔ `/` ½áβ¡£ ÔÚÔËÐÐʱ£¬ËüÃǽ«±»¸½¼ÓÉÏÓÉ `spring.config.name` Éú³ÉµÄÃû³Æ£¬È»ºó±»¼ÓÔØ¡£ ÔÚ `spring.config.location` ÖÐÖ¸¶¨µÄÎļþ±»Ö±½Óµ¼Èë¡£
+
+
+
+
+
+| | Ŀ¼ºÍÎļþλÖÃÖµÒ²±»À©Õ¹£¬ÒÔ¼ì²é[ÌØ¶¨µÄÅäÖÃÎļþ](https://springdoc.cn/spring-boot/features.html#features.external-config.files.profile-specific)¡£ÀýÈ磬Èç¹ûÄãµÄ `spring.config.location` ÊÇ `classpath:myconfig.properties`£¬ÄãÒ²»á·¢ÏÖÊʵ±µÄ `classpath:myconfig-.properties` Îļþ±»¼ÓÔØ¡£ |
+| --- | --- |
+
+
+
+
+
+ÔÚ´ó¶àÊýÇé¿öÏ£¬ÄãÌí¼ÓµÄÿ¸ö `spring.config.location` ÏÒýÓÃÒ»¸öÎļþ»òĿ¼¡£ λÖÃÊǰ´ÕÕËüÃDZ»¶¨ÒåµÄ˳ÐòÀ´´¦ÀíµÄ£¬ºóÃæµÄλÖÿÉÒÔ¸²¸ÇÇ°ÃæµÄλÖõÄÖµ¡£
+
+
+
+
+
+Èç¹ûÄãÓÐÒ»¸ö¸´ÔÓµÄλÖÃÉèÖ㬶øÇÒÄãʹÓÃÌØ¶¨µÄÅäÖÃÎļþ£¬Äã¿ÉÄÜÐèÒªÌṩ½øÒ»²½µÄÌáʾ£¬ÒÔ±ãSpring BootÖªµÀËüÃÇÓ¦¸ÃÈçºÎ·Ö×é¡£Ò»¸öλÖÃ×éÊÇÒ»¸öλÖõļ¯ºÏ£¬ÕâЩλÖö¼±»ÈÏΪÊÇÔÚͬһ¼¶±ð¡£ÀýÈ磬Äã¿ÉÄÜÏë°ÑËùÓÐclasspathλÖ÷Ö×飬ȻºóÊÇËùÓÐÍⲿλÖá£Ò»¸öλÖÃ×éÄÚµÄÏîĿӦ¸ÃÓà `;` ·Ö¸ô¡£¸ü¶àϸ½Ú¼û ¡°[Ö¸¶¨ profile](https://springdoc.cn/spring-boot/features.html#features.external-config.files.profile-specific)¡± ²¿·ÖµÄÀý×Ó¡£
+
+
+
+
+
+ͨ¹ýʹÓà `spring.config.location` ÅäÖõÄλÖÃÈ¡´úĬÈÏλÖᣠÀýÈ磬Èç¹û `spring.config.location` ±»ÅäÖÃΪ `optional:classpath:/custom-config/,optional:file:./custom-config/` £¬¿¼ÂǵÄÍêÕûλÖü¯ÈçÏ¡£
+
+
+
+
+
+1. `optional:classpath:custom-config/`
+
+2. `optional:file:./custom-config/`
+
+
+
+
+
+Èç¹ûÄãϲ»¶Ìí¼Ó¶îÍâµÄλÖ㬶ø²»ÊÇÌæ»»ËüÃÇ£¬Äã¿ÉÒÔʹÓà `spring.config.extra-location` ¡£ ´Ó¸½¼ÓλÖüÓÔØµÄÊôÐÔ¿ÉÒÔ¸²¸ÇĬÈÏλÖõÄÊôÐÔ¡£ ÀýÈ磬Èç¹û `spring.config.extra-location` ±»ÅäÖÃΪ `optional:classpath:/custom-config/,optional:file:./custom-config/` £¬¿¼ÂǵÄÍêÕûλÖü¯ÈçÏ¡£
+
+
+
+
+
+1. `optional:classpath:/;optional:classpath:/config/`
+
+2. `optional:file:./;optional:file:./config/;optional:file:./config/*/`
+
+3. `optional:classpath:custom-config/`
+
+4. `optional:file:./custom-config/`
+
+
+
+
+
+ÕâÖÖËÑË÷ÅÅÐòÈÃÄãÔÚÒ»¸öÅäÖÃÎļþÖÐÖ¸¶¨Ä¬ÈÏÖµ£¬È»ºóÔÚÁíÒ»¸öÎļþÖÐÑ¡ÔñÐԵظ²¸ÇÕâЩֵ¡£ Äã¿ÉÒÔÔÚÆäÖÐÒ»¸öĬÈÏλÖÃµÄ `application.properties` £¨»òÄãÓà `spring.config.name` Ñ¡ÔñµÄÆäËûbasename£©ÖÐΪÄãµÄÓ¦ÓóÌÐòÌṩĬÈÏÖµ¡£ È»ºó£¬ÕâЩĬÈÏÖµ¿ÉÒÔÔÚÔËÐÐʱ±»Î»ÓÚÆäÖÐÒ»¸ö×Ô¶¨ÒåλÖõIJ»Í¬Îļþ¸²¸Ç¡£
+
+
+
+
+
+| | Èç¹ûÄãʹÓû·¾³±äÁ¿¶ø²»ÊÇϵͳÊôÐÔ£¬´ó¶àÊý²Ù×÷ϵͳ²»ÔÊÐíʹÓþäµã·Ö¸ôµÄ¼üÃû£¬µ«Äã¿ÉÒÔʹÓÃÏ»®Ïß´úÌæ£¨ÀýÈ磬 `SPRING_CONFIG_NAME` ¶ø²»ÊÇ `spring.config.name` £©¡£ ²Î¼û[´Ó»·¾³±äÁ¿°ó¶¨](https://springdoc.cn/spring-boot/features.html#features.external-config.typesafe-configuration-properties.relaxed-binding.environment-variables) Á˽âÏêÇé¡£ |
+| --- | --- |
+
+
+
+
+
+| | Èç¹ûÄãµÄÓ¦ÓóÌÐòÔÚservletÈÝÆ÷»òÓ¦Ó÷þÎñÆ÷ÖÐÔËÐУ¬ÄÇôJNDIÊôÐÔ£¨ÔÚ `java:comp/env` ÖУ©»òservletÉÏÏÂÎijõʼ»¯²ÎÊý¿ÉÒÔ´úÌæ»·¾³±äÁ¿»òϵͳÊôÐÔ£¬»òÕßÓëÖ®Ò»Ñù¡£ |
+| --- | --- |
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/features.html#features.external-config.files.optional-prefix)2.3.1\. ¿ÉÑ¡µÄλÖÃ(Optional Locations)
+
+
+
+ĬÈÏÇé¿öÏ£¬µ±Ö¸¶¨µÄÅäÖÃÊý¾ÝλÖò»´æÔÚʱ£¬Spring Boot½«Å׳öÒ»¸ö `ConfigDataLocationNotFoundException` £¬ÄãµÄÓ¦ÓóÌÐò½«ÎÞ·¨Æô¶¯¡£
+
+
+
+
+
+Èç¹ûÄãÏëÖ¸¶¨Ò»¸öλÖ㬵«Äã²»½éÒâËü²¢²»×ÜÊÇ´æÔÚ£¬Äã¿ÉÒÔʹÓà `optional:` ǰ׺¡£Äã¿ÉÒÔÔÚ `spring.config.locationºÍspring.config.extra-location` ÊôÐÔÖÐʹÓÃÕâ¸öǰ׺£¬Ò²¿ÉÒÔÔÚ [`spring.config.import`](https://springdoc.cn/spring-boot/features.html#features.external-config.files.importing) ÉùÃ÷ÖÐʹÓá£
+
+
+
+
+
+ÀýÈ磬`spring.config.import` ֵΪ `optional:file:./myconfig.properties` ÔÊÐíÄãµÄÓ¦ÓóÌÐòÆô¶¯£¬¼´Ê¹ `myconfig.properties` Îļþ¶ªÊ§¡£
+
+
+
+
+
+Èç¹ûÄãÏëºöÂÔËùÓÐµÄ `ConfigDataLocationNotFoundExceptions` ²¢Ê¼ÖÕ¼ÌÐøÆô¶¯ÄãµÄÓ¦ÓóÌÐò£¬Äã¿ÉÒÔʹÓà `spring.config.on-not-found` ÊôÐÔ¡£ ʹÓà `SpringApplication.setDefaultProperties(..)` »òʹÓÃϵͳ/»·¾³±äÁ¿½«ÆäÖµÉèÖÃΪ `ignore`¡£
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/features.html#features.external-config.files.wildcard-locations)2.3.2\. ͨÅä·ûµØÖ·
+
+
+
+Èç¹ûÒ»¸öÅäÖÃÎļþµÄλÖÃÔÚ×îºóÒ»¸ö·¾¶¶ÎÖаüº¬ `*` ×Ö·û£¬Ëü¾Í±»ÈÏΪÊÇÒ»¸öͨÅä·ûλÖᣠͨÅä·ûÔÚ¼ÓÔØÅäÖÃʱ±»À©Õ¹£¬Òò´Ë£¬Ö±½ÓµÄ×ÓĿ¼Ҳ±»¼ì²é¡£ ͨÅä·ûλÖÃÔÚKubernetesÕâÖÖÓжà¸öÅäÖÃÊôÐÔµÄÀ´Ô´µÄ»·¾³ÖÐÌØ±ðÓÐÓá£
+
+
+
+
+
+ÀýÈ磬Èç¹ûÄãÓÐһЩRedisÅäÖúÍһЩMySQLÅäÖã¬Äã¿ÉÄÜÏë°ÑÕâÁ½²¿·ÖÅäÖ÷ֿª£¬Í¬Ê±ÒªÇóÕâÁ½²¿·Ö¶¼´æÔÚÓÚÒ»¸ö `application.properties` ÎļþÖС£
+
+
+
+
+
+Õâ¿ÉÄܻᵼÖÂÁ½¸ö¶ÀÁ¢µÄ `application.properties` Îļþ¹ÒÔØÔÚ²»Í¬µÄλÖã¬Èç `/config/redis/application.properties` ºÍ `/config/mysql/application.properties` ¡£ ÔÚÕâÖÖÇé¿öÏ£¬ÓÐÒ»¸öͨÅä·ûλÖà `config/*/` £¬½«µ¼ÖÂÁ½¸öÎļþ±»´¦Àí¡£
+
+
+
+
+
+ĬÈÏÇé¿öÏ£¬Spring Boot½« `config/*/` ÁÐÈëĬÈÏËÑË÷λÖᣠÕâÒâζ×ÅÄãµÄjarÖ®ÍâµÄ `/config` Ŀ¼µÄËùÓÐ×ÓĿ¼¶¼»á±»ËÑË÷µ½¡£
+
+
+
+
+
+Äã¿ÉÒÔÔÚ `spring.config.location` ºÍ `spring.config.extra-location` ÊôÐÔÖÐʹÓÃͨÅä·ûλÖá£
+
+
+
+
+
+| | ͨÅä·ûλÖñØÐëÖ»°üº¬Ò»¸ö `*` ²¢ÒÔ `*/` ½á⣬ÓÃÓÚËÑË÷ÊôÓÚĿ¼µÄλÖ㬻ò `*/` ÓÃÓÚËÑË÷ÊôÓÚÎļþµÄλÖᣠ´øÓÐͨÅä·ûµÄλÖý«¸ù¾ÝÎļþÃûµÄ¾ø¶Ô·¾¶°´×Öĸ˳ÐòÅÅÐò¡£ |
+| --- | --- |
+
+
+
+
+
+| | ͨÅä·ûλÖÃÖ»¶ÔÍⲿĿ¼Æð×÷ÓᣠÄã²»ÄÜÔÚ `classpath:` λÖÃÖÐʹÓÃͨÅä·û¡£ |
+| --- | --- |
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/features.html#features.external-config.files.profile-specific)2.3.3\. ÌØ¶¨Îļþ£¨Profile Specific Files£©
+
+
+
+³ýÁË `application` ÊôÐÔÎļþ£¬Spring Boot»¹½«³¢ÊÔʹÓà `application-{profile}` µÄÃüÃû¹ßÀý¼ÓÔØprofileÌØ¶¨µÄÎļþ¡£ ÀýÈ磬Èç¹ûÄãµÄÓ¦ÓóÌÐò¼¤»îÁËÃûΪ `prod` µÄÅäÖÃÎļþ£¨`spring.profiles.active=prod`£©²¢Ê¹ÓÃYAMLÎļþ£¬ÄÇô `application.yml` ºÍ `application-prod.yml` ¶¼½«±»¿¼ÂÇ¡£
+
+
+
+
+
+ÌØ¶¨Îļþ(`profiles`)µÄÊôÐÔÓë±ê×¼µÄ `application.properties` µÄλÖÃÏàͬ£¬Ìض¨Îļþ×ÜÊÇÓÅÏÈÓÚ·ÇÌØ¶¨Îļþ¡£ Èç¹ûÖ¸¶¨Á˼¸¸öÅäÖÃÎļþ£¬Ôò²ÉÓÃ×îºóʤ³öµÄ²ßÂÔ¡£ ÀýÈ磬Èç¹ûÅäÖÃÎļþ `prod,live` ÊÇÓÉ `spring.profiles.active` ÊôÐÔÖ¸¶¨µÄ£¬`application-prod.properties` ÖеÄÖµ¿ÉÒÔ±» `application-live.properties` ÖеÄÖµËù¸²¸Ç¡£
+
+
+
+
+
+| | ×îºóʤ³öµÄ²ßÂÔÊÊÓÃÓÚ[location group](https://springdoc.cn/spring-boot/features.html#features.external-config.files.location-groups)¼¶±ð¡£ `spring.config.location` µÄ `classpath:/cfg/,classpath:/ext/` ½«²»»áÓÐÓë `classpath:/cfg/;classpath:/ext/` ÏàͬµÄ¸²¸Ç¹æÔò¡£ÀýÈ磬ÄÃÎÒÃÇÉÏÃæµÄ `prod,live` Àý×ÓÀ´Ëµ£¬ÎÒÃÇ¿ÉÄÜÓÐÒÔÏÂÎļþ¡£ /cfg application-live.properties/ext application-live.properties application-prod.properties µ±ÎÒÃÇÓÐÒ»¸ö `spring.config.location` Ϊ `classpath:/cfg/,classpath:/ext/` ʱ£¬ÎÒÃÇ»áÔÚËùÓÐ `/ext` Îļþ֮ǰ´¦ÀíËùÓÐ `/cfg` Îļþ¡£1. `/cfg/application-live.properties` 2. `/ext/application-prod.properties` 3. `/ext/application-live.properties` µ±ÎÒÃÇÓà `classpath:/cfg/;classpath:/ext/` ´úÌæÊ±£¨Óà `;` ·Ö¸ô·û£©£¬ÎÒÃÇÔÚͬһ¼¶±ð´¦Àí `/cfg` ºÍ `/ext` ¡£1. `/ext/application-prod.properties` 2. `/cfg/application-live.properties` 3. `/ext/application-live.properties` |
+| --- | --- |
+
+
+
+
+
+`Environment` ÓÐÒ»×éĬÈϵÄÅäÖÃÎļþ£¨Ä¬ÈÏΪ `[default]` £©£¬Èç¹ûûÓÐÉèÖûµÄÅäÖÃÎļþ£¬¾Í»áʹÓÃÕâЩÅäÖÃÎļþ¡£ »»¾ä»°Ëµ£¬Èç¹ûûÓÐÃ÷È·¼¤»îµÄÅäÖÃÎļþ£¬ÄÇô¾Í»á¿¼ÂÇÀ´×Ô `application-default` µÄÊôÐÔ¡£
+
+
+
+
+
+| | ÊôÐÔÎļþÖ»±»¼ÓÔØÒ»´Î¡£ Èç¹ûÄãÒѾֱ½Ó[µ¼ÈëÁË](https://springdoc.cn/spring-boot/features.html#features.external-config.files.importing)Ò»¸öÅäÖÃÎļþµÄÌØ¶¨ÊôÐÔÎļþ£¬ÄÇôËü½«²»»á±»µÚ¶þ´Îµ¼Èë¡£ |
+| --- | --- |
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/features.html#features.external-config.files.importing)2.3.4\. µ¼Èë¶îÍâµÄÊý¾Ý
+
+
+
+application properties ÖпÉÒÔʹÓà `spring.config.import` ÊôÐÔ´ÓÆäËûµØ·½µ¼Èë¸ü¶àµÄÅäÖÃÊý¾Ý¡£ µ¼ÈëÔÚ±»·¢ÏÖʱ±»´¦Àí£¬²¢±»ÊÓΪ½ô½Ó×ÅÉùÃ÷µ¼ÈëµÄÎļþÏÂÃæ²åÈëµÄ¶îÍâÎļþ¡£
+
+
+
+
+
+ÀýÈ磬Äã¿ÉÄÜÔÚÄãµÄ classpath `application.properties` ÎļþÖÐÓÐÒÔÏÂÄÚÈÝ¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+spring.application.name=myapp
+spring.config.import=optional:file:./dev.properties
+
+```
+
+
+
+
+
+
+
+Õ⽫´¥·¢µ¼È뵱ǰĿ¼Ï嵀 `dev.properties` Îļþ£¨Èç¹û´æÔÚÕâÑùµÄÎļþ£©¡£ µ¼ÈëµÄ `dev.properties` ÖеÄÖµ½«ÓÅÏÈÓÚ´¥·¢µ¼ÈëµÄÎļþ¡£ ÔÚÉÏÃæµÄÀý×ÓÖУ¬`dev.properties` ¿ÉÒÔ½« `spring.application.name` ÖØÐ¶¨ÒåΪһ¸ö²»Í¬µÄÖµ¡£
+
+
+
+
+
+Ò»¸öµ¼ÈëÖ»»á±»µ¼ÈëÒ»´Î£¬ÎÞÂÛËü±»ÉùÃ÷¶àÉٴΡ£ Ò»¸öµ¼ÈëÔÚproperties/yamlÎļþÄڵĵ¥¸öÎļþÖб»¶¨ÒåµÄ˳Ðò²¢²»ÖØÒª¡£ ÀýÈ磬ÏÂÃæµÄÁ½¸öÀý×Ó²úÉúÏàͬµÄ½á¹û¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+spring.config.import=my.properties
+my.property=value
+
+```
+
+
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+my.property=value
+spring.config.import=my.properties
+
+```
+
+
+
+
+
+
+
+ÔÚÉÏÊöÁ½¸öÀý×ÓÖУ¬`my.properties` ÎļþµÄÖµ½«ÓÅÏÈÓÚ´¥·¢Æäµ¼ÈëµÄÎļþ¡£
+
+
+
+
+
+ÔÚÒ»¸öµ¥Ò»µÄ `spring.config.import` ÊôÐÔÏ¿ÉÒÔÖ¸¶¨¶à¸öλÖᣠλÖý«°´ÕÕËüÃDZ»¶¨ÒåµÄ˳Ðò±»´¦Àí£¬ºóÀ´µÄµ¼È뽫±»ÓÅÏÈ´¦Àí¡£
+
+
+
+
+
+| | ÔÚÊʵ±µÄʱºò£¬[ÌØ¶¨ÅäÖÃÎļþµÄ±äÌå](https://springdoc.cn/spring-boot/features.html#features.external-config.files.profile-specific)Ò²±»¿¼Âǵ¼Èë¡£ ÉÏÃæµÄÀý×Ó½«µ¼Èë `my.properties` ÒÔ¼°ÈκΠ`my-.properties` ±äÌå¡£ |
+| --- | --- |
+
+
+
+
+
+| | Spring Boot ÌṩÁ˿ɲå°ÎµÄAPI£¨²å¼þ£©£¬ÔÊÐíÖ§³Ö¸÷ÖÖ²»Í¬µÄλÖõØÖ·¡£ ĬÈÏÇé¿öÏ£¬Äã¿ÉÒÔµ¼ÈëJava Properties¡¢YAMLºÍ ¡°[ÅäÖÃÊ÷](https://springdoc.cn/spring-boot/features.html#features.external-config.files.configtree)¡± ¡£µÚÈý·½jar¿ÉÒÔÌṩ¶ÔÆäËû¼¼ÊõµÄÖ§³Ö£¨²»ÒªÇó±ØÐëÊDZ¾µØÎļþ£©¡£ ÀýÈ磬Äã¿ÉÒÔÏëÏóÅäÖÃÊý¾ÝÀ´×ÔÍⲿ´æ´¢£¬ÈçConsul¡¢Apache ZooKeeper»òNetflix Archaius£¨°üÀ¨Nacos£©¡£Èç¹ûÄãÏëÖ§³ÖÄã×Ô¼ºµÄλÖã¨ÊµÏÖ×Ô¼º¶¨ÒåµÄÅäÖüÓÔØ£©£¬Çë²ÎÔÄ `org.springframework.boot.context.config` °üÖÐµÄ `ConfigDataLocationResolver` ºÍ `ConfigDataLoader` Àà¡£ |
+| --- | --- |
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/features.html#features.external-config.files.importing-extensionless)2.3.5\. µ¼ÈëÎÞÀ©Õ¹ÃûµÄÎļþ
+
+
+
+ÓÐÐ©ÔÆÆ½Ì¨²»ÄÜΪ¾í×°Îļþ£¨volume mounted files£©Ìí¼ÓÎļþÀ©Õ¹Ãû¡£ Òªµ¼ÈëÕâЩÎÞÀ©Õ¹ÃûµÄÎļþ£¬ÄãÐèÒª¸øSpring BootÒ»¸öÌáʾ£¬ÒÔ±ãËüÖªµÀÈçºÎ¼ÓÔØËüÃÇ¡£ Äã¿ÉÒÔͨ¹ý°ÑÀ©Õ¹ÃûÌáʾ·ÅÔÚ·½À¨ºÅÀïÀ´×öµ½ÕâÒ»µã¡£
+
+
+
+
+
+ÀýÈ磬¼ÙÉèÄãÓÐÒ»¸ö `/etc/config/myconfig` Îļþ£¬ÄãÏ£ÍûÒÔyamlÐÎʽµ¼Èë¡£ Äã¿ÉÒÔÓÃÏÂÃæµÄ·½·¨´ÓÄãµÄ `application.properties` Öе¼ÈëËü¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+spring.config.import=file:/etc/config/myconfig[.yaml]
+
+```
+
+
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/features.html#features.external-config.files.configtree)2.3.6\. ʹÓÃÅäÖÃÊ÷£¨Configuration Trees£©
+
+
+
+µ±ÔÚÔÆÆ½Ì¨£¨ÈçKubernetes£©ÉÏÔËÐÐÓ¦ÓóÌÐòʱ£¬Äã¾³£ÐèÒª¶Áȡƽ̨ÌṩµÄÅäÖÃÖµ¡£ ½«»·¾³±äÁ¿ÓÃÓÚ´ËÀàÄ¿µÄ²¢²»ÉÙ¼û£¬µ«Õâ¿ÉÄÜÓÐȱµã£¬ÌرðÊÇÈç¹û¸ÃÖµÊÇ secret µÄ¡£
+
+
+
+
+
+×÷Ϊ»·¾³±äÁ¿µÄÌæ´ú·½°¸£¬Ðí¶àÔÆÆ½Ì¨ÏÖÔÚÔÊÐíÄ㽫ÅäÖÃÓ³Éäµ½¹ÒÔØµÄÊý¾Ý¾í¡£ ÀýÈ磬Kubernetes ¿ÉÒÔ¾í¹ÒÔØ [`ConfigMaps`](https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/#populate-a-volume-with-data-stored-in-a-configmap) ºÍ [`Secrets`](https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets-as-files-from-a-pod)¡£
+
+
+
+
+
+¿ÉÒÔʹÓÃÁ½ÖÖ³£¼ûµÄ volume ¹ÒÔØÄ£Ê½£º
+
+
+
+
+
+1. Ò»¸öÎļþ°üº¬Ò»Ì×ÍêÕûµÄÊôÐÔ£¨Í¨³£Ð´³ÉYAML£©¡£
+
+2. ¶à¸öÎļþ±»Ð´ÈëÒ»¸öĿ¼Ê÷ÖУ¬ÎļþÃû³ÉΪ ¡®key¡¯£¬ÄÚÈݳÉΪ ¡®value¡¯¡£
+
+
+
+
+
+¶ÔÓÚµÚÒ»ÖÖÇé¿ö£¬Äã¿ÉÒÔʹÓà `spring.config.import` Ö±½Óµ¼ÈëYAML»òÊôÐÔÎļþ£¬[ÈçÉÏËùÊö](https://springdoc.cn/spring-boot/features.html#features.external-config.files.importing)¡£ ¶ÔÓÚµÚ¶þÖÖÇé¿ö£¬ÄãÐèҪʹÓà `configtree:` ǰ׺£¬ÒÔ±ãSpring BootÖªµÀËüÐèÒª½«ËùÓÐÎļþ×÷ΪÊôÐÔ¹«¿ª¡£
+
+
+
+
+
+¾Ù¸öÀý×Ó£¬ÈÃÎÒÃÇÏëÏóһϣ¬KubernetesÒѾ¹ÒÔØÁËÒÔÏÂvolume¡£
+
+
+
+
+
+
+
+ etc/
+ config/
+ myapp/
+ username
+ password
+
+
+
+
+
+
+
+`username` ÎļþµÄÄÚÈݽ«ÊÇÒ»¸öÅäÖÃÖµ£¬¶ø `password` µÄÄÚÈݽ«ÊÇÒ»¸ö secret¡£
+
+
+
+
+
+Òªµ¼ÈëÕâЩÊôÐÔ£¬Äã¿ÉÒÔÔÚÄãµÄ `application.properties` »ò `application.yaml` ÎļþÖÐÌí¼ÓÒÔÏÂÄÚÈÝ¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+spring.config.import=optional:configtree:/etc/config/
+
+```
+
+
+
+
+
+
+
+È»ºóÄã¿ÉÒÔ´Ó `Environment` ÖÐÒÔ³£¹æ·½Ê½·ÃÎÊ»ò×¢Èë `myapp.username` ºÍ `myapp.password` ÊôÐÔ¡£
+
+
+
+
+
+| | ÅäÖÃÊ÷ϵÄÎļþ¼Ð¹¹³ÉÁËÊôÐÔÃû³Æ¡£ ÔÚÉÏÃæµÄÀý×ÓÖУ¬ÎªÁË·ÃÎÊÊôÐÔΪ `username` ºÍ `password`£¬Äã¿ÉÒÔ½« `spring.config.import` ÉèÖÃΪ `optional:configtree:/etc/config/myapp` ¡£ |
+| --- | --- |
+
+
+
+
+
+| | ´øÓеã·ûºÅµÄÎļþÃûÒ²»á±»ÕýÈ·Ó³Éä¡£ ÀýÈ磬ÔÚÉÏÃæµÄÀý×ÓÖУ¬`/etc/config` ÖÐÃûΪ `myapp.username` µÄÎļþÔÚ `Environment` ÖеÄÊôÐÔÃû½«»áÊÇ `myapp.username` ¡£ |
+| --- | --- |
+
+
+
+
+
+| | ÅäÖÃÊ÷µÄÖµ¿ÉÒÔ±»°ó¶¨µ½×Ö·û´® `String` ºÍ `byte[]` ÀàÐÍ£¬ÕâÈ¡¾öÓÚÔ¤ÆÚµÄÄÚÈÝ¡£ |
+| --- | --- |
+
+
+
+
+
+Èç¹ûÄãÓжà¸öÅäÖÃÊ÷Òª´Óͬһ¸ö¸¸Îļþ¼Ðµ¼È룬Äã¿ÉÒÔʹÓÃͨÅä·û¿ì½Ý·½Ê½¡£ ÈκÎÒÔ `/*/` ½áβµÄ `configtree:` λÖý«µ¼ÈëËùÓÐÖ±½ÓµÄ×ÓÎļþ¼Ð×÷ΪÅäÖÃÊ÷¡£
+
+
+
+
+
+ÀýÈ磬¸ø¶¨ÒÔÏÂvolume£º
+
+
+
+
+
+
+
+ etc/
+ config/
+ dbconfig/
+ db/
+ username
+ password
+ mqconfig/
+ mq/
+ username
+ password
+
+
+
+
+
+
+
+Äã¿ÉÒÔʹÓà `configtree:/etc/config/*/` ×÷Ϊµ¼ÈëλÖá£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+spring.config.import=optional:configtree:/etc/config/*/
+
+```
+
+
+
+
+
+
+
+Õ⽫Ìí¼Ó `db.username`¡¢`db.password`¡¢`mq.username` ºÍ `mq.password` ÊôÐÔ¡£
+
+
+
+
+
+| | ʹÓÃͨÅä·û¼ÓÔØµÄĿ¼Êǰ´×Öĸ˳ÐòÅÅÁеġ£ Èç¹ûÄãÐèÒªÒ»¸ö²»Í¬µÄ˳Ðò£¬ÄÇôÄãÓ¦¸Ã°Ñÿ¸öλÖÃ×÷Ϊһ¸öµ¥¶ÀµÄµ¼ÈëÁгö¡£ |
+| --- | --- |
+
+
+
+
+
+ÅäÖÃÊ÷Ò²¿ÉÓÃÓÚDocker secret¡£ µ±Docker swarm·þÎñ±»ÊÚÓè¶ÔsecretµÄ·ÃÎÊȨʱ£¬¸Ãsecret»á±»×°Ôص½ÈÝÆ÷ÖС£ ÀýÈ磬Èç¹ûÒ»¸öÃûΪ `db.password` µÄsecret¡£±»¹ÒÔØÔÚ `/run/secrets/` µÄλÖã¬Äã¿ÉÒÔÓÃÒÔÏ·½·¨Èà `db.password` ¶ÔSpring»·¾³¿ÉÓá£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+spring.config.import=optional:configtree:/run/secrets/
+
+```
+
+
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/features.html#features.external-config.files.property-placeholders)2.3.7\. ÊôÐÔռλ·û
+
+
+
+`application.properties` ºÍ `application.yml` ÖеÄÖµÔÚʹÓÃʱͨ¹ýÏÖÓÐµÄ `Environment` ¹ýÂË£¬ËùÒÔÄã¿ÉÒԲο¼ÒÔǰ¶¨ÒåµÄÖµ£¨ÀýÈ磬À´×ÔϵͳÊôÐÔ»ò»·¾³±äÁ¿£©¡£ ±ê×¼µÄ `${name}` ÊôÐÔռλ·ûÓï·¨¿ÉÒÔÓÃÔÚÒ»¸öÖµµÄÈκεط½¡£ ÊôÐÔռλ·ûÒ²¿ÉÒÔÖ¸¶¨Ò»¸öĬÈÏÖµ£¬Ê¹Óà `:` À´·Ö¸ôĬÈÏÖµºÍÊôÐÔÃû³Æ£¬ÀýÈç `${name:default}` ¡£
+
+
+
+
+
+ÏÂÃæµÄÀý×ÓÏÔʾÁË´øÄ¬ÈÏÖµºÍ²»´øÄ¬ÈÏÖµµÄռλ·ûµÄʹÓÃÇé¿ö¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+app.name=MyApp
+app.description=${app.name} is a Spring Boot application written by ${username:Unknown}
+
+```
+
+
+
+
+
+
+
+¼ÙÉè `username` ÊôÐÔûÓÐÔÚÆäËûµØ·½ÉèÖã¬`app.description` µÄÖµ½«ÊÇ `MyApp is a Spring Boot application written by Unknown`¡£
+
+
+
+
+
+| | ÄãÓ¦¸ÃʼÖÕʹÓÃռλ·ûÖеÄÊôÐÔÃû³ÆµÄ¹æ·¶ÐÎʽ£¨½öʹÓÃСд×ÖĸµÄkebab-case£©À´ÒýÓÃËüÃÇ¡£ Õ⽫ÔÊÐíSpring BootʹÓÃÓë[¿íËɰó¶¨](https://springdoc.cn/spring-boot/features.html#features.external-config.typesafe-configuration-properties.relaxed-binding) `@ConfigurationProperties` ʱÏàͬµÄÂß¼¡£ÀýÈ磬`${demo.item-price}` ½«´Ó `application.properties` ÎļþÖлñÈ¡ `demo.item-price` ºÍ `demo.itemPrice` ÐÎʽµÄÊôÐÔ£¬ÒÔ¼°´Óϵͳ»·¾³ÖлñÈ¡ `DEMO_ITEMPRICE` ¡£ Èç¹ûÄãÓà `${demo.itemPrice}` µÄ»°£¬ `demo.item-price` ºÍ `DEMO_ITEMPRICE` ¾Í²»»á±»¿¼ÂÇ¡£ |
+| --- | --- |
+
+
+
+
+
+| | ÄãÒ²¿ÉÒÔʹÓÃÕâÖÖ¼¼ÊõÀ´´´½¨ÏÖÓÐSpring BootÊôÐ﵀ ¡°short¡± ±äÌå¡£ ÏêÇéÇë²Î¼û_[howto.html](https://springdoc.cn/spring-boot/howto.html#howto.properties-and-configuration.short-command-line-arguments)_µÄ·½·¨¡£ |
+| --- | --- |
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/features.html#features.external-config.files.multi-document)2.3.8\. ʹÓöàÎĵµÎļþ£¨Working with Multi-Document Files£©
+
+
+
+Spring BootÔÊÐíÄ㽫һ¸öÎïÀíÎļþ·Ö³É¶à¸öÂß¼Îļþ£¬Ã¿¸öÎļþ¶¼ÊǶÀÁ¢Ìí¼ÓµÄ¡£ ÎļþÊǰ´Ë³Ðò´¦ÀíµÄ£¬´ÓÉϵ½Ï¡£ ºóÃæµÄÎļþ¿ÉÒÔ¸²¸ÇÇ°ÃæÎļþÖж¨ÒåµÄÊôÐÔ¡£
+
+
+
+
+
+¶ÔÓÚ `application.yml` Îļþ£¬Ê¹Óñê×¼µÄYAML¶àÎĵµÓï·¨¡£ Èý¸öÁ¬ÐøµÄÁ¬×Ö·û£¨`---`£©´ú±íÒ»¸öÎļþµÄ½áÊø£¬ºÍÏÂÒ»¸öÎļþµÄ¿ªÊ¼¡£
+
+
+
+
+
+ÀýÈ磬ÏÂÃæµÄÎļþÓÐÁ½¸öÂß¼Îĵµ¡£
+
+
+
+
+
+
+
+```
+spring:
+ application:
+ name: "MyApp"
+---
+spring:
+ application:
+ name: "MyCloudApp"
+ config:
+ activate:
+ on-cloud-platform: "kubernetes"
+```
+
+
+
+
+
+
+
+¶ÔÓÚ `application.properties` Îļþ£¬Ò»¸öÌØÊâµÄ `#---` »ò `!---` ×¢Êͱ»ÓÃÀ´±ê¼ÇÎļþµÄ·Ö¸î¡£
+
+
+
+
+
+
+
+```
+spring.application.name=MyApp
+#---
+spring.application.name=MyCloudApp
+spring.config.activate.on-cloud-platform=kubernetes
+```
+
+
+
+
+
+
+
+| | properties ÎļþµÄ·Ö¸ô·û²»ÄÜÓÐÈκÎǰµ¼¿Õ°×£¬²¢ÇÒ±ØÐëÕýºÃÓÐÈý¸öÁ¬×Ö·û¡£ ·Ö¸ô·ûµÄǰºóÁ½Ðв»ÄÜÊÇÏàͬµÄ×¢ÊÍǰ׺¡£ |
+| --- | --- |
+
+
+
+
+
+| | ¶àÎĵµÊôÐÔÎļþͨ³£Ó뼤»îÊôÐÔÒ»ÆðʹÓã¬Èç `spring.config.activated.on-profile`¡£ Ïê¼û[ÏÂÒ»½Ú](https://springdoc.cn/spring-boot/features.html#features.external-config.files.activation-properties)¡£ |
+| --- | --- |
+
+
+
+
+
+| | ¶àÎĵµÊôÐÔÎļþ²»ÄÜͨ¹ýʹÓà `@PropertySource` »ò `@TestPropertySource` ×¢½â¼ÓÔØ¡£ |
+| --- | --- |
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/features.html#features.external-config.files.activation-properties)2.3.9\. ¼¤»îÊôÐÔ£¨Activation Properties£©
+
+
+
+ÓÐʱ£¬Ö»ÔÚÂú×ãijЩÌõ¼þʱ¼¤»îÒ»×éÌØ¶¨µÄÊôÐÔÊǺÜÓÐÓõġ£ ÀýÈ磬Äã¿ÉÄÜÓÐһЩÊôÐÔÖ»ÓÐÔÚÌØ¶¨µÄÅäÖÃÎļþ±»¼¤»îʱ²ÅÏà¹Ø¡£
+
+
+
+
+
+Äã¿ÉÒÔʹÓà `spring.config.activation.*` ÓÐÌõ¼þµØ¼¤»îÒ»¸öÊôÐÔÎļþ¡£
+
+
+
+
+
+¼¤»îÊôÐÔÓÐÈçÏ¡£
+
+
+
+Table 2\. activation properties
+| ÊôÐÔ | ˵Ã÷ |
+| --- | --- |
+| `on-profile` | Ò»¸ö±ØÐëÓë֮ƥÅäµÄÅäÖÃÎļþ±í´ïʽ£¬ÒÔʹÎļþ´¦Óڻ״̬£¨¼¤»îÖ¸¶¨µÄÅäÖÃÎļþʱÓÐЧ£©¡£ |
+| `on-cloud-platform` | ±ØÐë¼ì²âµ½µÄ `CloudPlatform`£¬ÒÔʹÎļþ´¦Óڻ״̬¡££¨ÔÆÆ½Ì¨×´Ì¬ÏÂÓÐЧ£© |
+
+
+
+ÀýÈ磬ÏÂÃæÖ¸¶¨µÚ¶þ¸öÎļþÖ»ÓÐÔÚKubernetesÉÏÔËÐÐʱ²ÅÓÐЧ£¬²¢ÇÒÖ»ÓÐÔÚ ¡°prod¡± »ò ¡°staging¡± ÅäÖÃÎļþ´¦Óڻ״̬ʱ²ÅÓÐЧ¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+myprop=always-set
+#---
+spring.config.activate.on-cloud-platform=kubernetes
+spring.config.activate.on-profile=prod | staging
+myotherprop=sometimes-set
+
+```
+
+
+
+
+
+
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/features.html#features.external-config.encrypting)2.4\. ¼ÓÃÜÅäÖÃÊôÐÔ£¨Encrypting Properties£©
+
+
+
+Spring BootûÓÐΪ¼ÓÃÜÊôÐÔÖµÌṩÈκÎÄÚÖÃÖ§³Ö£¬µ«ËüÌṩÁËHookm£¬¿ÉÒÔÓÃÀ´ÐÞ¸ÄSpring `Environment` Öаüº¬µÄÖµ¡£ `EnvironmentPostProcessor` ½Ó¿ÚÔÊÐíÄãÔÚÓ¦ÓóÌÐòÆô¶¯Ç°²Ù×÷ `Environment`¡£ ²Î¼û[howto.html](https://springdoc.cn/spring-boot/howto.html#howto.application.customize-the-environment-or-application-context)ÒÔÁ˽âÏêÇé¡£
+
+
+
+
+
+Èç¹ûÄãÐèÒªÒ»ÖÖ°²È«µÄ·½Ê½À´´æ´¢Æ¾Ö¤ºÍÃÜÂ룬 [Spring Cloud Vault](https://cloud.spring.io/spring-cloud-vault/) ÏîÄ¿ÌṩÁ˶ÔÔÚ [HashiCorp Vault](https://www.vaultproject.io/)Öд洢Íⲿ»¯ÅäÖõÄÖ§³Ö¡£
+
+
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/features.html#features.external-config.yaml)2.5\. ʹÓà YAML
+
+
+
+[YAML](https://yaml.org/) ÊÇJSONµÄ³¬¼¯£¬Òò´ËÊÇÖ¸¶¨·Ö²ãÅäÖÃÊý¾ÝµÄ·½±ã¸ñʽ¡£ Ö»ÒªÄãµÄclasspathÉÏÓÐ [SnakeYAML](https://github.com/snakeyaml/snakeyaml) ¿â£¬`SpringApplication` Àà¾Í»á×Ô¶¯Ö§³ÖYAML×÷ΪpropertiesµÄÌæ´úÆ·¡£
+
+
+
+
+
+| | Èç¹ûÄãʹÓà ¡°Starter¡±£¬SnakeYAML½«ÓÉ `spring-boot-starter` ×Ô¶¯Ìṩ¡£ |
+| --- | --- |
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/features.html#features.external-config.yaml.mapping-to-properties)2.5.1\. ½«YAMLÓ³Éäµ½Properties
+
+
+
+YAML ÎĵµÐèÒª´ÓÆä·Ö²ã¸ñʽת»»Îª¿ÉÓë Spring `Environment` Ò»ÆðʹÓÃµÄ±âÆ½½á¹¹¡£ ÀýÈ磬¿¼ÂÇÏÂÃæÕâ¸öYAMLÎĵµ¡£
+
+
+
+
+
+
+
+```
+environments:
+ dev:
+ url: "https://dev.example.com"
+ name: "Developer Setup"
+ prod:
+ url: "https://another.example.com"
+ name: "My Cool App"
+```
+
+
+
+
+
+
+
+ΪÁË´Ó `Environment` ÖзÃÎÊÕâЩÊôÐÔ£¬ËüÃǽ«±»±âƽ»¯£¬ÈçÏÂËùʾ¡£
+
+
+
+
+
+
+
+```
+environments.dev.url=https://dev.example.com
+environments.dev.name=Developer Setup
+environments.prod.url=https://another.example.com
+environments.prod.name=My Cool App
+```
+
+
+
+
+
+
+
+ͬÑùµØ£¬YAMLÖеÄÁбíÒ²ÐèÒª½øÐÐ±âÆ½»¯´¦Àí¡£ ËüÃDZ»±íʾΪ´øÓÐ `[index]` Ë÷ÒýµÄkey¡£ ÀýÈ磬¿¼ÂÇÏÂÃæµÄYAML¡£
+
+
+
+
+
+
+
+```
+my:
+ servers:
+ - "dev.example.com"
+ - "another.example.com"
+```
+
+
+
+
+
+
+
+Ç°ÃæµÄÀý×Ó½«±»×ª»¯ÎªÈçÏÂÊôÐÔ¡£
+
+
+
+
+
+
+
+```
+my.servers[0]=dev.example.com
+my.servers[1]=another.example.com
+```
+
+
+
+
+
+
+
+| | ʹÓà `[index]` ·ûºÅµÄÊôÐÔ¿ÉÒÔʹÓÃSpring BootµÄ `Binder` Àà°ó¶¨µ½Java `List` »ò `Set` ¶ÔÏó¡£ ¸ü¶àϸ½Ú¼ûÏÂÃæµÄ ¡°[ÀàÐͰ²È«µÄÅäÖÃÊôÐÔ](https://springdoc.cn/spring-boot/features.html#features.external-config.typesafe-configuration-properties)¡± ²¿·Ö¡£ |
+| --- | --- |
+
+
+
+
+
+| | YAMLÎļþ²»ÄÜͨ¹ýʹÓà `@PropertySource` »ò `@TestPropertySource` ×¢½âÀ´¼ÓÔØ¡£ ËùÒÔ£¬ÔÚÄãÐèÒªÒÔÕâÖÖ·½Ê½¼ÓÔØÖµµÄÇé¿öÏ£¬ÄãÐèҪʹÓÃÒ»¸ö properties Îļþ¡£ |
+| --- | --- |
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/features.html#features.external-config.yaml.directly-loading)2.5.2\. Ö±½Ó¼ÓÔØYAML
+
+
+
+Spring FrameworkÌṩÁËÁ½¸ö·½±ãµÄÀ࣬¿ÉÒÔÓÃÀ´¼ÓÔØYAMLÎĵµ¡£ `YamlPropertiesFactoryBean` ½«YAML×÷Ϊ `Properties` ¼ÓÔØ£¬`YamlMapFactoryBean` ½«YAML×÷Ϊ `Map` ¼ÓÔØ¡£
+
+
+
+
+
+Èç¹ûÄãÏë°ÑYAML¼ÓÔØÎªSpringµÄ `PropertySource` £¬ÄãÒ²¿ÉÒÔʹÓà `YamlPropertySourceLoader` Àà¡£
+
+
+
+
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/features.html#features.external-config.random-values)2.6\. ÅäÖÃËæ»úÖµ
+
+
+
+The `RandomValuePropertySource` is useful for injecting random values (for example, into secrets or test cases). It can produce integers, longs, uuids, or strings, as shown in the following example:
+
+
+
+
+
+`RandomValuePropertySource` ¶ÔÓÚ×¢ÈëËæ»úÖµºÜÓÐÓã¨ÀýÈ磬עÈëÃÜÂë»ò²âÊÔ°¸Àý£©¡£ Ëü¿ÉÒÔ²úÉúInteger¡¢Long¡¢UUID£¬»òString£¬ÈçÏÂÃæµÄÀý×ÓËùʾ¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+my.secret=${random.value}
+my.number=${random.int}
+my.bignumber=${random.long}
+my.uuid=${random.uuid}
+my.number-less-than-ten=${random.int(10)}
+my.number-in-range=${random.int[1024,65536]}
+
+```
+
+
+
+
+
+
+
+`random.int*` µÄÓï·¨ÊÇ `OPEN value (,max) CLOSE`£¬ÆäÖÐ `OPEN,CLOSE` ÊÇÈκÎ×Ö·û£¬ `value,max` ÊÇÕûÊý¡£ Èç¹ûÌṩÁË `max`£¬ÄÇô `value` ÊÇ×îСֵ£¬ `max` ÊÇ×î´óÖµ£¨¶ÀÕ¼£©¡£
+
+
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/features.html#features.external-config.system-environment)2.7\. ÅäÖÃϵͳ»·¾³ÊôÐÔ
+
+
+
+Spring BootÖ§³ÖΪ»·¾³ÊôÐÔÉèÖÃÒ»¸öǰ׺¡£ Èç¹ûϵͳ»·¾³±»¶à¸ö¾ßÓв»Í¬ÅäÖÃÒªÇóµÄSpring BootÓ¦ÓóÌÐò¹²Ïí£¬Õâ¾ÍºÜÓÐÓᣠϵͳ»·¾³ÊôÐÔµÄǰ׺¿ÉÒÔÖ±½ÓÔÚ `SpringApplication` ÉÏÉèÖá£
+
+
+
+
+
+ÀýÈ磬Èç¹ûÄ㽫ǰ׺ÉèÖÃΪ `input` £¬ÖîÈç `remote.timeout` ÕâÑùµÄÊôÐÔÔÚϵͳ»·¾³ÖÐÒ²½«±»½âÎöΪ `input.remote.timeout`¡£
+
+
+
+
+
+
+
+### [](https://springdoc.cn/spring-boot/features.html#features.external-config.typesafe-configuration-properties)2.8\. ÀàÐͰ²È«µÄÅäÖÃÊôÐÔ
+
+
+
+ʹÓà `@Value("${property}")` ×¢½âÀ´×¢ÈëÅäÖÃÊôÐÔÓÐʱ»áºÜÂé·³£¬ÌرðÊǵ±ÄãÒª´¦Àí¶à¸öÊôÐÔ»òÄãµÄÊý¾ÝÊÇ·Ö²ãµÄ¡£ Spring BootÌṩÁËÒ»ÖÖ´¦ÀíÊôÐÔµÄÌæ´ú·½·¨£¬ÈÃÇ¿ÀàÐ͵ÄBean¹ÜÀíºÍÑéÖ¤ÄãµÄÓ¦ÓóÌÐòµÄÅäÖá£
+
+
+
+
+
+| | ÁíÇë²Î¼û[`@Value` ºÍÀàÐͰ²È«ÅäÖÃÊôÐÔÖ®¼äµÄÇø±ð](https://springdoc.cn/spring-boot/features.html#features.external-config.typesafe-configuration-properties.vs-value-annotation)¡£ |
+| --- | --- |
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/features.html#features.external-config.typesafe-configuration-properties.java-bean-binding)2.8.1\. JavaBean ÊôÐÔ°ó¶¨
+
+
+
+ÈçÏÂÃæµÄÀý×ÓËùʾ£¬¿ÉÒÔ°ó¶¨Ò»¸öÉùÃ÷Á˱ê×¼JavaBeanÊôÐÔµÄbean¡£
+
+
+
+
+
+
+
+Java
+
+Kotlin
+
+
+
+
+
+```
+@ConfigurationProperties("my.service")
+public class MyProperties {
+
+ private boolean enabled;
+
+ private InetAddress remoteAddress;
+
+ private final Security security = new Security();
+
+ // getters / setters...
+
+ public static class Security {
+
+ private String username;
+
+ private String password;
+
+ private List roles = new ArrayList<>(Collections.singleton("USER"));
+
+ // getters / setters...
+
+ }
+
+}
+
+```
+
+
+
+
+
+
+
+Ç°ÃæµÄPOJO¶¨ÒåÁËÒÔÏÂÊôÐÔ¡£
+
+
+
+
+
+* `my.service.enabled`£¬Ä¬ÈÏֵΪ`false`¡£
+
+* `my.service.remote-address`£¬ÆäÀàÐÍ¿ÉÓÉ`String`Ç¿ÖÆÌṩ¡£
+
+* `my.service.security.username`£¬ÓÐÒ»¸öǶÌ×µÄ `security` ¶ÔÏ󣬯äÃû³ÆÓɸÃÊôÐÔµÄÃû³Æ¾ö¶¨¡£ ÌØ±ðÊÇ£¬ÄÇÀïÍêȫûÓÐʹÓÃÀàÐÍ£¬¿ÉÒÔÊÇ `SecurityProperties`¡£
+
+* `my.service.security.password`.
+
+* `my.service.security.role`£¬ÓÐÒ»¸ö `String` µÄ¼¯ºÏ£¬Ä¬ÈÏΪ `USER`¡£
+
+
+
+
+
+| | Ó³Éäµ½Spring BootÖпÉÓÃµÄ `@ConfigurationProperties` ÀàµÄÊôÐÔ£¬Í¨¹ýpropertiesÎļþ¡¢YAMLÎļþ¡¢»·¾³±äÁ¿ºÍÆäËû»úÖÆ½øÐÐÅäÖã¬ÕâЩÊôÐÔÊǹ«¹²API£¬µ«Àà±¾ÉíµÄ getters/setters ²¢²»Òâζ×Å¿ÉÒÔÖ±½ÓʹÓã¨Ò»¾ä»°£¬SpringÒ²ÊÇͨ¹ýgetter/setterÕâЩpublic·½·¨½øÐÐÉèÖÃÖµµÄ£¬Äã±ðÓã©¡£ |
+| --- | --- |
+
+
+
+
+
+| | ÕâÑùµÄÉè¼ÆÒÀÀµÓÚÒ»¸öĬÈϵÄÎ޲ι¹Ô캯Êý£¬getterºÍsetterͨ³£ÊDZØÐëµÄ£¬ÒòΪ°ó¶¨ÊÇͨ¹ý±ê×¼µÄJava Beans property descriptor£¨JavaÄÚÊ¡£©ÊµÏֵ쬾ÍÏñÔÚSpring MVCÖÐÒ»Ñù¡£ ÔÚÒÔÏÂÇé¿öÏ£¬¿ÉÒÔÊ¡ÂÔsetter¡£* Map, Ö»ÒªËüÃDZ»³õʼ»¯£¬¾ÍÐèÒªÒ»¸ögetter£¬µ«²»Ò»¶¨ÐèÒªÒ»¸ösetter£¬ÒòΪËüÃÇ¿ÉÒÔ±»°ó¶¨Æ÷Í»±ä¡£ * CollectionºÍarray ¿ÉÒÔͨ¹ýË÷Òý£¨Í¨³£ÓÃYAML£©»òʹÓõ¥¸ö¶ººÅ·Ö¸ôµÄÖµ£¨ÊôÐÔ£©À´·ÃÎÊ¡£ ÔÚºóÒ»ÖÖÇé¿öÏ£¬Ò»¸ösetterÊDZØÐëµÄ¡£ ÎÒÃǽ¨Òé×ÜÊÇΪÕâÀàÀàÐÍÌí¼ÓÒ»¸ösetter¡£ Èç¹ûÄã³õʼ»¯Ò»¸ö¼¯ºÏ£¬È·±£Ëü²»ÊDz»¿É±äµÄ£¨ÈçÇ°ÃæµÄÀý×Ó£©¡£ * Èç¹ûǶÌ×µÄPOJOÊôÐÔ±»³õʼ»¯£¨¾ÍÏñÇ°ÃæÀý×ÓÖÐµÄ `Security` ×ֶΣ©£¬¾Í²»ÐèÒªsetter¡£ Èç¹ûÄãÏëÈÃ°ó¶¨Æ÷ͨ¹ýʹÓÃËüµÄĬÈϹ¹Ô캯ÊýÀ´¼´Ê±´´½¨ÊµÀý£¬ÄãÐèÒªÒ»¸ösetter¡£ ÓÐЩÈËʹÓÃProject LombokÀ´×Ô¶¯Ìí¼ÓgetterºÍsetter¡£ ÇëÈ·±£Lombok²»»áΪÕâÑùµÄÀàÐÍÉú³ÉÈκÎÌØ¶¨µÄ¹¹Ô캯Êý£¬ÒòΪËü±»ÈÝÆ÷×Ô¶¯ÓÃÀ´ÊµÀý»¯¶ÔÏó¡£×îºó£¬Ö»¿¼ÂDZê×¼µÄJava BeanÊôÐÔ£¬²»Ö§³Ö¶Ô¾²Ì¬ÊôÐԵİ󶨡£ |
+| --- | --- |
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/features.html#features.external-config.typesafe-configuration-properties.constructor-binding)2.8.2\. ¹¹Ô캯Êý°ó¶¨
+
+
+
+ÉÏÒ»½ÚµÄÀý×Ó¿ÉÒÔÓò»¿É±äµÄ·½Ê½ÖØÐ´£¬ÈçÏÂÀýËùʾ¡£
+
+
+
+
+
+
+
+Java
+
+Kotlin
+
+
+
+
+
+```
+@ConfigurationProperties("my.service")
+public class MyProperties {
+
+ // fields...
+
+ public MyProperties(boolean enabled, InetAddress remoteAddress, Security security) {
+ this.enabled = enabled;
+ this.remoteAddress = remoteAddress;
+ this.security = security;
+ }
+
+ // getters...
+
+ public static class Security {
+
+ // fields...
+
+ public Security(String username, String password, @DefaultValue("USER") List roles) {
+ this.username = username;
+ this.password = password;
+ this.roles = roles;
+ }
+
+ // getters...
+
+ }
+
+}
+
+```
+
+
+
+
+
+
+
+ÔÚÕâÖÖÉèÖÃÖУ¬Î¨Ò»µÄ¡°´ø²ÎÊý¹¹Ô캯Êý¡±µÄ´æÔÚÒâζ×ÅÓ¦¸ÃʹÓøù¹Ô캯Êý½øÐа󶨡£ ÕâÒâζ×Ű󶍯÷»áÕÒµ½Ò»¸ö´øÓÐÄãÏ£Íû°ó¶¨µÄ²ÎÊýµÄ¹¹Ô캯Êý¡£ Èç¹ûÄãµÄÀàÓжà¸ö¹¹Ô캯Êý£¬¿ÉÒÔʹÓà `@ConstructorBinding` ×¢½âÀ´Ö¸¶¨Ê¹ÓÃÄĸö¹¹Ô캯Êý½øÐй¹Ô캯Êý°ó¶¨¡£ Èç¹ûҪΪһ¸öÖ»ÓÐÒ»¸ö¡°´ø²ÎÊý¹¹Ô캯Êý¡±µÄÀàÑ¡Ôñ²»°ó¶¨¹¹Ô캯Êý£¬¸Ã¹¹Ô캯Êý±ØÐëÓà `@Autowired` À´×¢½â¡£ ¹¹Ô캯Êý°ó¶¨¿ÉÒÔÓë `Record` Ò»ÆðʹÓᣠ³ý·ÇÄãµÄ¼Ç¼Óжà¸ö¹¹Ô캯Êý£¬·ñÔòûÓбØÒªÊ¹Óà `@ConstructorBinding`¡£
+
+
+
+
+
+¹¹Ô캯Êý°ó¶¨ÀàµÄǶÌ׳ÉÔ±£¨ÈçÉÏÃæÀý×ÓÖÐµÄ `Security`£©Ò²½«Í¨¹ýÆä¹¹Ô캯Êý±»°ó¶¨¡£
+
+
+
+
+
+ĬÈÏÖµ¿ÉÒÔÔÚ¹¹Ô캯Êý²ÎÊýºÍRecord×é¼þÉÏʹÓà `@DefaultValue` À´Ö¸¶¨¡£ ת»»·þÎñ½«±»Ó¦ÓÃÓÚ½«×¢½âµÄ `String` ÖµÇ¿ÖÆ×ª»»ÎªÈ±Ê§ÊôÐÔµÄÄ¿±êÀàÐÍ¡£
+
+
+
+
+
+²Î¿¼Ç°ÃæµÄÀý×Ó£¬Èç¹ûûÓÐÊôÐ԰󶨵½ `Security` £¬ `MyProperties` ʵÀý½«°üº¬Ò»¸ö `security` ÀàÐ굀 `null` Öµ¡£ ΪÁËʹËü°üº¬Ò»¸ö·Ç null µÄ `Security` ʵÀý£¬¼´Ê¹Ã»ÓÐÊôÐÔÓëÖ®°ó¶¨£¨µ±Ê¹ÓÃKotlinʱ£¬Õ⽫ҪÇó `Security` µÄ `username` ºÍ `password` ²ÎÊý±»ÉùÃ÷Ϊ nullable£¬ÒòΪËüÃÇûÓÐĬÈÏÖµ£©£¬Ê¹ÓÃÒ»¸ö¿ÕµÄ `@DefaultValue` ×¢½â¡£
+
+
+
+
+
+
+
+Java
+
+Kotlin
+
+
+
+
+
+```
+public MyProperties(boolean enabled, InetAddress remoteAddress, @DefaultValue Security security) {
+ this.enabled = enabled;
+ this.remoteAddress = remoteAddress;
+ this.security = security;
+}
+
+```
+
+
+
+
+
+
+
+| | ҪʹÓù¹Ô캯Êý°ó¶¨£¬¸ÃÀà±ØÐëʹÓà `@EnableConfigurationProperties` »òÅäÖÃÊôÐÔɨÃèÀ´ÆôÓᣠÄã²»ÄܶÔͨ¹ý³£¹æSpring»úÖÆ´´½¨µÄBeanʹÓù¹Ô캯Êý°ó¶¨£¨ÀýÈç `@Component` Bean£¬Í¨¹ýʹÓà `@Bean` ·½·¨´´½¨µÄBean»òͨ¹ýʹÓà `@Import` ¼ÓÔØµÄBean£©¡£ |
+| --- | --- |
+
+
+
+
+
+| | ÒªÔÚÔÉú¾µÏñÖÐʹÓù¹Ô캯Êý°ó¶¨£¬±ØÐëÓà `-parameters` ²ÎÊý±àÒë¸ÃÀà¡£Èç¹ûÄãʹÓà Spring Boot µÄ Gradle ²å¼þ»òʹÓà Maven ºÍ `spring-boot-starter-parent`£¬Õ⽫×Ô¶¯ÅäÖᣠ|
+| --- | --- |
+
+
+
+
+
+| | ²»½¨Ò齫 `java.util.Optional` Óë `@ConfigurationProperties` Ò»ÆðʹÓã¬ÒòΪËüÖ÷ÒªÊÇ×÷Ϊһ¸ö·µ»ØÀàÐÍʹÓᣠÒò´Ë£¬Ëü²¢²»ÊʺÏÅäÖÃÊôÐÔ×¢Èë¡£ ΪÁËÓëÆäËûÀàÐ͵ÄÊôÐÔ±£³ÖÒ»Ö£¬Èç¹ûÄãȷʵÉùÃ÷ÁËÒ»¸ö `Optional` ÊôÐÔ£¬µ«ËüûÓÐÖµ£¬`null` ¶ø²»ÊÇÒ»¸ö¿ÕµÄ `Optional` ½«±»°ó¶¨¡£ |
+| --- | --- |
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/features.html#features.external-config.typesafe-configuration-properties.enabling-annotated-types)2.8.3\. ÆôÓÃ @ConfigurationProperties Àà
+
+
+
+Spring BootÌṩÁË°ó¶¨ `@ConfigurationProperties` ÀàÐͲ¢½«Æä×¢²áΪBeanµÄ»ù´¡ÉèÊ©¡£ Äã¿ÉÒÔÔÚÖð¸öÀàµÄ»ù´¡ÉÏÆôÓÃÅäÖÃÊôÐÔ£¬»òÕ߯ôÓÃÅäÖÃÊôÐÔɨÃ裬Æä¹¤×÷·½Ê½Óë×é¼þɨÃèÀàËÆ¡£
+
+
+
+
+
+ÓÐʱ£¬Óà `@ConfigurationProperties` ×¢½âµÄÀà¿ÉÄܲ»ÊʺÏɨÃ裬ÀýÈ磬Èç¹ûÄãÕýÔÚ¿ª·¢Äã×Ô¼ºµÄ×Ô¶¯ÅäÖûòÕßÄãÏëÓÐÌõ¼þµØÆôÓÃËüÃÇ¡£ ÔÚÕâЩÇé¿öÏ£¬Ê¹Óà `@EnableConfigurationProperties` ×¢½âÖ¸¶¨Òª´¦ÀíµÄÀàÐÍÁÐ±í£¬ Ëü¿ÉÒÔ×¢½âÔÚÈκΠ`@Configuration` ÀàÉÏ£¬ÈçÏÂÃæµÄÀý×ÓËùʾ¡£
+
+
+
+
+
+
+
+Java
+
+Kotlin
+
+
+
+
+
+```
+@Configuration(proxyBeanMethods = false)
+@EnableConfigurationProperties(SomeProperties.class)
+public class MyConfiguration {
+
+}
+
+```
+
+
+
+
+
+
+
+
+
+Java
+
+Kotlin
+
+
+
+
+
+```
+@ConfigurationProperties("some.properties")
+public class SomeProperties {
+
+}
+
+```
+
+
+
+
+
+
+
+ҪʹÓÃÅäÖÃÊôÐÔɨÃ裬ÇëÏòÄãµÄapplicationÌí¼Ó `@ConfigurationPropertiesScan` ×¢½â¡£ ͨ³££¬Ëü±»Ìí¼Óµ½Óà `@SpringBootApplication` ×¢½âµÄmainÀàÖУ¬µ«ËüÒ²¿ÉÒÔ±»Ìí¼Óµ½ÈκΠ`@Configuration` ÀàÉÏ¡£ ĬÈÏÇé¿öÏ£¬É¨Ãè»á´Ó×¢½âËùÔڵİü¿ªÊ¼£¬ÄãÈç¹ûÏë×Ô¶¨ÒåɨÃèÆäËû°ü£¬¿ÉÒԲο¼ÈçÏ¡£
+
+
+
+
+
+
+
+Java
+
+Kotlin
+
+
+
+
+
+```
+@SpringBootApplication
+@ConfigurationPropertiesScan({ "com.example.app", "com.example.another" })
+public class MyApplication {
+
+}
+
+```
+
+
+
+
+
+
+
+| | µ± `@ConfigurationProperties` BeanʹÓÃÅäÖÃÊôÐÔɨÃè»òͨ¹ý `@EnableConfigurationProperties` ×¢²áʱ£¬¸ÃBeanÓÐÒ»¸ö³£¹æÃû³Æ£º`-`£¬ÆäÖÐ `` ÊÇ `@ConfigurationProperties` ×¢½âÖÐÖ¸¶¨µÄ»·¾³¼üǰ׺£¬ `` ÊÇBeanµÄÍêÈ«ÏÞ¶¨Ãû³Æ¡£ Èç¹û×¢½âûÓÐÌṩÈκÎǰ׺£¬ÔòֻʹÓÃBeanµÄÍêÈ«ÏÞ¶¨Ãû³Æ¡£¼ÙÉèËüÔÚ `com.example.app` °üÖУ¬ÉÏÃæµÄ `SomeProperties` Àý× bean Ãû³ÆÊÇ `some.properties-com.example.app.SomeProperties`¡£ |
+| --- | --- |
+
+
+
+
+
+ÎÒÃǽ¨Òé `@ConfigurationProperties` Ö»´¦Àí environment£¬ÌرðÊDz»´ÓÉÏÏÂÎÄ×¢ÈëÆäËûBean¡£ ¶ÔÓڱ߽ǰ¸Àý£¨ÌØÊâÇé¿ö£©£¬¿ÉÒÔʹÓà setter ×¢Èë»ò¿ò¼ÜÌṩµÄÈκΠ`*Aware` ½Ó¿Ú£¨Èç `EnvironmentAware` £¬Èç¹ûÄãÐèÒª·ÃÎÊ `Environment`£©¡£ Èç¹ûÄãÈÔÈ»ÏëʹÓù¹ÔìÆ÷×¢ÈëÆäËûBean£¬ÅäÖÃÊôÐÔBean±ØÐëÓà `@Component` À´×¢½â£¬²¢Ê¹ÓûùÓÚJavaBeanµÄÊôÐ԰󶨡£
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/features.html#features.external-config.typesafe-configuration-properties.using-annotated-types)2.8.4\. ʹÓà @ConfigurationProperties Àà
+
+
+
+ÕâÖÖÅäÖ÷½Ê½Óë `SpringApplication` ÍⲿYAMLÅäÖÃÅäºÏµÃÌØ±ðºÃ£¬ÈçÒÔÏÂÀý×ÓËùʾ¡£
+
+
+
+
+
+
+
+```
+my:
+ service:
+ remote-address: 192.168.1.1
+ security:
+ username: "admin"
+ roles:
+ - "USER"
+ - "ADMIN"
+```
+
+
+
+
+
+
+
+ҪʹÓà `@ConfigurationProperties` Bean£¬Äã¿ÉÒÔÓÃÓëÆäËûBeanÏàͬµÄ·½Ê½×¢ÈëËüÃÇ£¬ÈçÏÂÀýËùʾ¡£
+
+
+
+
+
+
+
+Java
+
+Kotlin
+
+
+
+
+
+```
+@Service
+public class MyService {
+
+ private final MyProperties properties;
+
+ public MyService(MyProperties properties) {
+ this.properties = properties;
+ }
+
+ public void openConnection() {
+ Server server = new Server(this.properties.getRemoteAddress());
+ server.start();
+ // ...
+ }
+
+ // ...
+
+}
+
+```
+
+
+
+
+
+
+
+| | ʹÓà `@ConfigurationProperties` »¹¿ÉÒÔÈÃÄãÉú³ÉÔªÊý¾ÝÎļþ£¬ÕâЩÎļþ¿ÉÒÔ±»IDEÓÃÀ´ÅäÖÃÊôÐԵġ°×Ô¶¯²¹È«¡±¹¦ÄÜ¡£ ÏêÇé¼û[¸½Â¼](https://springdoc.cn/spring-boot/configuration-metadata.html#appendix.configuration-metadata)¡£ |
+| --- | --- |
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/features.html#features.external-config.typesafe-configuration-properties.third-party-configuration)2.8.5\. µÚÈý·½ÅäÖÃ
+
+
+
+³ýÁËʹÓà `@ConfigurationProperties` À´×¢½âÒ»¸öÀàÖ®Í⣬Ä㻹¿ÉÒÔÔÚ¹«¹²µÄ `@Bean` ·½·¨ÉÏʹÓÃËü¡£ µ±ÄãÏë°ÑÊôÐ԰󶨵½Äã¿ØÖÆÖ®ÍâµÄµÚÈý·½×é¼þʱ£¬ÕâÑù×öÌØ±ðÓÐÓá£
+
+
+
+
+
+Òª´Ó `Environment` ÊôÐÔÖÐÅäÖÃÒ»¸öBean£¬ÇëÔÚÆäBean×¢²áÖÐÌí¼Ó `@ConfigurationProperties` £¬ÈçÏÂÀýËùʾ¡£
+
+
+
+
+
+
+
+Java
+
+Kotlin
+
+
+
+
+
+```
+@Configuration(proxyBeanMethods = false)
+public class ThirdPartyConfiguration {
+
+ @Bean
+ @ConfigurationProperties(prefix = "another")
+ public AnotherComponent anotherComponent() {
+ return new AnotherComponent();
+ }
+
+}
+
+```
+
+
+
+
+
+
+
+ÈκÎÓà `another` ǰ׺¶¨ÒåµÄJavaBeanÊôÐÔ¶¼»á±»Ó³Éäµ½ `AnotherComponent` BeanÉÏ£¬Æä·½Ê½ÀàËÆÓÚÇ°ÃæµÄ `SomeProperties` Àý×Ó¡£
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/features.html#features.external-config.typesafe-configuration-properties.relaxed-binding)2.8.6\. ¿íËɵİó¶¨
+
+
+
+Spring BootÔÚ½« `Environment` ÊôÐ԰󶨵½ `@ConfigurationProperties` beanʱʹÓÃÁËһЩ¿íËɵĹæÔò£¬Òò´Ë `Environment` ÊôÐÔÃû³ÆºÍbeanÊôÐÔÃû³ÆÖ®¼ä²»ÐèÒªÍêȫƥÅä¡£ ÕâºÜÓÐÓ㬳£¼ûµÄÀý×Ó°üÀ¨ÆÆÕۺŷָôµÄÊôÐÔÃû³Æ£¨ÀýÈ磬 `context-path` °ó¶¨µ½ `contextPath` £©£¬ºÍ´óдµÄÊôÐÔÃû³Æ£¨ÀýÈ磬`PORT` °ó¶¨µ½ `port` £©¡£
+
+
+
+
+
+ÑÝʾһ¸öÀý×Ó£¬¿¼ÂÇÒÔÏ `@ConfigurationProperties` Àà¡£
+
+
+
+
+
+
+
+Java
+
+Kotlin
+
+
+
+
+
+```
+@ConfigurationProperties(prefix = "my.main-project.person")
+public class MyPersonProperties {
+
+ private String firstName;
+
+ public String getFirstName() {
+ return this.firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+}
+
+```
+
+
+
+
+
+
+
+¶ÔÒÔÉϵĴúÂëÀ´Ëµ£¬ÒÔϵÄÊôÐÔÃû³Æ¶¼¿ÉÒÔʹÓá£
+
+
+
+Table 3\. relaxed binding
+| Property | Note |
+| --- | --- |
+| `my.main-project.person.first-name` | Kebab ·ç¸ñ£¨¶ÌºáÏ߸ô¿ª£©£¬½¨ÒéÔÚ `.properties` ºÍ `.yml` ÎļþÖÐʹÓᣠ|
+| `my.main-project.person.firstName` | ±ê×¼µÄÍÕ·åÓï·¨¡£ |
+| `my.main-project.person.first_name` | Ï»®Ïߣ¬ÕâÊÇÒ»ÖÖÓÃÓÚ `.properties` ºÍ `.yml` ÎļþµÄÌæ´ú¸ñʽ¡£ |
+| `MY_MAINPROJECT_PERSON_FIRSTNAME` | ´óд¸ñʽ£¬ÔÚʹÓÃϵͳ»·¾³±äÁ¿Ê±½¨ÒéʹÓôóд¸ñʽ¡£ |
+
+
+
+| | ×¢½âµÄ `prefix` Öµ _±ØÐë_ ÊÇkebab·ç¸ñ£¨Ð¡Ð´²¢ÒÔ `-` ·Ö¸ô£¬Èç `my.main-project.person` £©¡£ |
+| --- | --- |
+
+
+
+Table 4\. ÿÖÖÊôÐÔÔ´µÄ¿íËɰ󶨹æÔò
+| ÊôÐÔÔ´ | ¼òµ¥µÄ | Áбí |
+| --- | --- | --- |
+| Properties Îļþ | ÍÕ·å, kebab , Ï»®Ïß | ʹÓà `[ ]` »ò¶ººÅ·Ö¸ôÖµµÄ±ê×¼ÁбíÓï·¨ |
+| YAML Îļþ | ÍÕ·å, kebab , Ï»®Ïß | ±ê×¼YAMLÁбíÓï·¨»ò¶ººÅ·Ö¸ôµÄÖµ |
+| »·¾³±äÁ¿ | ´óд£¬Ï»®ÏßΪ·Ö¸ô·û(¼û [´Ó»·¾³±äÁ¿°ó¶¨](https://springdoc.cn/spring-boot/features.html#features.external-config.typesafe-configuration-properties.relaxed-binding.environment-variables)). | Numeric values surrounded by underscores (see [´Ó»·¾³±äÁ¿°ó¶¨](https://springdoc.cn/spring-boot/features.html#features.external-config.typesafe-configuration-properties.relaxed-binding.environment-variables)) |
+| ϵͳÊôÐÔ£¨System properties£© | ÍÕ·å, kebab , Ï»®Ïß | ʹÓà `[ ]` »ò¶ººÅ·Ö¸ôÖµµÄ±ê×¼ÁбíÓï·¨ |
+
+
+
+| | ÎÒÃǽ¨Ò飬ÔÚ¿ÉÄܵÄÇé¿öÏ£¬ÊôÐÔÓ¦ÒÔСдµÄkebab¸ñʽ´æ´¢£¬ÀýÈç `my.person.first-name=Rod` ¡£ |
+| --- | --- |
+
+
+
+
+
+##### [](https://springdoc.cn/spring-boot/features.html#features.external-config.typesafe-configuration-properties.relaxed-binding.maps)°ó¶¨Map
+
+
+
+µ±°ó¶¨µ½ `Map` ÊôÐÔʱ£¬Äã¿ÉÄÜÐèҪʹÓÃÒ»¸öÌØÊâµÄÀ¨ºÅ·ûºÅ£¬ÒԱ㱣ÁôÔʼµÄ `key` Öµ¡£ Èç¹ûkeyûÓб» `[ ]` °ü¹ü£¬ÈκηÇ×ÖĸÊý×Ö¡¢`-` »ò `.` µÄ×Ö·û½«±»É¾³ý¡£
+
+
+
+
+
+ÀýÈ磬¿¼Âǽ«ÒÔÏÂÊôÐ԰󶨵½Ò»¸ö `Map`¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+my.map.[/key1]=value1
+my.map.[/key2]=value2
+my.map./key3=value3
+```
+
+
+
+
+
+
+
+| | ¶ÔÓÚYAMLÎļþ£¬À¨ºÅÐèÒªÓÃÒýºÅ°ü¹ü£¬ÒÔʹkey±»ÕýÈ·½âÎö¡£ |
+| --- | --- |
+
+
+
+
+
+ÉÏÃæµÄÊôÐÔ½«°ó¶¨µ½Ò»¸ö `Map` £¬`/key1`£¬`/key2` ºÍ `key3` ×÷ΪmapµÄkey¡£ бÏßÒѾ´Ó `key3` ÖÐɾ³ý£¬ÒòΪËüûÓб»·½À¨ºÅ°ü¹ü¡£
+
+
+
+
+
+µ±°ó¶¨µ½±êÁ¿ÖµÊ±£¬´øÓÐ `.` µÄ¼ü²»ÐèÒªÓà `[]` °ü¹ü¡£ ±êÁ¿Öµ°üÀ¨Ã¶¾ÙºÍËùÓÐ `java.lang` °üÖеÄÀàÐÍ£¬³ýÁË `Object` ¡£ ½« `a.b=c` °ó¶¨µ½ `Map` ½«±£Áô¼üÖÐµÄ `.` £¬²¢·µ»ØÒ»¸ö´øÓÐ `{"a.b"="c"}` EntryµÄMap¡£ ¶ÔÓÚÈÎºÎÆäËûÀàÐÍ£¬Èç¹ûÄãµÄ `key` °üº¬ `.` £¬ÄãÐèҪʹÓÃÀ¨ºÅ·ûºÅ¡£ ÀýÈ磬½« `a.b=c` °ó¶¨µ½ `Map` ½«·µ»ØÒ»¸ö´øÓÐ `{"a"={"b"="c"}` entryµÄMap£¬¶ø `[a.b]=c` ½«·µ»ØÒ»¸ö´øÓÐ `{"a.b"="c"}` entry µÄMap¡£
+
+
+
+
+
+
+
+##### [](https://springdoc.cn/spring-boot/features.html#features.external-config.typesafe-configuration-properties.relaxed-binding.environment-variables)´Ó»·¾³±äÁ¿°ó¶¨
+
+
+
+ÀýÈ磬Linux shell±äÁ¿Ö»Äܰüº¬×Öĸ£¨`a` µ½ `z` »ò `A` µ½ `Z` £©¡¢Êý×Ö£¨ `0` µ½ `9` £©»òÏ»®Ïß×Ö·û£¨ `_` £©¡£ °´ÕÕ¹ßÀý£¬Unix shell±äÁ¿µÄÃû³ÆÒ²½«²ÉÓôóд×Öĸ¡£
+
+
+
+
+
+Spring Boot¿íËɵİ󶨹æÔò±»Éè¼ÆÎª¾¡¿ÉÄܵØÓëÕâЩÃüÃûÏÞÖÆ¼æÈÝ¡£
+
+
+
+
+
+Òª½«¹æ·¶ÐÎʽµÄÊôÐÔÃû³Æ×ª»»Îª»·¾³±äÁ¿Ãû³Æ£¬Äã¿ÉÒÔ×ñÑÕâЩ¹æÔò¡£
+
+
+
+
+
+* ÓÃÏ»®Ïߣ¨`_`£©Ìæ»»µã£¨`.`£©¡£
+
+* ɾ³ýÈÎºÎÆÆÕۺţ¨`-`£©¡£
+
+* ת»»Îª´óд×Öĸ¡£
+
+
+
+
+
+ÀýÈ磬ÅäÖÃÊôÐÔ `spring.main.log-startup-info` ½«ÊÇÒ»¸öÃûΪ `SPRING_MAIN_LOGSTARTUPINFO` µÄ»·¾³±äÁ¿¡£
+
+
+
+
+
+»·¾³±äÁ¿Ò²¿ÉÒÔÔڰ󶨵½¶ÔÏóÁÐ±í£¨List£©Ê±Ê¹ÓᣠҪ°ó¶¨µ½Ò»¸ö `List`£¬ÔÚ±äÁ¿Ãû³ÆÖУ¬ÔªËرàºÅ£¨Ë÷Òý£©Ó¦¸ÃÓÃÏ»®Ïß°ü¹ü¡£
+
+
+
+
+
+ÀýÈ磬ÅäÖÃÊôÐÔ `my.service[0].other` ½«Ê¹ÓÃÒ»¸öÃûΪ `MY_SERVICE_0_OTHER` µÄ»·¾³±äÁ¿¡£
+
+
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/features.html#features.external-config.typesafe-configuration-properties.merging-complex-types)2.8.7\. ºÏ²¢¸´ÔÓµÄÀàÐÍ
+
+
+
+µ±List±»ÅäÖÃÔÚ¶à¸öµØ·½Ê±£¬¸²¸ÇµÄ×÷ÓÃÊÇÌæ»»Õû¸ölist¡£
+
+
+
+
+
+ÀýÈ磬¼ÙÉèÒ»¸ö `MyPojo` ¶ÔÏóµÄ `name` ºÍ `description` ÊôÐÔĬÈÏΪ `null`¡£ ÏÂÃæµÄÀý×Ó´Ó `MyProperties` Öб©Â¶ÁËÒ»¸ö `MyPojo` ¶ÔÏóµÄÁÐ±í¡£
+
+
+
+
+
+
+
+Java
+
+Kotlin
+
+
+
+
+
+```
+@ConfigurationProperties("my")
+public class MyProperties {
+
+ private final List list = new ArrayList<>();
+
+ public List getList() {
+ return this.list;
+ }
+
+}
+
+```
+
+
+
+
+
+
+
+¿¼ÂÇÒÔÏÂÅäÖá£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+my.list[0].name=my name
+my.list[0].description=my description
+#---
+spring.config.activate.on-profile=dev
+my.list[0].name=my another name
+
+```
+
+
+
+
+
+
+
+Èç¹û `dev` ÅäÖÃÎļþδ±»¼¤»î£¬`MyProperties.list` °üº¬Ò»¸ö `MyPojo` ÌõÄ¿£¬Èç֮ǰ¶¨ÒåµÄÄÇÑù¡£ È»¶ø£¬Èç¹û `dev` ÅäÖÃÎļþ±»¼¤»î£¬`list` ÈÔȻֻ°üº¬Ò»¸öÌõÄ¿£¨name Ϊ `my another name`£¬descriptionΪ `null`£©¡£ ÕâÖÖÅäÖò»»áÔÚÁбíÖÐÌí¼ÓµÚ¶þ¸ö `MyPojo` ʵÀý£¬Ò²²»»áºÏ²¢ÏîÄ¿¡£
+
+
+
+
+
+µ±Ò»¸ö `List` ÔÚ¶à¸öÅäÖÃÎļþÖб»Ö¸¶¨Ê±£¬½«Ê¹ÓþßÓÐ×î¸ßÓÅÏȼ¶µÄÄǸö£¨²¢ÇÒÖ»ÓÐÄǸö£©¡£ ¿¼ÂÇÏÂÃæµÄÀý×Ó¡£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+my.list[0].name=my name
+my.list[0].description=my description
+my.list[1].name=another name
+my.list[1].description=another description
+#---
+spring.config.activate.on-profile=dev
+my.list[0].name=my another name
+
+```
+
+
+
+
+
+
+
+ÔÚÇ°ÃæµÄÀý×ÓÖУ¬Èç¹û `dev` ÅäÖÃÎļþÊǼ¤»îµÄ£¬`MyProperties.list` °üº¬ _Ò»¸ö_ `MyPojo` ÌõÄ¿£¨name ÊÇ `my another name`£¬descriptionÊÇ `null`£©¡£ ¶ÔÓÚYAML£¬¶ººÅ·Ö¸ôµÄÁбíºÍYAMLÁÐ±í¶¼¿ÉÒÔÓÃÀ´ÍêÈ«¸²¸ÇÁбíµÄÄÚÈÝ¡£
+
+
+
+
+
+¶ÔÓÚ `Map` ÊôÐÔ£¬Äã¿ÉÒÔÓôӶà¸öÀ´Ô´»ñÈ¡µÄÊôÐÔÖµ½øÐа󶨡£ È»¶ø£¬¶ÔÓÚ¶à¸öÀ´Ô´ÖеÄͬһÊôÐÔ£¬Ê¹ÓþßÓÐ×î¸ßÓÅÏȼ¶µÄÄǸö¡£ ÏÂÃæµÄÀý×Ó´Ó `MyProperties` ±©Â¶ÁËÒ»¸ö `Map`¡£
+
+
+
+
+
+
+
+Java
+
+Kotlin
+
+
+
+
+
+```
+@ConfigurationProperties("my")
+public class MyProperties {
+
+ private final Map map = new LinkedHashMap<>();
+
+ public Map getMap() {
+ return this.map;
+ }
+
+}
+
+```
+
+
+
+
+
+
+
+¿¼ÂÇÒÔÏÂÅäÖá£
+
+
+
+
+
+
+
+Properties
+
+Yaml
+
+
+
+
+
+```
+my.map.key1.name=my name 1
+my.map.key1.description=my description 1
+#---
+spring.config.activate.on-profile=dev
+my.map.key1.name=dev name 1
+my.map.key2.name=dev name 2
+my.map.key2.description=dev description 2
+
+```
+
+
+
+
+
+
+
+Èç¹û `dev` ÅäÖÃÎļþûÓм¤»î£¬`MyProperties.map` °üº¬Ò»¸ökeyΪ `key1` µÄÌõÄ¿£¨nameΪ `my name 1` £¬descriptionΪ `my description 1` £©¡£ È»¶ø£¬Èç¹û `dev` ÅäÖÃÎļþ±»¼¤»î£¬`map` °üº¬Á½¸öÌõÄ¿£¬keyΪ `key1` £¨nameΪ `dev name 1`£¬descriptionΪ `my description 1` £©ºÍ `key2`£¨nameΪ `dev name 2`£¬descriptionΪ `dev description 2`£©¡£
+
+
+
+
+
+| | Ç°ÃæµÄºÏ²¢¹æÔòÊÊÓÃÓÚËùÓÐÊôÐÔÔ´µÄÊôÐÔ£¬¶ø²»½ö½öÊÇÎļþ¡£ |
+| --- | --- |
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/features.html#features.external-config.typesafe-configuration-properties.conversion)2.8.8\. ÊôÐÔ£¨Properties£©×ª»»
+
+
+
+µ±Spring BootÓë `@ConfigurationProperties` Bean°ó¶¨Ê±£¬ËüÊÔͼ½«Íⲿapplication propertiesÇ¿ÖÆ¸ÄΪÕýÈ·µÄÀàÐÍ¡£ Èç¹ûÄãÐèÒª×Ô¶¨ÒåÀàÐÍת»»£¬Äã¿ÉÒÔÌṩһ¸ö `ConversionService` bean£¨BeanµÄÃû³ÆÎª `conversionService` £©»ò×Ô¶¨ÒåÊôÐÔ±à¼Æ÷£¨Í¨¹ý `CustomEditorConfigurer` bean£©»ò×Ô¶¨Òå `Converters` Bean£¨Ê¹Óà `@ConfigurationPropertiesBinding` ×¢½â£©¡£
+
+
+
+
+
+| | ÓÉÓÚÕâ¸öBeanÊÇÔÚÓ¦ÓóÌÐòÉúÃüÖÜÆÚµÄÔçÆÚ±»ÇëÇóµÄ£¬ÇëÈ·±£ÏÞÖÆÄãµÄ `ConversionService` ËùʹÓõÄÒÀÀµ¹ØÏµ¡£ ͨ³£Çé¿öÏ£¬ÄãËùÐèÒªµÄÈκÎÒÀÀµ¹ØÏµÔÚ´´½¨Ê±¿ÉÄÜûÓÐÍêÈ«³õʼ»¯¡£ Èç¹ûÄãµÄ×Ô¶¨Òå `ConversionService` ²»ÐèÒªÅäÖÃkeys coercion£¬Äã¿ÉÄÜÏëÖØÃüÃûËü£¬²¢ÇÒÖ»ÒÀÀµÓà `@ConfigurationPropertiesBinding` ÏÞ¶¨µÄ×Ô¶¨Òåת»»Æ÷¡£ |
+| --- | --- |
+
+
+
+
+
+##### [](https://springdoc.cn/spring-boot/features.html#features.external-config.typesafe-configuration-properties.conversion.durations)ת»»Îª Duration
+
+
+
+Spring Boot¶Ô±í´ï³ÖÐøÊ±¼äÓÐרÃŵÄÖ§³Ö¡£ Èç¹ûÄ㹫¿ªÁËÒ»¸ö `java.time.Duration` ÊôÐÔ£¬application propertiesÖеÄÒÔϸñʽ¾Í¿ÉÓá£
+
+
+
+
+
+* ÆÕͨµÄ `long` £¨Ê¹ÓúÁÃë×÷ΪĬÈϵ¥Î»£¬³ý·ÇÖ¸¶¨ÁË `@DurationUnit` £©¡£
+
+* ±ê×¼µÄISO-8601¸ñʽ [ÓÉ `java.time.Duration` ʹÓÃ](https://docs.oracle.com/javase/17/docs/api/java/time/Duration.html#parse-java.lang.CharSequence-)¡£
+
+* Ò»¸ö¸üÒ×¶ÁµÄ¸ñʽ£¬ÆäÖÐÖµºÍµ¥Î»ÊÇñîºÏµÄ£¨`10s` ±íʾ10Ã룩¡£
+
+
+
+
+
+Ç뿼ÂÇÒÔÏÂÀý×Ó¡£
+
+
+
+
+
+
+
+Java
+
+Kotlin
+
+
+
+
+
+```
+@ConfigurationProperties("my")
+public class MyProperties {
+
+ @DurationUnit(ChronoUnit.SECONDS)
+ private Duration sessionTimeout = Duration.ofSeconds(30);
+
+ private Duration readTimeout = Duration.ofMillis(1000);
+
+ // getters / setters...
+
+}
+
+```
+
+
+
+
+
+
+
+ÒªÖ¸¶¨Ò»¸ö30ÃëµÄ»á»°³¬Ê±£¬ `30` ¡¢ `PT30S` ºÍ `30s` ¶¼Êǵȼ۵ġ£ ¶ÁÈ¡³¬Ê±Îª500ms£¬¿ÉÒÔÓÃÒÔÏÂÈκÎÒ»ÖÖÐÎʽָ¶¨¡£ `500`, `PT0.5S` ºÍ `500ms`.
+
+
+
+
+
+ÄãÒ²¿ÉÒÔʹÓÃÈçÏÂÖ§³ÖµÄʱ¼äµ¥Î»¡£
+
+
+
+
+
+* `ns` ÄÉÃë
+
+* `us` ΢Ãë
+
+* `ms` ºÁÃë
+
+* `s` Ãë
+
+* `m` ·Ö
+
+* `h` Сʱ
+
+* `d` Ìì
+
+
+
+
+
+ĬÈϵ¥Î»ÊǺÁÃ룬¿ÉÒÔʹÓà `@DurationUnit` À´ÖØÐ´£¬ÈçÉÏÃæµÄÀý×ÓËùʾ¡£
+
+
+
+
+
+Èç¹ûÄãϲ»¶Ê¹Óù¹Ô캯Êý°ó¶¨£¬Í¬ÑùµÄÊôÐÔ¿ÉÒÔ±»±©Â¶³öÀ´£¬ÈçÏÂÃæµÄÀý×ÓËùʾ¡£
+
+
+
+
+
+
+
+Java
+
+Kotlin
+
+
+
+
+
+```
+@ConfigurationProperties("my")
+public class MyProperties {
+
+ // fields...
+
+ public MyProperties(@DurationUnit(ChronoUnit.SECONDS) @DefaultValue("30s") Duration sessionTimeout,
+ @DefaultValue("1000ms") Duration readTimeout) {
+ this.sessionTimeout = sessionTimeout;
+ this.readTimeout = readTimeout;
+ }
+
+ // getters...
+
+}
+
+```
+
+
+
+
+
+
+
+| | Èç¹ûÄãÒªÉý¼¶Ò»¸ö `Long` µÄÊôÐÔ£¬Èç¹ûËü²»ÊǺÁÃ룬ÇëÈ·±£¶¨Ò嵥λ£¨Ê¹Óà `@DurationUnit` £©¡£ ÕâÑù×öÌṩÁËÒ»¸ö͸Ã÷µÄÉý¼¶Â·¾¶£¬Í¬Ê±Ö§³Ö¸ü·á¸»µÄ¸ñʽ |
+| --- | --- |
+
+
+
+
+
+
+
+##### [](https://springdoc.cn/spring-boot/features.html#features.external-config.typesafe-configuration-properties.conversion.periods)ת»»ÎªÆÚ¼ä£¨Period£©
+
+
+
+³ýÁËduration£¬Spring Boot»¹¿ÉÒÔʹÓà `java.time.Period` ÀàÐÍ¡£ ÒÔϸñʽ¿ÉÒÔÔÚapplication propertiesÖÐʹÓá£
+
+
+
+
+
+* Ò»¸ö³£¹æµÄ `int` ±íʾ·¨£¨Ê¹ÓÃÌì×÷ΪĬÈϵ¥Î»£¬³ý·ÇÖ¸¶¨ÁË `@PeriodUnit` £©¡£
+
+* ±ê×¼µÄISO-8601¸ñʽ [ÓÉ `java.time.Period` ʹÓÃ](https://docs.oracle.com/javase/17/docs/api/java/time/Period.html#parse-java.lang.CharSequence-)¡£
+
+* Ò»¸ö¸ü¼òµ¥µÄ¸ñʽ£¬ÆäÖÐÖµºÍµ¥Î»¶ÔÊÇñîºÏµÄ£¨ `1y3d` ±íʾ1Äê3Ì죩¡£
+
+
+
+
+
+Ö§³ÖÏÂÁмòµ¥µÄµ¥Î»¸ñʽ¡£
+
+
+
+
+
+* `y` Äê
+
+* `m` ÔÂ
+
+* `w` ÖÜ
+
+* `d` ÈÕ
+
+
+
+
+
+| | `java.time.Period` ÀàÐÍʵ¼ÊÉÏ´Óδ´æ´¢¹ýÖÜÊý£¬ËüÊÇÒ»¸ö¿ì½Ý·½Ê½£¬Òâζ×Å ¡°7Ì족¡£ |
+| --- | --- |
+
+
+
+
+
+
+
+##### [](https://springdoc.cn/spring-boot/features.html#features.external-config.typesafe-configuration-properties.conversion.data-sizes)ת»»ÎªÊý¾Ý´óС£¨Data Sizes£©
+
+
+
+Spring FrameworkÓÐÒ»¸ö `DataSize` ÖµÀàÐÍ£¬ÒÔ×Ö½ÚΪµ¥Î»±í´ï´óС¡£ Èç¹ûÄ㹫¿ªÁËÒ»¸ö `DataSize` ÊôÐÔ£¬application propertiesÖеÄÒÔϸñʽ¾Í¿ÉÓá£
+
+
+
+
+
+* Ò»¸ö³£¹æµÄ `long` ±íʾ£¨Ê¹ÓÃ×Ö½Ú×÷ΪĬÈϵ¥Î»£¬³ý·ÇÖ¸¶¨ÁË `@DataSizeUnit`£©¡£
+
+* Ò»¸ö¸üÒ×¶ÁµÄ¸ñʽ£¬ÆäÖÐÖµºÍµ¥Î»ÊÇñîºÏµÄ£¨`10MB` Òâζ×Å10Õ××Ö½Ú£©¡£
+
+
+
+
+
+¿¼ÂÇÒÔÏÂÀý×Ó¡£
+
+
+
+
+
+
+
+Java
+
+Kotlin
+
+
+
+
+
+```
+@ConfigurationProperties("my")
+public class MyProperties {
+
+ @DataSizeUnit(DataUnit.MEGABYTES)
+ private DataSize bufferSize = DataSize.ofMegabytes(2);
+
+ private DataSize sizeThreshold = DataSize.ofBytes(512);
+
+ // getters/setters...
+
+}
+
+```
+
+
+
+
+
+
+
+ÒªÖ¸¶¨Ò»¸ö10Õ××Ö½Ú£¨Mb£©µÄ»º³åÇø´óС£¬ `10` ºÍ `10MB` Êǵȼ۵ġ£ 256×ֽڵĴóСãÐÖµ¿ÉÒÔÖ¸¶¨Îª `256` »ò `256B`¡£
+
+
+
+
+
+ÄãÒ²¿ÉÒÔʹÓÃÈçÏÂÕâЩ֧³ÖµÄµ¥Î»¡£
+
+
+
+
+
+* `B` ×Ö½Ú
+
+* `KB` KB
+
+* `MB` MB
+
+* `GB` GB
+
+* `TB` TB
+
+
+
+
+
+ĬÈϵ¥Î»ÊÇ×Ö½Ú£¬¿ÉÒÔʹÓà `@DataSizeUnit` À´ÖØÐ´£¬ÈçÉÏÃæµÄÀý×ÓËùʾ¡£
+
+
+
+
+
+Èç¹ûÄãϲ»¶Ê¹Óù¹Ô캯Êý°ó¶¨£¬Í¬ÑùµÄÊôÐÔ¿ÉÒÔ±»±©Â¶³öÀ´£¬ÈçÏÂÃæµÄÀý×ÓËùʾ¡£
+
+
+
+
+
+
+
+Java
+
+Kotlin
+
+
+
+
+
+```
+@ConfigurationProperties("my")
+public class MyProperties {
+
+ // fields...
+
+ public MyProperties(@DataSizeUnit(DataUnit.MEGABYTES) @DefaultValue("2MB") DataSize bufferSize,
+ @DefaultValue("512B") DataSize sizeThreshold) {
+ this.bufferSize = bufferSize;
+ this.sizeThreshold = sizeThreshold;
+ }
+
+ // getters...
+
+}
+
+```
+
+
+
+
+
+
+
+| | Èç¹ûÄãÕýÔÚÉý¼¶Ò»¸ö `Long` ÊôÐÔ£¬È·±£¶¨Ò嵥λ£¨Ê¹Óà `@DataSizeUnit`£©£¬Èç¹ûËü²»ÊÇ×Ö½Ú¡£ ÕâÑù×öÌṩÁËÒ»¸ö͸Ã÷µÄÉý¼¶Â·¾¶£¬Í¬Ê±Ö§³Ö¸ü·á¸»µÄ¸ñʽ¡£ |
+| --- | --- |
+
+
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/features.html#features.external-config.typesafe-configuration-properties.validation)2.8.9\. @ConfigurationProperties УÑé
+
+
+
+ֻҪʹÓÃSpringµÄ `@Validated` ×¢½â£¬Spring Boot¾Í»á³¢ÊÔÑéÖ¤ `@ConfigurationProperties` Àà¡£ Äã¿ÉÒÔÖ±½ÓÔÚÄãµÄÅäÖÃÀàÉÏʹÓÃJSR-303µÄ `jakarta.validation` Ô¼Êø×¢½â¡£ Òª×öµ½ÕâÒ»µã£¬ÇëÈ·±£ÄãµÄclasspathÉÏÓÐÒ»¸ö¼æÈݵÄJSR-303ʵÏÖ£¬È»ºó½«Ô¼Êø×¢½âÌí¼Óµ½ÄãµÄ×Ö¶ÎÖУ¬ÈçÏÂÃæµÄÀý×ÓËùʾ¡£
+
+
+
+
+
+
+
+Java
+
+Kotlin
+
+
+
+
+
+```
+@ConfigurationProperties("my.service")
+@Validated
+public class MyProperties {
+
+ @NotNull
+ private InetAddress remoteAddress;
+
+ // getters/setters...
+
+}
+
+```
+
+
+
+
+
+
+
+| | ÄãÒ²¿ÉÒÔͨ¹ýÔÚ configuration properties µÄ `@Bean` ·½·¨ÉÏ×¢½â `@Validated` À´´¥·¢ÑéÖ¤¡£ |
+| --- | --- |
+
+
+
+
+
+ΪÁËÈ·±£×ÜÊÇΪǶÌ×µÄÊôÐÔ´¥·¢ÑéÖ¤£¬¼´Ê¹Ã»ÓÐÕÒµ½ÊôÐÔ£¬Ïà¹ØµÄ×ֶαØÐëÓà `@Valid` À´×¢ÊÍ¡£ ÏÂÃæµÄÀý×Ó½¨Á¢ÔÚÇ°ÃæµÄ `MyProperties` µÄ»ù´¡ÉÏ¡£
+
+
+
+
+
+
+
+Java
+
+Kotlin
+
+
+
+
+
+```
+@ConfigurationProperties("my.service")
+@Validated
+public class MyProperties {
+
+ @NotNull
+ private InetAddress remoteAddress;
+
+ @Valid
+ private final Security security = new Security();
+
+ // getters/setters...
+
+ public static class Security {
+
+ @NotEmpty
+ private String username;
+
+ // getters/setters...
+
+ }
+
+}
+
+```
+
+
+
+
+
+
+
+ÄãÒ²¿ÉÒÔͨ¹ý´´½¨Ò»¸öÃûΪ `configurationPropertiesValidator` µÄbean¶¨ÒåÀ´Ìí¼ÓÒ»¸ö×Ô¶¨ÒåµÄSpring `Validator`¡£ `@Bean` ·½·¨Ó¦¸Ã±»ÉùÃ÷Ϊ `static`¡£ ÅäÖÃÊôÐÔÑéÖ¤Æ÷ÊÇÔÚÓ¦ÓóÌÐòÉúÃüÖÜÆÚµÄÔçÆÚ´´½¨µÄ£¬½« `@Bean` ·½·¨ÉùÃ÷Ϊ¾²Ì¬£¬¿ÉÒÔÈÃBeanµÄ´´½¨²»ÐèҪʵÀý»¯ `@Configuration` Àà¡£ ÕâÑù×ö¿ÉÒÔ±ÜÃâ¹ýÔçʵÀý»¯¿ÉÄÜÒýÆðµÄÈκÎÎÊÌâ¡£
+
+
+
+
+
+| | `spring-boot-actuator` Ä£¿é°üÀ¨Ò»¸ö±©Â¶ËùÓÐ `@ConfigurationProperties` Bean µÄ¶Ëµã¡£ Äã¿ÉÒÔͨ¹ýä¯ÀÀÆ÷·ÃÎÊ `/actuator/configprops` »òʹÓÃÏàÓ¦µÄJMX¶Ëµã¡£ ÏêÇé¼û"[Éú²ú¾ÍÐ÷](https://springdoc.cn/spring-boot/actuator.html#actuator.endpoints)"²¿·Ö¡£ |
+| --- | --- |
+
+
+
+
+
+
+
+#### [](https://springdoc.cn/spring-boot/features.html#features.external-config.typesafe-configuration-properties.vs-value-annotation)2.8.10\. @ConfigurationProperties vs. @Value
+
+
+
+`@Value` ×¢½âÊÇÒ»¸öºËÐĵÄÈÝÆ÷¹¦ÄÜ£¬Ëü²»ÌṩÓëÀàÐͰ²È«µÄÅäÖÃÊôÐÔÏàͬµÄ¹¦ÄÜ¡£ ϱí×ܽáÁË `@ConfigurationProperties` ºÍ `@Value` ËùÖ§³ÖµÄ¹¦ÄÜ¡£
+
+
+
+
+| ¹¦ÄÜ | `@ConfigurationProperties` | `@Value` |
+| --- | --- | --- |
+| [¿íËɰó¶¨](https://springdoc.cn/spring-boot/features.html#features.external-config.typesafe-configuration-properties.relaxed-binding) | Yes | ÓÐÏÞÖÆ (¼û [ÏÂÎÄ×¢ÊÍ](https://springdoc.cn/spring-boot/features.html#features.external-config.typesafe-configuration-properties.vs-value-annotation.note)) |
+| [Ö§³Ö Meta-data](https://springdoc.cn/spring-boot/configuration-metadata.html#appendix.configuration-metadata) | Yes | No |
+| `SpEL` ±í´ïʽ | No | Yes |
+
+
+
+| | Èç¹ûÄãȷʵÏëʹÓà `@Value`£¬ÎÒÃǽ¨ÒéÄãʹÓÃÊôÐÔÃû³ÆµÄ¹æ·¶ÐÎʽ£¨½öʹÓÃСд×ÖĸµÄkebab-case£©À´ÒýÓÃÊôÐÔÃû³Æ¡£ Õ⽫ÔÊÐíSpring BootʹÓÃÓë [¿íËɰó¶¨](https://springdoc.cn/spring-boot/features.html#features.external-config.typesafe-configuration-properties.relaxed-binding) `@ConfigurationProperties` ʱÏàͬµÄÂß¼¡£ÀýÈ磬`@Value("${demo.item-price}")` ½«´Ó `application.properties` ÎļþÖлñÈ¡ `demo.item-price` ºÍ `demo.itemPrice` ÐÎʽ£¬ÒÔ¼°´Óϵͳ»·¾³ÖлñÈ¡ `DEMO_ITEMPRICE`¡£ Èç¹ûÄãÓà `@Value("${demo.itemPrice}")` ´úÌæ£¬`demo.item-price` ºÍ `DEMO_ITEMPRICE` ½«²»»á±»¿¼ÂÇ¡£ |
+| --- | --- |
+
+
+
+
+
+Èç¹ûÄãΪÄã×Ô¼ºµÄ×é¼þ¶¨ÒåÁËÒ»×éÅäÖüü£¬ÎÒÃǽ¨ÒéÄ㽫ËüÃÇ·Ö×éÔÚÒ»¸öÓà `@ConfigurationProperties` ×¢½âµÄPOJOÖС£ ÕâÑù×ö½«ÎªÄãÌṩ½á¹¹»¯µÄ¡¢ÀàÐͰ²È«µÄ¶ÔÏó£¬Äã¿ÉÒÔ½«Æä×¢Èëµ½Äã×Ô¼ºµÄbeanÖС£
+
+
+
+
+
+À´×ÔÓ¦ÓÃ[application property](https://springdoc.cn/spring-boot/features.html#features.external-config.files) ÎļþµÄ `SpEL` ±í´ïʽÔÚ½âÎöÕâЩÎļþºÍÌî³äenvironmentʱ²»»á±»´¦Àí¡£ È»¶ø£¬¿ÉÒÔÔÚ `@Value` ÖÐдһ¸ö `SpEL` ±í´ïʽ¡£ Èç¹ûÀ´×ÔÓ¦ÓóÌÐòÊôÐÔÎļþµÄÊôÐÔÖµÊÇÒ»¸ö `SpEL` ±í´ïʽ£¬Ëü½«ÔÚ±» `@Value` Ïû·Ñʱ±»½âÎö¡£
+
+
+
+
+
+
+
+
+
+
+
+
+
+## [](https://springdoc.cn/spring-boot/features.html#features.profiles)
+
diff --git "a/docs/spring/SpringBoot/SpringBoot\350\207\252\345\270\246\347\232\204\347\203\255\351\203\250\347\275\262\345\267\245\345\205\267.md" "b/docs/spring/SpringBoot/SpringBoot\350\207\252\345\270\246\347\232\204\347\203\255\351\203\250\347\275\262\345\267\245\345\205\267.md"
new file mode 100644
index 0000000..477370a
--- /dev/null
+++ "b/docs/spring/SpringBoot/SpringBoot\350\207\252\345\270\246\347\232\204\347\203\255\351\203\250\347\275\262\345\267\245\345\205\267.md"
@@ -0,0 +1,345 @@
+# SpringBootÈëÃÅ - ÅäÖÃÈȲ¿Êðdevtools¹¤¾ß
+
+> ÔÚSpringBoot¿ª·¢µ÷ÊÔÖУ¬Èç¹ûÎÒÿÐдúÂëµÄÐ޸ͼÐèÒªÖØÆôÆô¶¯ÔÙµ÷ÊÔ£¬¿ÉÄܱȽϷÑʱ¼ä£»SpringBootÍŶÓÕë¶Ô´ËÎÊÌâÌṩÁËspring-boot-devtools£¨¼ò³Ædevtools£©²å¼þ£¬ËüÊÔͼÌáÉý¿ª·¢µ÷ÊÔµÄЧÂÊ¡£@pdai
+
+* [SpringBootÈëÃÅ - ÅäÖÃÈȲ¿Êðdevtools¹¤¾ß](#springboot%E5%85%A5%E9%97%A8---%E9%85%8D%E7%BD%AE%E7%83%AD%E9%83%A8%E7%BD%B2devtools%E5%B7%A5%E5%85%B7)
+ * [×¼±¸ÖªÊ¶µã](#%E5%87%86%E5%A4%87%E7%9F%A5%E8%AF%86%E7%82%B9)
+ * [ʲôÊÇÈȲ¿ÊðºÍÈȼÓÔØ£¿](#%E4%BB%80%E4%B9%88%E6%98%AF%E7%83%AD%E9%83%A8%E7%BD%B2%E5%92%8C%E7%83%AD%E5%8A%A0%E8%BD%BD)
+ * [ʲôÊÇLiveLoad£¿](#%E4%BB%80%E4%B9%88%E6%98%AFliveload)
+ * [ÅäÖÃdevtoolsʵÏÖÈȲ¿Êð](#%E9%85%8D%E7%BD%AEdevtools%E5%AE%9E%E7%8E%B0%E7%83%AD%E9%83%A8%E7%BD%B2)
+ * [POMÅäÖÃ](#pom%E9%85%8D%E7%BD%AE)
+ * [IDEAÅäÖÃ](#idea%E9%85%8D%E7%BD%AE)
+ * [application.ymlÅäÖÃ](#applicationyml%E9%85%8D%E7%BD%AE)
+ * [ʹÓÃLiveLoad](#%E4%BD%BF%E7%94%A8liveload)
+ * [½øÒ»²½Àí½â](#%E8%BF%9B%E4%B8%80%E6%AD%A5%E7%90%86%E8%A7%A3)
+ * [devtoolµÄÔÀí£¿ÎªºÎ»á×Ô¶¯ÖØÆô£¿](#devtool%E7%9A%84%E5%8E%9F%E7%90%86%E4%B8%BA%E4%BD%95%E4%BC%9A%E8%87%AA%E5%8A%A8%E9%87%8D%E5%90%AF)
+ * [devtoolÊÇ·ñ»á±»´ò°ü½øJar£¿](#devtool%E6%98%AF%E5%90%A6%E4%BC%9A%E8%A2%AB%E6%89%93%E5%8C%85%E8%BF%9Bjar)
+ * [devtoolΪºÎ»áĬÈϽûÓûº´æÑ¡Ï](#devtool%E4%B8%BA%E4%BD%95%E4%BC%9A%E9%BB%98%E8%AE%A4%E7%A6%81%E7%94%A8%E7%BC%93%E5%AD%98%E9%80%89%E9%A1%B9)
+ * [devtoolÊÇ·ñ¿ÉÒÔ¸øËùÓÐSpringbootÓ¦ÓÃ×öÈ«¾ÖµÄÅäÖã¿](#devtool%E6%98%AF%E5%90%A6%E5%8F%AF%E4%BB%A5%E7%BB%99%E6%89%80%E6%9C%89springboot%E5%BA%94%E7%94%A8%E5%81%9A%E5%85%A8%E5%B1%80%E7%9A%84%E9%85%8D%E7%BD%AE)
+ * [Èç¹ûÎÒ²»ÓÃdevtool£¬»¹ÓÐʲôѡÔñ£¿](#%E5%A6%82%E6%9E%9C%E6%88%91%E4%B8%8D%E7%94%A8devtool%E8%BF%98%E6%9C%89%E4%BB%80%E4%B9%88%E9%80%89%E6%8B%A9)
+ * [ʾÀýÔ´Âë](#%E7%A4%BA%E4%BE%8B%E6%BA%90%E7%A0%81)
+ * [²Î¿¼ÎÄÕÂ](#%E5%8F%82%E8%80%83%E6%96%87%E7%AB%A0)
+
+## [#](#×¼±¸ÖªÊ¶µã) ×¼±¸ÖªÊ¶µã
+
+### [#](#ʲôÊÇÈȲ¿ÊðºÍÈȼÓÔØ) ʲôÊÇÈȲ¿ÊðºÍÈȼÓÔØ£¿
+
+> ÈȲ¿ÊðºÍÈȼÓÔØÊÇÔÚÓ¦ÓÃÕýÔÚÔËÐеÄʱºò£¬×Ô¶¯¸üУ¨ÖØÐ¼ÓÔØ»òÕßÌæ»»classµÈ£©Ó¦ÓõÄÒ»ÖÖÄÜÁ¦¡££¨PS£ºspring-boot-devtoolsÌṩµÄ·½°¸Ò²ÊÇÒªÖØÆôµÄ£¬Ö»ÊÇÎÞÐèÊÖ¶¯ÖØÆôÄÜʵÏÖ×Ô¶¯¼ÓÔØ¶øÒÑ¡££©
+
+ÑϸñÒâÒåÉÏ£¬ÎÒÃÇÐè񻂿·ÖÏÂÈȲ¿ÊðºÍÈȼÓÔØ, ¶ÔÓÚJavaÏîÄ¿¶øÑÔ£º
+
+* **ÈȲ¿Êð**
+
+ * ÔÚ·þÎñÆ÷ÔËÐÐÊ±ÖØÐ²¿ÊðÏîÄ¿
+ * ËüÊÇÖ±½ÓÖØÐ¼ÓÔØÕû¸öÓ¦Óã¬ÕâÖÖ·½Ê½»áÊÍ·ÅÄڴ棬±ÈÈȼÓÔØ¸ü¼Ó¸É¾»³¹µ×£¬µ«Í¬Ê±Ò²¸ü·Ñʱ¼ä¡£
+* **ÈȼÓÔØ**
+
+ * ÔÚÔÚÔËÐÐÊ±ÖØÐ¼ÓÔØclass£¬´Ó¶øÉý¼¶Ó¦Óá£
+ * ÈȼÓÔØµÄʵÏÖÔÀíÖ÷ÒªÒÀÀµ[javaµÄÀà¼ÓÔØ»úÖÆ](/md/java/jvm/java-jvm-classload.html)£¬ÔÚʵÏÖ·½Ê½¿ÉÒÔ¸ÅÀ¨ÎªÔÚÈÝÆ÷Æô¶¯µÄʱºòÆðÒ»Ìõºǫ́Ị̈߳¬¶¨Ê±µÄ¼ì²âÀàÎļþµÄʱ¼ä´Á±ä»¯£¬Èç¹ûÀàµÄʱ¼ä´Á±äµôÁË£¬Ôò½«ÀàÖØÐÂÔØÈë¡£
+ * ¶Ô±È·´Éä»úÖÆ£¬·´ÉäÊÇÔÚÔËÐÐʱ»ñÈ¡ÀàÐÅÏ¢£¬Í¨¹ý¶¯Ì¬µÄµ÷ÓÃÀ´¸Ä±ä³ÌÐòÐÐΪ£» ÈȼÓÔØÔòÊÇÔÚÔËÐÐʱͨ¹ýÖØÐ¼ÓÔØ¸Ä±äÀàÐÅÏ¢£¬Ö±½Ó¸Ä±ä³ÌÐòÐÐΪ¡£
+
+### [#](#ʲôÊÇliveload) ʲôÊÇLiveLoad£¿
+
+LiveLoadÊÇÌṩä¯ÀÀÆ÷¿Í»§¶Ë×Ô¶¯¼ÓÔØ¸üÐµĹ¤¾ß£¬·ÖΪLiveLoad·þÎñÆ÷ºÍLiveloadä¯ÀÀÆ÷²å¼þÁ½²¿·Ö£» devtoolsÖÐÒѾ¼¯³ÉÁËLiveLoad·þÎñÆ÷£¬ËùÒÔÈç¹ûÎÒÃÇ¿ª·¢µÄÊÇwebÓ¦Ó㬲¢ÇÒÆÚÍûä¯ÀÀÆ÷×Ô¶¯Ë¢Ð£¬ Õâʱºò¿ÉÒÔ¿¼ÂÇLiveLoad.
+
+
+
+ͬһʱ¼äÖ»ÄÜÔËÐÐÒ»¸öLiveReload·þÎñÆ÷¡£ ¿ªÊ¼Ó¦ÓóÌÐò֮ǰ£¬ÇëÈ·±£Ã»ÓÐÆäËûLiveReload·þÎñÆ÷ÕýÔÚÔËÐС£Èç¹û´ÓIDEÆô¶¯¶à¸öÓ¦ÓóÌÐò£¬ÔòÖ»ÓеÚÒ»¸öÓ¦ÓóÌÐò½«Ö§³ÖLiveReload¡£
+
+## [#](#ÅäÖÃdevtoolsʵÏÖÈȲ¿Êð) ÅäÖÃdevtoolsʵÏÖÈȲ¿Êð
+
+> ÎÒÃÇͨ¹ýÈçÏÂÅäÖÃÀ´ÊµÏÖ×Ô¶¯ÖØÆô·½Ê½µÄÈȲ¿Êð¡£
+
+### [#](#pomÅäÖÃ) POMÅäÖÃ
+
+Ìí¼Óspring-boot-devtoolsµÄÒÀÀµ
+
+
+
+```
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ true
+
+
+
+```
+
+
+
+### [#](#ideaÅäÖÃ) IDEAÅäÖÃ
+
+> Èç¹ûÄãʹÓÃIDEA¿ª·¢¹¤¾ß£¬Í¨³£ÓÐÈçÏÂÁ½ÖÖ·½Ê½£º
+
+* ·½Ê½Ò»£º **ÎÞÈκÎÅäÖÃʱ£¬ÊÖ¶¯´¥·¢ÖØÆô¸üУ¨Ctrl+F9£©**
+
+
+£¨Ò²¿ÉÒÔÓÃ`mvn compile`±àÒë´¥·¢ÖØÆô¸üУ©
+
+* ·½Ê½¶þ£º **IDEAÐ迪ÆôÔËÐÐʱ±àÒ룬×Ô¶¯ÖØÆô¸üÐÂ**
+
+**ÉèÖÃ1**£º
+
+File->Setting->Build,Execution,Deployment->Compile
+
+¹´Ñ¡£ºMake project automatically
+
+
+
+**ÉèÖÃ2**£º
+
+¿ì½Ý¼ü£ºctrl+alt+shift+/
+
+Ñ¡Ôñ£ºRegistry
+
+¹´Ñ¡£ºcompiler.automake.allow.when.app.running
+
+а汾µÄIDEA¿ÉÒÔÔÚFile->setting->Advanced SetttingsÀïÃæµÄµÚÒ»¸öÉèÖãº
+
+
+### [#](#application-ymlÅäÖÃ) application.ymlÅäÖÃ
+
+
+
+```
+spring:
+ devtools:
+ restart:
+ enabled: true #ÉèÖÿªÆôÈȲ¿Êð
+ additional-paths: src/main/java #ÖØÆôĿ¼
+ exclude: WEB-INF/**
+ thymeleaf:
+ cache: false #ʹÓÃThymeleafÄ£°åÒýÇæ£¬¹Ø±Õ»º´æ
+
+```
+
+
+
+### [#](#ʹÓÃliveload) ʹÓÃLiveLoad
+
+spring-boot-devtoolsÄ£¿é°üº¬**ǶÈëʽLiveReload·þÎñÆ÷**£¬¿ÉÒÔÔÚ×ÊÔ´¸ü¸ÄʱÓÃÓÚ´¥·¢ä¯ÀÀÆ÷ˢС£ LiveReloadä¯ÀÀÆ÷À©Õ¹³ÌÐòÖ§³ÖChrome£¬FirefoxºÍSafari£¬Äã¿ÉÒÔ´Ólivereload.comÃâ·ÑÏÂÔØ¡£
+
+
+»òÕß´Óä¯ÀÀÆ÷²å¼þÖÐÐÄÏÂÔØ£¬±ÈÈçfirefox:
+
+
+
+°²×°ÍêÖ®ºó£¬¿ÉÒÔͨ¹ýÈçÏÂͼ±ê¹ÜÀí
+
+
+
+Èç¹ûÄã²»ÏëÔÚÓ¦ÓóÌÐòÔËÐÐʱÆô¶¯LiveReload·þÎñÆ÷£¬Ôò¿ÉÒÔ½«spring.devtools.livereload.enabledÊôÐÔÉèÖÃΪfalse ¡£
+
+ͬһʱ¼äÖ»ÄÜÔËÐÐÒ»¸öLiveReload·þÎñÆ÷¡£ ¿ªÊ¼Ó¦ÓóÌÐò֮ǰ£¬ÇëÈ·±£Ã»ÓÐÆäËûLiveReload·þÎñÆ÷ÕýÔÚÔËÐС£Èç¹û´ÓIDEÆô¶¯¶à¸öÓ¦ÓóÌÐò£¬ÔòÖ»ÓеÚÒ»¸öÓ¦ÓóÌÐò½«Ö§³ÖLiveReload¡£
+
+## [#](#½øÒ»²½Àí½â) ½øÒ»²½Àí½â
+
+> ËäȻһЩ¿ª·¢Õß»áʹÓÃdevtool¹¤¾ß£¬µ«ÊǺÜÉÙÓÐÄܹ»ÉîÈëÀí½âµÄ£»ÈÃÎÒÃÇÀí½âÈçϼ¸¸öÎÊÌ⣬°ïÖúÄã½øÒ»²½Àí½â¡£@pdai
+
+### [#](#devtoolµÄÔÀí-ΪºÎ»á×Ô¶¯ÖØÆô) devtoolµÄÔÀí£¿ÎªºÎ»á×Ô¶¯ÖØÆô£¿
+
+> ΪʲôͬÑùÊÇÖØÆôÓ¦Óã¬ÎªÊ²Ã´²»ÊÖ¶¯ÖØÆô£¬¶øÊǽ¨ÒéʹÓÃspring-boot-devtools½øÐÐÈȲ¿ÊðÖØÆô£¿
+
+spring-boot-devtoolsʹÓÃÁËÁ½¸öÀà¼ÓÔØÆ÷ClassLoader£¬Ò»¸öClassLoader¼ÓÔØ²»»á·¢Éú¸ü¸ÄµÄÀࣨµÚÈý·½jar°ü£©£¬ÁíÒ»¸öClassLoader£¨restart ClassLoader£©¼ÓÔØ»á¸ü¸ÄµÄÀࣨ×Ô¶¨ÒåµÄÀࣩ¡£
+
+ºǫ́Æô¶¯Ò»¸ö**Îļþ¼àÌýỊ̈߳¨File Watcher£©**£¬**¼à²âµÄĿ¼ÖеÄÎļþ·¢Éú±ä¶¯Ê±£¬ ÔÀ´µÄrestart ClassLoader±»¶ªÆú£¬½«»áÖØÐ¼ÓÔØÐµÄrestart ClassLoader**¡£
+
+ÒòΪÎļþ±ä¶¯ºó£¬µÚÈý·½jar°ü²»ÔÙÖØÐ¼ÓÔØ£¬Ö»¼ÓÔØ×Ô¶¨ÒåµÄÀ࣬¼ÓÔØµÄÀà±È½ÏÉÙ£¬ËùÒÔÖØÆô±È½Ï¿ì¡£
+
+ÕâÒ²ÊÇΪʲô£¬Í¬ÑùÊÇÖØÆôÓ¦Óã¬ÎªÊ²Ã´²»ÊÖ¶¯ÖØÆô£¬½¨ÒéʹÓÃspring-boot-devtools½øÐÐÈȲ¿ÊðÖØÆô¡£
+
+ÔÚ×Ô¶¯ÖØÆôÖÐÓм¸µãÐèҪעÒâ:
+
+* **×Ô¶¯ÖØÆô»á¼Ç¼ÈÕÖ¾µÄ**
+
+£¨¼Ç¼ÔÚʲôÇé¿öÏÂÖØÆôµÄÈÕÖ¾£©
+
+¿ÉÒÔͨ¹ýÈçϹرÕ
+
+
+
+```
+spring:
+ devtools:
+ restart:
+ log-condition-evaluation-delta: false
+
+```
+
+
+
+* **ÅųýһЩ²»ÐèÒª×Ô¶¯ÖØÆôµÄ×ÊÔ´**
+
+ijЩ×ÊÔ´ÔÚ¸ü¸Äʱ²»Ò»¶¨ÐèÒª´¥·¢ÖØÐÂÆô¶¯¡£Ä¬ÈÏÇé¿öÏ£¬¸Ä±ä×ÊÔ´/META-INF/maven£¬/META-INF/resources£¬/resources£¬/static£¬/public£¬»ò/templates²»´¥·¢ÖØÐÂÆô¶¯£¬µ«È·»á´¥·¢ÏÖ³¡ÖØ×°¡£Èç¹ûÒª×Ô¶¨ÒåÕâЩÅųýÏ¿ÉÒÔʹÓøÃspring.devtools.restart.excludeÊôÐÔ¡£ÀýÈ磬Ҫ½öÅųý/static£¬/publicÄ㽫ÉèÖÃÒÔÏÂÊôÐÔ£º
+
+
+
+```
+spring:
+ devtools:
+ restart:
+ exclude: "static/**,public/**"
+
+```
+
+
+
+Èç¹ûÒª±£ÁôÕâЩĬÈÏÖµ²¢Ìí¼ÓÆäËûÅųýÏÇë¸ÄÓøÃspring.devtools.restart.additional-excludeÊôÐÔ¡£
+
+* **×Ô¶¨ÒåÖØÆôÀà¼ÓÔØÆ÷**
+
+ÖØÆô¹¦ÄÜÊÇͨ¹ýʹÓÃÁ½¸öÀà¼ÓÔØÆ÷À´ÊµÏֵġ£¶ÔÓÚ´ó¶àÊýÓ¦ÓóÌÐò£¬ÕâÖÖ·½·¨Ð§¹ûºÜºÃ¡£µ«ÊÇ£¬ËüÓÐʱ»áµ¼ÖÂÀà¼ÓÔØÎÊÌâ¡£
+
+ĬÈÏÇé¿öÏ£¬IDE ÖеÄÈκδò¿ªÏîÄ¿¶¼Ê¹Óá°ÖØÆô¡±Àà¼ÓÔØÆ÷¼ÓÔØ£¬Èκγ£¹æ.jarÎļþ¶¼Ê¹Óá°»ù±¾¡±Àà¼ÓÔØÆ÷¼ÓÔØ¡£Èç¹ûÄã´¦ÀíÒ»¸ö¶àÄ£¿éÏîÄ¿£¬²¢ÇÒ²»ÊÇÿ¸öÄ£¿é¶¼µ¼Èëµ½ÄãµÄ IDE ÖУ¬Äã¿ÉÄÜÐèÒª×Ô¶¨ÒåһЩ¶«Î÷¡£Îª´Ë£¬Äã¿ÉÒÔ´´½¨Ò»¸öMETA-INF/spring-devtools.propertiesÎļþ¡£
+
+¸Ãspring-devtools.propertiesÎļþ¿ÉÒÔ°üº¬ÒÔrestart.excludeºÍΪǰ׺µÄÊôÐÔrestart.include¡£¸ÃincludeÔªËØÊÇÓ¦¸Ã±»À¸ßµ½¡°ÖØÆô¡±µÄÀà¼ÓÔØÆ÷µÄÏîÄ¿£¬ÒÔ¼°excludeÒªËØÊÇÓ¦¸ÃÏòÏÂÍÆÈë¡°Base¡±Àà¼ÓÔØÆ÷µÄÏîÄ¿¡£¸ÃÊôÐÔµÄÖµÊÇÓ¦ÓÃÓÚÀà·¾¶µÄÕýÔò±í´ïʽģʽ£¬ÈçÒÔÏÂʾÀýËùʾ£º
+
+
+
+```
+restart:
+ exclude:
+ companycommonlibs: "/mycorp-common-[\\w\\d-\\.]+\\.jar"
+ include:
+ projectcommon: "/mycorp-myproj-[\\w\\d-\\.]+\\.jar"
+
+```
+
+
+
+¸ü¶àÏà¹ØµÄÐÅÏ¢¿ÉÒÔÔÚ[ÕâÀïÔÚд°¿Ú´ò¿ª](https://docs.spring.io/spring-boot/docs/current/reference/html/using.html#using.devtools)²é¿´¡£
+
+### [#](#devtoolÊÇ·ñ»á±»´ò°ü½øjar) devtoolÊÇ·ñ»á±»´ò°ü½øJar£¿
+
+> devtoolÔÔòÉÏÀ´ËµÓ¦¸ÃÊÇÖ»ÔÚ¿ª·¢µ÷ÊÔµÄʱºòʹÓ㬶øÔÚÉú²ú»·¾³ÔËÐÐjar°üʱÊDz»ÐèÒªµÄ£¬ËùÒÔSpring´ò°ü»á²»»á°ÑËü´ò½øJARÂð£¿
+
+* **ĬÈÏÇé¿öÏ£¬²»»á±»´ò°ü½øJAR**
+
+ÔËÐдò°üµÄÓ¦ÓóÌÐòʱ£¬¿ª·¢ÈËÔ±¹¤¾ß**»á×Ô¶¯½ûÓÃ**¡£Èç¹ûÄãͨ¹ý java -jar»òÕ߯äËûÌØÊâµÄÀà¼ÓÔØÆ÷½øÐÐÆô¶¯Ê±£¬¶¼»á±»ÈÏΪÊÇ¡°Éú²ú»·¾³µÄÓ¦Óᱡ£
+
+* **Èç¹ûÎÒÃÇÆÚÍûÔ¶³Ìµ÷ÊÔÓ¦ÓÃ**
+
+£¨_Éú²ú»·¾³ÎðÓã¬Ö»ÓÐÔÚÊÜÐÅÈεÄÍøÂçÉÏÔËÐлòʹÓà SSL ½øÐб£»¤Ê±£¬²ÅÓ¦ÆôÓÃËü_£©
+
+ÔÚÕâÖÖÇé¿öÏ£¬devtoolÒ²¾ß±¸Ô¶³Ìµ÷ÊÔµÄÄÜÁ¦£ºÔ¶³Ì¿Í»§¶ËÓ¦ÓóÌÐòÖ¼ÔÚ´ÓÄãµÄ IDE ÖÐÔËÐС£ÄãÐèÒªorg.springframework.boot.devtools.RemoteSpringApplicationʹÓÃÓëÄãÁ¬½ÓµÄÔ¶³ÌÏîÄ¿ÏàͬµÄÀà·¾¶ÔËÐС£Ó¦ÓóÌÐòµÄΨһ±ØÐè²ÎÊýÊÇËüÁ¬½Óµ½µÄÔ¶³Ì URL¡£
+
+ÀýÈ磬Èç¹ûʹÓà Eclipse »ò Spring Tools£¬²¢ÇÒÄãÓÐÒ»¸ömy-appÒѲ¿Êðµ½ Cloud Foundry µÄÃûΪµÄÏîÄ¿£¬Ö´ÐÐÒÔϲÙ×÷£º
+
+1. Ñ¡ÔñRun Configurations¡?´ÓRun²Ëµ¥¡£
+2. ´´½¨Ò»¸öеÄJava Application¡°Æô¶¯ÅäÖᱡ£
+3. ä¯ÀÀmy-appÏîÄ¿¡£
+4. ʹÓÃorg.springframework.boot.devtools.RemoteSpringApplication×÷ΪÖ÷Àà¡£
+5. Ìí¼Óhttps://myapp.cfapps.ioµ½Program arguments£¨»òÈκÎÄãµÄÔ¶³Ì URL£©¡£
+
+ÕýÔÚÔËÐеÄÔ¶³Ì¿Í»§¶Ë¿ÉÄÜÀàËÆÓÚÒÔÏÂÁÐ±í£º
+
+
+
+```
+ . ____ _ __ _ _
+ /\\ / ___'_ __ _ _(_)_ __ __ _ ___ _ \ \ \ \
+( ( )\___ | '_ | '_| | '_ \/ _` | | _ \___ _ __ ___| |_ ___ \ \ \ \
+ \\/ ___)| |_)| | | | | || (_| []::::::[] / -_) ' \/ _ \ _/ -_) ) ) ) )
+ ' |____| .__|_| |_|_| |_\__, | |_|_\___|_|_|_\___/\__\___|/ / / /
+ =========|_|==============|___/===================================/_/_/_/
+ :: Spring Boot Remote :: 2.5.4
+
+2015-06-10 18:25:06.632 INFO 14938 --- [ main] o.s.b.devtools.RemoteSpringApplication : Starting RemoteSpringApplication on pwmbp with PID 14938 (/Users/pwebb/projects/spring-boot/code/spring-boot-project/spring-boot-devtools/target/classes started by pwebb in /Users/pwebb/projects/spring-boot/code)
+2015-06-10 18:25:06.671 INFO 14938 --- [ main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@2a17b7b6: startup date [Wed Jun 10 18:25:06 PDT 2015]; root of context hierarchy
+2015-06-10 18:25:07.043 WARN 14938 --- [ main] o.s.b.d.r.c.RemoteClientConfiguration : The connection to http://localhost:8080 is insecure. You should use a URL starting with 'https://'.
+2015-06-10 18:25:07.074 INFO 14938 --- [ main] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729
+2015-06-10 18:25:07.130 INFO 14938 --- [ main] o.s.b.devtools.RemoteSpringApplication : Started RemoteSpringApplication in 0.74 seconds (JVM running for 1.105)
+
+```
+
+
+
+### [#](#devtoolΪºÎ»áĬÈϽûÓûº´æÑ¡Ïî) devtoolΪºÎ»áĬÈϽûÓûº´æÑ¡Ï
+
+> Spring Boot Ö§³ÖµÄһЩ¿â**ʹÓûº´æÀ´Ìá¸ßÐÔÄÜ**¡£ÀýÈ磬ģ°åÒýÇæ»º´æÒѱàÒëµÄÄ£°åÒÔ±ÜÃâÖØ¸´½âÎöÄ£°åÎļþ¡£´ËÍ⣬Spring MVC ¿ÉÒÔÔÚÌṩ¾²Ì¬×ÊԴʱÏòÏìÓ¦Ìí¼Ó HTTP »º´æ±êÍ·¡£
+
+ËäÈ»»º´æ**ÔÚÉú²úÖзdz£ÓÐÒæ£¬µ«ÔÚ¿ª·¢¹ý³ÌÖпÉÄÜ»áÊÊµÃÆä·´**£¬Ê¹ÄãÎÞ·¨¿´µ½¸Õ¸ÕÔÚÓ¦ÓóÌÐòÖÐËù×öµÄ¸ü¸Ä¡£³öÓÚÕâ¸öÔÒò£¬ spring-boot-devtools ĬÈϽûÓûº´æÑ¡Ïî¡£
+
+±ÈÈçThymeleaf ÌṩÁËspring.thymeleaf.cacheÀ´ÉèÖÃÄ£°åÒýÇæµÄ»º´æ£¬Ê¹ÓÃspring-boot-devtoolsÄ£¿éʱÊDz»ÐèÒªÊÖ¶¯ÉèÖÃÕâЩÊôÐԵģ¬ÒòΪspring-boot-devtools»á×Ô¶¯½øÐÐÉèÖá£
+
+ÄÇô»á×Ô¶¯ÉèÖÃÄÄЩÅäÖÃÄØ£¿Äã¿ÉÒÔÔÚDevToolsPropertyDefaultsPostProcessorÀàÕÒµ½¶ÔÓ¦µÄĬÈÏÅäÖá£
+
+
+
+```
+public class DevToolsPropertyDefaultsPostProcessor implements EnvironmentPostProcessor {
+
+ static {
+ Map properties = new HashMap<>();
+ properties.put("spring.thymeleaf.cache", "false");
+ properties.put("spring.freemarker.cache", "false");
+ properties.put("spring.groovy.template.cache", "false");
+ properties.put("spring.mustache.cache", "false");
+ properties.put("server.servlet.session.persistent", "true");
+ properties.put("spring.h2.console.enabled", "true");
+ properties.put("spring.web.resources.cache.period", "0");
+ properties.put("spring.web.resources.chain.cache", "false");
+ properties.put("spring.template.provider.cache", "false");
+ properties.put("spring.mvc.log-resolved-exception", "true");
+ properties.put("server.error.include-binding-errors", "ALWAYS");
+ properties.put("server.error.include-message", "ALWAYS");
+ properties.put("server.error.include-stacktrace", "ALWAYS");
+ properties.put("server.servlet.jsp.init-parameters.development", "true");
+ properties.put("spring.reactor.debug", "true");
+ PROPERTIES = Collections.unmodifiableMap(properties);
+ }
+
+```
+
+
+
+µ±È»Èç¹ûÄã²»Ïë±»Ó¦ÓÃÊôÐÔ±»spring-boot-devtoolsĬÈÏÉèÖ㬠¿ÉÒÔͨ¹ýspring.devtools.add-propertiesµ½falseÄãapplication.ymlÖС£
+
+### [#](#devtoolÊÇ·ñ¿ÉÒÔ¸øËùÓÐspringbootÓ¦ÓÃ×öÈ«¾ÖµÄÅäÖÃ) devtoolÊÇ·ñ¿ÉÒÔ¸øËùÓÐSpringbootÓ¦ÓÃ×öÈ«¾ÖµÄÅäÖã¿
+
+> ¿ÉÒÔͨ¹ý½«spring-boot-devtools.ymlÎļþÌí¼Óµ½$HOME/.config/spring-bootĿ¼À´**ÅäÖÃÈ«¾Ö devtools ÉèÖÃ**¡£
+
+Ìí¼Óµ½ÕâЩÎļþµÄÈκÎÊôÐÔ¶¼ÊÊÓÃÓÚÄã»úÆ÷ÉÏʹÓà devtools µÄËùÓÐSpring Boot Ó¦ÓóÌÐò¡£ÀýÈ磬Ҫ½«ÖØÐÂÆô¶¯ÅäÖÃΪʼÖÕʹÓô¥·¢Æ÷Îļþ£¬ÄãÐèÒª½«ÒÔÏÂÊôÐÔÌí¼Óµ½ÄãµÄspring-boot-devtoolsÎļþÖУº
+
+
+
+```
+spring:
+ devtools:
+ restart:
+ trigger-file: ".reloadtrigger"
+
+```
+
+
+
+### [#](#Èç¹ûÎÒ²»ÓÃdevtool-»¹ÓÐʲôѡÔñ) Èç¹ûÎÒ²»ÓÃdevtool£¬»¹ÓÐʲôѡÔñ£¿
+
+> Èç¹ûÎÒ²»ÓÃdevtool£¬»¹ÓÐʲôѡÔñ£¿
+
+**ÔÚʵ¼ÊµÄ¿ª·¢¹ý³ÌÖУ¬ÎÒÒ²²»»áȥʹÓÃdevtool¹¤¾ß**, ÒòΪ£º
+
+* devtool±¾Éí»ùÓÚÖØÆô·½Ê½£¬ÕâÖÖÈÔÈ»²»ÊÇÕæÕýµÄÈÈÌæ»»·½°¸£¬JRebel²ÅÊÇ£¨ËüÊÇÊշѵģ©
+* ¿ª·¢µ÷ÊÔ×îÖØÒªµÄ»¹ÊÇÒ»ÖÖȨºâ
+ * ×Ô¶¯ÖØÆôµÄ¿ªÏúÈç¹ûºÍÊÖ¶¯ÖØÆôûÓÐʲô̫´ó²î±ð£¬ÄÇô»¹²»ÈçÊÖ¶¯ÖØÆô£¨°´ÐèÖØÆô£©
+ * ¶àÊýÇé¿öÏ£¬Èç¹ûÊÇ**·½·¨ÄÚ²¿µÄÐ޸ĻòÕß¾²Ì¬×ÊÔ´µÄÐÞ¸Ä**£¬ÔÚIDEAÖÐÊÇ¿ÉÒÔͨ¹ýRebuild£¨Ctrl + Shift + F9£©½øÐÐÈȸüµÄ
+
+
+
+* ´ËÍ⻹ÓÐÒ»¸ö¹¤¾ßspring loaded£¬ ¿ÉʵÏÖÐÞ¸ÄÀàÎļþµÄÈȲ¿Ê𣬾ßÌå¿É¿´Æä[githubµØÖ·ÔÚд°¿Ú´ò¿ª](https://github.com/spring-projects/spring-loaded)ÉϵÄ˵Ã÷¡£
+
+## [#](#ʾÀýÔ´Âë) ʾÀýÔ´Âë
+
+https://github.com/realpdai/tech-pdai-spring-demos
+
+## [#](#²Î¿¼ÎÄÕÂ) ²Î¿¼ÎÄÕÂ
+
+https://docs.spring.io/spring-boot/docs/current/reference/html/using.html#using.devtools
+
+https://liayun.blog.csdn.net/article/details/116541775
+
+* * *
+
+Öø×÷Ȩ¹é@pdaiËùÓÐ ÔÎÄÁ´½Ó£ºhttps://pdai.tech/md/spring/springboot/springboot-x-hello-devtool.html
\ No newline at end of file
diff --git "a/docs/spring/SpringBoot/SpringBoot\351\233\206\346\210\220Swagger\345\256\236\347\216\260API\346\226\207\346\241\243\350\207\252\345\212\250\347\224\237\346\210\220.md" "b/docs/spring/SpringBoot/SpringBoot\351\233\206\346\210\220Swagger\345\256\236\347\216\260API\346\226\207\346\241\243\350\207\252\345\212\250\347\224\237\346\210\220.md"
new file mode 100644
index 0000000..e225d74
--- /dev/null
+++ "b/docs/spring/SpringBoot/SpringBoot\351\233\206\346\210\220Swagger\345\256\236\347\216\260API\346\226\207\346\241\243\350\207\252\345\212\250\347\224\237\346\210\220.md"
@@ -0,0 +1,625 @@
+
+
+Ŀ¼
+
+* [SwaggerµÄ½éÉÜ](https://www.cnblogs.com/progor/p/13297904.html#swagger%E7%9A%84%E4%BB%8B%E7%BB%8D)
+ * [ÓŵãÓëȱµã](https://www.cnblogs.com/progor/p/13297904.html#%E4%BC%98%E7%82%B9%E4%B8%8E%E7%BC%BA%E7%82%B9)
+* [Ìí¼Óswagger](https://www.cnblogs.com/progor/p/13297904.html#%E6%B7%BB%E5%8A%A0swagger)
+ * [1.Ìí¼ÓÒÀÀµ°ü£º](https://www.cnblogs.com/progor/p/13297904.html#1%E6%B7%BB%E5%8A%A0%E4%BE%9D%E8%B5%96%E5%8C%85)
+ * [2.ÅäÖÃSwagger:](https://www.cnblogs.com/progor/p/13297904.html#2%E9%85%8D%E7%BD%AEswagger)
+ * [3.²âÊÔ](https://www.cnblogs.com/progor/p/13297904.html#3%E6%B5%8B%E8%AF%95)
+* [³¡¾°£º](https://www.cnblogs.com/progor/p/13297904.html#%E5%9C%BA%E6%99%AF)
+ * [¶¨Òå½Ó¿Ú×é](https://www.cnblogs.com/progor/p/13297904.html#%E5%AE%9A%E4%B9%89%E6%8E%A5%E5%8F%A3%E7%BB%84)
+ * [¶¨Òå½Ó¿Ú](https://www.cnblogs.com/progor/p/13297904.html#%E5%AE%9A%E4%B9%89%E6%8E%A5%E5%8F%A3)
+ * [¶¨Òå½Ó¿ÚÇëÇó²ÎÊý](https://www.cnblogs.com/progor/p/13297904.html#%E5%AE%9A%E4%B9%89%E6%8E%A5%E5%8F%A3%E8%AF%B7%E6%B1%82%E5%8F%82%E6%95%B0)
+ * [³¡¾°Ò»£ºÇëÇó²ÎÊýÊÇʵÌåÀà¡£](https://www.cnblogs.com/progor/p/13297904.html#%E5%9C%BA%E6%99%AF%E4%B8%80%E8%AF%B7%E6%B1%82%E5%8F%82%E6%95%B0%E6%98%AF%E5%AE%9E%E4%BD%93%E7%B1%BB)
+ * [³¡¾°¶þ£ºÇëÇó²ÎÊýÊÇ·ÇʵÌåÀà¡£](https://www.cnblogs.com/progor/p/13297904.html#%E5%9C%BA%E6%99%AF%E4%BA%8C%E8%AF%B7%E6%B1%82%E5%8F%82%E6%95%B0%E6%98%AF%E9%9D%9E%E5%AE%9E%E4%BD%93%E7%B1%BB)
+ * [¶¨Òå½Ó¿ÚÏìÓ¦](https://www.cnblogs.com/progor/p/13297904.html#%E5%AE%9A%E4%B9%89%E6%8E%A5%E5%8F%A3%E5%93%8D%E5%BA%94)
+ * [ÏìÓ¦ÊÇʵÌåÀࣺ](https://www.cnblogs.com/progor/p/13297904.html#%E5%93%8D%E5%BA%94%E6%98%AF%E5%AE%9E%E4%BD%93%E7%B1%BB)
+ * [ÏìÓ¦ÊÇ·ÇʵÌåÀࣺ](https://www.cnblogs.com/progor/p/13297904.html#%E5%93%8D%E5%BA%94%E6%98%AF%E9%9D%9E%E5%AE%9E%E4%BD%93%E7%B1%BB)
+* [Swagger UIÔöÇ¿](https://www.cnblogs.com/progor/p/13297904.html#swagger-ui%E5%A2%9E%E5%BC%BA)
+ * [UI¶Ô±È£º](https://www.cnblogs.com/progor/p/13297904.html#ui%E5%AF%B9%E6%AF%94)
+ * [ʹÓÃ](https://www.cnblogs.com/progor/p/13297904.html#%E4%BD%BF%E7%94%A8)
+ * [Óŵã](https://www.cnblogs.com/progor/p/13297904.html#%E4%BC%98%E7%82%B9)
+* [ÕûºÏSpring Security×¢Òâ](https://www.cnblogs.com/progor/p/13297904.html#%E6%95%B4%E5%90%88spring-security%E6%B3%A8%E6%84%8F)
+* [¶ÔÓÚtokenµÄ´¦Àí](https://www.cnblogs.com/progor/p/13297904.html#%E5%AF%B9%E4%BA%8Etoken%E7%9A%84%E5%A4%84%E7%90%86)
+* [SwaggerµÄ°²È«¹ÜÀí](https://www.cnblogs.com/progor/p/13297904.html#swagger%E7%9A%84%E5%AE%89%E5%85%A8%E7%AE%A1%E7%90%86)
+
+
+
+* * *
+
+# SwaggerµÄ½éÉÜ
+
+?Äã¿ÉÄܳ¢ÊÔ¹ýдÍêÒ»¸ö½Ó¿Úºó£¬×Ô¼ºÈ¥´´½¨½Ó¿ÚÎĵµ£¬»òÕßÐ޸ĽӿںóÐ޸ĽӿÚÎĵµ¡£¶àÁËÖ®ºó£¬Äã¿Ï¶¨»á·¢ÉúÒ»¸ö²Ù×÷£¬ÄǾÍÊÇÍü¼ÇÁËÐÞ¸ÄÎĵµ»òÕß´´½¨Îĵµ£¨³ý·ÇÄãÃǹ«Ë¾°Ñ½Ó¿ÚÎĵµºÍд½Ó¿ÚÒªÇóµÃºÜ½ôÃÜ?Íü¼ÇдÎĵµ¾Í¿Û¹¤×Ê£¿£¬·ñÔòÁ½¸ö·ÖÀëµÄ¹¤×÷×ÜÊÇÓпÉÄÜÒÅ©µÄ£©¡£¶øswagger¾ÍÊÇÒ»¸öÔÚÄãд½Ó¿ÚµÄʱºò×Ô¶¯°ïÄãÉú³É½Ó¿ÚÎĵµµÄ¶«Î÷£¬Ö»ÒªÄã×ñÑËüµÄ¹æ·¶²¢Ð´Ò»Ð©½Ó¿ÚµÄ˵Ã÷×¢½â¼´¿É¡£
+
+## ÓŵãÓëȱµã
+
+?Óŵ㣺
+
+* ×Ô¶¯Éú³ÉÎĵµ£¬Ö»ÐèÒªÔÚ½Ó¿ÚÖÐʹÓÃ×¢½â½øÐбê×¢£¬¾ÍÄÜÉú³É¶ÔÓ¦µÄ½Ó¿ÚÎĵµ¡£
+* ×Ô¶¯¸üÐÂÎĵµ£¬ÓÉÓÚÊǶ¯Ì¬Éú³ÉµÄ£¬ËùÒÔÈç¹ûÄãÐÞ¸ÄÁ˽ӿڣ¬ÎĵµÒ²»á×Ô¶¯¶ÔÓ¦Ð޸ģ¨Èç¹ûÄãÒ²¸üÐÂÁË×¢½âµÄ»°£©¡£ÕâÑù¾Í²»»á·¢ËÍÎÒÐÞ¸ÄÁ˽ӿڣ¬È´Íü¼Ç¸üнӿÚÎĵµµÄÇé¿ö¡£
+* Ö§³ÖÔÚÏßµ÷ÊÔ£¬swaggerÌṩÁËÔÚÏßµ÷ÓýӿڵŦÄÜ¡£
+
+?ȱµã£º
+
+* ²»ÄÜ´´½¨²âÊÔÓÃÀý£¬ËùÒÔËûÔÝʱ²»ÄܰïÄã´¦ÀíÍêËùÓеÄÊÂÇé¡£ËûÖ»ÄÜÌṩһ¸ö¼òµ¥µÄÔÚÏßµ÷ÊÔ£¬Èç¹ûÄãÏë´æ´¢ÄãµÄ²âÊÔÓÃÀý£¬¿ÉÒÔʹÓÃPostman»òÕßYAPIÕâÑùÖ§³Ö´´½¨²âÊÔÓû§µÄ¹¦ÄÜ¡£
+* Òª×ñÑһЩ¹æ·¶£¬Ëü²»ÊÇÈÎÒâ¹æ·¶µÄ¡£±ÈÈç˵£¬Äã¿ÉÄܻ᷵»ØÒ»¸öjsonÊý¾Ý£¬¶øÕâ¸öÊý¾Ý¿ÉÄÜÊÇÒ»¸öMap¸ñʽµÄ£¬ÄÇôÎÒÃÇ´Ëʱ²»Äܱê×¢Õâ¸öMap¸ñʽµÄ·µ»ØÊý¾ÝµÄÿ¸ö×ֶεÄ˵Ã÷£¬¶øÈç¹ûËüÊÇÒ»¸öʵÌåÀàµÄ»°£¬ÎÒÃÇ¿ÉÒÔͨ¹ý±ê×¢ÀàµÄÊôÐÔÀ´¸ø·µ»Ø×ֶμÓ˵Ã÷¡£Ò²±ÈÈç˵£¬¶ÔÓÚswagger£¬²»ÍƼöÔÚʹÓÃGET·½Ê½Ìá½»Êý¾ÝµÄʱºò»¹Ê¹ÓÃBody£¬½öÍÆ¼öʹÓÃquery²ÎÊý¡¢header²ÎÊý»òÕß·¾¶²ÎÊý£¬µ±È»ÁËÕâ¸öÏÞÖÆÖ»ÊÊÓÃÓÚÔÚÏßµ÷ÊÔ¡£
+* ûÓнӿÚÎĵµ¸üйÜÀí£¬ËäȻһ¸ö½Ó¿Ú¸üÐÂÖ®ºó£¬¿ÉÄܲ»»á¹ØÐľɰæµÄ½Ó¿ÚÐÅÏ¢£¬µ«Äã¡°¿ÉÄÜ¡±Ïë¿´¿´¾É°æµÄ½Ó¿ÚÐÅÏ¢£¬ÀýÈçÓÐЩ»Ò¶È¸üз¢²¼µÄʱºò¿ÉÄÜ»¹»á¹ØÐľɰæµÄ½Ó¿Ú¡£ÄÇô´ËʱֻÄÜÓɺó¶ËÈ¥¿´¿´ÓÐûÓÐ×¢ÊÍÁôÏÂÁË£¬ËùÒÔ¿ÉÒÔ¿¼ÂǽӿÚÎĵµ´ó¸üеÄʱºò×¢Ê;ɰæµÄ£¬È»ºóдÏÂаæµÄ¡£¡¾µ±È»Õâ¸öÎÊÌâ¿ÉÒÔͨ¹ýµ¼³ö½Ó¿ÚÎĵµÀ´¶Ô±È¡£¡¿
+* ËäÈ»ÏÖÔÚJavaµÄʵÌåÀàÖÐÓв»ÉÙÄ£ÐÍ£¬po,dto,voµÈ£¬Ä£Ð͵ÄÇø·ÖÊÇΪÁËÆÁ±ÎһЩ¶àÓà²ÎÊý£¬±ÈÈçÒ»¸öÓû§µÇ¼µÄʱºòÖ»ÐèÒªusername,password£¬µ«²éȨÏÞµÄʱºòÐèÒªÁ¬½ÓÉÏȨÏÞ±íµÄÐÅÏ¢£¬¶øÈç¹ûÉÏÊöÁ½¸ö²Ù×÷¶¼ÊÇʹÓÃÁËUserÕâ¸öʵÌåµÄ»°£¬ÔÚÎĵµÖоͻá×Ô¶¯Éú³ÉÁ˶àÓàµÄÐÅÏ¢£¬Õâ¾ÍÒªÇóÁËÄã»ùÓÚÄ£ÐÍÀ´´´½¨¶à¸öʵÌåÀ࣬±ÈÈçµÇ¼µÄʱºòÒ»¸öLoginForm£¬ÐèÒªÓû§-ȨÏÞµÈÐÅÏ¢µÄʱºò²ÅʹÓÃUserÀà¡££¨µ±È»ÁË£¬Õâ¸öÎÊÌâµÈÄã»áswaggerÖ®ºóÄã¾Í´ó¸Å¾Í»áÔõô¹æ±ÜÕâ¸öÎÊÌâÁË¡££©
+
+?ÉÏÃæµÄȱµãºÃÏñдµÄÓеã¶à£¬Äã¿ÉÄÜ»á¾õµÃswaggerÕâ¸ö¿ÓÓеã´ó¡£µ«ÆäʵÖ÷ÒªÊǹ淶ÎÊÌ⣬¶ø¹æ·¶ÎÊÌâÓÐʱºòÓÖ»áÌá¸ßÄãµÄ´úÂë¹æ·¶ÐÔ£¬Õâ¸ö¾Í¼ûÈʼûÖÇÁË£¬ÄãÒÔǰ¿ÉÄÜʲô½Ó¿ÚµÄ²ÎÊý¶¼Ê¹ÓÃÒ»¸öÀ࣬¶øÏÖÔÚswaggerÒªÇóÄã·Ö¿ªºó£¬Ä³ÖÖ²ã´ÎÉÏÌá¸ßÁËÄãµÄ´úÂë¹æ·¶ÐÔ¡£
+
+?×¢£ºÒÔÏ´úÂëʾÀý»ùÓÚSpring Boot¡£ÍêÕû´úÂë¿ÉÒԲο¼£º[swagger-demo](https://github.com/alprogor/swagger-demo)
+
+* * *
+
+# Ìí¼Óswagger
+
+?ÕâÀïÏȽ²Ìí¼Óswagger£¬Ò²¾ÍÊÇÏÈÕûºÏ½øÀ´£¬ÖÁÓÚÔõôʹÓã¬ÏÂÃæµÄ¡°³¡¾°¡±ÖÐÔÙ½²½â¡£
+
+## 1.Ìí¼ÓÒÀÀµ°ü£º
+
+?×¢Ò⣬ÕâÀïµÄǰÌáÊÇÒѾµ¼ÈëÁËspring bootµÄweb°ü¡£
+
+¸´ÖÆ´úÂë
+
+```
+
+ io.springfox
+ springfox-swagger2
+ 2.9.2
+
+
+ io.springfox
+ springfox-swagger-ui
+ 2.9.2
+
+
+```
+
+## 2.ÅäÖÃSwagger:
+
+ҪʹÓÃswagger£¬ÎÒÃDZØÐë¶Ôswagger½øÐÐÅäÖã¬ÎÒÃÇÐèÒª´´½¨Ò»¸öswaggerµÄÅäÖÃÀ࣬±ÈÈç¿ÉÒÔÃüÃûΪSwaggerConfig.java
+
+¸´ÖÆ´úÂë
+
+```
+package com.example.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+@Configuration // ±êÃ÷ÊÇÅäÖÃÀà
+@EnableSwagger2 //¿ªÆôswagger¹¦ÄÜ
+public class SwaggerConfig {
+ @Bean
+ public Docket createRestApi() {
+ return new Docket(DocumentationType.SWAGGER_2) // DocumentationType.SWAGGER_2 ¹Ì¶¨µÄ£¬´ú±íswagger2
+// .groupName("·Ö²¼Ê½ÈÎÎñϵͳ") // Èç¹ûÅäÖöà¸öÎĵµµÄʱºò£¬ÄÇôÐèÒªÅäÖÃgroupNameÀ´·Ö×é±êʶ
+ .apiInfo(apiInfo()) // ÓÃÓÚÉú³ÉAPIÐÅÏ¢
+ .select() // select()º¯Êý·µ»ØÒ»¸öApiSelectorBuilderʵÀý,ÓÃÀ´¿ØÖƽӿڱ»swagger×ö³ÉÎĵµ
+ .apis(RequestHandlerSelectors.basePackage("com.example.controller")) // ÓÃÓÚÖ¸¶¨É¨ÃèÄĸö°üϵĽӿÚ
+ .paths(PathSelectors.any())// Ñ¡ÔñËùÓеÄAPI,Èç¹ûÄãÏëֻΪ²¿·ÖAPIÉú³ÉÎĵµ£¬¿ÉÒÔÅäÖÃÕâÀï
+ .build();
+ }
+
+ /**
+ * ÓÃÓÚ¶¨ÒåAPIÖ÷½çÃæµÄÐÅÏ¢£¬±ÈÈç¿ÉÒÔÉùÃ÷ËùÓеÄAPIµÄ×ܱêÌâ¡¢ÃèÊö¡¢°æ±¾
+ * @return
+ */
+ private ApiInfo apiInfo() {
+ return new ApiInfoBuilder()
+ .title("XXÏîÄ¿API") // ¿ÉÒÔÓÃÀ´×Ô¶¨ÒåAPIµÄÖ÷±êÌâ
+ .description("XXÏîÄ¿SwaggerAPI¹ÜÀí") // ¿ÉÒÔÓÃÀ´ÃèÊöÕûÌåµÄAPI
+ .termsOfServiceUrl("") // ÓÃÓÚ¶¨Òå·þÎñµÄÓòÃû
+ .version("1.0") // ¿ÉÒÔÓÃÀ´¶¨Òå°æ±¾¡£
+ .build(); //
+ }
+}
+
+```
+
+## 3.²âÊÔ
+
+ÔËÐÐÎÒÃǵÄSpring BootÏîÄ¿£¬£¨ÎÒĬÈÏÊÇ8080¶Ë¿Ú£¬Èç¹ûÄã²»Ò»Ñù£¬Çë×¢ÒâÐ޸ĺóÐøµÄurl£©£¬·ÃÎÊ`http://localhost:8080/swagger-ui.html`
+È»ºóÄã¾Í¿ÉÒÔ¿´µ½Ò»¸öÈçϵĽçÃæ£¬ÓÉÓÚÎÒÃÇÔÝʱûÓÐÅäÖýӿÚÊý¾Ý£¬ËùÒÔÏÂÃæÏÔʾ`No operations defined in spec!`
+
+
+
+?ÏÂÃæÎÒÃǽ«½éÉÜÈçºÎ¶¨Òå½Ó¿Ú£¬ÒÔ¼°ÔÚswagger UI½çÃæÖеÄÄÚÈÝ¡£
+
+* * *
+
+# ³¡¾°£º
+
+## ¶¨Òå½Ó¿Ú×é
+
+½Ó¿ÚÓÐʱºòÓ¦¸ÃÊÇ·Ö×éµÄ£¬¶øÇҴ󲿷ֶ¼ÊÇÔÚÒ»¸öcontrollerÖе쬱ÈÈçÓû§¹ÜÀíÏà¹ØµÄ½Ó¿ÚÓ¦¸Ã¶¼ÔÚUserControllerÖУ¬ÄÇô²»Í¬µÄÒµÎñµÄʱºò£¬Ó¦¸Ã¶¨Òå/»®·Ö²»Í¬µÄ½Ó¿Ú×é¡£½Ó¿Ú×é¿ÉÒÔʹÓÃ`@Api`À´»®·Ö¡£
+±ÈÈ磺
+
+¸´ÖÆ´úÂë
+
+```
+@Api(tags = "½ÇÉ«¹ÜÀí") // tags£ºÄã¿ÉÒÔµ±×÷ÊÇÕâ¸ö×éµÄÃû×Ö¡£
+@RestController
+public class RoleController {
+}
+
+```
+
+ºÍ
+
+¸´ÖÆ´úÂë
+
+```
+@Api(tags = "Óû§¹ÜÀí") // tags£ºÄã¿ÉÒÔµ±×÷ÊÇÕâ¸ö×éµÄÃû×Ö¡£
+@RestController
+public class UserController {
+}
+
+```
+
+?ÄãÒ²¿ÉÒÔÀí½â³É»ùÓÚtagsÀ´·Ö×飬¾ÍºÃÏñһЩÎÄÕÂÀïÃæµÄ±êǩһÑù£¬Ê¹ÓñêÇ©À´·ÖÀà¡£
+?Èç¹ûÕâ¸öControllerÏ£¨½Ó¿Ú×飩ÏÂÃæÃ»Óнӿڣ¬ÄÇôÔÚswagger uiÖÐÊDz»»áÏÔʾµÄ£¬Èç¹ûÓеϰ¾Í»áÕâÑùÏÔʾ£º
+
+
+## ¶¨Òå½Ó¿Ú
+
+ʹÓÃÁË`@Api`À´±ê×¢Ò»¸öControllerÖ®ºó£¬Èç¹ûÏÂÃæÓнӿڣ¬ÄÇô¾Í»áĬÈÏÉú³ÉÎĵµ£¬µ«Ã»ÓÐÎÒÃÇ×Ô¶¨ÒåµÄ˵Ã÷£º
+
+¸´ÖÆ´úÂë
+
+```
+@Api(tags = "Óû§¹ÜÀí")
+@RestController
+public class UserController {
+ // ×¢Ò⣬¶ÔÓÚswagger£¬²»ÒªÊ¹ÓÃ@RequestMapping£¬
+ // ÒòΪ@RequestMappingÖ§³ÖÈÎÒâÇëÇó·½Ê½£¬swagger»áΪÕâ¸ö½Ó¿ÚÉú³É7ÖÖÇëÇó·½Ê½µÄ½Ó¿ÚÎĵµ
+ @GetMapping("/info")
+ public String info(String id){
+ return "aaa";
+ }
+}
+
+```
+
+
+
+
+
+ÎÒÃÇ¿ÉÒÔʹÓÃ`@ApiOperation`À´ÃèÊö½Ó¿Ú£¬±ÈÈ磺
+
+¸´ÖÆ´úÂë
+
+```
+ @ApiOperation(value = "Óû§²âÊÔ",notes = "Óû§²âÊÔnotes")
+ @GetMapping("/test")
+ public String test(String id){
+ return "test";
+ }
+
+```
+
+
+³£ÓÃÅäÖÃÏ
+
+* value£º¿ÉÒÔµ±×÷Êǽӿڵļò³Æ
+* notes£º½Ó¿ÚµÄÃèÊö
+* tags£º¿ÉÒÔ¶îÍⶨÒå½Ó¿Ú×飬±ÈÈçÕâ¸ö½Ó¿ÚÍâ²ãÒѾÓÐ`@Api(tags = "Óû§¹ÜÀí")`£¬½«½Ó¿Ú»®·Öµ½ÁË¡°Óû§¹ÜÀí¡±ÖУ¬µ«Äã¿ÉÒÔ¶îÍâµÄʹÓÃtags£¬ÀýÈç`tags = "½ÇÉ«¹ÜÀí"`ÈýÇÉ«¹ÜÀíÖÐÒ²ÓÐÕâ¸ö½Ó¿ÚÎĵµ¡£
+
+## ¶¨Òå½Ó¿ÚÇëÇó²ÎÊý
+
+ÉÏÃæÊ¹ÓÃÁË`@ApiOperation`À´ÁËÃèÊö½Ó¿Ú£¬µ«Æäʵ»¹È±ÉÙ½Ó¿ÚÇëÇó²ÎÊýµÄ˵Ã÷£¬ÏÂÃæÎÒÃÇ·Ö³¡¾°À´½²¡£
+?×¢Òâһϣ¬**¶ÔÓÚGET·½Ê½£¬swagger²»ÍƼöʹÓÃbody·½Ê½À´´«µÝÊý¾Ý**£¬Ò²¾ÍÊDz»Ï£ÍûÔÚGET·½Ê½Ê±Ê¹ÓÃjson¡¢form-dataµÈ·½Ê½À´´«µÝ£¬Õâʱºò×îºÃʹÓ÷¾¶²ÎÊý»òÕßurl²ÎÊý¡£(?ËäÈ»POSTMANµÈÊÇÖ§³ÖµÄ)£¬ËùÒÔÈç¹û½Ó¿Ú´«µÝµÄÊý¾ÝÊÇjson»òÕßform-data·½Ê½µÄ£¬»¹ÊÇʹÓÃPOST·½Ê½ºÃ¡£
+
+### ³¡¾°Ò»£ºÇëÇó²ÎÊýÊÇʵÌåÀà¡£
+
+´ËʱÎÒÃÇÐèҪʹÓÃ`@ApiModel`À´±êעʵÌåÀ࣬ȻºóÔÚ½Ó¿ÚÖж¨ÒåÈë²ÎΪʵÌåÀ༴¿É£º
+
+* @ApiModel£ºÓÃÀ´±êÀà
+ * ³£ÓÃÅäÖÃÏ
+ * value£ºÊµÌåÀà¼ò³Æ
+ * description£ºÊµÌåÀà˵Ã÷
+* @ApiModelProperty£ºÓÃÀ´ÃèÊöÀàµÄ×ֶεÄÒâÒå¡£
+ * ³£ÓÃÅäÖÃÏ
+ * value£º×Ö¶Î˵Ã÷
+ * example£ºÉèÖÃÇëÇóʾÀý£¨Example Value£©µÄĬÈÏÖµ£¬Èç¹û²»ÅäÖ㬵±×Ö¶ÎΪstringµÄʱºò£¬´ËʱÇëÇóʾÀýÖÐĬÈÏֵΪ"".
+ * name£ºÓÃеÄ×Ö¶ÎÃûÀ´Ìæ´ú¾ÉµÄ×Ö¶ÎÃû¡£
+ * allowableValues£ºÏÞÖÆÖµµÃ·¶Î§£¬ÀýÈç`{1,2,3}`´ú±íÖ»ÄÜÈ¡ÕâÈý¸öÖµ£»`[1,5]`´ú±íÈ¡1µ½5µÄÖµ£»`(1,5)`´ú±í1µ½5µÄÖµ£¬²»°üÀ¨1ºÍ5£»»¹¿ÉÒÔʹÓÃinfinity»ò-infinityÀ´ÎÞÏÞÖµ£¬±ÈÈç`[1, infinity]`´ú±í×îСֵΪ1£¬×î´óÖµÎÞÇî´ó¡£
+ * required£º±ê¼Ç×Ö¶ÎÊÇ·ñ±ØÌĬÈÏÊÇfalse,
+ * hidden£ºÓÃÀ´Òþ²Ø×ֶΣ¬Ä¬ÈÏÊÇfalse£¬Èç¹ûÒªÒþ²ØÐèҪʹÓÃtrue£¬ÒòΪ×Ö¶ÎĬÈ϶¼»áÏÔʾ£¬¾ÍËãûÓÐ`@ApiModelProperty`¡£
+
+¸´ÖÆ´úÂë
+
+```
+// ÏÈʹÓÃ@ApiModelÀ´±ê×¢Àà
+@ApiModel(value="Óû§µÇ¼±íµ¥¶ÔÏó",description="Óû§µÇ¼±íµ¥¶ÔÏó")
+public class LoginForm {
+ // ʹÓÃApiModelPropertyÀ´±ê×¢×Ö¶ÎÊôÐÔ¡£
+ @ApiModelProperty(value = "Óû§Ãû",required = true,example = "root")
+ private String username;
+ @ApiModelProperty(value = "ÃÜÂë",required = true,example = "123456")
+ private String password;
+
+ // ´Ë´¦Ê¡ÂÔÈë²Î¸³ÖµÊ±ÐèÒªµÄgetter,setter,swaggerÒ²ÐèÒªÕâ¸ö
+}
+
+```
+
+¶¨Òå³ÉÈë²Î£º
+
+¸´ÖÆ´úÂë
+
+```
+ @ApiOperation(value = "µÇ¼½Ó¿Ú",notes = "µÇ¼½Ó¿ÚµÄ˵Ã÷")
+ @PostMapping("/login")
+ public LoginForm login(@RequestBody LoginForm loginForm){
+ return loginForm;
+ }
+
+```
+
+Ч¹û£º
+
+
+
+### ³¡¾°¶þ£ºÇëÇó²ÎÊýÊÇ·ÇʵÌåÀà¡£
+
+£¨**ÔÙ˵һ´Î£º¶ÔÓÚGET·½Ê½£¬swagger²»ÍƼöʹÓÃbody·½Ê½À´´«µÝÊý¾Ý£¬ËùÒÔËäÈ»Spring MVC¿ÉÒÔ×Ô¶¯·â×°²ÎÊý£¬µ«¶ÔÓÚGETÇëÇó»¹ÊDz»ÒªÊ¹ÓÃform-data£¬jsonµÈ·½Ê½´«µÝ²ÎÊý£¬³ý·ÇÄãʹÓÃPostmanÀ´²âÊÔ½Ó¿Ú£¬swaggerÔÚÏß²âÊÔÊDz»Ö§³ÖÕâ¸ö²Ù×÷µÄ**£©
+¶ÔÓÚ·ÇʵÌåÀà²ÎÊý£¬¿ÉÒÔʹÓÃ`@ApiImplicitParams`ºÍ`@ApiImplicitParam`À´ÉùÃ÷ÇëÇó²ÎÊý¡£
+`@ApiImplicitParams`ÓÃÔÚ·½·¨Í·ÉÏ£¬`@ApiImplicitParam`¶¨ÒåÔÚ`@ApiImplicitParams`ÀïÃæ£¬Ò»¸ö`@ApiImplicitParam`¶ÔÓ¦Ò»¸ö²ÎÊý¡£
+`@ApiImplicitParam`³£ÓÃÅäÖÃÏ
+
+* name£ºÓÃÀ´¶¨Òå²ÎÊýµÄÃû×Ö£¬Ò²¾ÍÊÇ×ֶεÄÃû×Ö,¿ÉÒÔÓë½Ó¿ÚµÄÈë²ÎÃû¶ÔÓ¦¡£**Èç¹û²»¶ÔÓ¦£¬Ò²»áÉú³É£¬ËùÒÔ¿ÉÒÔÓÃÀ´¶¨Òå¶îÍâ²ÎÊý£¡**
+* value£ºÓÃÀ´ÃèÊö²ÎÊý
+* required£ºÓÃÀ´±ê×¢²ÎÊýÊÇ·ñ±ØÌî
+* paramTypeÓÐpath,query,body,form,headerµÈ·½Ê½£¬µ«¶ÔÓÚ¶ÔÓÚ·ÇʵÌåÀà²ÎÊýµÄʱºò£¬³£ÓõÄÖ»ÓÐpath,query,header£»bodyºÍformÊDz»³£Óõġ£body²»ÊÊÓÃÓÚ¶à¸öÁãÉ¢²ÎÊýµÄÇé¿ö£¬Ö»ÊÊÓÃÓÚjson¶ÔÏóµÈÇé¿ö¡£¡¾Èç¹ûÄãµÄ½Ó¿ÚÊÇ`form-data`,`x-www-form-urlencoded`µÄʱºò¿ÉÄܲ»ÄÜʹÓÃswaggerÒ³ÃæAPIµ÷ÊÔ£¬µ«¿ÉÒÔÔÚºóÃæ½²µ½»ùÓÚBootstrapUIµÄswaggerÔöÇ¿Öе÷ÊÔ£¬»ùÓÚBootstrapUIµÄswaggerÖ§³ÖÖ¸¶¨`form-data`»ò`x-www-form-urlencoded`¡¿
+
+ʾÀýÒ»£ºÉùÃ÷Èë²ÎÊÇURL²ÎÊý
+
+¸´ÖÆ´úÂë
+
+```
+ // ʹÓÃURL query²ÎÊý
+ @ApiOperation(value = "µÇ¼½Ó¿Ú2",notes = "µÇ¼½Ó¿ÚµÄ˵Ã÷2")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "username",//²ÎÊýÃû×Ö
+ value = "Óû§Ãû",//²ÎÊýµÄÃèÊö
+ required = true,//ÊÇ·ñ±ØÐë´«Èë
+ //paramType¶¨Òå²ÎÊý´«µÝÀàÐÍ£ºÓÐpath,query,body,form,header
+ paramType = "query"
+ )
+ ,
+ @ApiImplicitParam(name = "password",//²ÎÊýÃû×Ö
+ value = "ÃÜÂë",//²ÎÊýµÄÃèÊö
+ required = true,//ÊÇ·ñ±ØÐë´«Èë
+ paramType = "query"
+ )
+ })
+ @PostMapping(value = "/login2")
+ public LoginForm login2(String username,String password){
+ System.out.println(username+":"+password);
+ LoginForm loginForm = new LoginForm();
+ loginForm.setUsername(username);
+ loginForm.setPassword(password);
+ return loginForm;
+ }
+
+```
+
+ʾÀý¶þ£ºÉùÃ÷Èë²ÎÊÇURL·¾¶²ÎÊý
+
+¸´ÖÆ´úÂë
+
+```
+ // ʹÓ÷¾¶²ÎÊý
+ @PostMapping("/login3/{id1}/{id2}")
+ @ApiOperation(value = "µÇ¼½Ó¿Ú3",notes = "µÇ¼½Ó¿ÚµÄ˵Ã÷3")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "id1",//²ÎÊýÃû×Ö
+ value = "Óû§Ãû",//²ÎÊýµÄÃèÊö
+ required = true,//ÊÇ·ñ±ØÐë´«Èë
+ //paramType¶¨Òå²ÎÊý´«µÝÀàÐÍ£ºÓÐpath,query,body,form,header
+ paramType = "path"
+ )
+ ,
+ @ApiImplicitParam(name = "id2",//²ÎÊýÃû×Ö
+ value = "ÃÜÂë",//²ÎÊýµÄÃèÊö
+ required = true,//ÊÇ·ñ±ØÐë´«Èë
+ paramType = "path"
+ )
+ })
+ public String login3(@PathVariable Integer id1,@PathVariable Integer id2){
+ return id1+":"+id2;
+ }
+
+```
+
+ʾÀýÈý£ºÉùÃ÷Èë²ÎÊÇheader²ÎÊý
+
+¸´ÖÆ´úÂë
+
+```
+ // ÓÃheader´«µÝ²ÎÊý
+ @PostMapping("/login4")
+ @ApiOperation(value = "µÇ¼½Ó¿Ú4",notes = "µÇ¼½Ó¿ÚµÄ˵Ã÷4")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "username",//²ÎÊýÃû×Ö
+ value = "Óû§Ãû",//²ÎÊýµÄÃèÊö
+ required = true,//ÊÇ·ñ±ØÐë´«Èë
+ //paramType¶¨Òå²ÎÊý´«µÝÀàÐÍ£ºÓÐpath,query,body,form,header
+ paramType = "header"
+ )
+ ,
+ @ApiImplicitParam(name = "password",//²ÎÊýÃû×Ö
+ value = "ÃÜÂë",//²ÎÊýµÄÃèÊö
+ required = true,//ÊÇ·ñ±ØÐë´«Èë
+ paramType = "header"
+ )
+ })
+ public String login4( @RequestHeader String username,
+ @RequestHeader String password){
+ return username+":"+password;
+ }
+
+```
+
+ʾÀýËÄ£ºÉùÃ÷ÎļþÉÏ´«²ÎÊý
+
+¸´ÖÆ´úÂë
+
+```
+ // ÓÐÎļþÉÏ´«Ê±ÒªÓÃ@ApiParam£¬Ó÷¨»ù±¾Óë@ApiImplicitParamÒ»Ñù£¬²»¹ý@ApiParamÓÃÔÚ²ÎÊýÉÏ
+ // »òÕßÄãÒ²¿ÉÒÔ²»×¢½â£¬swagger»á×Ô¶¯Éú³É˵Ã÷
+ @ApiOperation(value = "ÉÏ´«Îļþ",notes = "ÉÏ´«Îļþ")
+ @PostMapping(value = "/upload")
+ public String upload(@ApiParam(value = "ͼƬÎļþ", required = true)MultipartFile uploadFile){
+ String originalFilename = uploadFile.getOriginalFilename();
+
+ return originalFilename;
+ }
+
+ // ¶à¸öÎļþÉÏ´«Ê±£¬**swaggerÖ»ÄܲâÊÔµ¥ÎļþÉÏ´«**
+ @ApiOperation(value = "ÉÏ´«¶à¸öÎļþ",notes = "ÉÏ´«¶à¸öÎļþ")
+ @PostMapping(value = "/upload2",consumes = "multipart/*", headers = "content-type=multipart/form-data")
+ public String upload2(@ApiParam(value = "ͼƬÎļþ", required = true,allowMultiple = true)MultipartFile[] uploadFile){
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < uploadFile.length; i++) {
+ System.out.println(uploadFile[i].getOriginalFilename());
+ sb.append(uploadFile[i].getOriginalFilename());
+ sb.append(",");
+ }
+ return sb.toString();
+ }
+
+ // ¼ÈÓÐÎļþ£¬ÓÖÓвÎÊý
+ @ApiOperation(value = "¼ÈÓÐÎļþ£¬ÓÖÓвÎÊý",notes = "¼ÈÓÐÎļþ£¬ÓÖÓвÎÊý")
+ @PostMapping(value = "/upload3")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "name",
+ value = "ͼƬÐÂÃû×Ö",
+ required = true
+ )
+ })
+ public String upload3(@ApiParam(value = "ͼƬÎļþ", required = true)MultipartFile uploadFile,
+ String name){
+ String originalFilename = uploadFile.getOriginalFilename();
+
+ return originalFilename+":"+name;
+ }
+
+```
+
+## ¶¨Òå½Ó¿ÚÏìÓ¦
+
+¶¨Òå½Ó¿ÚÏìÓ¦£¬ÊÇ·½±ã²é¿´½Ó¿ÚÎĵµµÄÈËÄܹ»ÖªµÀ½Ó¿Ú·µ»ØµÄÊý¾ÝµÄÒâÒå¡£
+
+### ÏìÓ¦ÊÇʵÌåÀࣺ
+
+Ç°ÃæÔÚ¶¨Òå½Ó¿ÚÇëÇó²ÎÊýµÄʱºòÓÐÌᵽʹÓÃ`@ApiModel`À´±ê×¢À࣬Èç¹û½Ó¿Ú·µ»ØÁËÕâ¸öÀ࣬ÄÇôÕâ¸öÀàÉϵÄ˵Ã÷Ò²»á×÷ΪÏìÓ¦µÄ˵Ã÷£º
+
+¸´ÖÆ´úÂë
+
+```
+ // ·µ»Ø±»@ApiModel±ê×¢µÄÀà¶ÔÏó
+ @ApiOperation(value = "ʵÌåÀàÏìÓ¦",notes = "·µ»ØÊý¾ÝΪʵÌåÀàµÄ½Ó¿Ú")
+ @PostMapping("/role1")
+ public LoginForm role1(@RequestBody LoginForm loginForm){
+ return loginForm;
+ }
+
+```
+
+
+
+### ÏìÓ¦ÊÇ·ÇʵÌåÀࣺ
+
+swaggerÎÞ·¨¶Ô·ÇʵÌåÀàµÄÏìÓ¦½øÐÐÏêϸ˵Ã÷£¬Ö»Äܱê×¢ÏìÓ¦ÂëµÈÐÅÏ¢¡£ÊÇͨ¹ý`@ApiResponses`ºÍ`@ApiResponse`À´ÊµÏֵġ£
+`@ApiResponses`ºÍ`@ApiResponse`¿ÉÒÔÓë`@ApiModel`Ò»ÆðʹÓá£
+
+¸´ÖÆ´úÂë
+
+```
+ // ÆäËûÀàÐ͵Ä,´Ëʱ²»ÄÜÔö¼Ó×Ö¶Î×¢ÊÍ£¬ËùÒÔÆäʵswaggerÍÆ¼öʹÓÃʵÌåÀà
+ @ApiOperation(value = "·ÇʵÌåÀà",notes = "·ÇʵÌåÀà")
+ @ApiResponses({
+ @ApiResponse(code=200,message = "µ÷Óóɹ¦"),
+ @ApiResponse(code=401,message = "ÎÞȨÏÞ" )
+ }
+ )
+ @PostMapping("/role2")
+ public String role2(){
+ return " {\n" +
+ " name:\"¹ã¶«\",\n" +
+ " citys:{\n" +
+ " city:[\"¹ãÖÝ\",\"ÉîÛÚ\",\"Ö麣\"]\n" +
+ " }\n" +
+ " }";
+ }
+
+```
+
+
+
+* * *
+
+# Swagger UIÔöÇ¿
+
+Äã¿ÉÄÜ»á¾õµÃÏÖÔÚÕâ¸öUI²»ÊǺܺÿ´£¬ÏÖÔÚÓÐһЩµÚÈý·½ÌṩÁËһЩSwagger UIÔöÇ¿£¬±È½ÏÁ÷ÐеÄÊÇ`swagger-bootstrap-ui`£¬ÎÒÃÇÕâÀïÒÔ`swagger-bootstrap-ui`ΪÀý¡£
+
+## UI¶Ô±È£º
+
+
+
+
+
+## ʹÓÃ
+
+1.Ìí¼ÓÒÀÀµ°ü£º
+
+¸´ÖÆ´úÂë
+
+```
+
+
+ io.springfox
+ springfox-swagger2
+ 2.9.2
+
+
+ io.springfox
+ springfox-swagger-ui
+ 2.9.2
+
+
+
+ com.github.xiaoymin
+ swagger-bootstrap-ui
+ 1.8.7
+
+
+```
+
+2.ÔÚswaggerÅäÖÃÀàÖÐÔö¼Ó×¢½â`@EnableSwaggerBootstrapUI`:
+
+¸´ÖÆ´úÂë
+
+```
+@Configuration // ±êÃ÷ÊÇÅäÖÃÀà
+@EnableSwagger2 //¿ªÆôswagger¹¦ÄÜ
+@EnableSwaggerBootstrapUI // ¿ªÆôSwaggerBootstrapUI
+public class SwaggerConfig {
+ // Ê¡ÂÔÅäÖÃÄÚÈÝ
+}
+
+```
+
+3.·ÃÎÊAPI£º`http://localhost:8080/doc.html`£¬¼´¿ÉÔ¤ÀÀµ½»ùÓÚbootstarpµÄSwagger UI½çÃæ¡£
+
+## Óŵã
+
+1.?½çÃæºÃ¿´ÁËÒ»µã
+
+2.ÉÏÃæËµ¹ýÁË£¬»ùÓÚBootstrapUIµÄswaggerÖ§³ÖÖ¸¶¨`form-data`»ò`x-www-form-urlencoded`£º
+
+
+3.Ö§³Ö¸´ÖƵ¥¸öAPIÎĵµºÍµ¼³öÈ«²¿APIÎĵµ£º
+
+
+
+
+* * *
+
+# ÕûºÏSpring Security×¢Òâ
+
+ÔÚSpring BootÕûºÏSpring SecurityºÍSwaggerµÄʱºò£¬ÐèÒªÅäÖÃÀ¹½ØµÄ·¾¶ºÍ·ÅÐеÄ·¾¶£¬×¢ÒâÊÇ·ÅÐÐÒÔϼ¸¸ö·¾¶¡£
+
+¸´ÖÆ´úÂë
+
+```
+.antMatchers("/swagger**/**").permitAll()
+.antMatchers("/webjars/**").permitAll()
+.antMatchers("/v2/**").permitAll()
+.antMatchers("/doc.html").permitAll() // Èç¹ûÄãÓÃÁËbootstarpµÄSwagger UI½çÃæ£¬¼ÓÒ»¸öÕâ¸ö¡£
+
+```
+
+* * *
+
+# ¶ÔÓÚtokenµÄ´¦Àí
+
+ÔÚswaggerÖÐÖ»Ö§³ÖÁ˼òµ¥µÄµ÷ÊÔ£¬µ«¶ÔÓÚһЩ½Ó¿Ú£¬ÎÒÃDzâÊÔµÄʱºò¿ÉÄÜÐèÒª°ÑtokenÐÅϢдµ½headerÖУ¬Ä¿Ç°ºÃÏñû¿´µ½¿ÉÒÔ×Ô¶¨Òå¼ÓÇëÇóÍ·µÄµØ·½£¿
+?·½·¨Ò»£º
+¡¡¡¡Èç¹ûÄãʹÓÃÁËSwagger BootstrapUI£¬ÄÇôÄã¿ÉÒÔÔÚ¡°Îĵµ¹ÜÀí¡±ÖÐÔö¼ÓÈ«¾Ö²ÎÊý£¬Õâ°üÀ¨ÁËÌí¼Óheader²ÎÊý¡£
+
+?·½·¨¶þ£ºÔÚswaggerÅäÖÃÀàÖÐÔö¼ÓÈ«¾Ö²ÎÊýÅäÖãº
+
+¸´ÖÆ´úÂë
+
+```
+ //Èç¹ûÓжîÍâµÄÈ«¾Ö²ÎÊý£¬±ÈÈç˵ÇëÇóÍ·²ÎÊý£¬¿ÉÒÔÕâÑùÌí¼Ó
+ ParameterBuilder parameterBuilder = new ParameterBuilder();
+ List parameters = new ArrayList();
+ parameterBuilder.name("authorization").description("ÁîÅÆ")
+ .modelRef(new ModelRef("string")).parameterType("header").required(false).build();
+ parameters.add(parameterBuilder.build());
+ return new Docket(DocumentationType.SWAGGER_2) // DocumentationType.SWAGGER_2 ¹Ì¶¨µÄ£¬´ú±íswagger2
+ .apiInfo(apiInfo()) // ÓÃÓÚÉú³ÉAPIÐÅÏ¢
+ .select() // select()º¯Êý·µ»ØÒ»¸öApiSelectorBuilderʵÀý,ÓÃÀ´¿ØÖƽӿڱ»swagger×ö³ÉÎĵµ
+ .apis(RequestHandlerSelectors.basePackage("com.example.controller")) // ÓÃÓÚÖ¸¶¨É¨ÃèÄĸö°üϵĽӿÚ
+ .paths(PathSelectors.any())// Ñ¡ÔñËùÓеÄAPI,Èç¹ûÄãÏëֻΪ²¿·ÖAPIÉú³ÉÎĵµ£¬¿ÉÒÔÅäÖÃÕâÀï
+ .build().globalOperationParameters(parameters);
+
+```
+
+?·½·¨Èý£ºÊ¹ÓÃ`@ApiImplicitParams`À´¶îÍâ±ê×¢Ò»¸öÇëÇóÍ·²ÎÊý£¬ÀýÈ磺
+
+¸´ÖÆ´úÂë
+
+```
+ // Èç¹ûÐèÒª¶îÍâµÄ²ÎÊý£¬·Ç±¾·½·¨Óõ½£¬µ«¹ýÂËÆ÷ÒªÓÃ,ÀàËÆÓÚȨÏÞtoken
+ @PostMapping("/login6")
+ @ApiOperation(value = "´øtokenµÄ½Ó¿Ú",notes = "´øtokenµÄ½Ó¿Ú")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "authorization",//²ÎÊýÃû×Ö
+ value = "ÊÚȨtoken",//²ÎÊýµÄÃèÊö
+ required = true,//ÊÇ·ñ±ØÐë´«Èë
+ paramType = "header"
+ )
+ ,
+ @ApiImplicitParam(name = "username",//²ÎÊýÃû×Ö
+ value = "Óû§Ãû",//²ÎÊýµÄÃèÊö
+ required = true,//ÊÇ·ñ±ØÐë´«Èë
+ paramType = "query"
+ )
+ })
+ public String login6(String username){
+ return username;
+ }
+
+```
+
+* * *
+
+# SwaggerµÄ°²È«¹ÜÀí
+
+1.Èç¹ûÄãÕûºÏÁËȨÏÞ¹ÜÀí£¬¿ÉÒÔ¸øswagger¼ÓÉÏȨÏÞ¹ÜÀí£¬ÒªÇó·ÃÎÊswaggerÒ³ÃæÊäÈëÓû§ÃûºÍÃÜÂ룬ÕâЩÊÇspring securityºÍshiroµÄÊÂÁË£¬ÕâÀï²»½²¡£
+
+2.Èç¹ûÄã½ö½öÊDz»ÏëÔÚÕýʽ»·¾³ÖпÉÒÔ·ÃÎÊ£¬¿ÉÒÔÔÚÕýʽ»·¾³ÖйرÕSwagger×Ô¶¯ÅäÖã¬Õâ¾Í²»»áÓÐswaggerÒ³ÃæÁË¡£Ê¹ÓÃ`@Profile({"dev","test"})`×¢½âÀ´ÏÞÖÆÖ»ÔÚdev»òÕßtestÏÂÆôÓÃSwagger×Ô¶¯ÅäÖá£
+È»ºóÔÚSpring BootÅäÖÃÎļþÖÐÐ޸ĵ±Ç°profile`spring.profiles.active=release`£¬ÖØÆôÖ®ºó£¬´ËʱÎÞ·¨·ÃÎÊ`http://localhost:8080/swagger-ui.html`
+
+* * *
+
+
+
+×÷Õߣº[progor](https://www.cnblogs.com/progor/)
+±¾ÎÄΪ×÷ÕßÔ´´£¬×ªÔØÇë×¢Ã÷³ö´¦
+
diff --git "a/docs/spring/SpringBoot/\345\237\272\344\272\216SpringBoot\344\270\255\347\232\204\345\274\200\346\272\220\347\233\221\346\216\247\345\267\245\345\205\267SpringBootAdmin.md" "b/docs/spring/SpringBoot/\345\237\272\344\272\216SpringBoot\344\270\255\347\232\204\345\274\200\346\272\220\347\233\221\346\216\247\345\267\245\345\205\267SpringBootAdmin.md"
new file mode 100644
index 0000000..fc25a2c
--- /dev/null
+++ "b/docs/spring/SpringBoot/\345\237\272\344\272\216SpringBoot\344\270\255\347\232\204\345\274\200\346\272\220\347\233\221\346\216\247\345\267\245\345\205\267SpringBootAdmin.md"
@@ -0,0 +1,294 @@
+Spring Boot Admin(SBA)ÊÇÒ»¸ö¿ªÔ´µÄÉçÇøÏîÄ¿£¬ÓÃÓÚ¹ÜÀíºÍ¼à¿Ø Spring Boot Ó¦ÓóÌÐò¡£Ó¦ÓóÌÐò¿ÉÒÔͨ¹ý http µÄ·½Ê½£¬»ò Spring Cloud ·þÎñ·¢ÏÖ»ú֯ע²áµ½ SBA ÖУ¬È»ºó¾Í¿ÉÒÔʵÏÖ¶Ô Spring Boot ÏîÄ¿µÄ¿ÉÊÓ»¯¹ÜÀíºÍ²é¿´ÁË¡£
+
+Spring Boot Admin ¿ÉÒÔ¼à¿Ø Spring Boot µ¥»ú»ò¼¯ÈºÏîÄ¿£¬ËüÌṩÏêϸµÄ½¡¿µ (Health)ÐÅÏ¢¡¢ÄÚ´æÐÅÏ¢¡¢JVM ϵͳºÍ»·¾³ÊôÐÔ¡¢À¬»ø»ØÊÕÐÅÏ¢¡¢ÈÕÖ¾ÉèÖúͲ鿴¡¢¶¨Ê±ÈÎÎñ²é¿´¡¢Spring Boot »º´æ²é¿´ºÍ¹ÜÀíµÈ¹¦ÄÜ¡£½ÓÏÂÀ´ÎÒÃÇÒ»ÆðÀ´´î½¨ºÍʹÓðɡ£
+
+Ëü×îÖÕµÄչʾЧ¹ûÈçÏ£º
+
+[](https://s5.51cto.com/oss/202201/14/5d142e8c6b544f7b981b3eff8099b3d8.png)
+
+## 1.´î½¨SBA¼à¿Ø¶Ë
+
+ÎÒÃÇÐèÒª´´½¨Ò»¸ö Spring Boot Admin ÏîÄ¿£¬ÓÃÀ´¼à¿ØºÍ¹ÜÀíÎÒÃÇµÄ Spring Boot ÏîÄ¿£¬´î½¨µÄ·½Ê½ºÍ´´½¨ÆÕͨµÄ Spring Boot ÏîÄ¿ÀàËÆ£¬¾ßÌå²½ÖèÈçÏ¡£Ê¹Óà Idea ´´½¨Ò»¸ö Spring Boot ÏîÄ¿£º
+
+[](https://s5.51cto.com/oss/202201/14/d97c492785db6ff2ded49175184ceda9.png)
+
+[](https://s3.51cto.com/oss/202201/14/8bb1f0389b95e174b56ac01ba313ec7b.png)
+
+ÕâÀïÐèҪעÒ⣬ÐèÒªÌí¼Ó Spring Boot Admin(Server)·þÎñ¶Ë¿ò¼ÜµÄÖ§³Ö£¬ÈçÏÂͼËùʾ£º
+
+[](https://s4.51cto.com/oss/202201/14/122e9f0726fde8ac0c8936c79ef12f5f.png)
+
+Ò²¾ÍÊÇ´´½¨µÄ Spring Boot ÏîÄ¿ÐèÒªÌí¼ÓÒÔÏÂÁ½¸öÖØÒªµÄ¿ò¼ÜÖ§³Ö£º
+
+
+
+
+
+```
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ de.codecentric
+ spring-boot-admin-starter-server
+
+
+```
+
+
+
+
+
+
+
+### 1.1 ¿ªÆôSBA·þÎñ
+
+´´½¨ÍêÏîĿ֮ºó£¬ÐèÒªÔÚÆô¶¯ÀàÉÏ¿ªÆô SBA ·þÎñ£º
+
+
+
+
+
+```
+import de.codecentric.boot.admin.server.config.EnableAdminServer;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@EnableAdminServer // Ìí¼Ó´ËÐдúÂë
+@SpringBootApplication
+public class SbaserverApplication {
+ public static void main(String[] args) {
+ SpringApplication.run(SbaserverApplication.class, args);
+ }
+}
+
+```
+
+
+
+
+
+### 1.2 ÅäÖÃSBA¶Ë¿ÚºÅ
+
+ÔÚ application.properties ÖÐÅäÖÃÒ»¸öÏîÄ¿µÄ¶Ë¿ÚºÅ¾Í¿ÉÒÔÖ±½ÓÆô¶¯ÁË£¬ÎÒÅäÖõĶ˿ںÅÊÇ 9001£º
+
+
+
+
+
+```
+server.port=9001
+
+```
+
+
+
+
+
+PS£ºÅäÖö˿ںŵÄÖ÷ҪĿµÄÊÇΪÁ˲»ºÍÆäËû Spring Boot ÏîÄ¿³åÍ»£¬Èç¹û SBA Êǵ¥¶À²¿Êð´Ë²½Öè¿ÉÒÔºöÂÔ¡£
+
+Æô¶¯ÏîĿ֮ºó£¬¾Í¿ÉÒÔ¿´µ½ SBA µÄÖ÷Ò³ÁË£¬ÈçÏÂͼËùʾ£º
+
+[](https://s5.51cto.com/oss/202201/14/20418ce88230b20b234f9e9c15e07f47.png)
+
+´Ëʱ SBA Öл¹Ã»ÓÐÌí¼ÓÈκÎÐèÒª¼à¿ØµÄÏîÄ¿£¬½ÓÏÂÀ´ÎÒÃÇÔÙ´´½¨Ò»¸ö Spring Boot ÏîÄ¿£¬¼ÓÈëµ½ SBA ÖÐÀ´½øÐÐ¼à¿ØºÍ¹ÜÀí°É¡£
+
+## 2.´´½¨Ò»¸öÆÕͨSpringBootÏîÄ¿
+
+Ê×ÏÈ£¬ÎÒÃÇÐèÒª´´½¨Ò»¸öÆÕͨµÄ Spring Boot ÏîÄ¿£¬¾ßÌåµÄ´´½¨²½ÖèÕâÀï¾Í²»ÑÝʾÁË¡£µ±´´½¨ºÃ Spring Boot ÏîĿ֮ºó£¬ÐèÒªÔÚÕâ¸ö Spring Boot ÏîÄ¿ÖÐÐèÒªÌí¼Ó SBA ¿Í»§¶Ë¿ò¼ÜµÄÖ§³Ö£¬Ò²¾ÍÊÇÔÚ pom.xml ÖÐÅäÖÃÈçÏÂÄÚÈÝ£º
+
+
+
+
+
+
+
+```
+
+ de.codecentric
+ spring-boot-admin-starter-client
+
+
+```
+
+
+
+
+
+È»ºóÔÚ application.properties ÎļþÖÐÅäÖà SBA ·þÎñÆ÷¶ËµØÖ·£¬Ò²¾ÍÊÇÔÛÃǵÚÒ»²½´´½¨ SBA ÏîÄ¿µÄµØÖ·£¬ÅäÖÃÄÚÈÝÈçÏ£º
+
+
+
+
+
+```
+# µ±Ç°ÏîÄ¿¶Ë¿ÚºÅ
+server.port=8080
+# Spring Boot Admin ¼à¿Ø·þÎñÆ÷¶ËµØÖ·
+spring.boot.admin.client.url=http://localhost:9001
+
+```
+
+
+
+
+
+ÆäÖС°spring.boot.admin.client.url¡±Îª SBA ¼à¿ØµØÖ·¡£
+
+## 3.SpringBootAdmin¼à¿Ø×ÜÀÀ
+
+ÅäÖÃÍêÒÔÉÏÐÅÏ¢Ö®ºó£¬´Ëʱ²é¿´ Spring Boot Admin Ò³ÃæÖоÍÓб»¼à¿ØµÄ Spring Boot ÏîÄ¿ÁË£¬ÈçÏÂͼËùʾ£º
+
+[](https://s5.51cto.com/oss/202201/14/c010770a5cdfe5fad0ad1e8f0c3b07dc.png)
+
+Ò²¿ÉÒÔµã»÷¡°Ó¦ÓÃǽ¡±²é¿´ Spring Boot Admin ÖÐËùÓб»¼à¿ØµÄ Spring Boot ÏîÄ¿£¬ÈçÏÂͼËùʾ£º
+
+[](https://s4.51cto.com/oss/202201/14/d88e33f87e116000f9717e8c19c43cc4.png)
+
+µã»÷Ó¦ÓýøÈëÏêÇéÒ³Ãæ£¬ÈçÏÂͼËùʾ£º
+
+[](https://s2.51cto.com/oss/202201/14/4c3609840ea5cb45779eafbc2b260324.png)
+
+[](https://s4.51cto.com/oss/202201/14/2912ed434d97f8dd49c27ce73252d34c.png)
+
+ʼþÈÕÖ¾Öаüº¬ Spring Boot ¸÷ÖÖ״̬µÄչʾ(UP ΪÕý³£¡¢OFFLINE ΪÒì³£)ºÍ·¢ÉúµÄʱ¼ä£¬ÈçÏÂͼËùʾ£º
+
+[](https://s5.51cto.com/oss/202201/14/5792a62fbcafe6978bfe3bd26cf1e3ab.png)
+
+## 4.SpringBootÒì³£¼à¿Ø
+
+µ±ÎÒÃÇÊÖ¶¯°Ñ±»¼à¿ØµÄ Spring Boot ÏîĿֹ֮ͣºó£¬ÔÚ Spring Boot Admin ÖоͿÉÒԲ鿴µ½Ò»¸öÓ¦ÓÃÒѾ±»Í£µôÁË£¬ÈçÏÂͼËùʾ£º
+
+[](https://s5.51cto.com/oss/202201/14/47569a3fe09e62b2364c26bdbd7da4bc.png)
+
+ÎÒÃÇÒ²¿ÉÒÔͨ¹ýʼþÈÕÖ¾²é¿´ Spring Boot å´»úµÄ¾ßÌåʱ¼ä£¬ÈçÏÂͼËùʾ£º
+
+[](https://s2.51cto.com/oss/202201/14/b63f631561fa646f85ccf3e1e4321939.png)
+
+## 5.ÅäÖò鿴¸ü¶à¼à¿ØÏî
+
+ͨ¹ýÉÏÃæµÄÄÚÈÝÎÒÃÇ¿ÉÒÔ¿´³ö£¬¼à¿ØµÄ Spring Boot Ñ¡ÏÊDZȽÏÉٵģ¬Ôõô²ÅÄܲ鿴¸ü¶àµÄ¼à¿ØÏîÄØ?Òª½â¾öÕâ¸öÎÊÌ⣬ÎÒÃÇÐèÒªÔÚ±»¼à¿ØµÄ Spring Boot ÏîÄ¿ÖÐÌí¼Ó spring-boot-starter-actuator ¿ò¼ÜµÄÖ§³Ö£¬²¢¿ªÆô²é¿´ËùÓÐ¼à¿ØÏîµÄÅäÖòÅÐУ¬×îÖÕչʾЧ¹ûÈçÏ£º
+
+[](https://s4.51cto.com/oss/202201/14/03938ac0bded4487b6720fc4657f9e99.png)
+
+½ÓÏÂÀ´ÎÒÃÇÀ´ÅäÖÃÒ»ÏÂÕâЩ¼à¿ØÏî¡£
+
+### 5.1 Ìí¼Óactuator¿ò¼ÜÖ§³Ö
+
+ÔÚ±»¼à¿ØµÄ Spring Boot ÏîÄ¿ÖÐÌí¼Ó actuator ¿ò¼ÜÖ§³Ö£¬Ò²¾ÍÊÇÔÚ pom.xml ÖÐÌí¼ÓÒÔÏÂÅäÖãº
+
+
+
+
+
+
+
+```
+
+ org.springframework.boot
+ spring-boot-starter-actuator
+
+
+```
+
+
+
+
+
+ÊÖ¶¯µã»÷ Maven µ¼ÈëÒÀÀµ°ü(Èç¹û¿ªÆôÁË×Ô¶¯µ¼È룬´Ë²½Öè¿ÉºöÂÔ)¡£
+
+### 5.2 ÅäÖÿª·ÅËùÓÐ¼à¿ØÏî
+
+ÔÚ±»¼à¿ØµÄ Spring Boot ÏîÄ¿ÖÐÌí¼ÓÒÔÏÂÅäÖãº
+
+
+
+
+
+```
+# ¿ªÆô¼à¿ØËùÓÐÏî
+management.endpoints.web.exposure.include=*
+
+```
+
+
+
+
+
+ÒÔÉϵÄÅäÖÃÊÇ¿ª·Å¼à¿ØËùÓÐÑ¡ÏÅäÖÃÍêÖ®ºó£¬ÖØÆô´Ë Spring Boot ÏîÄ¿£¬È»ºóÔÙˢРSpring Boot Admin ¸ü¶àµÄ¼à¿ØÏî¾Íչʾ³öÀ´ÁË£¬ÈçÏÂͼËùʾ£º
+
+[](https://s6.51cto.com/oss/202201/14/2cc24e05bc6185ba1869872db5a864a5.png)
+
+### 5.3 ¼à¿ØÏîĿԤÀÀ
+
+½« Spring Boot µÄËùÓÐ¼à¿ØÏî¶¼¿ªÆôÖ®ºó£¬Í¨¹ý SBA ¾Í¿ÉÒԲ鿴ÒÔÏÂÄÚÈÝÁË£º
+
+* Æô¶¯Ê±¼ä¡¢ÀÛ¼ÆÔËÐÐʱ¼ä;
+* ½ø³ÌºÍÏß³ÌÊýÁ¿ºÍÕ¼ÓÃµÄ CPU ×ÊÔ´;
+* À¬»ø»ØÊÕÏêÇéÐÅÏ¢£¬»ØÊÕ´ÎÊýºÍ»¨·Ñʱ¼ä;
+* JVM Ïß³Ìת´¢¡¢ÄÚ´æ×ª´¢ÏêÇéºÍ¶ÔÓ¦µÄÎļþÏÂÔØ;
+* ¿ÉÒԲ鿴ºÍÅäÖà Spring Boot ÏîÄ¿ÖеÄÈÕÖ¾¼¶±ð;
+* ²é¿´ Spring Boot ÏîÄ¿ÐÔÄÜ¼à¿Ø;
+* ²é¿´ Spring Boot ÔËÐл·¾³ÐÅÏ¢;
+* ²é¿´ Spring Boot ËùÓÐÀàÐÅÏ¢;
+* ²é¿´ Spring Boot ÖеĶ¨Ê±ÈÎÎñ;
+* ²é¿´ºÍ¹ÜÀí Spring Boot ÏîÄ¿ÖеÄËùÓлº´æ¡£
+
+ÒÔÏÂÊǼ¸¸öÖØÒªÒ³ÃæµÄ½ØÍ¼£¬ÎÒÃÇÒ»ÆðÀ´¿´¡£
+
+### 5.3.1 ²é¿´ÔËÐл·¾³
+
+[](https://s5.51cto.com/oss/202201/14/a9db77b1b0e378450086edd1ab438df5.png)
+
+[](https://s2.51cto.com/oss/202201/14/17604f4f5eb388a2a6c08f55e1e050ac.png)
+
+### 5.3.2 ²é¿´¶¨Ê±ÈÎÎñ
+
+[](https://s5.51cto.com/oss/202201/14/113d94b9bd488e239967915aededc89c.png)
+
+### 5.3.3 ÏîÄ¿ÈÕÖ¾¼¶±ðÅäÖÃ
+
+[](https://s3.51cto.com/oss/202201/14/8da60846eecbdbd9472ae6dbf17d951f.png)
+
+ÎÒÃÇ¿ÉÒÔͨ¹ý Spring Boot Admin À´¶¯Ì¬µÄÅäÖÃÏîÄ¿ÖеÄÈÕÖ¾¼¶±ð¡£
+
+### 5.3.4 JVMÏ̺߳ÍÄÚ´æ²é¿´
+
+[](https://s2.51cto.com/oss/202201/14/d3f98228a8b19675475c863457821034.png)
+
+### 5.3.5 ²é¿´SpringBootËùÓлº´æ
+
+[](https://s5.51cto.com/oss/202201/14/ae811102080c26b11135be50cd889710.png)
+
+µ±È»ÎÒÃÇ»¹¿ÉÒÔ¶ÔÕâЩ»º´æ½øÐÐɾ³ý²Ù×÷¡£
+
+## 6.²é¿´ÏîĿʵʱÈÕÖ¾
+
+ÏëÒª²é¿´¼à¿ØÏîÄ¿ÖеÄÈÕÖ¾ÐÅÏ¢£¬ÓÐÒ»¸öǰÌáÌõ¼þ£¬Ç°ÌáÌõ¼þÊÇÄã±»¼à¿ØµÄ Spring Boot ÏîÄ¿£¬±ØÐëÅäÖÃÁËÈÕÖ¾µÄ±£´æÂ·¾¶»òÕßÈÕÖ¾±£´æÎļþÃû£¬Ö»ÓÐÅäÖÃÕâÁ½ÏîÖеÄÈÎÒâÒ»ÏÄãµÄ Spring Boot ÏîÄ¿²Å»á½«ÈÕÖ¾±£´æµ½´ÅÅÌÉÏ£¬ÕâÑù²ÅÄÜͨ¹ý SBA ²é¿´µ½£¬ÎÒÅäÖõÄÊÇÈÕ־·¾¶£¬ÔÚ Spring Boot µÄ application.properties ÅäÖÃÎļþÖÐÌí¼ÓÒÔÏÂÅäÖãº
+
+
+
+
+
+```
+# ÉèÖÃÈÕÖ¾±£´æÂ·¾¶
+logging.file.path=C:\\work\\log
+
+```
+
+
+
+
+
+ÉèÖÃÍê³ÉÖ®ºó£¬ÖØÆôÄãµÄ Spring Boot ÏîÄ¿£¬È»ºóˢРSBA Ò³Ãæ£¬×îÖÕչʾЧ¹ûÈçÏ£º
+
+[](https://s6.51cto.com/oss/202201/14/3f03c6402cc8a2532ed45ab43be156ac.png)
+
+´ËʱÎÒÃǾͿÉÒԲ鿴ʵʱµÄÈÕÖ¾ÐÅÏ¢ÁË£¬µ±È»ÄãÒ²¿ÉÒÔËæÊ±ÏÂÔØÈÕÖ¾£¬Èç¹ûÐèÒªµÄ»°¡£
+
+## ×ܽá
+
+Spring Boot Admin(SBA)ÊÇÒ»¸öÉçÇø¿ªÔ´ÏîÄ¿£¬ÓÃÓÚ¹ÜÀíºÍ¼àÊÓ Spring Boot Ó¦ÓóÌÐò£¬ËüÌṩÏêϸµÄ½¡¿µ (Health)ÐÅÏ¢¡¢ÄÚ´æÐÅÏ¢¡¢JVM ϵͳºÍ»·¾³ÊôÐÔ¡¢À¬»ø»ØÊÕÐÅÏ¢¡¢ÈÕÖ¾ÉèÖúͲ鿴¡¢¶¨Ê±ÈÎÎñ²é¿´¡¢Spring Boot »º´æ²é¿´ºÍ¹ÜÀíµÈ¹¦ÄÜ¡£
+
+ÎÒÃÇÐèÒª´´½¨Ò»¸ö SBA ·þÎñÆ÷¶ËÓÃÀ´¼à¿ØÒ»¸ö»ò¶à¸ö Spring Boot ÏîÄ¿£¬±»¼à¿ØµÄ Spring Boot ÏîĿҪÌí¼Ó SBA Client ¿ò¼ÜµÄÖ§³Ö£¬ÇÒÌí¼Ó actuator ¿ò¼ÜºÍÏàÓ¦µÄÅäÖ㬾ͿÉÒÔʵÏÖ¶Ô Spring Boot ÏîÄ¿µÄÍêÃÀ¼à¿ØÁË¡£
\ No newline at end of file
diff --git "a/docs/spring/\347\273\231\344\275\240\344\270\200\344\273\275SpringBoot\347\237\245\350\257\206\346\270\205\345\215\225.md" "b/docs/spring/SpringBoot/\347\273\231\344\275\240\344\270\200\344\273\275SpringBoot\347\237\245\350\257\206\346\270\205\345\215\225.md"
similarity index 100%
rename from "docs/spring/\347\273\231\344\275\240\344\270\200\344\273\275SpringBoot\347\237\245\350\257\206\346\270\205\345\215\225.md"
rename to "docs/spring/SpringBoot/\347\273\231\344\275\240\344\270\200\344\273\275SpringBoot\347\237\245\350\257\206\346\270\205\345\215\225.md"
diff --git "a/docs/spring/SpringMVC/SpringMVC\344\270\255\347\232\204\345\233\275\351\231\205\345\214\226\345\212\237\350\203\275.md" "b/docs/spring/SpringMVC/SpringMVC\344\270\255\347\232\204\345\233\275\351\231\205\345\214\226\345\212\237\350\203\275.md"
new file mode 100644
index 0000000..374388b
--- /dev/null
+++ "b/docs/spring/SpringMVC/SpringMVC\344\270\255\347\232\204\345\233\275\351\231\205\345\214\226\345\212\237\350\203\275.md"
@@ -0,0 +1,179 @@
+#### ¹ú¼Ê»¯
+
+* * *
+
+ÔÚ¿ª·¢Ó¦ÓóÌÐòµÄʱºò£¬¾³£»áÓöµ½Ö§³Ö¶àÓïÑÔµÄÐèÇó£¬ÕâÖÖÖ§³Ö¶àÓïÑԵŦÄܳÆÖ®Îª¹ú¼Ê»¯£¬Ó¢ÎÄÊÇinternationalization£¬ËõдΪi18n£¨ÒòΪÊ××ÖĸiºÍÄ©×ÖĸnÖмäÓÐ18¸ö×Öĸ£©¡£
+
+»¹ÓÐÕë¶ÔÌØ¶¨µØÇøµÄ±¾µØ»¯¹¦ÄÜ£¬Ó¢ÎÄÊÇlocalization£¬ËõдΪL10n£¬±¾µØ»¯ÊÇÖ¸¸ù¾ÝµØÇøµ÷ÕûÀàËÆÐÕÃû¡¢ÈÕÆÚµÄÏÔʾµÈ¡£
+
+Ò²ÓаÑÉÏÃæÁ½ÕߺϳÆÎªÈ«Çò»¯£¬Ó¢ÎÄÊÇglobalization£¬ËõдΪg11n¡£
+
+ÔÚJavaÖУ¬Ö§³Ö¶àÓïÑԺͱ¾µØ»¯ÊÇͨ¹ý`MessageFormat`ÅäºÏ`Locale`ʵÏֵģº
+
+
+¶ÔÓÚWebÓ¦ÓóÌÐò£¬ÒªÊµÏÖ¹ú¼Ê»¯¹¦ÄÜ£¬Ö÷ÒªÊÇäÖȾViewµÄʱºò£¬Òª°Ñ¸÷ÖÖÓïÑÔµÄ×ÊÔ´ÎļþÌá³öÀ´£¬ÕâÑù£¬²»Í¬µÄÓû§·ÃÎÊͬһ¸öÒ³ÃæÊ±£¬ÏÔʾµÄÓïÑÔ¾ÍÊDz»Í¬µÄ¡£
+
+ÎÒÃÇÀ´¿´¿´ÔÚSpring MVCÓ¦ÓóÌÐòÖÐÈçºÎʵÏÖ¹ú¼Ê»¯¡£
+
+### »ñÈ¡Locale
+
+ʵÏÖ¹ú¼Ê»¯µÄµÚÒ»²½ÊÇ»ñÈ¡µ½Óû§µÄ`Locale`¡£ÔÚWebÓ¦ÓóÌÐòÖУ¬HTTP¹æ·¶¹æ¶¨ÁËä¯ÀÀÆ÷»áÔÚÇëÇóÖÐЯ´ø`Accept-Language`Í·£¬ÓÃÀ´Ö¸Ê¾Óû§ä¯ÀÀÆ÷É趨µÄÓïÑÔ˳Ðò£¬È磺
+
+```
+Accept-Language: zh-CN,zh;q=0.8,en;q=0.2
+
+```
+
+ÉÏÊöHTTPÇëÇóÍ·±íʾÓÅÏÈÑ¡Ôñ¼òÌåÖÐÎÄ£¬Æä´ÎÑ¡ÔñÖÐÎÄ£¬×îºóÑ¡ÔñÓ¢ÎÄ¡£`q`±íÊ¾È¨ÖØ£¬½âÎöºóÎÒÃǿɻñµÃÒ»¸ö¸ù¾ÝÓÅÏȼ¶ÅÅÐòµÄÓïÑÔÁÐ±í£¬°ÑËüת»»ÎªJavaµÄ`Locale`£¬¼´»ñµÃÁËÓû§µÄ`Locale`¡£´ó¶àÊý¿ò¼Üͨ³£Ö»·µ»ØÈ¨ÖØ×î¸ßµÄ`Locale`¡£
+
+Spring MVCͨ¹ý`LocaleResolver`À´×Ô¶¯´Ó`HttpServletRequest`ÖлñÈ¡`Locale`¡£ÓжàÖÖ`LocaleResolver`µÄʵÏÖÀ࣬ÆäÖÐ×î³£ÓõÄÊÇ`CookieLocaleResolver`£º
+
+```
+@Primary
+@Bean
+LocaleResolver createLocaleResolver() {
+ var clr = new CookieLocaleResolver(); clr.setDefaultLocale(Locale.ENGLISH); clr.setDefaultTimeZone(TimeZone.getDefault()); return clr;}
+
+```
+
+`CookieLocaleResolver`´Ó`HttpServletRequest`ÖлñÈ¡`Locale`ʱ£¬Ê×Ïȸù¾ÝÒ»¸öÌØ¶¨µÄCookieÅжÏÊÇ·ñÖ¸¶¨ÁË`Locale`£¬Èç¹ûûÓУ¬¾Í´ÓHTTPÍ·»ñÈ¡£¬Èç¹û»¹Ã»ÓУ¬¾Í·µ»ØÄ¬ÈϵÄ`Locale`¡£
+
+µ±Óû§µÚÒ»´Î·ÃÎÊÍøÕ¾Ê±£¬`CookieLocaleResolver`Ö»ÄÜ´ÓHTTPÍ·»ñÈ¡`Locale`£¬¼´Ê¹ÓÃä¯ÀÀÆ÷µÄĬÈÏÓïÑÔ¡£Í¨³£ÍøÕ¾Ò²ÔÊÐíÓû§×Ô¼ºÑ¡ÔñÓïÑÔ£¬´Ëʱ£¬`CookieLocaleResolver`¾Í»á°ÑÓû§Ñ¡ÔñµÄÓïÑÔ´æ·Åµ½CookieÖУ¬ÏÂÒ»´Î·ÃÎÊʱ£¬¾Í»á·µ»ØÓû§ÉÏ´ÎÑ¡ÔñµÄÓïÑÔ¶ø²»ÊÇä¯ÀÀÆ÷ĬÈÏÓïÑÔ¡£
+
+### ÌáÈ¡×ÊÔ´Îļþ
+
+µÚ¶þ²½ÊǰÑдËÀÔÚÄ£°åÖеÄ×Ö·û´®ÒÔ×ÊÔ´ÎļþµÄ·½Ê½´æ´¢ÔÚÍⲿ¡£¶ÔÓÚ¶àÓïÑÔ£¬Ö÷ÎļþÃûÈç¹ûÃüÃûΪ`messages`£¬ÄÇô×ÊÔ´Îļþ±ØÐë°´ÈçÏ·½Ê½ÃüÃû²¢·ÅÈëclasspathÖУº
+
+* ĬÈÏÓïÑÔ£¬ÎļþÃû±ØÐëΪ`messages.properties`£»
+* ¼òÌåÖÐÎÄ£¬LocaleÊÇ`zh_CN`£¬ÎļþÃû±ØÐëΪ`messages_zh_CN.properties`£»
+* ÈÕÎÄ£¬LocaleÊÇ`ja_JP`£¬ÎļþÃû±ØÐëΪ`messages_ja_JP.properties`£»
+* ÆäËü¸ü¶àÓïÑÔ¡¡
+
+ÿ¸ö×ÊÔ´Îļþ¶¼ÓÐÏàͬµÄkey£¬ÀýÈ磬ĬÈÏÓïÑÔÊÇÓ¢ÎÄ£¬Îļþ`messages.properties`ÄÚÈÝÈçÏ£º
+
+```
+language.select=Language
+home=Home
+signin=Sign In
+copyright=Copyright?{0,number,#}
+
+```
+
+Îļþ`messages_zh_CN.properties`ÄÚÈÝÈçÏ£º
+
+```
+language.select=ÓïÑÔ
+home=Ê×Ò³
+signin=怬
+copyright=°æÈ¨ËùÓÐ?{0,number,#}
+
+```
+
+### ´´½¨MessageSource
+
+µÚÈý²½ÊÇ´´½¨Ò»¸öSpringÌṩµÄ`MessageSource`ʵÀý£¬Ëü×Ô¶¯¶ÁÈ¡ËùÓеÄ`.properties`Îļþ£¬²¢Ìṩһ¸öͳһ½Ó¿ÚÀ´ÊµÏÖ¡°·Ò롱£º
+
+```
+// code, arguments, locale:
+String text = messageSource.getMessage("signin", null, locale);
+
+```
+
+ÆäÖУ¬`signin`ÊÇÎÒÃÇÔÚ`.properties`ÎļþÖж¨ÒåµÄkey£¬µÚ¶þ¸ö²ÎÊýÊÇ`Object[]`Êý×é×÷Ϊ¸ñʽ»¯Ê±´«ÈëµÄ²ÎÊý£¬×îºóÒ»¸ö²ÎÊý¾ÍÊÇ»ñÈ¡µÄÓû§`Locale`ʵÀý¡£
+
+´´½¨`MessageSource`ÈçÏ£º
+
+```
+@Bean("i18n")
+MessageSource createMessageSource() {
+ var messageSource = new ResourceBundleMessageSource(); // Ö¸¶¨ÎļþÊÇUTF-8±àÂë:
+ messageSource.setDefaultEncoding("UTF-8"); // Ö¸¶¨Ö÷ÎļþÃû:
+ messageSource.setBasename("messages"); return messageSource;}
+
+```
+
+×¢Òâµ½`ResourceBundleMessageSource`»á×Ô¶¯¸ù¾ÝÖ÷ÎļþÃû×Ô¶¯°ÑËùÓÐÏà¹ØÓïÑÔµÄ×ÊÔ´Îļþ¶¼¶Á½øÀ´¡£
+
+ÔÙ×¢Òâµ½SpringÈÝÆ÷»á´´½¨²»Ö»Ò»¸ö`MessageSource`ʵÀý£¬ÎÒÃÇ×Ô¼º´´½¨µÄÕâ¸ö`MessageSource`ÊÇרßøÒ³Ãæ¹ú¼Ê»¯Ê¹Óõģ¬Òò´ËÃüÃûΪ`i18n`£¬²»»áÓëÆäËü`MessageSource`ʵÀý³åÍ»¡£
+
+### ʵÏÖ¶àÓïÑÔ
+
+ÒªÔÚViewÖÐʹÓÃ`MessageSource`¼ÓÉÏ`Locale`Êä³ö¶àÓïÑÔ£¬ÎÒÃÇͨ¹ý±àдһ¸ö`MvcInterceptor`£¬°ÑÏà¹Ø×ÊÔ´×¢Èëµ½`ModelAndView`ÖУº
+
+```
+@Component
+public class MvcInterceptor implements HandlerInterceptor {
+ @Autowired LocaleResolver localeResolver;
+ // ×¢Òâ×¢ÈëµÄMessageSourceÃû³ÆÊÇi18n:
+ @Autowired @Qualifier("i18n") MessageSource messageSource;
+ public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { if (modelAndView != null) { // ½âÎöÓû§µÄLocale:
+ Locale locale = localeResolver.resolveLocale(request); // ·ÅÈëModel:
+ modelAndView.addObject("__messageSource__", messageSource); modelAndView.addObject("__locale__", locale); } }}
+
+```
+
+²»ÒªÍüÁËÔÚ`WebMvcConfigurer`ÖÐ×¢²á`MvcInterceptor`¡£ÏÖÔÚ£¬¾Í¿ÉÒÔÔÚViewÖе÷ÓÃ`MessageSource.getMessage()`·½·¨À´ÊµÏÖ¶àÓïÑÔ£º
+
+```
+{{ __messageSource__.getMessage('signin', null, __locale__) }}
+
+```
+
+ÉÏÊöÕâÖÖд·¨ËäÈ»¿ÉÐУ¬µ«¸ñʽ̫¸´ÔÓÁË¡£Ê¹ÓÃViewʱ£¬Òª¸ù¾Ýÿ¸öÌØ¶¨µÄViewÒýÇæ¶¨Öƹú¼Ê»¯º¯Êý¡£ÔÚPebbleÖУ¬ÎÒÃÇ¿ÉÒÔ·â×°Ò»¸ö¹ú¼Ê»¯º¯Êý£¬Ãû³Æ¾ÍÊÇÏ»®Ïß`_`£¬¸ÄÔìһϴ´½¨`ViewResolver`µÄ´úÂ룺
+
+```
+@Bean
+ViewResolver createViewResolver(@Autowired ServletContext servletContext, @Autowired @Qualifier("i18n") MessageSource messageSource) {
+ var engine = new PebbleEngine.Builder() .autoEscaping(true) .cacheActive(false) .loader(new Servlet5Loader(servletContext)) // Ìí¼ÓÀ©Õ¹:
+ .extension(createExtension(messageSource)) .build(); var viewResolver = new PebbleViewResolver(); viewResolver.setPrefix("/WEB-INF/templates/"); viewResolver.setSuffix(""); viewResolver.setPebbleEngine(engine); return viewResolver;}
+
+private Extension createExtension(MessageSource messageSource) {
+ return new AbstractExtension() { @Override public Map getFunctions() { return Map.of("_", new Function() { public Object execute(Map args, PebbleTemplate self, EvaluationContext context, int lineNumber) { String key = (String) args.get("0"); List