diff --git a/ReadMe.md b/ReadMe.md
index dc53ae6..84572da 100644
--- a/ReadMe.md
+++ b/ReadMe.md
@@ -29,227 +29,333 @@
+ +# Java基础 + +## 基础知识 +* [é�¢å�‘对象基础](docs/Java/basic/é�¢å�‘对象基础.md) +* [Java基本数æ�®ç±»åž‹](docs/Java/basic/Java基本数æ�®ç±»åž‹.md) +* [string和包装类](docs/Java/basic/string和包装类.md) +* [final关键å—特性](docs/Java/basic/final关键å—特性.md) +* [Java类和包](docs/Java/basic/Java类和包.md) +* [抽象类和接å�£](docs/Java/basic/抽象类和接å�£.md) +* [代ç �å�—和代ç �执行顺åº�](docs/Java/basic/代ç �å�—和代ç �执行顺åº�.md) +* [Java自动拆箱装箱里éš�è—�的秘密](docs/Java/basic/Java自动拆箱装箱里éš�è—�的秘密.md) +* [Javaä¸çš„Class类和Objectç±»](docs/Java/basic/Javaä¸çš„Class类和Objectç±».md) +* [Java异常](docs/Java/basic/Java异常.md) +* [解读Javaä¸çš„回调](docs/Java/basic/解读Javaä¸çš„回调.md) +* [å��å°„](docs/Java/basic/å��å°„.md) +* [泛型](docs/Java/basic/泛型.md) +* [枚举类](docs/Java/basic/枚举类.md) +* [Java注解和最佳实践](docs/Java/basic/Java注解和最佳实践.md) +* [JavaIOæµ�](docs/Java/basic/JavaIOæµ�.md) +* [多线程](docs/Java/basic/多线程.md) +* [深入ç�†è§£å†…部类](docs/Java/basic/深入ç�†è§£å†…部类.md) +* [javacå’Œjavap](docs/Java/basic/javacå’Œjavap.md) +* [Java8新特性终æž�指å�—](docs/Java/basic/Java8新特性终æž�指å�—.md) +* [åº�列化和å��åº�列化](docs/Java/basic/åº�列化和å��åº�列化.md) +* [继承å°�装多æ€�的实现原ç�†](docs/Java/basic/继承å°�装多æ€�的实现原ç�†.md) + +## 集å�ˆç±» + +* [Java集å�ˆç±»æ€»ç»“](docs/Java/collection/Java集å�ˆç±»æ€»ç»“.md) +* [Java集å�ˆè¯¦è§£ï¼šä¸€æ–‡è¯»æ‡‚ArrayList,Vector与Stack使用方法和实现原ç�†](docs/Java/collection/Java集å�ˆè¯¦è§£ï¼šä¸€æ–‡è¯»æ‡‚ArrayList,Vector与Stack使用方法和实现原ç�†.md) +* [Java集å�ˆè¯¦è§£ï¼šQueueå’ŒLinkedList](docs/Java/collection/Java集å�ˆè¯¦è§£ï¼šQueueå’ŒLinkedList.md) +* [Java集å�ˆè¯¦è§£ï¼šIterator,fail-fast机制与比较器](docs/Java/collection/Java集å�ˆè¯¦è§£ï¼šIterator,fail-fast机制与比较器.md) +* [Java集å�ˆè¯¦è§£ï¼šHashMapå’ŒHashTable](docs/Java/collection/Java集å�ˆè¯¦è§£ï¼šHashMapå’ŒHashTable.md) +* [Java集å�ˆè¯¦è§£ï¼šæ·±å…¥ç�†è§£LinkedHashMapå’ŒLRU缓å˜](docs/Java/collection/Java集å�ˆè¯¦è§£ï¼šæ·±å…¥ç�†è§£LinkedHashMapå’ŒLRU缓å˜.md) +* [Java集å�ˆè¯¦è§£ï¼šTreeMapå’Œçº¢é»‘æ ‘](docs/Java/collection/Java集å�ˆè¯¦è§£ï¼šTreeMapå’Œçº¢é»‘æ ‘.md) +* [Java集å�ˆè¯¦è§£ï¼šHashSet,TreeSet与LinkedHashSet](docs/Java/collection/Java集å�ˆè¯¦è§£ï¼šHashSet,TreeSet与LinkedHashSet.md) +* [Java集å�ˆè¯¦è§£ï¼šJava集å�ˆç±»ç»†èŠ‚ç²¾è®²](docs/Java/collection/Java集å�ˆè¯¦è§£ï¼šJava集å�ˆç±»ç»†èŠ‚ç²¾è®².md) + +# JavaWeb + +* [èµ°è¿›JavaWeb技术世界:JavaWeb的由æ�¥å’ŒåŸºç¡€çŸ¥è¯†](docs/JavaWeb/èµ°è¿›JavaWeb技术世界:JavaWeb的由æ�¥å’ŒåŸºç¡€çŸ¥è¯†.md) +* [èµ°è¿›JavaWeb技术世界:JSP与Servlet的曾ç»�与现在](docs/JavaWeb/èµ°è¿›JavaWeb技术世界:JSP与Servlet的曾ç»�与现在.md) +* [èµ°è¿›JavaWeb技术世界:JDBCçš„è¿›åŒ–ä¸Žè¿žæŽ¥æ± æŠ€æœ¯](docs/JavaWeb/èµ°è¿›JavaWeb技术世界:JDBCçš„è¿›åŒ–ä¸Žè¿žæŽ¥æ± æŠ€æœ¯.md) +* [èµ°è¿›JavaWeb技术世界:Servlet工作原ç�†è¯¦è§£](docs/JavaWeb/èµ°è¿›JavaWeb技术世界:Servlet工作原ç�†è¯¦è§£.md) +* [èµ°è¿›JavaWeb技术世界:åˆ�探Tomcatçš„HTTP请求过程](docs/JavaWeb/èµ°è¿›JavaWeb技术世界:åˆ�探Tomcatçš„HTTP请求过程.md) +* [èµ°è¿›JavaWeb技术世界:Tomcat5总体架构剖æž�](docs/JavaWeb/èµ°è¿›JavaWeb技术世界:Tomcat5总体架构剖æž�.md) +* [èµ°è¿›JavaWeb技术世界:Tomcat和其他WEB容器的区别](docs/JavaWeb/èµ°è¿›JavaWeb技术世界:Tomcat和其他WEB容器的区别.md) +* [èµ°è¿›JavaWeb技术世界:浅æž�Tomcat9请求处ç�†æµ�程与å�¯åŠ¨éƒ¨ç½²è¿‡ç¨‹](docs/JavaWeb/èµ°è¿›JavaWeb技术世界:浅æž�Tomcat9请求处ç�†æµ�程与å�¯åŠ¨éƒ¨ç½²è¿‡ç¨‹.md) +* [èµ°è¿›JavaWeb技术世界:Java日志系统的诞生与å�‘展](docs/JavaWeb/èµ°è¿›JavaWeb技术世界:Java日志系统的诞生与å�‘展.md) +* [èµ°è¿›JavaWeb技术世界:从JavaBean讲到Spring](docs/JavaWeb/èµ°è¿›JavaWeb技术世界:从JavaBean讲到Spring.md) +* [èµ°è¿›JavaWeb技术世界:å�•元测试框架Junit](docs/JavaWeb/èµ°è¿›JavaWeb技术世界:å�•元测试框架Junit.md) +* [èµ°è¿›JavaWeb技术世界:从手动编译打包到项目构建工具Maven](docs/JavaWeb/èµ°è¿›JavaWeb技术世界:从手动编译打包到项目构建工具Maven.md) +* [èµ°è¿›JavaWeb技术世界:Hibernate入门ç»�典与注解å¼�å¼€å�‘](docs/JavaWeb/èµ°è¿›JavaWeb技术世界:Hibernate入门ç»�典与注解å¼�å¼€å�‘.md) +* [èµ°è¿›JavaWeb技术世界:Mybatis入门](docs/JavaWeb/èµ°è¿›JavaWeb技术世界:Mybatis入门.md) +* [èµ°è¿›JavaWeb技术世界:深入浅出Mybatis基本原ç�†](docs/JavaWeb/èµ°è¿›JavaWeb技术世界:深入浅出Mybatis基本原ç�†.md) +* [èµ°è¿›JavaWeb技术世界:æž�简é…�置的SpringBoot](docs/JavaWeb/èµ°è¿›JavaWeb技术世界:æž�简é…�置的SpringBoot.md) + +# Java进阶 + +## å¹¶å�‘编程 + +* [Javaå¹¶å�‘指å�—:并å�‘基础与Java多线程](docs/Java/concurrency/Javaå¹¶å�‘指å�—:并å�‘基础与Java多线程.md) +* [Javaå¹¶å�‘指å�—:深入ç�†è§£Javaå†…å˜æ¨¡åž‹JMM](docs/Java/concurrency/Javaå¹¶å�‘指å�—:深入ç�†è§£Javaå†…å˜æ¨¡åž‹JMM.md) +* [Javaå¹¶å�‘指å�—:并å�‘三大问题与volatile关键å—,CASæ“�作](docs/Java/concurrency/Javaå¹¶å�‘指å�—:并å�‘三大问题与volatile关键å—,CASæ“�作.md) +* [Javaå¹¶å�‘指å�—:Javaä¸çš„é”�Lockå’Œsynchronized](docs/Java/concurrency/Javaå¹¶å�‘指å�—:Javaä¸çš„é”�Lockå’Œsynchronized.md) +* [Javaå¹¶å�‘指å�—:JMMä¸çš„final关键å—è§£æž�](docs/Java/concurrency/Javaå¹¶å�‘指å�—:JMMä¸çš„final关键å—è§£æž�.md) +* [Javaå¹¶å�‘指å�—:Javaå†…å˜æ¨¡åž‹JMM总结](docs/Java/concurrency/Javaå¹¶å�‘指å�—:Javaå†…å˜æ¨¡åž‹JMM总结.md) +* [Javaå¹¶å�‘指å�—:JUCçš„æ ¸å¿ƒç±»AQS详解](docs/Java/concurrency/Javaå¹¶å�‘指å�—:JUCçš„æ ¸å¿ƒç±»AQS详解.md) +* [Javaå¹¶å�‘指å�—:AQSä¸çš„公平é”�与é�žå…¬å¹³é”�,Condtion](docs/Java/concurrency/Javaå¹¶å�‘指å�—:AQSä¸çš„公平é”�与é�žå…¬å¹³é”�,Condtion.md) +* [Javaå¹¶å�‘指å�—:AQS共享模å¼�与并å�‘工具类的实现](docs/Java/concurrency/Javaå¹¶å�‘指å�—:AQS共享模å¼�与并å�‘工具类的实现.md) +* [Javaå¹¶å�‘指å�—:Java读写é”�ReentrantReadWriteLockæº�ç �分æž�](docs/Java/concurrency/Javaå¹¶å�‘指å�—:Java读写é”�ReentrantReadWriteLockæº�ç �分æž�.md) +* [Javaå¹¶å�‘指å�—:解读Java阻塞队列BlockingQueue](docs/Java/concurrency/Javaå¹¶å�‘指å�—:解读Java阻塞队列BlockingQueue.md) +* [Javaå¹¶å�‘指å�—:深度解读javaçº¿ç¨‹æ± è®¾è®¡æ€�想å�Šæº�ç �实现](docs/Java/concurrency/Javaå¹¶å�‘指å�—:深度解读Javaçº¿ç¨‹æ± è®¾è®¡æ€�想å�Šæº�ç �实现.md) +* [Javaå¹¶å�‘指å�—:Javaä¸çš„HashMapå’ŒConcurrentHashMap全解æž�](docs/Java/concurrency/Javaå¹¶å�‘指å�—:Javaä¸çš„HashMapå’ŒConcurrentHashMap全解æž�.md) +* [Javaå¹¶å�‘指å�—:JUCä¸å¸¸ç”¨çš„Unsafeå’ŒLocksupport](docs/Java/concurrency/Javaå¹¶å�‘指å�—:JUCä¸å¸¸ç”¨çš„Unsafeå’ŒLocksupport.md) +* [Javaå¹¶å�‘指å�—:ForkJoinå¹¶å�‘框架与工作窃å�–算法剖æž�](docs/Java/concurrency/Javaå¹¶å�‘指å�—:ForkJoinå¹¶å�‘框架与工作窃å�–算法剖æž�.md) +* [Javaå¹¶å�‘编程å¦ä¹ 总结](docs/Java/concurrency/Javaå¹¶å�‘编程å¦ä¹ 总结.md) + +## JVM + +* [JVM总结](docs/Java/JVM/JVM总结.md) +* [深入ç�†è§£JVM虚拟机:JVM内å˜çš„结构与消失的永久代](docs/Java/JVM/深入ç�†è§£JVM虚拟机:JVM内å˜çš„结构与消失的永久代.md) +* [深入ç�†è§£JVM虚拟机:JVM垃圾回收基本原ç�†å’Œç®—法](docs/Java/JVM/深入ç�†è§£JVM虚拟机:JVM垃圾回收基本原ç�†å’Œç®—法.md) +* [深入ç�†è§£JVM虚拟机:垃圾回收器详解](docs/Java/JVM/深入ç�†è§£JVM虚拟机:垃圾回收器详解.md) +* [深入ç�†è§£JVM虚拟机:Javaclass介ç»�与解æž�实践](docs/Java/JVM/深入ç�†è§£JVM虚拟机:Javaå—节ç �介ç»�与解æž�实践.md) +* [深入ç�†è§£JVM虚拟机:虚拟机å—节ç �执行引擎](docs/Java/JVM/深入ç�†è§£JVM虚拟机:虚拟机å—节ç �执行引擎.md) +* [深入ç�†è§£JVM虚拟机:深入ç�†è§£JVMç±»åŠ è½½æœºåˆ¶](docs/Java/JVM/深入ç�†è§£JVM虚拟机:深入ç�†è§£JVMç±»åŠ è½½æœºåˆ¶.md) +* [深入ç�†è§£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虚拟机: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) + +## Java网络编程 + +* [Java网络编程和NIO详解:JAVA ä¸åŽŸç”Ÿçš„ socket 通信机制](docs/Java/network/Java网络编程与NIO详解:JAVAä¸åŽŸç”Ÿçš„socket通信机制.md) +* [Java网络编程与NIO详解:JAVA NIO ä¸€æ¥æ¥æž„建IO多路å¤�用的请求模型](docs/Java/network/Java网络编程与NIO详解:JavaNIOä¸€æ¥æ¥æž„建IO多路å¤�用的请求模型.md) +* [Java网络编程和NIO详解:IO模型与Java网络编程模型](docs/Java/network/Java网络编程与NIO详解:IO模型与Java网络编程模型.md) +* [Java网络编程与NIO详解:浅æž�NIO包ä¸çš„BufferChannelå’ŒSelector](docs/Java/network/Java网络编程与NIO详解:浅æž�NIO包ä¸çš„BufferChannelå’ŒSelector.md) +* [Java网络编程和NIO详解:Javaé�žé˜»å¡žIO和异æ¥IO](docs/Java/network/Java网络编程与NIO详解:Javaé�žé˜»å¡žIO和异æ¥IO.md) +* [Java网络编程与NIO详解:LinuxEpoll实现原ç�†è¯¦è§£](docs/Java/network/Java网络编程与NIO详解:LinuxEpoll实现原ç�†è¯¦è§£.md.md) +* [Java网络编程与NIO详解:浅谈Linuxä¸Selector的实现原ç�†](docs/Java/network/Java网络编程与NIO详解:浅谈Linuxä¸Selector的实现原ç�†.md) +* [Java网络编程与NIO详解:浅æž�mmapå’ŒDirectBuffer](docs/Java/network/Java网络编程与NIO详解:浅æž�mmapå’ŒDirectBuffer.md) +* [Java网络编程与NIO详解:基于NIO的网络编程框架Netty](docs/Java/network/Java网络编程与NIO详解:基于NIO的网络编程框架Netty.md) +* [Java网络编程与NIO详解:Java网络编程与NIO详解](docs/Java/network/Java网络编程与NIO详解:深度解读Tomcatä¸çš„NIO模型.md) +* [Java网络编程与NIO详解:Tomcatä¸çš„Connectoræº�ç �分æž�(NIO)](docs/Java/network/Java网络编程与NIO详解:Tomcatä¸çš„Connectoræº�ç �分æž�(NIO).md) + +# Spring全家桶 + +## Spring + +* [SpringAOP的概念与作用](docs/Spring全家桶/Spring/Spring常è§�注解.md) +* [SpringBean的定义与管ç�†ï¼ˆæ ¸å¿ƒï¼‰](docs/Spring全家桶/Spring/Spring常è§�注解.md) +* [Springä¸å¯¹äºŽæ•°æ�®åº“的访问](docs/Spring全家桶/Spring/Spring常è§�注解.md) +* [Springä¸å¯¹äºŽæ ¡éªŒåŠŸèƒ½çš„æ”¯æŒ�](docs/Spring全家桶/Spring/Spring常è§�注解.md) +* [Springä¸çš„Environment环境å�˜é‡�](docs/Spring全家桶/Spring/Spring常è§�注解.md) +* [Springä¸çš„事件处ç�†æœºåˆ¶](docs/Spring全家桶/Spring/Spring常è§�注解.md) +* [Springä¸çš„资æº�管ç�†](docs/Spring全家桶/Spring/Spring常è§�注解.md) +* [Springä¸çš„é…�置元数æ�®ï¼ˆç®¡ç�†é…�置的基本数æ�®ï¼‰](docs/Spring全家桶/Spring/Spring常è§�注解.md) +* [Spring事务基本用法](docs/Spring全家桶/Spring/Spring常è§�注解.md) +* [Springå�ˆé›†](docs/Spring全家桶/Spring/Spring常è§�注解.md) +* [Spring容器与IOC](docs/Spring全家桶/Spring/Spring常è§�注解.md) +* [Spring常è§�注解](docs/Spring全家桶/Spring/Spring常è§�注解.md) +* [Spring概述](docs/Spring全家桶/Spring/Spring常è§�注解.md) +* [第一个Spring应用](docs/Spring全家桶/Spring/Spring常è§�注解.md) + +## Springæº�ç �分æž� + +### 综å�ˆ +* [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) + +### AOP +* [AnnotationAwareAspectJAutoProxyCreator 分æž�(上)](docs/Spring全家桶/Springæº�ç �分æž�/SpringAOP/AnnotationAwareAspectJAutoProxyCreator分æž�(上).md) +* [AnnotationAwareAspectJAutoProxyCreator 分æž�(下)](docs/Spring全家桶/Springæº�ç �分æž�/SpringAOP/AnnotationAwareAspectJAutoProxyCreator分æž�(下).md) +* [AOP示例demoå�Š@EnableAspectJAutoProxy](docs/Spring全家桶/Springæº�ç �分æž�/SpringAOP/AOP示例demoå�Š@EnableAspectJAutoProxy.md) +* [SpringAop(四):jdk 动æ€�代ç�†](docs/Spring全家桶/Springæº�ç �分æž�/SpringAOP/SpringAop(四):jdk动æ€�代ç�†.md) +* [SpringAop(五):cglib 代ç�†](docs/Spring全家桶/Springæº�ç �分æž�/SpringAOP/SpringAop(五):cglib代ç�†.md) +* [SpringAop(å…):aop 总结](docs/Spring全家桶/Springæº�ç �分æž�/SpringAOP/SpringAop(å…):aop总结.md) + +### 事务 +* [spring 事务(一):认识事务组件](docs/Spring全家桶/Springæº�ç �分æž�/Spring事务/Spring事务(一):认识事务组件.md) +* [spring 事务(二):事务的执行æµ�程](docs/Spring全家桶/Springæº�ç �分æž�/Spring事务/Spring事务(二):事务的执行æµ�程.md) +* [spring äº‹åŠ¡ï¼ˆä¸‰ï¼‰ï¼šäº‹åŠ¡çš„éš”ç¦»çº§åˆ«ä¸Žä¼ æ’æ–¹å¼�的处ç�†](docs/Spring全家桶/Springæº�ç �分æž�/Spring事务/Springäº‹åŠ¡ï¼ˆä¸‰ï¼‰ï¼šäº‹åŠ¡çš„éš”ç¦»çº§åˆ«ä¸Žä¼ æ’æ–¹å¼�的处ç�†01.md) +* [spring äº‹åŠ¡ï¼ˆå››ï¼‰ï¼šäº‹åŠ¡çš„éš”ç¦»çº§åˆ«ä¸Žä¼ æ’æ–¹å¼�的处ç�†](docs/Spring全家桶/Springæº�ç �分æž�/Spring事务/Springäº‹åŠ¡ï¼ˆå››ï¼‰ï¼šäº‹åŠ¡çš„éš”ç¦»çº§åˆ«ä¸Žä¼ æ’æ–¹å¼�的处ç�†02.md) +* [spring äº‹åŠ¡ï¼ˆäº”ï¼‰ï¼šäº‹åŠ¡çš„éš”ç¦»çº§åˆ«ä¸Žä¼ æ’æ–¹å¼�的处ç�†](docs/Spring全家桶/Springæº�ç �分æž�/Spring事务/Springäº‹åŠ¡ï¼ˆäº”ï¼‰ï¼šäº‹åŠ¡çš„éš”ç¦»çº§åˆ«ä¸Žä¼ æ’æ–¹å¼�的处ç�†03.md) +* [spring 事务(å…ï¼‰ï¼šäº‹åŠ¡çš„éš”ç¦»çº§åˆ«ä¸Žä¼ æ’æ–¹å¼�的处ç�†](docs/Spring全家桶/Springæº�ç �分æž�/Spring事务/Spring事务(å…ï¼‰ï¼šäº‹åŠ¡çš„éš”ç¦»çº§åˆ«ä¸Žä¼ æ’æ–¹å¼�的处ç�†04.md) + +### å�¯åЍæµ�程 +* [springå�¯åЍæµ�程(一):å�¯åЍæµ�程概览](docs/Spring全家桶/Springæº�ç �分æž�/Springå�¯åЍæµ�程/Springå�¯åЍæµ�程(一):å�¯åЍæµ�程概览.md) +* [springå�¯åЍæµ�程(二):ApplicationContext 的创建](docs/Spring全家桶/Springæº�ç �分æž�/Springå�¯åЍæµ�程/Springå�¯åЍæµ�程(二):ApplicationContext的创建.md) +* [springå�¯åЍæµ�程(三):包的扫æ��æµ�程](docs/Spring全家桶/Springæº�ç �分æž�/Springå�¯åЍæµ�程/Springå�¯åЍæµ�程(三):包的扫æ��æµ�程.md) +* [springå�¯åЍæµ�程(四):å�¯åЍå‰�的准备工作](docs/Spring全家桶/Springæº�ç �分æž�/Springå�¯åЍæµ�程/Springå�¯åЍæµ�程(四):å�¯åЍå‰�的准备工作.md) +* [springå�¯åЍæµ�程(五):执行 BeanFactoryPostProcessor](docs/Spring全家桶/Springæº�ç �分æž�/Springå�¯åЍæµ�程/Springå�¯åЍæµ�程(五):执行BeanFactoryPostProcessor.md) +* [springå�¯åЍæµ�程(å…):注册 BeanPostProcessor](docs/Spring全家桶/Springæº�ç �分æž�/Springå�¯åЍæµ�程/Springå�¯åЍæµ�程(å…):注册BeanPostProcessor.md) +* [springå�¯åЍæµ�程(七):国际化与事件处ç�†](docs/Spring全家桶/Springæº�ç �分æž�/Springå�¯åЍæµ�程/Springå�¯åЍæµ�程(七):国际化与事件处ç�†.md) +* [springå�¯åЍæµ�程(八):完æˆ� BeanFactory çš„åˆ�始化](docs/Spring全家桶/Springæº�ç �分æž�/Springå�¯åЍæµ�程/Springå�¯åЍæµ�程(八):完æˆ�BeanFactoryçš„åˆ�始化.md) +* [springå�¯åЍæµ�程(ä¹�):å�•例 bean 的创建](docs/Spring全家桶/Springæº�ç �分æž�/Springå�¯åЍæµ�程/Springå�¯åЍæµ�程(ä¹�):å�•例bean的创建.md) +* [springå�¯åЍæµ�程(å��):å�¯åŠ¨å®Œæˆ�的处ç�†](docs/Spring全家桶/Springæº�ç �分æž�/Springå�¯åЍæµ�程/Springå�¯åЍæµ�程(å��):å�¯åŠ¨å®Œæˆ�的处ç�†.md) +* [springå�¯åЍæµ�程(å��一):å�¯åЍæµ�程总结](docs/Spring全家桶/Springæº�ç �分æž�/Springå�¯åЍæµ�程/Springå�¯åЍæµ�程(å��一):å�¯åЍæµ�程总结.md) + +### 组件分æž� +* [spring 组件之 ApplicationContext](docs/Spring全家桶/Springæº�ç �分æž�/Spring组件分æž�/Spring组件之ApplicationContext.md) +* [spring 组件之 BeanDefinition](docs/Spring全家桶/Springæº�ç �分æž�/Spring组件分æž�/Spring组件之BeanDefinition.md) +* [Spring 组件之 BeanFactory](docs/Spring全家桶/Springæº�ç �分æž�/Spring组件分æž�/Spring组件之BeanFactory.md) +* [spring 组件之 BeanFactoryPostProcessor](docs/Spring全家桶/Springæº�ç �分æž�/Spring组件分æž�/Spring组件之BeanFactoryPostProcessor.md) +* [spring 组件之 BeanPostProcessor](docs/Spring全家桶/Springæº�ç �分æž�/Spring组件分æž�/Spring组件之BeanPostProcessor.md) + +### é‡�è¦�机制探秘 + +* [ConfigurationClassPostProcessor(一):处ç�† @ComponentScan 注解](docs/Spring全家桶/Springæº�ç �分æž�/Springé‡�è¦�机制探秘/ConfigurationClassPostProcessor(一):处ç�†@ComponentScan注解.md) +* [ConfigurationClassPostProcessor(三):处ç�† @Import 注解](docs/Spring全家桶/Springæº�ç �分æž�/Springé‡�è¦�机制探秘/ConfigurationClassPostProcessor(三):处ç�†@Import注解.md) +* [ConfigurationClassPostProcessor(二):处ç�† @Bean 注解](docs/Spring全家桶/Springæº�ç �分æž�/Springé‡�è¦�机制探秘/ConfigurationClassPostProcessor(二):处ç�†@Bean注解.md) +* [ConfigurationClassPostProcessor(四):处ç�† @Conditional 注解](docs/Spring全家桶/Springæº�ç �分æž�/Springé‡�è¦�机制探秘/ConfigurationClassPostProcessor(四):处ç�†@Conditional注解.md) +* [Spring 探秘之 AOP 的执行顺åº�](docs/Spring全家桶/Springæº�ç �分æž�/Springé‡�è¦�机制探秘/Spring探秘之AOP的执行顺åº�.md) +* [Spring 探秘之 Spring 事件机制](docs/Spring全家桶/Springæº�ç �分æž�/Springé‡�è¦�机制探秘/Spring探秘之Spring事件机制.md) +* [spring 探秘之循环ä¾�赖的解决(一):ç�†è®ºåŸºçŸ³](docs/Spring全家桶/Springæº�ç �分æž�/Springé‡�è¦�机制探秘/Spring探秘之循环ä¾�赖的解决(一):ç�†è®ºåŸºçŸ³.md) +* [spring 探秘之循环ä¾�赖的解决(二):æº�ç �分æž�](docs/Spring全家桶/Springæº�ç �分æž�/Springé‡�è¦�机制探秘/Spring探秘之循环ä¾�赖的解决(二):æº�ç �分æž�.md) +* [spring 探秘之监å�¬å™¨æ³¨è§£ @EventListener](docs/Spring全家桶/Springæº�ç �分æž�/Springé‡�è¦�机制探秘/spring探秘之监å�¬å™¨æ³¨è§£@EventListener.md) +* [spring 探秘之组å�ˆæ³¨è§£çš„处ç�†](docs/Spring全家桶/Springæº�ç �分æž�/Springé‡�è¦�机制探秘/Spring探秘之组å�ˆæ³¨è§£çš„处ç�†.md) + +## SpringMVC + +* [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) +* [DispatcherServlet åˆ�始化æµ�程 ](docs/Spring全家桶/SpringMVCæº�ç �分æž�/DispatcherServletåˆ�始化æµ�程.md) +* [RequestMapping åˆ�始化æµ�程 ](docs/Spring全家桶/SpringMVCæº�ç �分æž�/RequestMappingåˆ�始化æµ�程.md) +* [Spring 容器å�¯åЍ Tomcat ](docs/Spring全家桶/SpringMVCæº�ç �分æž�/Spring容器å�¯åЍTomcat.md) +* [SpringMVC demo 与@EnableWebMvc 注解 ](docs/Spring全家桶/SpringMVCæº�ç �分æž�/SpringMVCçš„Demo与@EnableWebMvc注解.md) +* [SpringMVC 整体æº�ç �结构总结 ](docs/Spring全家桶/SpringMVCæº�ç �分æž�/SpringMVC整体æº�ç �结构总结.md) +* [请求执行æµ�程(一)之获å�– Handler ](docs/Spring全家桶/SpringMVCæº�ç �分æž�/请求执行æµ�程(一)之获å�–Handler.md) +* [请求执行æµ�程(二)之执行 Handler 方法 ](docs/Spring全家桶/SpringMVCæº�ç �分æž�/请求执行æµ�程(二)之执行Handler方法.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) + +## SpringBootæº�ç �分æž� +* [@SpringBootApplication 注解](docs/Spring全家桶/SpringBootæº�ç �è§£æž�/@SpringBootApplication注解.md) +* [springboot web应用(一):servlet 组件的注册æµ�程](docs/Spring全家桶/SpringBootæº�ç �è§£æž�/SpringBootWeb应用(一):servlet组件的注册æµ�程.md) +* [springboot web应用(二):WebMvc 装é…�过程](docs/Spring全家桶/SpringBootæº�ç �è§£æž�/SpringBootWeb应用(二):WebMvc装é…�过程.md) + +* [SpringBoot å�¯åЍæµ�程(一):准备 SpringApplication](docs/Spring全家桶/SpringBootæº�ç �è§£æž�/SpringBootå�¯åЍæµ�程(一):准备SpringApplication.md) +* [SpringBoot å�¯åЍæµ�程(二):准备è¿�行环境](docs/Spring全家桶/SpringBootæº�ç �è§£æž�/SpringBootå�¯åЍæµ�程(二):准备è¿�行环境.md) +* [SpringBoot å�¯åЍæµ�程(三):准备IOC容器](docs/Spring全家桶/SpringBootæº�ç �è§£æž�/SpringBootå�¯åЍæµ�程(三):准备IOC容器.md) +* [springboot å�¯åЍæµ�程(四):å�¯åЍIOC容器](docs/Spring全家桶/SpringBootæº�ç �è§£æž�/SpringBootå�¯åЍæµ�程(四):å�¯åЍIOC容器.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 自动装é…�(三):自动装é…�顺åº�](docs/Spring全家桶/SpringBootæº�ç �è§£æž�/SpringBoot自动装é…�(三):自动装é…�顺åº�.md) + +## SpringCloud +* [SpringCloud概述](docs/Spring全家桶/SpringCloud/SpringCloud概述.md) +* [Spring Cloud Config](docs/Spring全家桶/SpringCloud/SpringCloudConfig.md) +* [Spring Cloud Consul](docs/Spring全家桶/SpringCloud/SpringCloudConsul.md) +* [Spring Cloud Eureka](docs/Spring全家桶/SpringCloud/SpringCloudEureka.md) +* [Spring Cloud Gateway](docs/Spring全家桶/SpringCloud/SpringCloudGateway.md) +* [Spring Cloud Hystrix](docs/Spring全家桶/SpringCloud/SpringCloudHystrix.md) +* [Spring Cloud LoadBalancer](docs/Spring全家桶/SpringCloud/SpringCloudLoadBalancer.md) +* [Spring Cloud OpenFeign](docs/Spring全家桶/SpringCloud/SpringCloudOpenFeign.md) +* [Spring Cloud Ribbon](docs/Spring全家桶/SpringCloud/SpringCloudRibbon.md) +* [Spring Cloud Sleuth](docs/Spring全家桶/SpringCloud/SpringCloudSleuth.md) +* [Spring Cloud Zuul](docs/Spring全家桶/SpringCloud/SpringCloudZuul.md) + +## SpringCloud æº�ç �分æž� +* [Spring Cloud Configæº�ç �分æž�](docs/Spring全家桶/SpringCloudæº�ç �分æž�/SpringCloudConfigæº�ç �分æž�.md) +* [Spring Cloud Eurekaæº�ç �分æž�](docs/Spring全家桶/SpringCloudæº�ç �分æž�/SpringCloudEurekaæº�ç �分æž�.md) +* [Spring Cloud Gatewayæº�ç �分æž�](docs/Spring全家桶/SpringCloudæº�ç �分æž�/SpringCloudGatewayæº�ç �分æž�.md) +* [Spring Cloud Hystrixæº�ç �分æž�](docs/Spring全家桶/SpringCloudæº�ç �分æž�/SpringCloudHystrixæº�ç �分æž�.md) +* [Spring Cloud LoadBalanceræº�ç �分æž�](docs/Spring全家桶/SpringCloudæº�ç �分æž�/SpringCloudLoadBalanceræº�ç �分æž�.md) +* [Spring Cloud OpenFeignæº�ç �分æž�](docs/Spring全家桶/SpringCloudæº�ç �分æž�/SpringCloudOpenFeignæº�ç �分æž�.md) +* [Spring Cloud Ribbonæº�ç �分æž�](docs/Spring全家桶/SpringCloudæº�ç �分æž�/SpringCloudRibbonæº�ç �分æž�.md) + +## SpringCloud Alibaba +* [SpringCloud Alibaba概览](docs/Spring全家桶/SpringCloudAlibaba/SpringCloudAlibaba概览.md) +* [SpringCloud Alibaba nacos](docs/Spring全家桶/SpringCloudAlibaba/SpringCloudAlibabaNacos.md) +* [SpringCloud Alibaba RocketMQ](docs/Spring全家桶/SpringCloudAlibaba/SpringCloudAlibabaRocketMQ.md) +* [SpringCloud Alibaba sentinel](docs/Spring全家桶/SpringCloudAlibaba/SpringCloudAlibabaSentinel.md) +* [SpringCloud Alibaba skywalking](docs/Spring全家桶/SpringCloudAlibaba/SpringCloudAlibabaSkywalking.md) +* [SpringCloud Alibaba seata](docs/Spring全家桶/SpringCloudAlibaba/SpringCloudAlibabaSeata.md) + +## SpringCloud Alibabaæº�ç �分æž� +* [Spring Cloud Seataæº�ç �分æž�](docs/Spring全家桶/SpringCloudAlibabaæº�ç �分æž�/SpringCloudSeataæº�ç �分æž�.md) +* [Spring Cloud Sentinelæº�ç �分æž�](docs/Spring全家桶/SpringCloudAlibabaæº�ç �分æž�/SpringCloudSentinelæº�ç �分æž�.md) +* [SpringCloudAlibaba nacosæº�ç �分æž�:概览](docs/Spring全家桶/SpringCloudAlibabaæº�ç �分æž�/SpringCloudAlibabaNacosæº�ç �分æž�:概览.md) +* [SpringCloudAlibaba nacosæº�ç �分æž�:æœ�务å�‘现](docs/Spring全家桶/SpringCloudAlibabaæº�ç �分æž�/SpringCloudAlibabaNacosæº�ç �分æž�:æœ�务å�‘现.md) +* [SpringCloudAlibaba nacosæº�ç �分æž�:æœ�务注册](docs/Spring全家桶/SpringCloudAlibabaæº�ç �分æž�/SpringCloudAlibabaNacosæº�ç �分æž�:æœ�务注册.md) +* [SpringCloudAlibaba nacosæº�ç �分æž�:é…�ç½®ä¸å¿ƒ](docs/Spring全家桶/SpringCloudAlibabaæº�ç �分æž�/SpringCloudAlibabaNacosæº�ç �分æž�:é…�ç½®ä¸å¿ƒ.md) +* [Spring Cloud RocketMQæº�ç �分æž�](docs/Spring全家桶/SpringCloudAlibabaæº�ç �分æž�/SpringCloudRocketMQæº�ç �分æž�.md) + +# 设计模å¼� + +* [设计模å¼�å¦ä¹ 总结](docs/Java/design-parttern/设计模å¼�å¦ä¹ 总结.md) +* [åˆ�探Java设计模å¼�:创建型模å¼�(工厂,å�•例ç‰ï¼‰.md](docs/Java/design-parttern/åˆ�探Java设计模å¼�:创建型模å¼�(工厂,å�•例ç‰ï¼‰.md) +* [åˆ�探Java设计模å¼�:结构型模å¼�(代ç�†æ¨¡å¼�,适é…�器模å¼�ç‰ï¼‰.md](docs/Java/design-parttern/åˆ�探Java设计模å¼�:结构型模å¼�(代ç�†æ¨¡å¼�,适é…�器模å¼�ç‰ï¼‰.md) +* [åˆ�探Java设计模å¼�:行为型模å¼�(ç–略,观察者ç‰ï¼‰.md](docs/Java/design-parttern/åˆ�探Java设计模å¼�:行为型模å¼�(ç–略,观察者ç‰ï¼‰.md) +* [åˆ�探Java设计模å¼�:JDKä¸çš„设计模å¼�.md](docs/Java/design-parttern/åˆ�探Java设计模å¼�:JDKä¸çš„设计模å¼�.md) +* [åˆ�探Java设计模å¼�:Spring涉å�Šåˆ°çš„ç§�设计模å¼�.md](docs/Java/design-parttern/åˆ�探Java设计模å¼�:Spring涉å�Šåˆ°çš„ç§�设计模å¼�.md) + + +# 计算机基础 + +## 计算机网络 todo -### æ“�作系统 +## æ“�作系统 todo -#### Linux相关 +## Linux相关 todo -### æ•°æ�®ç»“构与算法 +## æ•°æ�®ç»“构与算法 todo -#### æ•°æ�®ç»“æž„ +## æ•°æ�®ç»“æž„ todo -#### 算法 +## 算法 todo -## æ•°æ�®åº“ +# æ•°æ�®åº“ todo -### MySQL +## MySQL * [Mysql原ç�†ä¸Žå®žè·µæ€»ç»“](docs/database/Mysql原ç�†ä¸Žå®žè·µæ€»ç»“.md) * [é‡�æ–°å¦ä¹ Mysqlæ•°æ�®åº“ï¼šæ— åºŸè¯�MySQL入门](docs/database/é‡�æ–°å¦ä¹ MySQLæ•°æ�®åº“ï¼šæ— åºŸè¯�MySQL入门.md) * [é‡�æ–°å¦ä¹ Mysqlæ•°æ�®åº“:『浅入浅出ã€�MySQLå’ŒInnoDB](docs/database/é‡�æ–°å¦ä¹ MySQLæ•°æ�®åº“:『浅入浅出ã€�MySQLå’ŒInnoDB.md) @@ -266,9 +372,9 @@ todo * [é‡�æ–°å¦ä¹ Mysqlæ•°æ�®åº“:Mysql主从å¤�制,读写分离,分表分库ç–略与实践](docs/database/é‡�æ–°å¦ä¹ MySQLæ•°æ�®åº“:Mysql主从å¤�制,读写分离,分表分库ç–略与实践.md) -## ç¼“å˜ +# ç¼“å˜ -### Redis +## Redis * [Redis原ç�†ä¸Žå®žè·µæ€»ç»“](docs/cache/Redis原ç�†ä¸Žå®žè·µæ€»ç»“.md) * [探索Redis设计与实现开篇:什么是Redis](docs/cache/探索Redis设计与实现开篇:什么是Redis.md) * [探索Redis设计与实现:Redis的基础数æ�®ç»“构概览](docs/cache/探索Redis设计与实现:Redis的基础数æ�®ç»“构概览.md) @@ -287,27 +393,46 @@ todo * [探索Redis设计与实现:Redis事务浅æž�与ACID特性介ç»�](docs/cache/探索Redis设计与实现:Redis事务浅æž�与ACID特性介ç»�.md) * [探索Redis设计与实现:Redis分布å¼�é”�进化å�² ](docs/cache/探索Redis设计与实现:Redis分布å¼�é”�进化å�².md ) -## 消æ�¯é˜Ÿåˆ— - -### Kafka - -## 大å�Žç«¯ -* [å�Žç«¯æŠ€æœ¯æ�‚谈开篇:云计算,大数æ�®ä¸ŽAI的故事](docs/big-backEnd/å�Žç«¯æŠ€æœ¯æ�‚谈开篇:云计算,大数æ�®ä¸ŽAI的故事.md) -* [å�Žç«¯æŠ€æœ¯æ�‚谈:æ�œç´¢å¼•擎基础倒排索引](docs/big-backEnd/å�Žç«¯æŠ€æœ¯æ�‚谈:æ�œç´¢å¼•擎基础倒排索引.md) -* [å�Žç«¯æŠ€æœ¯æ�‚谈:æ�œç´¢å¼•擎工作原ç�†](docs/big-backEnd/å�Žç«¯æŠ€æœ¯æ�‚谈:æ�œç´¢å¼•擎工作原ç�†.md) -* [å�Žç«¯æŠ€æœ¯æ�‚谈:Lucene基础原ç�†ä¸Žå®žè·µ](docs/big-backEnd/å�Žç«¯æŠ€æœ¯æ�‚谈:Lucene基础原ç�†ä¸Žå®žè·µ.md) -* [å�Žç«¯æŠ€æœ¯æ�‚谈:Elasticsearch与solr入门实践](docs/big-backEnd/å�Žç«¯æŠ€æœ¯æ�‚谈:Elasticsearch与solr入门实践.md) -* [å�Žç«¯æŠ€æœ¯æ�‚谈:云计算的å‰�世今生](docs/big-backEnd/å�Žç«¯æŠ€æœ¯æ�‚谈:云计算的å‰�世今生.md) -* [å�Žç«¯æŠ€æœ¯æ�‚谈:白è¯�虚拟化技术](docs/big-backEnd/å�Žç«¯æŠ€æœ¯æ�‚谈:白è¯�虚拟化技术.md ) -* [å�Žç«¯æŠ€æœ¯æ�‚谈:OpenStack的基石KVM](docs/big-backEnd/å�Žç«¯æŠ€æœ¯æ�‚谈:OpenStack的基石KVM.md) -* [å�Žç«¯æŠ€æœ¯æ�‚谈:OpenStack架构设计](docs/big-backEnd/å�Žç«¯æŠ€æœ¯æ�‚谈:OpenStack架构设计.md) -* [å�Žç«¯æŠ€æœ¯æ�‚谈:先æ�žæ‡‚Dockeræ ¸å¿ƒæ¦‚å¿µå�§](docs/big-backEnd/å�Žç«¯æŠ€æœ¯æ�‚谈:先æ�žæ‡‚Dockeræ ¸å¿ƒæ¦‚å¿µå�§.md) -* [å�Žç«¯æŠ€æœ¯æ�‚谈:Docker æ ¸å¿ƒæŠ€æœ¯ä¸Žå®žçŽ°åŽŸç�†](docs/big-backEnd/å�Žç«¯æŠ€æœ¯æ�‚谈:Docker%æ ¸å¿ƒæŠ€æœ¯ä¸Žå®žçŽ°åŽŸç�†.md) -* [å�Žç«¯æŠ€æœ¯æ�‚谈:å��分钟ç�†è§£Kubernetesæ ¸å¿ƒæ¦‚å¿µ](docs/big-backEnd/å�Žç«¯æŠ€æœ¯æ�‚谈:å��分钟ç�†è§£Kubernetesæ ¸å¿ƒæ¦‚å¿µ.md) -* [å�Žç«¯æŠ€æœ¯æ�‚谈:æ�‹ä¸€æ�‹å¤§æ•°æ�®ç ”å�‘的基本概念](docs/big-backEnd/å�Žç«¯æŠ€æœ¯æ�‚谈:æ�‹ä¸€æ�‹å¤§æ•°æ�®ç ”å�‘的基本概念.md) - -## 分布å¼� -### ç�†è®º +# 消æ�¯é˜Ÿåˆ— + +## Kafka +* [消æ�¯é˜Ÿåˆ—kafka详解:Kafka快速上手(Java版)](docs/mq/kafka/消æ�¯é˜Ÿåˆ—kafka详解:Kafka快速上手(Java版).md) +* [消æ�¯é˜Ÿåˆ—kafka详解:Kafka一æ�¡æ¶ˆæ�¯å˜åˆ°broker的过程](docs/mq/kafka/消æ�¯é˜Ÿåˆ—kafka详解:Kafka一æ�¡æ¶ˆæ�¯å˜åˆ°broker的过程.md) +* [消æ�¯é˜Ÿåˆ—kafka详解:消æ�¯é˜Ÿåˆ—kafka详解:Kafka介ç»�](docs/mq/kafka/消æ�¯é˜Ÿåˆ—kafka详解:Kafka介ç»�.md) +* [消æ�¯é˜Ÿåˆ—kafka详解:Kafka原ç�†åˆ†æž�总结篇](docs/mq/kafka/消æ�¯é˜Ÿåˆ—kafka详解:Kafka原ç�†åˆ†æž�总结篇.md) +* [消æ�¯é˜Ÿåˆ—kafka详解:Kafka常è§�命令å�Šé…�置总结](docs/mq/kafka/消æ�¯é˜Ÿåˆ—kafka详解:Kafka常è§�命令å�Šé…�置总结.md) +* [消æ�¯é˜Ÿåˆ—kafka详解:Kafka架构介ç»�](docs/mq/kafka/消æ�¯é˜Ÿåˆ—kafka详解:Kafka架构介ç»�.md) +* [消æ�¯é˜Ÿåˆ—kafka详解:Kafka的集群工作原ç�†](docs/mq/kafka/消æ�¯é˜Ÿåˆ—kafka详解:Kafka的集群工作原ç�†.md) +* [消æ�¯é˜Ÿåˆ—kafka详解:Kafkaé‡�è¦�知识点+é�¢è¯•题大全](docs/mq/kafka/消æ�¯é˜Ÿåˆ—kafka详解:Kafkaé‡�è¦�知识点+é�¢è¯•题大全.md) +* [消æ�¯é˜Ÿåˆ—kafka详解:如何实现延迟队列](docs/mq/kafka/消æ�¯é˜Ÿåˆ—kafka详解:如何实现延迟队列.md) +* [消æ�¯é˜Ÿåˆ—kafka详解:如何实现æ»ä¿¡é˜Ÿåˆ—](docs/mq/kafka/消æ�¯é˜Ÿåˆ—kafka详解:如何实现æ»ä¿¡é˜Ÿåˆ—.md) + +## RocketMQ +* [RocketMQ系列:事务消æ�¯ï¼ˆæœ€ç»ˆä¸€è‡´æ€§ï¼‰](docs/mq/RocketMQ/RocketMQ系列:事务消æ�¯ï¼ˆæœ€ç»ˆä¸€è‡´æ€§ï¼‰.md) +* [RocketMQ系列:基本概念](docs/mq/RocketMQ/RocketMQ系列:基本概念.md) +* [RocketMQ系列:广æ’与延迟消æ�¯](docs/mq/RocketMQ/RocketMQ系列:广æ’与延迟消æ�¯.md) +* [RocketMQ系列:批é‡�å�‘é€�与过滤](docs/mq/RocketMQ/RocketMQ系列:批é‡�å�‘é€�与过滤.md) +* [RocketMQ系列:消æ�¯çš„生产与消费](docs/mq/RocketMQ/RocketMQ系列:消æ�¯çš„生产与消费.md) +* [RocketMQ系列:环境æ�建](docs/mq/RocketMQ/RocketMQ系列:环境æ�建.md) +* [RocketMQ系列:顺åº�消费](docs/mq/RocketMQ/RocketMQ系列:顺åº�消费.md) + +# 大å�Žç«¯ +* [å�Žç«¯æŠ€æœ¯æ�‚谈开篇:云计算,大数æ�®ä¸ŽAI的故事](docs/backend/å�Žç«¯æŠ€æœ¯æ�‚谈开篇:云计算,大数æ�®ä¸ŽAI的故事.md) +* [å�Žç«¯æŠ€æœ¯æ�‚谈:æ�œç´¢å¼•擎基础倒排索引](docs/backend/å�Žç«¯æŠ€æœ¯æ�‚谈:æ�œç´¢å¼•擎基础倒排索引.md) +* [å�Žç«¯æŠ€æœ¯æ�‚谈:æ�œç´¢å¼•擎工作原ç�†](docs/backend/å�Žç«¯æŠ€æœ¯æ�‚谈:æ�œç´¢å¼•擎工作原ç�†.md) +* [å�Žç«¯æŠ€æœ¯æ�‚谈:Lucene基础原ç�†ä¸Žå®žè·µ](docs/backend/å�Žç«¯æŠ€æœ¯æ�‚谈:Lucene基础原ç�†ä¸Žå®žè·µ.md) +* [å�Žç«¯æŠ€æœ¯æ�‚谈:Elasticsearch与solr入门实践](docs/backend/å�Žç«¯æŠ€æœ¯æ�‚谈:Elasticsearch与solr入门实践.md) +* [å�Žç«¯æŠ€æœ¯æ�‚谈:云计算的å‰�世今生](docs/backend/å�Žç«¯æŠ€æœ¯æ�‚谈:云计算的å‰�世今生.md) +* [å�Žç«¯æŠ€æœ¯æ�‚谈:白è¯�虚拟化技术](docs/backend/å�Žç«¯æŠ€æœ¯æ�‚谈:白è¯�虚拟化技术.md ) +* [å�Žç«¯æŠ€æœ¯æ�‚谈:OpenStack的基石KVM](docs/backend/å�Žç«¯æŠ€æœ¯æ�‚谈:OpenStack的基石KVM.md) +* [å�Žç«¯æŠ€æœ¯æ�‚谈:OpenStack架构设计](docs/backend/å�Žç«¯æŠ€æœ¯æ�‚谈:OpenStack架构设计.md) +* [å�Žç«¯æŠ€æœ¯æ�‚谈:先æ�žæ‡‚Dockeræ ¸å¿ƒæ¦‚å¿µå�§](docs/backend/å�Žç«¯æŠ€æœ¯æ�‚谈:先æ�žæ‡‚Dockeræ ¸å¿ƒæ¦‚å¿µå�§.md) +* [å�Žç«¯æŠ€æœ¯æ�‚谈:Docker æ ¸å¿ƒæŠ€æœ¯ä¸Žå®žçŽ°åŽŸç�†](docs/backend/å�Žç«¯æŠ€æœ¯æ�‚谈:Docker%æ ¸å¿ƒæŠ€æœ¯ä¸Žå®žçŽ°åŽŸç�†.md) +* [å�Žç«¯æŠ€æœ¯æ�‚谈:å��分钟ç�†è§£Kubernetesæ ¸å¿ƒæ¦‚å¿µ](docs/backend/å�Žç«¯æŠ€æœ¯æ�‚谈:å��分钟ç�†è§£Kubernetesæ ¸å¿ƒæ¦‚å¿µ.md) +* [å�Žç«¯æŠ€æœ¯æ�‚谈:æ�‹ä¸€æ�‹å¤§æ•°æ�®ç ”å�‘的基本概念](docs/backend/å�Žç«¯æŠ€æœ¯æ�‚谈:æ�‹ä¸€æ�‹å¤§æ•°æ�®ç ”å�‘的基本概念.md) + +# 分布å¼� +## 分布å¼�ç�†è®º * [分布å¼�系统ç�†è®ºåŸºç¡€ï¼šä¸€è‡´æ€§PCå’ŒPC ](docs/distributed/basic/分布å¼�系统ç�†è®ºåŸºç¡€ï¼šä¸€è‡´æ€§PCå’ŒPC.md) * [分布å¼�系统ç�†è®ºåŸºç¡€ï¼šCAP ](docs/distributed/basic/分布å¼�系统ç�†è®ºåŸºç¡€ï¼šCAP.md) * [分布å¼�系统ç�†è®ºåŸºç¡€ï¼šæ—¶é—´æ—¶é’Ÿå’Œäº‹ä»¶é¡ºåº�](docs/distributed/basic/分布å¼�系统ç�†è®ºåŸºç¡€ï¼šæ—¶é—´æ—¶é’Ÿå’Œäº‹ä»¶é¡ºåº�.md) @@ -316,22 +441,15 @@ todo * [分布å¼�系统ç�†è®ºåŸºç¡€ï¼šRaftZab ](docs/distributed/basic/分布å¼�系统ç�†è®ºåŸºç¡€ï¼šRaftZab.md) * [分布å¼�系统ç�†è®ºè¿›é˜¶ï¼šPaxoså�˜ç§�和优化 ](docs/distributed/basic/分布å¼�系统ç�†è®ºè¿›é˜¶ï¼šPaxoså�˜ç§�和优化.md) * [分布å¼�系统ç�†è®ºåŸºç¡€ï¼šzookeeper分布å¼�å��è°ƒæœ�务 ](docs/distributed/basic/分布å¼�系统ç�†è®ºåŸºç¡€ï¼šzookeeper分布å¼�å��è°ƒæœ�务.md) +* [分布å¼�ç�†è®ºæ€»ç»“](docs/distributed/分布å¼�技术实践总结.md) -* [分布å¼�技术实践总结](docs/distributed/分布å¼�ç�†è®ºæ€»ç»“.md) - -### 技术 +## 分布å¼�技术 * [æ�žæ‡‚分布å¼�技术:分布å¼�系统的一些基本概念](docs/distributed/practice/æ�žæ‡‚分布å¼�技术:分布å¼�系统的一些基本概念.md ) * [æ�žæ‡‚分布å¼�技术:分布å¼�一致性å��议与Paxos,Raft算法](docs/distributed/practice/æ�žæ‡‚分布å¼�技术:分布å¼�一致性å��议与Paxos,Raft算法.md) * [æ�žæ‡‚分布å¼�技术:åˆ�探分布å¼�å��è°ƒæœ�务zookeeper](docs/distributed/practice/æ�žæ‡‚分布å¼�技术:åˆ�探分布å¼�å��è°ƒæœ�务zookeeper.md ) * [æ�žæ‡‚分布å¼�技术:ZABå��议概述与选主æµ�程详解](docs/distributed/practice/æ�žæ‡‚分布å¼�技术:ZABå��议概述与选主æµ�程详解.md ) * [æ�žæ‡‚分布å¼�技术:Zookeeperçš„é…�置与集群管ç�†å®žæˆ˜](docs/distributed/practice/æ�žæ‡‚分布å¼�技术:Zookeeperçš„é…�置与集群管ç�†å®žæˆ˜.md) * [æ�žæ‡‚分布å¼�技术:Zookeeper典型应用场景å�Šå®žè·µ](docs/distributed/practice/æ�žæ‡‚分布å¼�技术:Zookeeper典型应用场景å�Šå®žè·µ.md ) - -[//]: # (* [æ�žæ‡‚分布å¼�技术:负载å�‡è¡¡æ¦‚念与主æµ�方案]docs/distributed/practice/æ�žæ‡‚分布å¼�技术:负载å�‡è¡¡æ¦‚念与主æµ�方案.md) - -[//]: # (* [æ�žæ‡‚分布å¼�技术:负载å�‡è¡¡åŽŸç�†å‰–æž� ]docs/distributed/practice/æ�žæ‡‚分布å¼�技术:负载å�‡è¡¡åŽŸç�†å‰–æž�.md ) - -[//]: # (* [æ�žæ‡‚分布å¼�技术: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 ) @@ -344,31 +462,31 @@ todo * [æ�žæ‡‚分布å¼�技术:使用RocketMQ事务消æ�¯è§£å†³åˆ†å¸ƒå¼�事务 ](docs/distributed/practice/æ�žæ‡‚分布å¼�技术:使用RocketMQ事务消æ�¯è§£å†³åˆ†å¸ƒå¼�事务.md ) * [æ�žæ‡‚分布å¼�技术:消æ�¯é˜Ÿåˆ—å› ä½•è€Œç”Ÿ](docs/distributed/practice/æ�žæ‡‚分布å¼�技术:消æ�¯é˜Ÿåˆ—å› ä½•è€Œç”Ÿ.md) * [æ�žæ‡‚分布å¼�技术:浅谈分布å¼�消æ�¯æŠ€æœ¯Kafka](docs/distributed/practice/æ�žæ‡‚分布å¼�技术:浅谈分布å¼�消æ�¯æŠ€æœ¯Kafka.md ) +* [分布å¼�技术实践总结](docs/distributed/分布å¼�ç�†è®ºæ€»ç»“.md) -* [分布å¼�ç�†è®ºæ€»ç»“](docs/distributed/分布å¼�技术实践总结.md) -## é�¢è¯•指å�— +# é�¢è¯•指å�— todo -### æ ¡æ‹›æŒ‡å�— +## æ ¡æ‹›æŒ‡å�— todo -### é�¢ç»� +## é�¢ç»� todo -## 工具 +# 工具 todo -## 资料 +# 资料 todo -### 书å�• +## 书å�• todo -## 待办 +# 待办 springbootå’Œspringcloud -## 微信公众å�· +# 微信公众å�· -### Java技术江湖 +## Java技术江湖 如果大家想è¦�å®žæ—¶å…³æ³¨æˆ‘æ›´æ–°çš„æ–‡ç« ä»¥å�Šåˆ†äº«çš„干货的è¯�,å�¯ä»¥å…³æ³¨æˆ‘的公众å�·ã€�Java技术江湖】  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" similarity index 99% rename from "docs/java/jvm/JVM\346\200\273\347\273\223.md" rename to "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å†…å˜æ¨¡åž‹) 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/\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/\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..ceda305 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/\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 @@ # 目录 + +* [æ ¸å¿ƒæ¦‚å¿µ(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\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" similarity index 99% 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\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" 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\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\206\205\345\255\230\347\232\204\347\273\223\346\236\204\344\270\216\346\266\210\345\244\261\347\232\204\346\260\270\344\271\205\344\273\243.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\206\205\345\255\230\347\232\204\347\273\223\346\236\204\344\270\216\346\266\210\345\244\261\347\232\204\346\260\270\344\271\205\344\273\243.md" similarity index 100% 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\206\205\345\255\230\347\232\204\347\273\223\346\236\204\344\270\216\346\266\210\345\244\261\347\232\204\346\260\270\344\271\205\344\273\243.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\206\205\345\255\230\347\232\204\347\273\223\346\236\204\344\270\216\346\266\210\345\244\261\347\232\204\346\260\270\344\271\205\344\273\243.md" 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" similarity index 99% 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\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" 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\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\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 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/\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..caac027 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/\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 @@ +# 目录 + * [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\232JVM\346\200\247\350\203\275\347\256\241\347\220\206\347\245\236\345\231\250VisualVM\344\273\213\347\273\215\344\270\216\345\256\236\346\210\230.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\346\200\247\350\203\275\347\256\241\347\220\206\347\245\236\345\231\250VisualVM\344\273\213\347\273\215\344\270\216\345\256\236\346\210\230.md" similarity index 100% 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\346\200\247\350\203\275\347\256\241\347\220\206\347\245\236\345\231\250VisualVM\344\273\213\347\273\215\344\270\216\345\256\236\346\210\230.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\346\200\247\350\203\275\347\256\241\347\220\206\347\245\236\345\231\250VisualVM\344\273\213\347\273\215\344\270\216\345\256\236\346\210\230.md" 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\347\233\221\346\216\247\345\267\245\345\205\267\344\270\216\350\257\212\346\226\255\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\347\233\221\346\216\247\345\267\245\345\205\267\344\270\216\350\257\212\346\226\255\345\256\236\350\267\265.md" similarity index 100% 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\347\233\221\346\216\247\345\267\245\345\205\267\344\270\216\350\257\212\346\226\255\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\347\233\221\346\216\247\345\267\245\345\205\267\344\270\216\350\257\212\346\226\255\345\256\236\350\267\265.md" 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\345\206\205\345\255\230\345\274\202\345\270\270\345\216\237\347\220\206\344\270\216\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\232Java\345\206\205\345\255\230\345\274\202\345\270\270\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265.md" similarity index 100% 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\232Java\345\206\205\345\255\230\345\274\202\345\270\270\345\216\237\347\220\206\344\270\216\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\232Java\345\206\205\345\255\230\345\274\202\345\270\270\345\216\237\347\220\206\344\270\216\345\256\236\350\267\265.md" 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\345\255\227\350\212\202\347\240\201\344\273\213\347\273\215\344\270\216\350\247\243\346\236\220\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\232Java\345\255\227\350\212\202\347\240\201\344\273\213\347\273\215\344\270\216\350\247\243\346\236\220\345\256\236\350\267\265.md" similarity index 100% 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\232Java\345\255\227\350\212\202\347\240\201\344\273\213\347\273\215\344\270\216\350\247\243\346\236\220\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\232Java\345\255\227\350\212\202\347\240\201\344\273\213\347\273\215\344\270\216\350\247\243\346\236\220\345\256\236\350\267\265.md" 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" similarity index 96% 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\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" 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\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" similarity index 99% 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\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" 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\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/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\236\203\345\234\276\345\233\236\346\224\266\345\231\250\350\257\246\350\247\243.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\236\203\345\234\276\345\233\236\346\224\266\345\231\250\350\257\246\350\247\243.md" similarity index 100% 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\232\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250\350\257\246\350\247\243.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\232\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250\350\257\246\350\247\243.md" 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\346\267\261\345\205\245\347\220\206\350\247\243JVM\347\261\273\345\212\240\350\275\275\346\234\272\345\210\266.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\346\267\261\345\205\245\347\220\206\350\247\243JVM\347\261\273\345\212\240\350\275\275\346\234\272\345\210\266.md" similarity index 100% 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\232\346\267\261\345\205\245\347\220\206\350\247\243JVM\347\261\273\345\212\240\350\275\275\346\234\272\345\210\266.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\232\346\267\261\345\205\245\347\220\206\350\247\243JVM\347\261\273\345\212\240\350\275\275\346\234\272\345\210\266.md" 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\350\231\232\346\213\237\346\234\272\345\255\227\350\212\202\347\240\201\346\211\247\350\241\214\345\274\225\346\223\216.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\350\231\232\346\213\237\346\234\272\345\255\227\350\212\202\347\240\201\346\211\247\350\241\214\345\274\225\346\223\216.md" similarity index 100% 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\232\350\231\232\346\213\237\346\234\272\345\255\227\350\212\202\347\240\201\346\211\247\350\241\214\345\274\225\346\223\216.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\232\350\231\232\346\213\237\346\234\272\345\255\227\350\212\202\347\240\201\346\211\247\350\241\214\345\274\225\346\223\216.md" diff --git "a/docs/java/basic/Java8\346\226\260\347\211\271\346\200\247\347\273\210\346\236\201\346\214\207\345\215\227.md" "b/docs/Java/basic/Java8\346\226\260\347\211\271\346\200\247\347\273\210\346\236\201\346\214\207\345\215\227.md" similarity index 100% rename from "docs/java/basic/Java8\346\226\260\347\211\271\346\200\247\347\273\210\346\236\201\346\214\207\345\215\227.md" rename to "docs/Java/basic/Java8\346\226\260\347\211\271\346\200\247\347\273\210\346\236\201\346\214\207\345\215\227.md" diff --git "a/docs/java/basic/JavaIO\346\265\201.md" "b/docs/Java/basic/JavaIO\346\265\201.md" similarity index 100% rename from "docs/java/basic/JavaIO\346\265\201.md" rename to "docs/Java/basic/JavaIO\346\265\201.md" diff --git "a/docs/java/basic/Java\344\270\255\347\232\204Class\347\261\273\345\222\214Object\347\261\273.md" "b/docs/Java/basic/Java\344\270\255\347\232\204Class\347\261\273\345\222\214Object\347\261\273.md" similarity index 100% rename from "docs/java/basic/Java\344\270\255\347\232\204Class\347\261\273\345\222\214Object\347\261\273.md" rename to "docs/Java/basic/Java\344\270\255\347\232\204Class\347\261\273\345\222\214Object\347\261\273.md" diff --git "a/docs/java/basic/Java\345\237\272\346\234\254\346\225\260\346\215\256\347\261\273\345\236\213.md" "b/docs/Java/basic/Java\345\237\272\346\234\254\346\225\260\346\215\256\347\261\273\345\236\213.md" similarity index 100% rename from "docs/java/basic/Java\345\237\272\346\234\254\346\225\260\346\215\256\347\261\273\345\236\213.md" rename to "docs/Java/basic/Java\345\237\272\346\234\254\346\225\260\346\215\256\347\261\273\345\236\213.md" diff --git "a/docs/java/basic/Java\345\274\202\345\270\270.md" "b/docs/Java/basic/Java\345\274\202\345\270\270.md" similarity index 100% rename from "docs/java/basic/Java\345\274\202\345\270\270.md" rename to "docs/Java/basic/Java\345\274\202\345\270\270.md" diff --git "a/docs/java/basic/Java\346\263\250\350\247\243\345\222\214\346\234\200\344\275\263\345\256\236\350\267\265.md" "b/docs/Java/basic/Java\346\263\250\350\247\243\345\222\214\346\234\200\344\275\263\345\256\236\350\267\265.md" similarity index 99% rename from "docs/java/basic/Java\346\263\250\350\247\243\345\222\214\346\234\200\344\275\263\345\256\236\350\267\265.md" rename to "docs/Java/basic/Java\346\263\250\350\247\243\345\222\214\346\234\200\344\275\263\345\256\236\350\267\265.md" index aace19c..435e587 100644 --- "a/docs/java/basic/Java\346\263\250\350\247\243\345\222\214\346\234\200\344\275\263\345\256\236\350\267\265.md" +++ "b/docs/Java/basic/Java\346\263\250\350\247\243\345\222\214\346\234\200\344\275\263\345\256\236\350\267\265.md" @@ -403,8 +403,8 @@ public class TheClass { ä½ å�¯ä»¥åƒ�è¿™æ ·æ�¥è®¿é—®å�˜é‡�的注解: ``` -Field field = ... //获å�–方法对象 -
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/docs/java/basic/Java\347\261\273\345\222\214\345\214\205.md" "b/docs/Java/basic/Java\347\261\273\345\222\214\345\214\205.md"
similarity index 100%
rename from "docs/java/basic/Java\347\261\273\345\222\214\345\214\205.md"
rename to "docs/Java/basic/Java\347\261\273\345\222\214\345\214\205.md"
diff --git "a/docs/java/basic/Java\350\207\252\345\212\250\346\213\206\347\256\261\350\243\205\347\256\261\351\207\214\351\232\220\350\227\217\347\232\204\347\247\230\345\257\206.md" "b/docs/Java/basic/Java\350\207\252\345\212\250\346\213\206\347\256\261\350\243\205\347\256\261\351\207\214\351\232\220\350\227\217\347\232\204\347\247\230\345\257\206.md"
similarity index 100%
rename from "docs/java/basic/Java\350\207\252\345\212\250\346\213\206\347\256\261\350\243\205\347\256\261\351\207\214\351\232\220\350\227\217\347\232\204\347\247\230\345\257\206.md"
rename to "docs/Java/basic/Java\350\207\252\345\212\250\346\213\206\347\256\261\350\243\205\347\256\261\351\207\214\351\232\220\350\227\217\347\232\204\347\247\230\345\257\206.md"
diff --git "a/docs/java/basic/Java\351\233\206\345\220\210\346\241\206\346\236\266\346\242\263\347\220\206.md" "b/docs/Java/basic/Java\351\233\206\345\220\210\346\241\206\346\236\266\346\242\263\347\220\206.md"
similarity index 100%
rename from "docs/java/basic/Java\351\233\206\345\220\210\346\241\206\346\236\266\346\242\263\347\220\206.md"
rename to "docs/Java/basic/Java\351\233\206\345\220\210\346\241\206\346\236\266\346\242\263\347\220\206.md"
diff --git "a/docs/java/basic/final\345\205\263\351\224\256\345\255\227\347\211\271\346\200\247.md" "b/docs/Java/basic/final\345\205\263\351\224\256\345\255\227\347\211\271\346\200\247.md"
similarity index 100%
rename from "docs/java/basic/final\345\205\263\351\224\256\345\255\227\347\211\271\346\200\247.md"
rename to "docs/Java/basic/final\345\205\263\351\224\256\345\255\227\347\211\271\346\200\247.md"
diff --git "a/docs/java/basic/javac\345\222\214javap.md" "b/docs/Java/basic/javac\345\222\214javap.md"
similarity index 98%
rename from "docs/java/basic/javac\345\222\214javap.md"
rename to "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/string\345\222\214\345\214\205\350\243\205\347\261\273.md" "b/docs/Java/basic/string\345\222\214\345\214\205\350\243\205\347\261\273.md"
similarity index 100%
rename from "docs/java/basic/string\345\222\214\345\214\205\350\243\205\347\261\273.md"
rename to "docs/Java/basic/string\345\222\214\345\214\205\350\243\205\347\261\273.md"
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"
similarity index 98%
rename from "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"
rename to "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\217\215\345\260\204.md" "b/docs/Java/basic/\345\217\215\345\260\204.md"
similarity index 100%
rename from "docs/java/basic/\345\217\215\345\260\204.md"
rename to "docs/Java/basic/\345\217\215\345\260\204.md"
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"
similarity index 98%
rename from "docs/java/basic/\345\244\232\347\272\277\347\250\213.md"
rename to "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/\345\272\217\345\210\227\345\214\226\345\222\214\345\217\215\345\272\217\345\210\227\345\214\226.md" "b/docs/Java/basic/\345\272\217\345\210\227\345\214\226\345\222\214\345\217\215\345\272\217\345\210\227\345\214\226.md"
similarity index 100%
rename from "docs/java/basic/\345\272\217\345\210\227\345\214\226\345\222\214\345\217\215\345\272\217\345\210\227\345\214\226.md"
rename to "docs/Java/basic/\345\272\217\345\210\227\345\214\226\345\222\214\345\217\215\345\272\217\345\210\227\345\214\226.md"
diff --git "a/docs/java/basic/\346\212\275\350\261\241\347\261\273\345\222\214\346\216\245\345\217\243.md" "b/docs/Java/basic/\346\212\275\350\261\241\347\261\273\345\222\214\346\216\245\345\217\243.md"
similarity index 100%
rename from "docs/java/basic/\346\212\275\350\261\241\347\261\273\345\222\214\346\216\245\345\217\243.md"
rename to "docs/Java/basic/\346\212\275\350\261\241\347\261\273\345\222\214\346\216\245\345\217\243.md"
diff --git "a/docs/java/basic/\346\236\232\344\270\276\347\261\273.md" "b/docs/Java/basic/\346\236\232\344\270\276\347\261\273.md"
similarity index 100%
rename from "docs/java/basic/\346\236\232\344\270\276\347\261\273.md"
rename to "docs/Java/basic/\346\236\232\344\270\276\347\261\273.md"
diff --git "a/docs/java/basic/\346\263\233\345\236\213.md" "b/docs/Java/basic/\346\263\233\345\236\213.md"
similarity index 100%
rename from "docs/java/basic/\346\263\233\345\236\213.md"
rename to "docs/Java/basic/\346\263\233\345\236\213.md"
diff --git "a/docs/java/basic/\346\267\261\345\205\245\347\220\206\350\247\243\345\206\205\351\203\250\347\261\273.md" "b/docs/Java/basic/\346\267\261\345\205\245\347\220\206\350\247\243\345\206\205\351\203\250\347\261\273.md"
similarity index 100%
rename from "docs/java/basic/\346\267\261\345\205\245\347\220\206\350\247\243\345\206\205\351\203\250\347\261\273.md"
rename to "docs/Java/basic/\346\267\261\345\205\245\347\220\206\350\247\243\345\206\205\351\203\250\347\261\273.md"
diff --git "a/docs/java/basic/\347\273\247\346\211\277\343\200\201\345\260\201\350\243\205\343\200\201\345\244\232\346\200\201\347\232\204\345\256\236\347\216\260\345\216\237\347\220\206.md" "b/docs/Java/basic/\347\273\247\346\211\277\343\200\201\345\260\201\350\243\205\343\200\201\345\244\232\346\200\201\347\232\204\345\256\236\347\216\260\345\216\237\347\220\206.md"
similarity index 100%
rename from "docs/java/basic/\347\273\247\346\211\277\343\200\201\345\260\201\350\243\205\343\200\201\345\244\232\346\200\201\347\232\204\345\256\236\347\216\260\345\216\237\347\220\206.md"
rename to "docs/Java/basic/\347\273\247\346\211\277\343\200\201\345\260\201\350\243\205\343\200\201\345\244\232\346\200\201\347\232\204\345\256\236\347\216\260\345\216\237\347\220\206.md"
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"
similarity index 99%
rename from "docs/java/basic/\350\247\243\350\257\273Java\344\270\255\347\232\204\345\233\236\350\260\203.md"
rename to "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/basic/\351\235\242\345\220\221\345\257\271\350\261\241\345\237\272\347\241\200.md" "b/docs/Java/basic/\351\235\242\345\220\221\345\257\271\350\261\241\345\237\272\347\241\200.md"
similarity index 100%
rename from "docs/java/basic/\351\235\242\345\220\221\345\257\271\350\261\241\345\237\272\347\241\200.md"
rename to "docs/Java/basic/\351\235\242\345\220\221\345\257\271\350\261\241\345\237\272\347\241\200.md"
diff --git "a/docs/java/collection/Java\351\233\206\345\220\210\347\261\273\346\200\273\347\273\223.md" "b/docs/Java/collection/Java\351\233\206\345\220\210\347\261\273\346\200\273\347\273\223.md"
similarity index 100%
rename from "docs/java/collection/Java\351\233\206\345\220\210\347\261\273\346\200\273\347\273\223.md"
rename to "docs/Java/collection/Java\351\233\206\345\220\210\347\261\273\346\200\273\347\273\223.md"
diff --git "a/docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\243\357\274\232HashMap\345\222\214HashTable.md" "b/docs/Java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\243\357\274\232HashMap\345\222\214HashTable.md"
similarity index 100%
rename from "docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\243\357\274\232HashMap\345\222\214HashTable.md"
rename to "docs/Java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\243\357\274\232HashMap\345\222\214HashTable.md"
diff --git "a/docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\243\357\274\232HashSet\357\274\214TreeSet\344\270\216LinkedHashSet.md" "b/docs/Java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\243\357\274\232HashSet\357\274\214TreeSet\344\270\216LinkedHashSet.md"
similarity index 100%
rename from "docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\243\357\274\232HashSet\357\274\214TreeSet\344\270\216LinkedHashSet.md"
rename to "docs/Java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\243\357\274\232HashSet\357\274\214TreeSet\344\270\216LinkedHashSet.md"
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"
similarity index 99%
rename from "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"
rename to "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\232Java\351\233\206\345\220\210\347\261\273\347\273\206\350\212\202\347\262\276\350\256\262.md" "b/docs/Java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\243\357\274\232Java\351\233\206\345\220\210\347\261\273\347\273\206\350\212\202\347\262\276\350\256\262.md"
similarity index 100%
rename from "docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\243\357\274\232Java\351\233\206\345\220\210\347\261\273\347\273\206\350\212\202\347\262\276\350\256\262.md"
rename to "docs/Java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\243\357\274\232Java\351\233\206\345\220\210\347\261\273\347\273\206\350\212\202\347\262\276\350\256\262.md"
diff --git "a/docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\243\357\274\232Queue\345\222\214LinkedList.md" "b/docs/Java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\243\357\274\232Queue\345\222\214LinkedList.md"
similarity index 100%
rename from "docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\243\357\274\232Queue\345\222\214LinkedList.md"
rename to "docs/Java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\243\357\274\232Queue\345\222\214LinkedList.md"
diff --git "a/docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\243\357\274\232TreeMap\345\222\214\347\272\242\351\273\221\346\240\221.md" "b/docs/Java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\243\357\274\232TreeMap\345\222\214\347\272\242\351\273\221\346\240\221.md"
similarity index 100%
rename from "docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\243\357\274\232TreeMap\345\222\214\347\272\242\351\273\221\346\240\221.md"
rename to "docs/Java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\243\357\274\232TreeMap\345\222\214\347\272\242\351\273\221\346\240\221.md"
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"
similarity index 98%
rename from "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"
rename to "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/collection/Java\351\233\206\345\220\210\350\257\246\350\247\243\357\274\232\346\267\261\345\205\245\347\220\206\350\247\243LinkedHashMap\345\222\214LRU\347\274\223\345\255\230.md" "b/docs/Java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\243\357\274\232\346\267\261\345\205\245\347\220\206\350\247\243LinkedHashMap\345\222\214LRU\347\274\223\345\255\230.md"
similarity index 100%
rename from "docs/java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\243\357\274\232\346\267\261\345\205\245\347\220\206\350\247\243LinkedHashMap\345\222\214LRU\347\274\223\345\255\230.md"
rename to "docs/Java/collection/Java\351\233\206\345\220\210\350\257\246\350\247\243\357\274\232\346\267\261\345\205\245\347\220\206\350\247\243LinkedHashMap\345\222\214LRU\347\274\223\345\255\230.md"
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"
similarity index 99%
rename from "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"
rename to "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\232AQS\345\205\261\344\272\253\346\250\241\345\274\217\344\270\216\345\271\266\345\217\221\345\267\245\345\205\267\347\261\273\347\232\204\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\232AQS\345\205\261\344\272\253\346\250\241\345\274\217\344\270\216\345\271\266\345\217\221\345\267\245\345\205\267\347\261\273\347\232\204\345\256\236\347\216\260.md"
similarity index 100%
rename from "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232AQS\345\205\261\344\272\253\346\250\241\345\274\217\344\270\216\345\271\266\345\217\221\345\267\245\345\205\267\347\261\273\347\232\204\345\256\236\347\216\260.md"
rename to "docs/Java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232AQS\345\205\261\344\272\253\346\250\241\345\274\217\344\270\216\345\271\266\345\217\221\345\267\245\345\205\267\347\261\273\347\232\204\345\256\236\347\216\260.md"
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"
similarity index 92%
rename from "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"
rename to "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"
similarity index 96%
rename from "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"
rename to "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..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,3 +1,12 @@
+# 目录
+
+ * [一�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\232JUC\344\270\255\345\270\270\347\224\250\347\232\204Unsafe\345\222\214Locksupport.md" "b/docs/Java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232JUC\344\270\255\345\270\270\347\224\250\347\232\204Unsafe\345\222\214Locksupport.md"
similarity index 100%
rename from "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232JUC\344\270\255\345\270\270\347\224\250\347\232\204Unsafe\345\222\214Locksupport.md"
rename to "docs/Java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232JUC\344\270\255\345\270\270\347\224\250\347\232\204Unsafe\345\222\214Locksupport.md"
diff --git "a/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232JUC\347\232\204\346\240\270\345\277\203\347\261\273AQS\350\257\246\350\247\243.md" "b/docs/Java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232JUC\347\232\204\346\240\270\345\277\203\347\261\273AQS\350\257\246\350\247\243.md"
similarity index 100%
rename from "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232JUC\347\232\204\346\240\270\345\277\203\347\261\273AQS\350\257\246\350\247\243.md"
rename to "docs/Java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232JUC\347\232\204\346\240\270\345\277\203\347\261\273AQS\350\257\246\350\247\243.md"
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"
similarity index 99%
rename from "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"
rename to "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\344\270\255\347\232\204\351\224\201Lock\345\222\214synchronized.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\204\351\224\201Lock\345\222\214synchronized.md"
similarity index 100%
rename from "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232Java\344\270\255\347\232\204\351\224\201Lock\345\222\214synchronized.md"
rename to "docs/Java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232Java\344\270\255\347\232\204\351\224\201Lock\345\222\214synchronized.md"
diff --git "a/docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232Java\345\206\205\345\255\230\346\250\241\345\236\213JMM\346\200\273\347\273\223.md" "b/docs/Java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232Java\345\206\205\345\255\230\346\250\241\345\236\213JMM\346\200\273\347\273\223.md"
similarity index 100%
rename from "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232Java\345\206\205\345\255\230\346\250\241\345\236\213JMM\346\200\273\347\273\223.md"
rename to "docs/Java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232Java\345\206\205\345\255\230\346\250\241\345\236\213JMM\346\200\273\347\273\223.md"
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"
similarity index 95%
rename from "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"
rename to "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"
similarity index 99%
rename from "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"
rename to "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\345\271\266\345\217\221\345\237\272\347\241\200\344\270\216Java\345\244\232\347\272\277\347\250\213.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\345\237\272\347\241\200\344\270\216Java\345\244\232\347\272\277\347\250\213.md"
similarity index 100%
rename from "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\345\237\272\347\241\200\344\270\216Java\345\244\232\347\272\277\347\250\213.md"
rename to "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\345\237\272\347\241\200\344\270\216Java\345\244\232\347\272\277\347\250\213.md"
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"
similarity index 98%
rename from "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"
rename to "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"
similarity index 98%
rename from "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"
rename to "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\346\214\207\345\215\227\357\274\232\350\247\243\350\257\273Java\351\230\273\345\241\236\351\230\237\345\210\227BlockingQueue.md" "b/docs/Java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232\350\247\243\350\257\273Java\351\230\273\345\241\236\351\230\237\345\210\227BlockingQueue.md"
similarity index 100%
rename from "docs/java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232\350\247\243\350\257\273Java\351\230\273\345\241\236\351\230\237\345\210\227BlockingQueue.md"
rename to "docs/Java/concurrency/Java\345\271\266\345\217\221\346\214\207\345\215\227\357\274\232\350\247\243\350\257\273Java\351\230\273\345\241\236\351\230\237\345\210\227BlockingQueue.md"
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"
similarity index 99%
rename from "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"
rename to "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"
similarity index 76%
rename from "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"
rename to "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..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,3 +1,34 @@
+# 目录
+
+ * [**一,结构型模�**](#一,结构型模�)
+ * [**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/design-parttern/\345\210\235\346\216\242Java\350\256\276\350\256\241\346\250\241\345\274\217\357\274\232Spring\346\266\211\345\217\212\345\210\260\347\232\204\347\247\215\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\232Spring\346\266\211\345\217\212\345\210\260\347\232\204\347\247\215\350\256\276\350\256\241\346\250\241\345\274\217.md"
similarity index 100%
rename from "docs/java/design-parttern/\345\210\235\346\216\242Java\350\256\276\350\256\241\346\250\241\345\274\217\357\274\232Spring\346\266\211\345\217\212\345\210\260\347\232\204\347\247\215\350\256\276\350\256\241\346\250\241\345\274\217.md"
rename to "docs/Java/design-parttern/\345\210\235\346\216\242Java\350\256\276\350\256\241\346\250\241\345\274\217\357\274\232Spring\346\266\211\345\217\212\345\210\260\347\232\204\347\247\215\350\256\276\350\256\241\346\250\241\345\274\217.md"
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\232\345\210\233\345\273\272\345\236\213\346\250\241\345\274\217\357\274\210\345\267\245\345\216\202\357\274\214\345\215\225\344\276\213\347\255\211\357\274\211.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\232\345\210\233\345\273\272\345\236\213\346\250\241\345\274\217\357\274\210\345\267\245\345\216\202\357\274\214\345\215\225\344\276\213\347\255\211\357\274\211.md"
similarity index 100%
rename from "docs/java/design-parttern/\345\210\235\346\216\242Java\350\256\276\350\256\241\346\250\241\345\274\217\357\274\232\345\210\233\345\273\272\345\236\213\346\250\241\345\274\217\357\274\210\345\267\245\345\216\202\357\274\214\345\215\225\344\276\213\347\255\211\357\274\211.md"
rename to "docs/Java/design-parttern/\345\210\235\346\216\242Java\350\256\276\350\256\241\346\250\241\345\274\217\357\274\232\345\210\233\345\273\272\345\236\213\346\250\241\345\274\217\357\274\210\345\267\245\345\216\202\357\274\214\345\215\225\344\276\213\347\255\211\357\274\211.md"
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\232\347\273\223\346\236\204\345\236\213\346\250\241\345\274\217\357\274\210\344\273\243\347\220\206\346\250\241\345\274\217\357\274\214\351\200\202\351\205\215\345\231\250\346\250\241\345\274\217\347\255\211\357\274\211.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\232\347\273\223\346\236\204\345\236\213\346\250\241\345\274\217\357\274\210\344\273\243\347\220\206\346\250\241\345\274\217\357\274\214\351\200\202\351\205\215\345\231\250\346\250\241\345\274\217\347\255\211\357\274\211.md"
similarity index 100%
rename from "docs/java/design-parttern/\345\210\235\346\216\242Java\350\256\276\350\256\241\346\250\241\345\274\217\357\274\232\347\273\223\346\236\204\345\236\213\346\250\241\345\274\217\357\274\210\344\273\243\347\220\206\346\250\241\345\274\217\357\274\214\351\200\202\351\205\215\345\231\250\346\250\241\345\274\217\347\255\211\357\274\211.md"
rename to "docs/Java/design-parttern/\345\210\235\346\216\242Java\350\256\276\350\256\241\346\250\241\345\274\217\357\274\232\347\273\223\346\236\204\345\236\213\346\250\241\345\274\217\357\274\210\344\273\243\347\220\206\346\250\241\345\274\217\357\274\214\351\200\202\351\205\215\345\231\250\346\250\241\345\274\217\347\255\211\357\274\211.md"
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\232\350\241\214\344\270\272\345\236\213\346\250\241\345\274\217\357\274\210\347\255\226\347\225\245\357\274\214\350\247\202\345\257\237\350\200\205\347\255\211\357\274\211.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\232\350\241\214\344\270\272\345\236\213\346\250\241\345\274\217\357\274\210\347\255\226\347\225\245\357\274\214\350\247\202\345\257\237\350\200\205\347\255\211\357\274\211.md"
similarity index 100%
rename from "docs/java/design-parttern/\345\210\235\346\216\242Java\350\256\276\350\256\241\346\250\241\345\274\217\357\274\232\350\241\214\344\270\272\345\236\213\346\250\241\345\274\217\357\274\210\347\255\226\347\225\245\357\274\214\350\247\202\345\257\237\350\200\205\347\255\211\357\274\211.md"
rename to "docs/Java/design-parttern/\345\210\235\346\216\242Java\350\256\276\350\256\241\346\250\241\345\274\217\357\274\232\350\241\214\344\270\272\345\236\213\346\250\241\345\274\217\357\274\210\347\255\226\347\225\245\357\274\214\350\247\202\345\257\237\350\200\205\347\255\211\357\274\211.md"
diff --git "a/docs/java/design-parttern/\350\256\276\350\256\241\346\250\241\345\274\217\345\255\246\344\271\240\346\200\273\347\273\223.md" "b/docs/Java/design-parttern/\350\256\276\350\256\241\346\250\241\345\274\217\345\255\246\344\271\240\346\200\273\347\273\223.md"
similarity index 100%
rename from "docs/java/design-parttern/\350\256\276\350\256\241\346\250\241\345\274\217\345\255\246\344\271\240\346\200\273\347\273\223.md"
rename to "docs/Java/design-parttern/\350\256\276\350\256\241\346\250\241\345\274\217\345\255\246\344\271\240\346\200\273\347\273\223.md"
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/Java\347\275\221\347\273\234\344\270\216NIO\346\200\273\347\273\223.md"
similarity index 97%
rename from "docs/java/network-programming/Java\347\275\221\347\273\234\344\270\216NIO\346\200\273\347\273\223.md"
rename to "docs/Java/network/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/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/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"
similarity index 93%
rename from "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"
rename to "docs/Java/network/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..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/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))
@@ -90,7 +108,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 +224,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\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/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"
similarity index 97%
rename from "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"
rename to "docs/Java/network/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/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/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"
similarity index 98%
rename from "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"
rename to "docs/Java/network/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/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/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"
similarity index 94%
rename from "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"
rename to "docs/Java/network/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..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/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)
@@ -32,7 +47,7 @@
ä¸Šä¸€ç¯‡æ–‡ç« ä»‹ç»�了 Java NIO ä¸ Bufferã€�Channel å’Œ Selector 的基本æ“�作,主è¦�是一些接å�£æ“�作,比较简å�•。
-本文将介ç»�**é�žé˜»å¡ž IO** 和**å¼‚æ¥ IO**,也就是大家耳熟能详的 NIO å’Œ AIO。很多åˆ�å¦è€…å�¯èƒ½åˆ†ä¸�清楚异æ¥å’Œé�žé˜»å¡žçš„区别,å�ªæ˜¯åœ¨å�„ç§�场å�ˆèƒ½å�¬åˆ°**异æ¥é�žé˜»å¡ž**这个è¯�。
+本文将介ç»�**é�žé˜»å¡ž IO**å’Œ**å¼‚æ¥ IO**,也就是大家耳熟能详的 NIO å’Œ AIO。很多åˆ�å¦è€…å�¯èƒ½åˆ†ä¸�清楚异æ¥å’Œé�žé˜»å¡žçš„区别,å�ªæ˜¯åœ¨å�„ç§�场å�ˆèƒ½å�¬åˆ°**异æ¥é�žé˜»å¡ž**这个è¯�。
本文会先介ç»�并演示阻塞模å¼�,然å�Žå¼•å…¥é�žé˜»å¡žæ¨¡å¼�æ�¥å¯¹é˜»å¡žæ¨¡å¼�进行优化,最å�Žå†�介ç»� JDK7 å¼•å…¥çš„å¼‚æ¥ IOï¼Œç”±äºŽç½‘ä¸Šå…³äºŽå¼‚æ¥ IO 的介ç»�相对较少,所以这部分内容我会介ç»�得具体一些。
@@ -160,7 +175,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 +254,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\232LinuxEpoll\345\256\236\347\216\260\345\216\237\347\220\206\350\257\246\350\247\243.md" "b/docs/Java/network/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"
similarity index 97%
rename from "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"
rename to "docs/Java/network/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/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/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"
similarity index 99%
rename from "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"
rename to "docs/Java/network/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/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/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"
similarity index 98%
rename from "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"
rename to "docs/Java/network/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..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/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简介)
@@ -169,7 +189,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/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/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"
similarity index 96%
rename from "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"
rename to "docs/Java/network/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/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/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"
similarity index 95%
rename from "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"
rename to "docs/Java/network/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/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/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"
similarity index 97%
rename from "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"
rename to "docs/Java/network/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/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/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"
similarity index 95%
rename from "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"
rename to "docs/Java/network/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/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/docs/java-web/JavaWeb\346\212\200\346\234\257\346\200\273\347\273\223.md" "b/docs/JavaWeb/JavaWeb\346\212\200\346\234\257\346\200\273\347\273\223.md"
similarity index 100%
rename from "docs/java-web/JavaWeb\346\212\200\346\234\257\346\200\273\347\273\223.md"
rename to "docs/JavaWeb/JavaWeb\346\212\200\346\234\257\346\200\273\347\273\223.md"
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/JavaWeb/\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"
similarity index 99%
rename from "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"
rename to "docs/JavaWeb/\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/JavaWeb/\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\232JDBC\347\232\204\350\277\233\345\214\226\344\270\216\350\277\236\346\216\245\346\261\240\346\212\200\346\234\257.md" "b/docs/JavaWeb/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232JDBC\347\232\204\350\277\233\345\214\226\344\270\216\350\277\236\346\216\245\346\261\240\346\212\200\346\234\257.md"
similarity index 100%
rename from "docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232JDBC\347\232\204\350\277\233\345\214\226\344\270\216\350\277\236\346\216\245\346\261\240\346\212\200\346\234\257.md"
rename to "docs/JavaWeb/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232JDBC\347\232\204\350\277\233\345\214\226\344\270\216\350\277\236\346\216\245\346\261\240\346\212\200\346\234\257.md"
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\232JSP\344\270\216Servlet\347\232\204\346\233\276\347\273\217\344\270\216\347\216\260\345\234\250.md" "b/docs/JavaWeb/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232JSP\344\270\216Servlet\347\232\204\346\233\276\347\273\217\344\270\216\347\216\260\345\234\250.md"
similarity index 100%
rename from "docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232JSP\344\270\216Servlet\347\232\204\346\233\276\347\273\217\344\270\216\347\216\260\345\234\250.md"
rename to "docs/JavaWeb/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232JSP\344\270\216Servlet\347\232\204\346\233\276\347\273\217\344\270\216\347\216\260\345\234\250.md"
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\232JavaWeb\347\232\204\347\224\261\346\235\245\345\222\214\345\237\272\347\241\200\347\237\245\350\257\206.md" "b/docs/JavaWeb/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232JavaWeb\347\232\204\347\224\261\346\235\245\345\222\214\345\237\272\347\241\200\347\237\245\350\257\206.md"
similarity index 100%
rename from "docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232JavaWeb\347\232\204\347\224\261\346\235\245\345\222\214\345\237\272\347\241\200\347\237\245\350\257\206.md"
rename to "docs/JavaWeb/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232JavaWeb\347\232\204\347\224\261\346\235\245\345\222\214\345\237\272\347\241\200\347\237\245\350\257\206.md"
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\232Java\346\227\245\345\277\227\347\263\273\347\273\237\347\232\204\350\257\236\347\224\237\344\270\216\345\217\221\345\261\225.md" "b/docs/JavaWeb/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232Java\346\227\245\345\277\227\347\263\273\347\273\237\347\232\204\350\257\236\347\224\237\344\270\216\345\217\221\345\261\225.md"
similarity index 100%
rename from "docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232Java\346\227\245\345\277\227\347\263\273\347\273\237\347\232\204\350\257\236\347\224\237\344\270\216\345\217\221\345\261\225.md"
rename to "docs/JavaWeb/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232Java\346\227\245\345\277\227\347\263\273\347\273\237\347\232\204\350\257\236\347\224\237\344\270\216\345\217\221\345\261\225.md"
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/JavaWeb/\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"
similarity index 98%
rename from "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"
rename to "docs/JavaWeb/\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..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/JavaWeb/\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技术江湖)
本文转载自互è�”网,侵åˆ
@@ -252,7 +249,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\232Servlet\345\267\245\344\275\234\345\216\237\347\220\206\350\257\246\350\247\243.md" "b/docs/JavaWeb/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232Servlet\345\267\245\344\275\234\345\216\237\347\220\206\350\257\246\350\247\243.md"
similarity index 100%
rename from "docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232Servlet\345\267\245\344\275\234\345\216\237\347\220\206\350\257\246\350\247\243.md"
rename to "docs/JavaWeb/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232Servlet\345\267\245\344\275\234\345\216\237\347\220\206\350\257\246\350\247\243.md"
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/JavaWeb/\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"
similarity index 98%
rename from "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"
rename to "docs/JavaWeb/\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/JavaWeb/\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\232Tomcat\345\222\214\345\205\266\344\273\226WEB\345\256\271\345\231\250\347\232\204\345\214\272\345\210\253.md" "b/docs/JavaWeb/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232Tomcat\345\222\214\345\205\266\344\273\226WEB\345\256\271\345\231\250\347\232\204\345\214\272\345\210\253.md"
similarity index 100%
rename from "docs/java-web/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232Tomcat\345\222\214\345\205\266\344\273\226WEB\345\256\271\345\231\250\347\232\204\345\214\272\345\210\253.md"
rename to "docs/JavaWeb/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232Tomcat\345\222\214\345\205\266\344\273\226WEB\345\256\271\345\231\250\347\232\204\345\214\272\345\210\253.md"
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\216JavaBean\350\256\262\345\210\260Spring.md" "b/docs/JavaWeb/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232\344\273\216JavaBean\350\256\262\345\210\260Spring.md"
similarity index 100%
rename from "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\216JavaBean\350\256\262\345\210\260Spring.md"
rename to "docs/JavaWeb/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232\344\273\216JavaBean\350\256\262\345\210\260Spring.md"
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/JavaWeb/\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"
similarity index 96%
rename from "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"
rename to "docs/JavaWeb/\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..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/JavaWeb/\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的比较)
@@ -90,7 +88,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 +185,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\345\210\235\346\216\242Tomcat9\347\232\204HTTP\350\257\267\346\261\202\350\277\207\347\250\213.md" "b/docs/JavaWeb/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232\345\210\235\346\216\242Tomcat9\347\232\204HTTP\350\257\267\346\261\202\350\277\207\347\250\213.md"
similarity index 100%
rename from "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\210\235\346\216\242Tomcat9\347\232\204HTTP\350\257\267\346\261\202\350\277\207\347\250\213.md"
rename to "docs/JavaWeb/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232\345\210\235\346\216\242Tomcat9\347\232\204HTTP\350\257\267\346\261\202\350\277\207\347\250\213.md"
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/JavaWeb/\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"
similarity index 99%
rename from "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"
rename to "docs/JavaWeb/\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/JavaWeb/\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/JavaWeb/\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"
similarity index 94%
rename from "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"
rename to "docs/JavaWeb/\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..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/JavaWeb/\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技术江湖)
本文转载自互è�”网,侵åˆ
@@ -120,7 +117,7 @@ public class HelloController {
@RequestMapping("/hello") public String hello() { return "Hello Spring Boot!"; }}
```
-* **@RestController 注解:** 该注解是 @Controller 和 @ResponseBody 注解的�体版
+* **@RestController 注解:**该注解是 @Controller 和 @ResponseBody 注解的�体版
#### 第三æ¥ï¼šåˆ©ç”¨ IDEA å�¯åЍ Spring Boot
@@ -163,7 +160,7 @@ public class HelloController {
org.springframework.boot spring-boot-maven-plugin
```
-我们å�¯ä»¥çœ‹åˆ°ä¸€ä¸ªæ¯”è¾ƒé™Œç”Ÿä¸€äº›çš„æ ‡ç¾Â ``Â ï¼Œè¿™ä¸ªæ ‡ç¾æ˜¯åœ¨é…�ç½® Spring Boot 的父级ä¾�赖:
+我们å�¯ä»¥çœ‹åˆ°ä¸€ä¸ªæ¯”è¾ƒé™Œç”Ÿä¸€äº›çš„æ ‡ç¾``ï¼Œè¿™ä¸ªæ ‡ç¾æ˜¯åœ¨é…�ç½® Spring Boot 的父级ä¾�赖:
```
@@ -176,12 +173,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 +206,7 @@ Spring Boot 的全局�置文件的作用是对一些默认�置的�置值

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

-* **问题:**Â è¿™æ ·å†™é…�置文件ç¹�ç��而且å�¯èƒ½ä¼šé€ æˆ�ç±»çš„è‡ƒè‚¿ï¼Œå› ä¸ºæœ‰è®¸è®¸å¤šå¤šçš„ @Value 注解。
+* **问题:**è¿™æ ·å†™é…�置文件ç¹�ç��而且å�¯èƒ½ä¼šé€ æˆ�ç±»çš„è‡ƒè‚¿ï¼Œå› ä¸ºæœ‰è®¸è®¸å¤šå¤šçš„ @Value 注解。
> * �装�置信�
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\265\205\346\236\220Tomcat\350\257\267\346\261\202\345\244\204\347\220\206\346\265\201\347\250\213\344\270\216\345\220\257\345\212\250\351\203\250\347\275\262\350\277\207\347\250\213.md" "b/docs/JavaWeb/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232\346\265\205\346\236\220Tomcat\350\257\267\346\261\202\345\244\204\347\220\206\346\265\201\347\250\213\344\270\216\345\220\257\345\212\250\351\203\250\347\275\262\350\277\207\347\250\213.md"
similarity index 100%
rename from "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\265\205\346\236\220Tomcat\350\257\267\346\261\202\345\244\204\347\220\206\346\265\201\347\250\213\344\270\216\345\220\257\345\212\250\351\203\250\347\275\262\350\277\207\347\250\213.md"
rename to "docs/JavaWeb/\350\265\260\350\277\233JavaWeb\346\212\200\346\234\257\344\270\226\347\225\214\357\274\232\346\265\205\346\236\220Tomcat\350\257\267\346\261\202\345\244\204\347\220\206\346\265\201\347\250\213\344\270\216\345\220\257\345\212\250\351\203\250\347\275\262\350\277\207\347\250\213.md"
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/JavaWeb/\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"
similarity index 97%
rename from "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"
rename to "docs/JavaWeb/\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/JavaWeb/\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/Spring\345\205\250\345\256\266\346\241\266/Spring/SpringAOP\347\232\204\346\246\202\345\277\265\344\270\216\344\275\234\347\224\250.md" "b/docs/Spring\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/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..c4de431
--- /dev/null
+++ "b/docs/Spring\345\205\250\345\256\266\346\241\266/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,183 @@
+### ÒÀÀµ×¢Èë
+
+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\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/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..de8dba7
--- /dev/null
+++ "b/docs/Spring\345\205\250\345\256\266\346\241\266/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,713 @@
+# 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\345\205\250\345\256\266\346\241\266/Spring/Spring\344\270\255\347\232\204Environment\347\216\257\345\242\203\345\217\230\351\207\217.md" "b/docs/Spring\345\205\250\345\256\266\346\241\266/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..99987fa
--- /dev/null
+++ "b/docs/Spring\345\205\250\345\256\266\346\241\266/Spring/Spring\344\270\255\347\232\204Environment\347\216\257\345\242\203\345\217\230\351\207\217.md"
@@ -0,0 +1,849 @@
+
+
+
+
+Èç½ñ£¬ÖÂÁ¦ÓÚ°ïÖú¿ª·¢ÕßÓøüÉٵĴúÂë¡¢¸ü¿ìµØÐ´³öÉú²ú¼¶ÏµÍ³µÄ 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`È¥»ñÈ¡ÊôÐÔÖµ¡£
+
+
+
+×÷Õߣº³ÌÐòÔ³¶ÅСͷ
+Á´½Ó£º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\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/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..98c55c3
--- /dev/null
+++ "b/docs/Spring\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/Spring/Spring\344\270\255\347\232\204\350\265\204\346\272\220\347\256\241\347\220\206.md" "b/docs/Spring\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/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..4515cad
--- /dev/null
+++ "b/docs/Spring\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/Spring/Spring\344\272\213\345\212\241\345\237\272\346\234\254\347\224\250\346\263\225.md" "b/docs/Spring\345\205\250\345\256\266\346\241\266/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..c247c82
--- /dev/null
+++ "b/docs/Spring\345\205\250\345\256\266\346\241\266/Spring/Spring\344\272\213\345\212\241\345\237\272\346\234\254\347\224\250\346\263\225.md"
@@ -0,0 +1,292 @@
+# 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 Ëùʾ¡£
+
+| ÊôÐÔÃû³Æ | Öµ | Ãè Êö |
+| --- | --- | --- |
+| 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\345\205\250\345\256\266\346\241\266/Spring/Spring\345\220\210\351\233\206.md" "b/docs/Spring\345\205\250\345\256\266\346\241\266/Spring/Spring\345\220\210\351\233\206.md"
new file mode 100644
index 0000000..931264e
--- /dev/null
+++ "b/docs/Spring\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/Spring/Spring\345\256\271\345\231\250\344\270\216IOC.md" "b/docs/Spring\345\205\250\345\256\266\346\241\266/Spring/Spring\345\256\271\345\231\250\344\270\216IOC.md"
new file mode 100644
index 0000000..35623db
--- /dev/null
+++ "b/docs/Spring\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/Spring/Spring\345\270\270\350\247\201\346\263\250\350\247\243.md" "b/docs/Spring\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/Spring/Spring\346\246\202\350\277\260.md" "b/docs/Spring\345\205\250\345\256\266\346\241\266/Spring/Spring\346\246\202\350\277\260.md"
new file mode 100644
index 0000000..e9a041f
--- /dev/null
+++ "b/docs/Spring\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/Spring/\347\254\254\344\270\200\344\270\252Spring\345\272\224\347\224\250.md" "b/docs/Spring\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/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/docs/Spring\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/SpringBoot/SpringBoot\344\270\255\347\232\204\346\227\245\345\277\227\347\256\241\347\220\206.md" "b/docs/Spring\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/SpringBoot/SpringBoot\345\270\270\350\247\201\346\263\250\350\247\243.md" "b/docs/Spring\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/SpringBoot/SpringBoot\346\211\223\345\214\205\344\270\216\345\220\257\345\212\250.md" "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringBoot/SpringBoot\346\211\223\345\214\205\344\270\216\345\220\257\345\212\250.md"
new file mode 100644
index 0000000..9f13c13
--- /dev/null
+++ "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringBoot/SpringBoot\346\211\223\345\214\205\344\270\216\345\220\257\345\212\250.md"
@@ -0,0 +1,1388 @@
+在使用`maven`构建`springboot`项目时,`springboot`相关 jar 包�以使用`parent方�`引入(�在`pom.xml`的`parent`节点引入`springboot`的`GAV`:`org.springframework.boot:spring-boot-starter-parent:2.1.1.RELEASE`),也�以使用`�parent方�`引入(�在 pom 的 dependencyManagement 节点引入`springboot`的`GAV`:`org.springframework.boot:spring-boot-dependencies:2.1.1.RELEASE`)。�时,在打包时,我们�以打� jar 包,也�以打� war 包,本文旨在梳��引入�打包方�的异�。
+
+### 1\. parent 方�引入,打� jar 包
+
+parent æ–¹å¼�,å�³åœ¨ pom 文件ä¸ï¼Œå°† springboot çš„ä¾�赖当æˆ�项目的 parent 引入,pom 文件示例如下:
+
+```
+
+
+ 4.0.0
+
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.1.1.RELEASE
+
+
+ com.gitee.funcy
+ springboot-parent-jar
+ 1.0.0
+ jar
+ springboot parent jar打包方�
+
+
+ UTF-8
+ UTF-8
+ 1.8
+ 3.8.1
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+ ${java.version}
+ ${java.version}
+ ${project.build.sourceEncoding}
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
+
+```
+
+æ·»åŠ ä¸€ä¸ª controller:
+
+```
+package com.gitee.funcy.mavenparent.jar.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * ï½›è¿™é‡Œæ·»åŠ æ��è¿°ï½�
+ *
+ * @author funcy
+ * @date 2019-12-13 10:43 下�
+ */
+@RestController
+public class IndexController {
+
+ @RequestMapping("/")
+ public String helloWorld() {
+ return "hello world";
+ }
+
+}
+
+```
+
+�引入�动类:
+
+```
+package com.gitee.funcy.mavenparent.jar;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * ï½›è¿™é‡Œæ·»åŠ æ��è¿°ï½�
+ *
+ * @author funcy
+ * @date 2019-12-13 10:36 下�
+ */
+@SpringBootApplication
+public class Main {
+
+ public static void main(String[] args) {
+ SpringApplication.run(Main.class, args);
+ }
+
+}
+
+```
+
+�行 Main 方法,请求`http://localhost:8080/`,结果如下:
+
+```
+ $ curl http://localhost:8080/
+hello world
+
+```
+
+�以看到,项目�行�功。
+
+接�,�试使用 jar 包�动:
+
+```
+# 打包
+ mvn clean install -Dmaven.test.skip=true
+ # �动jar包
+ java -jar target/springboot-parent-jar-1.0.0.jar
+
+```
+
+å�¯ä»¥çœ‹åˆ°ï¼Œé¡¹ç›®å�¯åЍæˆ�功,请求请求`http://localhost:8080/`,也能显示æ£ç¡®ç»“果。
+
+### 2\. � parent 方�引入,打� jar 包
+
+在实际项目ä¸ï¼Œé¡¹ç›®çš„ parent ä¾�èµ–å�¯èƒ½ç»™äº†å…¶ä»–é¡¹ç›®ï¼Œæ¤æ—¶ parent å¼•ç”¨å°±æ— æ³•è¿›è¡Œäº†ï¼Œè¿™æ—¶æˆ‘ä»¬éœ€è¦�é�ž parent 引入。é�ž parent 引入的 pom 如下:
+
+```
+
+
+ 4.0.0
+
+ com.gitee.funcy
+ springboot-jar
+ 1.0.0
+ jar
+ springboot�parent jar打包方�
+
+
+ UTF-8
+ UTF-8
+ 1.8
+ 2.1.1.RELEASE
+ 3.8.1
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+ ${spring-boot.version}
+ pom
+ import
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+ ${java.version}
+ ${java.version}
+ ${project.build.sourceEncoding}
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ ${spring-boot.version}
+
+
+
+
+ repackage
+
+
+
+
+
+
+
+
+
+```
+
+å†�æ·»åŠ ä¸€ä¸ª`ControllerIndexController.java`与å�¯åŠ¨ç±»`Main.java`,这两个文件与上述示例相å�Œï¼Œè¿™é‡Œå°±ä¸�作展示了。
+
+�行 Main 方法,请求`http://localhost:8080/`,结果如下:
+
+```
+ $ curl http://localhost:8080/
+hello world
+
+```
+
+�以看到,项目�行�功。
+
+接�,�试使用 jar 包�动:
+
+```
+# 打包
+ mvn clean install -Dmaven.test.skip=true
+ # �动jar包
+ java -jar target/springboot-jar-1.0.0.jar
+
+```
+
+å�¯ä»¥çœ‹åˆ°ï¼Œé¡¹ç›®å�¯åЍæˆ�功,请求请求`http://localhost:8080/`,也能显示æ£ç¡®ç»“果。
+
+### 3\. parent 方�引入,打� war 包
+
+以上两ç§�æ–¹å¼�都是打æˆ� jarï¼Œä¸ºäº†å…¼å®¹ä¼ ç»Ÿçš„ servlet 应用,springboot 也支æŒ�打包 war 包,parent 引入打包 war 包的 pom 文件如下:
+
+```
+
+
+ 4.0.0
+
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.1.1.RELEASE
+
+
+ com.gitee.funcy
+ springboot-parent-war
+ 1.0.0
+
+ war
+ springboot parent war打包方�
+
+
+ UTF-8
+ UTF-8
+ 1.8
+ 3.8.1
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-test
+ provided
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+ ${java.version}
+ ${java.version}
+ ${project.build.sourceEncoding}
+
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+
+ 3.2.2
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
+```
+
+å†�æ·»åŠ ä¸€ä¸ª`ControllerIndexController.java`与å�¯åŠ¨ç±»`Main.java`,这两个文件与上述示例相å�Œï¼Œè¿™é‡Œå°±ä¸�作展示了。
+
+除æ¤ä¹‹å¤–,war 包方å¼�还需è¦�æ·»åŠ ä¸€ä¸ªç±»ï¼Œç”¨ä»¥å®žçŽ°`SpringBootServletInitializer`,该类与å�¯åŠ¨ç±»`Main.java`ä½�于å�Œä¸€ä¸ªåŒ…下,主è¦�是用æ�¥å¼•导 tomcat ç‰ servlet å®¹å™¨åŠ è½½ servlet,内容如下:
+
+```
+/**
+ * ï½›è¿™é‡Œæ·»åŠ æ��è¿°ï½�
+ *
+ * @author funcy
+ * @date 2019-12-20 1:22 下�
+ */
+public class StartApplication extends SpringBootServletInitializer {
+
+ @Override
+ protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
+ // 注�这里�指�原先用main方法执行的Application�动类
+ return builder.sources(Main.class);
+ }
+}
+
+```
+
+�行 Main 方法,请求`http://localhost:8080/`,结果如下:
+
+```
+ $ curl http://localhost:8080/
+hello world
+
+```
+
+�以看到,项目�行�功。
+
+接�,�试使用 jar 包�动:
+
+```
+# 打包
+ mvn clean install -Dmaven.test.skip=true
+ # �动jar包
+ java -jar target/springboot-parent-war-1.0.0.jar
+
+```
+
+å�¯ä»¥çœ‹åˆ°ï¼Œé¡¹ç›®å�¯åЍæˆ�功,请求请求`http://localhost:8080/`,也能显示æ£ç¡®ç»“果。
+
+### 4\. � parent 方�引入,打� war 包
+
+å�Œæ ·åœ°ï¼Œæ‰“æˆ� war 包时,也å�¯ä½¿ç”¨é�ž parent 引入方å¼�:
+
+```
+
+
+ 4.0.0
+
+ com.gitee.funcy
+ springboot-war
+ 1.0.0
+
+ war
+ springboot�parent war打包方�
+
+
+ UTF-8
+ UTF-8
+ 1.8
+ 2.1.1.RELEASE
+ 3.8.1
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+ ${spring-boot.version}
+ pom
+ import
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-test
+ provided
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+ ${java.version}
+ ${java.version}
+ ${project.build.sourceEncoding}
+
+
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+
+ 3.2.2
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ ${spring-boot.version}
+
+
+
+ repackage
+
+
+
+
+
+
+
+
+
+```
+
+å†�æ·»åŠ ä¸€ä¸ª`ControllerIndexController.java`ã€�`StartApplication.java`与å�¯åŠ¨ç±»`Main.java`,这三个文件与上述示例相å�Œï¼Œè¿™é‡Œå°±ä¸�作展示了。
+
+�行 Main 方法,请求`http://localhost:8080/`,结果如下:
+
+```
+ $ curl http://localhost:8080/
+hello world
+
+```
+
+�以看到,项目�行�功。
+
+接�,�试使用 jar 包�动:
+
+```
+# 打包
+ mvn clean install -Dmaven.test.skip=true
+ # �动jar包
+ java -jar target/springboot-war-1.0.0.jar
+
+```
+
+å�¯ä»¥çœ‹åˆ°ï¼Œé¡¹ç›®å�¯åЍæˆ�功,请求请求`http://localhost:8080/`,也能显示æ£ç¡®ç»“果。
+
+### 5\. 总结
+
+springboot 引入�打包方�组�下�有如下四�:
+
+| 打包 / 引入 | parent 方� | � parent 方� |
+| --- | --- | --- |
+| jar | parent-jar 方� | � parent-jar 方� |
+| war | parent-war 方� | � parent-war 方� |
+
+### 1\. 开�时�动
+
+在开å�‘æ—¶å�¯åЍ springboot 应用,指的是直接è¿�行æº�ç �,如在开å�‘时在 ide ä¸è¿�行å�¯åŠ¨ç±»çš„ main () 方法。
+
+#### 1.1 在 ide 䏿‰§è¡Œå�¯åŠ¨ç±»çš„`main()`方法
+
+自从有了 springboot å�Žï¼Œweb 项目就ä¸�å¿…å†�放到 web 容器ä¸è¿�行了,直接è¿�行项目的`main()`方法就行了:
+
+
+
+�动日志如下:
+
+```
+ . ____ _ __ _ _
+ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
+( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
+ \\/ ___)| |_)| | | | | || (_| | ) ) ) )
+ ' |____| .__|_| |_|_| |_\__, | / / / /
+ =========|_|==============|___/=/_/_/_/
+ :: Spring Boot :: (v2.1.1.RELEASE)
+
+2020-01-07 21:11:16.365 INFO 84046 --- [ main] com.gitee.funcy.maven.jar.Main : Starting Main on l with PID 84046 (/Users/funcy/IdeaProjects/myproject/springboot-demo/springboot-maven/springboot-jar/target/classes started by funcy in /Users/funcy/IdeaProjects/myproject/springboot-demo)
+2020-01-07 21:11:16.368 INFO 84046 --- [ main] com.gitee.funcy.maven.jar.Main : No active profile set, falling back to default profiles: default
+2020-01-07 21:11:17.468 INFO 84046 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
+2020-01-07 21:11:17.497 INFO 84046 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
+2020-01-07 21:11:17.497 INFO 84046 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/9.0.13
+2020-01-07 21:11:17.513 INFO 84046 --- [ main] o.a.catalina.core.AprLifecycleListener : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [/Users/funcy/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:.]
+2020-01-07 21:11:17.605 INFO 84046 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
+2020-01-07 21:11:17.605 INFO 84046 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1206 ms
+2020-01-07 21:11:17.861 INFO 84046 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
+2020-01-07 21:11:18.096 INFO 84046 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
+2020-01-07 21:11:18.100 INFO 84046 --- [ main] com.gitee.funcy.maven.jar.Main : Started Main in 1.988 seconds (JVM running for 2.34)
+2020-01-07 21:11:32.155 INFO 84046 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
+2020-01-07 21:11:32.155 INFO 84046 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
+2020-01-07 21:11:32.223 INFO 84046 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 68 ms
+
+```
+
+访问`http://localhost:8080/`,结果如下:
+
+```
+$ curl http://localhost:8080
+hello world
+
+```
+
+以上�动方�**war 与 jar 打包方�**都支�。
+
+#### 1.2`mvn spring-boot:run`�动
+
+è¿™ç§�æ–¹å¼�也是æº�ç �å�¯åŠ¨ï¼Œåœ¨å‘½ä»¤è¡Œç•Œé�¢è¿›å…¥é¡¹ç›®å¯¹åº”çš„æº�ç �目录下,然å�Žæ‰§è¡Œ`mvn spring-boot:run`命令:
+
+```
+springboot-parent-war $ mvn spring-boot:run
+[INFO] Scanning for projects...
+[INFO]
+[INFO] ---------------< com.gitee.funcy:springboot-parent-war >----------------
+[INFO] Building springboot parent war打包方� 1.0.0
+[INFO] --------------------------------[ war ]---------------------------------
+[INFO]
+[INFO] >>> spring-boot-maven-plugin:2.1.1.RELEASE:run (default-cli) > test-compile @ springboot-parent-war >>>
+[INFO]
+[INFO] --- maven-resources-plugin:3.1.0:resources (default-resources) @ springboot-parent-war ---
+[INFO] Using 'UTF-8' encoding to copy filtered resources.
+[INFO] Copying 0 resource
+[INFO] Copying 0 resource
+[INFO]
+[INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ springboot-parent-war ---
+[INFO] Changes detected - recompiling the module!
+[INFO] Compiling 3 source files to /Users/funcy/IdeaProjects/myproject/springboot-demo/springboot-maven/springboot-parent-war/target/classes
+[INFO]
+[INFO] --- maven-resources-plugin:3.1.0:testResources (default-testResources) @ springboot-parent-war ---
+[INFO] Using 'UTF-8' encoding to copy filtered resources.
+[INFO] skip non existing resourceDirectory /Users/funcy/IdeaProjects/myproject/springboot-demo/springboot-maven/springboot-parent-war/src/test/resources
+[INFO]
+[INFO] --- maven-compiler-plugin:3.8.1:testCompile (default-testCompile) @ springboot-parent-war ---
+[INFO] No sources to compile
+[INFO]
+[INFO] <<< spring-boot-maven-plugin:2.1.1.RELEASE:run (default-cli) < test-compile @ springboot-parent-war <<<
+[INFO]
+[INFO]
+[INFO] --- spring-boot-maven-plugin:2.1.1.RELEASE:run (default-cli) @ springboot-parent-war ---
+
+ . ____ _ __ _ _
+ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
+( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
+ \\/ ___)| |_)| | | | | || (_| | ) ) ) )
+ ' |____| .__|_| |_|_| |_\__, | / / / /
+ =========|_|==============|___/=/_/_/_/
+ :: Spring Boot :: (v2.1.1.RELEASE)
+
+2020-01-07 21:40:50.577 INFO 84448 --- [ main] com.gitee.funcy.mavenparent.war.Main : Starting Main on funcydeMacBook-Pro.local with PID 84448 (/Users/funcy/IdeaProjects/myproject/springboot-demo/springboot-maven/springboot-parent-war/target/classes started by funcy in /Users/funcy/IdeaProjects/myproject/springboot-demo/springboot-maven/springboot-parent-war)
+2020-01-07 21:40:50.579 INFO 84448 --- [ main] com.gitee.funcy.mavenparent.war.Main : No active profile set, falling back to default profiles: default
+2020-01-07 21:40:51.311 INFO 84448 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
+2020-01-07 21:40:51.336 INFO 84448 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
+2020-01-07 21:40:51.337 INFO 84448 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/9.0.13
+2020-01-07 21:40:51.347 INFO 84448 --- [ main] o.a.catalina.core.AprLifecycleListener : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [/Users/funcy/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:.]
+2020-01-07 21:40:51.406 INFO 84448 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
+2020-01-07 21:40:51.406 INFO 84448 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 800 ms
+2020-01-07 21:40:51.582 INFO 84448 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
+2020-01-07 21:40:51.736 INFO 84448 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
+2020-01-07 21:40:51.739 INFO 84448 --- [ main] com.gitee.funcy.mavenparent.war.Main : Started Main in 1.39 seconds (JVM running for 3.943)
+2020-01-07 21:41:04.068 INFO 84448 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
+2020-01-07 21:41:04.069 INFO 84448 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
+2020-01-07 21:41:04.076 INFO 84448 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 7 ms
+
+```
+
+�以看到,项目�动�功,请求`http://localhost:8080`,也能获得结果:
+
+```
+ $ curl http://localhost:8080
+hello world
+
+```
+
+以上�动方�**war 与 jar 打包方�**都支�。
+
+### 2\. jar 包�动
+
+#### 2.1`java -jar`方��动
+
+对于打�`jar包`的`springboot`项目,使用`java -jar xxx.jar`命令���动:
+
+```
+:target $ java -jar springboot-jar-1.0.0.jar
+
+ . ____ _ __ _ _
+ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
+( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
+ \\/ ___)| |_)| | | | | || (_| | ) ) ) )
+ ' |____| .__|_| |_|_| |_\__, | / / / /
+ =========|_|==============|___/=/_/_/_/
+ :: Spring Boot :: (v2.1.1.RELEASE)
+
+2020-01-07 21:47:47.075 INFO 85080 --- [ main] com.gitee.funcy.maven.jar.Main : Starting Main on funcydeMacBook-Pro.local with PID 85080 (/Users/funcy/IdeaProjects/myproject/springboot-demo/springboot-maven/springboot-jar/target/springboot-jar-1.0.0.jar started by funcy in /Users/funcy/IdeaProjects/myproject/springboot-demo/springboot-maven/springboot-jar/target)
+2020-01-07 21:47:47.077 INFO 85080 --- [ main] com.gitee.funcy.maven.jar.Main : No active profile set, falling back to default profiles: default
+2020-01-07 21:47:48.152 INFO 85080 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
+2020-01-07 21:47:48.186 INFO 85080 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
+2020-01-07 21:47:48.186 INFO 85080 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/9.0.13
+2020-01-07 21:47:48.202 INFO 85080 --- [ main] o.a.catalina.core.AprLifecycleListener : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [/Users/funcy/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:.]
+2020-01-07 21:47:48.303 INFO 85080 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
+2020-01-07 21:47:48.303 INFO 85080 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1177 ms
+2020-01-07 21:47:48.502 INFO 85080 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
+2020-01-07 21:47:48.677 INFO 85080 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
+2020-01-07 21:47:48.680 INFO 85080 --- [ main] com.gitee.funcy.maven.jar.Main : Started Main in 1.977 seconds (JVM running for 2.398)
+
+```
+
+访问`http://localhost:8080`,å�Œæ ·ä¹Ÿèƒ½èŽ·å¾—ç»“æžœ.
+
+#### 2.2`java org.springframework.boot.loader.JarLauncher`方��动
+
+è¿™ç§�å�¯åŠ¨æ–¹å¼�å°±é”幻了:好好的一个 jar,è¦�先解压,然å�Žç›´æŽ¥è¿�行里é�¢çš„类,æ“�作如下:
+
+```
+target $ unzip -d ./tmp springboot-jar-1.0.0.jar
+Archive: springboot-jar-1.0.0.jar
+ creating: ./tmp/META-INF/
+ inflating: ./tmp/META-INF/MANIFEST.MF
+ creating: ./tmp/org/
+ creating: ./tmp/org/springframework/
+ creating: ./tmp/org/springframework/boot/
+··· �略其他内容
+target $ cd tmp/
+tmp $ java org.springframework.boot.loader.JarLauncher
+
+ . ____ _ __ _ _
+ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
+( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
+ \\/ ___)| |_)| | | | | || (_| | ) ) ) )
+ ' |____| .__|_| |_|_| |_\__, | / / / /
+ =========|_|==============|___/=/_/_/_/
+ :: Spring Boot :: (v2.1.1.RELEASE)
+
+2020-01-07 21:56:00.472 INFO 85431 --- [ main] com.gitee.funcy.maven.jar.Main : Starting Main on funcydeMacBook-Pro.local with PID 85431 (/Users/funcy/IdeaProjects/myproject/springboot-demo/springboot-maven/springboot-jar/target/tmp/BOOT-INF/classes started by funcy in /Users/funcy/IdeaProjects/myproject/springboot-demo/springboot-maven/springboot-jar/target/tmp)
+2020-01-07 21:56:00.475 INFO 85431 --- [ main] com.gitee.funcy.maven.jar.Main : No active profile set, falling back to default profiles: default
+2020-01-07 21:56:01.589 INFO 85431 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
+2020-01-07 21:56:01.619 INFO 85431 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
+2020-01-07 21:56:01.619 INFO 85431 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/9.0.13
+2020-01-07 21:56:01.634 INFO 85431 --- [ main] o.a.catalina.core.AprLifecycleListener : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [/Users/funcy/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:.]
+2020-01-07 21:56:01.722 INFO 85431 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
+2020-01-07 21:56:01.722 INFO 85431 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1203 ms
+2020-01-07 21:56:01.931 INFO 85431 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
+2020-01-07 21:56:02.154 INFO 85431 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
+2020-01-07 21:56:02.157 INFO 85431 --- [ main] com.gitee.funcy.maven.jar.Main : Started Main in 2.025 seconds (JVM running for 2.472)
+
+```
+
+总结下,æ¥éª¤å¦‚下:
+
+1. 进入项目`target/`目录
+2. 解压`jar包`到`tmp`目录:`unzip -d ./tmp springboot-jar-1.0.0.jar`
+3. 进入`tmp目录`:`cd tmp/`
+4. �行:`java org.springframework.boot.loader.JarLauncher`
+
+访问`http://localhost:8080`,也能得到æ£ç¡®ç»“果。
+
+> 注:这ç§�神奇的å�¯åŠ¨æ–¹å¼�在什么情况下会使用呢?我曾ç»�è§�过一些项目组,为了安全会把生产的é…�置文件放在æœ�务器上,在部署项目的时候,先解压 jar 包,然å�Žæ›¿æ�¢ç›¸åº”çš„é…�置文件,å†�è¿�行。这ç§�解压 jar 包ã€�替æ�¢é…�置文件的方å¼�å°±å�¯ä»¥ç”¨æ¤å�¯åŠ¨æ–¹å¼�了。当然,这些解压ã€�替æ�¢ã€�å�¯åŠ¨ç‰æ“�作都会写进 shell 脚本里,自动化è¿�行。
+
+### 3\. war 包�动
+
+#### 3.1`java -jar`方��动
+
+项目都打�`war包`了,还能使用`java -jar`�动?是的,`springboot`就是这么方便:
+
+```
+target $ java -jar springboot-war-1.0.0.war
+
+ . ____ _ __ _ _
+ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
+( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
+ \\/ ___)| |_)| | | | | || (_| | ) ) ) )
+ ' |____| .__|_| |_|_| |_\__, | / / / /
+ =========|_|==============|___/=/_/_/_/
+ :: Spring Boot :: (v2.1.1.RELEASE)
+
+2020-01-07 22:11:54.284 INFO 85638 --- [ main] com.gitee.funcy.maven.war.Main : Starting Main on funcydeMacBook-Pro.local with PID 85638 (/Users/funcy/IdeaProjects/myproject/springboot-demo/springboot-maven/springboot-war/target/springboot-war-1.0.0.war started by funcy in /Users/funcy/IdeaProjects/myproject/springboot-demo/springboot-maven/springboot-war/target)
+2020-01-07 22:11:54.287 INFO 85638 --- [ main] com.gitee.funcy.maven.war.Main : No active profile set, falling back to default profiles: default
+2020-01-07 22:11:55.257 INFO 85638 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
+2020-01-07 22:11:55.286 INFO 85638 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
+2020-01-07 22:11:55.287 INFO 85638 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/9.0.13
+2020-01-07 22:11:55.299 INFO 85638 --- [ main] o.a.catalina.core.AprLifecycleListener : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [/Users/funcy/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:.]
+2020-01-07 22:11:55.711 INFO 85638 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
+2020-01-07 22:11:55.711 INFO 85638 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1379 ms
+2020-01-07 22:11:55.873 INFO 85638 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
+2020-01-07 22:11:56.031 INFO 85638 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
+2020-01-07 22:11:56.034 INFO 85638 --- [ main] com.gitee.funcy.maven.war.Main : Started Main in 2.066 seconds (JVM running for 2.469)
+2020-01-07 22:12:01.189 INFO 85638 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
+2020-01-07 22:12:01.190 INFO 85638 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
+2020-01-07 22:12:01.195 INFO 85638 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 5 ms
+
+```
+
+看,项目真的跑起�了�
+
+#### 3.2`java org.springframework.boot.loader.WarLauncher`方��动
+
+`springboot`çš„`jar包`å�¯ä»¥è§£åŽ‹ï¼Œç„¶å�Žè¿�行æŸ�个类æ�¥å�¯åŠ¨ï¼Œ`war包`竟然也有这ç§�方法ï¼�`jar包`çš„å�¯åŠ¨ç±»æ˜¯`org.springframework.boot.loader.JarLauncher`,相应的`war包`å�¯åŠ¨ç±»æ˜¯`org.springframework.boot.loader.WarLauncher`,æ¥éª¤å¦‚下:
+
+1. 进入项目`target/`目录
+2. 解压`war包`到`tmp`目录:`unzip -d ./tmp springboot-war-1.0.0.war`
+3. 进入`tmp目录`:`cd tmp/`
+4. �行:`java org.springframework.boot.loader.WarLauncher`
+
+过程如下:
+
+```
+target $ unzip -d ./tmp springboot-war-1.0.0.war
+Archive: springboot-war-1.0.0.war
+ creating: ./tmp/META-INF/
+ inflating: ./tmp/META-INF/MANIFEST.MF
+ creating: ./tmp/org/
+ creating: ./tmp/org/springframework/
+ creating: ./tmp/org/springframework/boot/
+··· �略其他
+target $ cd tmp/
+tmp $ java org.springframework.boot.loader.WarLauncher
+
+ . ____ _ __ _ _
+ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
+( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
+ \\/ ___)| |_)| | | | | || (_| | ) ) ) )
+ ' |____| .__|_| |_|_| |_\__, | / / / /
+ =========|_|==============|___/=/_/_/_/
+ :: Spring Boot :: (v2.1.1.RELEASE)
+
+2020-01-07 22:17:09.637 INFO 85782 --- [ main] com.gitee.funcy.maven.war.Main : Starting Main on funcydeMacBook-Pro.local with PID 85782 (/Users/funcy/IdeaProjects/myproject/springboot-demo/springboot-maven/springboot-war/target/tmp/WEB-INF/classes started by funcy in /Users/funcy/IdeaProjects/myproject/springboot-demo/springboot-maven/springboot-war/target/tmp)
+2020-01-07 22:17:09.640 INFO 85782 --- [ main] com.gitee.funcy.maven.war.Main : No active profile set, falling back to default profiles: default
+2020-01-07 22:17:10.576 INFO 85782 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
+2020-01-07 22:17:10.603 INFO 85782 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
+2020-01-07 22:17:10.604 INFO 85782 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/9.0.13
+2020-01-07 22:17:10.616 INFO 85782 --- [ main] o.a.catalina.core.AprLifecycleListener : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [/Users/funcy/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:.]
+2020-01-07 22:17:10.725 INFO 85782 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
+2020-01-07 22:17:10.725 INFO 85782 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1046 ms
+2020-01-07 22:17:10.942 INFO 85782 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
+2020-01-07 22:17:11.137 INFO 85782 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
+2020-01-07 22:17:11.140 INFO 85782 --- [ main] com.gitee.funcy.maven.war.Main : Started Main in 1.817 seconds (JVM running for 2.183)
+2020-01-07 22:17:15.024 INFO 85782 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
+2020-01-07 22:17:15.024 INFO 85782 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
+2020-01-07 22:17:15.029 INFO 85782 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 5 ms
+
+```
+
+�以看到,项目也�动�功了�
+
+#### 3.3 ä¼ ç»Ÿæ–¹å¼�å�¯åŠ¨ï¼šä½¿ç”¨ tomcat 容器
+
+最åˆ�çš„`war包`就是放在 tomcat ç‰å®¹å™¨ä¸è¿�行的,我们也æ�¥è¯•试`war包`在 tomcat 容器ä¸è¿�行情况如何。这里说的 tomcat 容器是指在[tomcat 官网](https://www.oschina.net/action/GoToLink?url=http%3A%2F%2Ftomcat.apache.org%2F "tomcat官网")下载的容器,é�ž`springboot`内置容器。这里我下载的是`apache-tomcat-8.5.47`,过程如下:
+
+```
+... �略tomcat日志输出
+ . ____ _ __ _ _
+ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
+( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
+ \\/ ___)| |_)| | | | | || (_| | ) ) ) )
+ ' |____| .__|_| |_|_| |_\__, | / / / /
+ =========|_|==============|___/=/_/_/_/
+ :: Spring Boot :: (v2.1.1.RELEASE)
+
+2020-01-07 22:28:23.519 INFO 85904 --- [ost-startStop-1] c.g.funcy.maven.war.StartApplication : Starting StartApplication on funcydeMacBook-Pro.local with PID 85904 (/Users/funcy/Applications/Tomcat/apache-tomcat-8.5.47/webapps/springboot-war-1.0.0/WEB-INF/classes started by funcy in /Users/funcy/Applications/Tomcat/apache-tomcat-8.5.47)
+2020-01-07 22:28:23.523 INFO 85904 --- [ost-startStop-1] c.g.funcy.maven.war.StartApplication : No active profile set, falling back to default profiles: default
+2020-01-07 22:28:24.256 INFO 85904 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 676 ms
+2020-01-07 22:28:24.655 INFO 85904 --- [ost-startStop-1] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
+2020-01-07 22:28:24.920 INFO 85904 --- [ost-startStop-1] c.g.funcy.maven.war.StartApplication : Started StartApplication in 1.86 seconds (JVM running for 3.98)
+07-Jan-2020 22:28:24.974 ä¿¡æ�¯ [localhost-startStop-1] org.apache.jasper.servlet.TldScanner.scanJars 至少有一个JAR被扫æ��用于TLD但尚未包å�«TLD。 为æ¤è®°å½•器å�¯ç”¨è°ƒè¯•日志记录,以获å�–已扫æ��ä½†æœªåœ¨å…¶ä¸æ‰¾åˆ°TLD的完整JAR列表。 在扫æ��期间跳过ä¸�需è¦�çš„JARå�¯ä»¥ç¼©çŸå�¯åŠ¨æ—¶é—´å’ŒJSP编译时间。
+07-Jan-2020 22:28:24.999 信� [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployWAR Deployment of web application archive [/Users/funcy/Applications/Tomcat/apache-tomcat-8.5.47/webapps/springboot-war-1.0.0.war] has finished in [3,468] ms
+07-Jan-2020 22:28:25.000 信� [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory 把web 应用程�部署到目录 [/Users/funcy/Applications/Tomcat/apache-tomcat-8.5.47/webapps/docs]
+07-Jan-2020 22:28:25.010 信� [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/Users/funcy/Applications/Tomcat/apache-tomcat-8.5.47/webapps/docs] has finished in [10] ms
+07-Jan-2020 22:28:25.010 信� [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory 把web 应用程�部署到目录 [/Users/funcy/Applications/Tomcat/apache-tomcat-8.5.47/webapps/manager]
+07-Jan-2020 22:28:25.027 信� [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/Users/funcy/Applications/Tomcat/apache-tomcat-8.5.47/webapps/manager] has finished in [17] ms
+07-Jan-2020 22:28:25.027 信� [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory 把web 应用程�部署到目录 [/Users/funcy/Applications/Tomcat/apache-tomcat-8.5.47/webapps/examples]
+07-Jan-2020 22:28:25.181 信� [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/Users/funcy/Applications/Tomcat/apache-tomcat-8.5.47/webapps/examples] has finished in [154] ms
+07-Jan-2020 22:28:25.181 信� [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory 把web 应用程�部署到目录 [/Users/funcy/Applications/Tomcat/apache-tomcat-8.5.47/webapps/ROOT]
+07-Jan-2020 22:28:25.191 信� [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/Users/funcy/Applications/Tomcat/apache-tomcat-8.5.47/webapps/ROOT] has finished in [10] ms
+07-Jan-2020 22:28:25.191 信� [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory 把web 应用程�部署到目录 [/Users/funcy/Applications/Tomcat/apache-tomcat-8.5.47/webapps/host-manager]
+07-Jan-2020 22:28:25.202 信� [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/Users/funcy/Applications/Tomcat/apache-tomcat-8.5.47/webapps/host-manager] has finished in [11] ms
+07-Jan-2020 22:28:25.206 信� [main] org.apache.coyote.AbstractProtocol.start 开始�议处��柄["http-nio-8080"]
+07-Jan-2020 22:28:25.212 信� [main] org.apache.coyote.AbstractProtocol.start 开始�议处��柄["ajp-nio-8009"]
+07-Jan-2020 22:28:25.213 信� [main] org.apache.catalina.startup.Catalina.start Server startup in 3717 ms
+2020-01-07 22:29:30.754 INFO 85904 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
+2020-01-07 22:29:30.767 INFO 85904 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Completed initialization in 12 ms
+
+```
+
+请求`http://localhost:8080/springboot-war-1.0.0/`,结果如下:
+
+```
+$ curl 'http://localhost:8080/springboot-war-1.0.0/'
+hello world
+
+```
+
+�以看到,已�部署�功了。
+
+### 4\. 总结
+
+| | main () 方法 | mvn 命令 | java -jar | java xxx.WarLauncher | java xxx.JarLauncher | 外置容器 |
+| --- | --- | --- | --- | --- | --- | --- |
+| war | 支� | 支� | 支� | 支� | �支� | 支� |
+| jar | 支� | 支� | 支� | �支� | 支� | �支�
+
+### 1\. maven 打包�的文件
+
+进入`springboot-jar/target`目录,使用`tree`命令,目录结构如下:
+
+```
+ $ tree
+.
+├── classes
+│ └── com
+│ └── gitee
+│ └── funcy
+│ └── maven
+│ └── jar
+│ ├── Main.class
+│ └── controller
+│ └── IndexController.class
+├── generated-sources
+│ └── annotations
+├── maven-archiver
+│ └── pom.properties
+├── maven-status
+│ └── maven-compiler-plugin
+│ └── compile
+│ └── default-compile
+│ ├── createdFiles.lst
+│ └── inputFiles.lst
+├── springboot-jar-1.0.0.jar
+└── springboot-jar-1.0.0.jar.original
+
+14 directories, 7 files
+
+```
+
+注æ„�`springboot-jar-1.0.0.jar`与`springboot-jar-1.0.0.jar.original`的区别:`springboot-jar-1.0.0.jar.original`属于原始 Maven 打包 jar 文件,该文件仅包å�«åº”用本地资æº�,如编译å�Žçš„ classes 目录下的资æº�文件ç‰ï¼Œæœªå¼•入第三方ä¾�赖资æº�;而`springboot-jar-1.0.0.jar`引入了第三方ä¾�赖资æº�(主è¦�为 jar 包)。
+
+使用`unzip springboot-jar-1.0.0.jar -d tmp`解压 jar 包,内容如下:
+
+```
+ $ tree tmp/
+tmp/
+├── BOOT-INF
+│ ├── classes
+│ │ └── com
+│ │ └── gitee
+│ │ └── funcy
+│ │ └── maven
+│ │ └── jar
+│ │ ├── Main.class
+│ │ └── controller
+│ │ └── IndexController.class
+│ └── lib
+│ ├── classmate-1.4.0.jar
+│ ├── hibernate-validator-6.0.13.Final.jar
+│ ├── jackson-annotations-2.9.0.jar
+│ ├── jackson-core-2.9.7.jar
+│ ├── jackson-databind-2.9.7.jar
+│ ├── jackson-datatype-jdk8-2.9.7.jar
+│ ├── jackson-datatype-jsr310-2.9.7.jar
+│ ├── jackson-module-parameter-names-2.9.7.jar
+│ ├── javax.annotation-api-1.3.2.jar
+│ ├── jboss-logging-3.3.2.Final.jar
+│ ├── jul-to-slf4j-1.7.25.jar
+│ ├── log4j-api-2.11.1.jar
+│ ├── log4j-to-slf4j-2.11.1.jar
+│ ├── logback-classic-1.2.3.jar
+│ ├── logback-core-1.2.3.jar
+│ ├── slf4j-api-1.7.25.jar
+│ ├── snakeyaml-1.23.jar
+│ ├── spring-aop-5.1.3.RELEASE.jar
+│ ├── spring-beans-5.1.3.RELEASE.jar
+│ ├── spring-boot-2.1.1.RELEASE.jar
+│ ├── spring-boot-autoconfigure-2.1.1.RELEASE.jar
+│ ├── spring-boot-starter-2.1.1.RELEASE.jar
+│ ├── spring-boot-starter-json-2.1.1.RELEASE.jar
+│ ├── spring-boot-starter-logging-2.1.1.RELEASE.jar
+│ ├── spring-boot-starter-tomcat-2.1.1.RELEASE.jar
+│ ├── spring-boot-starter-web-2.1.1.RELEASE.jar
+│ ├── spring-context-5.1.3.RELEASE.jar
+│ ├── spring-core-5.1.3.RELEASE.jar
+│ ├── spring-expression-5.1.3.RELEASE.jar
+│ ├── spring-jcl-5.1.3.RELEASE.jar
+│ ├── spring-web-5.1.3.RELEASE.jar
+│ ├── spring-webmvc-5.1.3.RELEASE.jar
+│ ├── tomcat-embed-core-9.0.13.jar
+│ ├── tomcat-embed-el-9.0.13.jar
+│ ├── tomcat-embed-websocket-9.0.13.jar
+│ └── validation-api-2.0.1.Final.jar
+├── META-INF
+│ ├── MANIFEST.MF
+│ └── maven
+│ └── com.gitee.funcy
+│ └── springboot-jar
+│ ├── pom.properties
+│ └── pom.xml
+└── org
+ └── springframework
+ └── boot
+ └── loader
+ ├── ExecutableArchiveLauncher.class
+ ├── JarLauncher.class
+ ├── LaunchedURLClassLoader$UseFastConnectionExceptionsEnumeration.class
+ ├── LaunchedURLClassLoader.class
+ ├── Launcher.class
+ ├── MainMethodRunner.class
+ ├── PropertiesLauncher$1.class
+ ├── PropertiesLauncher$ArchiveEntryFilter.class
+ ├── PropertiesLauncher$PrefixMatchingArchiveFilter.class
+ ├── PropertiesLauncher.class
+ ├── WarLauncher.class
+ ├── archive
+ │ ├── Archive$Entry.class
+ │ ├── Archive$EntryFilter.class
+ │ ├── Archive.class
+ │ ├── ExplodedArchive$1.class
+ │ ├── ExplodedArchive$FileEntry.class
+ │ ├── ExplodedArchive$FileEntryIterator$EntryComparator.class
+ │ ├── ExplodedArchive$FileEntryIterator.class
+ │ ├── ExplodedArchive.class
+ │ ├── JarFileArchive$EntryIterator.class
+ │ ├── JarFileArchive$JarFileEntry.class
+ │ └── JarFileArchive.class
+ ├── data
+ │ ├── RandomAccessData.class
+ │ ├── RandomAccessDataFile$1.class
+ │ ├── RandomAccessDataFile$DataInputStream.class
+ │ ├── RandomAccessDataFile$FileAccess.class
+ │ └── RandomAccessDataFile.class
+ ├── jar
+ │ ├── AsciiBytes.class
+ │ ├── Bytes.class
+ │ ├── CentralDirectoryEndRecord.class
+ │ ├── CentralDirectoryFileHeader.class
+ │ ├── CentralDirectoryParser.class
+ │ ├── CentralDirectoryVisitor.class
+ │ ├── FileHeader.class
+ │ ├── Handler.class
+ │ ├── JarEntry.class
+ │ ├── JarEntryFilter.class
+ │ ├── JarFile$1.class
+ │ ├── JarFile$2.class
+ │ ├── JarFile$JarFileType.class
+ │ ├── JarFile.class
+ │ ├── JarFileEntries$1.class
+ │ ├── JarFileEntries$EntryIterator.class
+ │ ├── JarFileEntries.class
+ │ ├── JarURLConnection$1.class
+ │ ├── JarURLConnection$JarEntryName.class
+ │ ├── JarURLConnection.class
+ │ ├── StringSequence.class
+ │ └── ZipInflaterInputStream.class
+ └── util
+ └── SystemPropertyUtils.class
+
+21 directories, 91 files
+
+```
+
+å�¯ä»¥çœ‹åˆ°ï¼Œæ–‡ä»¶ä¸ä¸»è¦�åˆ†ä¸ºå¦‚ä¸‹å‡ ä¸ªç›®å½•ï¼š
+
+* `BOOT-INF/classes`ç›®å½•å˜æ”¾åº”用编译å�Žçš„ class 文件;
+* `BOOT-INF/lib`ç›®å½•å˜æ”¾åº”用ä¾�èµ–çš„ jar 包;
+* `META-INF/`ç›®å½•å˜æ”¾åº”用ä¾�èµ–çš„ jar 包;
+* `org/`ç›®å½•å˜æ”¾ spring boot 相关的 class 文件。
+
+### 2.`java -jar`�动 springboot jar 包
+
+java 官方规定,`java -jar`命令引导的具体å�¯åŠ¨ç±»å¿…é¡»é…�置在`MANIFEST.MF`文件ä¸ï¼Œè€Œæ ¹æ�®`jar文件规范`,`MANIFEST.MF`æ–‡ä»¶å¿…é¡»å˜æ”¾åœ¨`/META-INF/`ç›®å½•ä¸‹ã€‚å› æ¤ï¼Œå�¯åŠ¨ç±»é…�置在 jar 包的`/META-INF/MANIFEST.MF`文件ä¸ï¼ŒæŸ¥çœ‹è¯¥æ–‡ä»¶ï¼Œå†…容如下:
+
+```
+$ cat MANIFEST.MF
+Manifest-Version: 1.0
+Archiver-Version: Plexus Archiver
+Built-By: fangchengyan
+Start-Class: com.gitee.funcy.maven.jar.Main
+Spring-Boot-Classes: BOOT-INF/classes/
+Spring-Boot-Lib: BOOT-INF/lib/
+Spring-Boot-Version: 2.1.1.RELEASE
+Created-By: Apache Maven 3.6.0
+Build-Jdk: 1.8.0_222
+Main-Class: org.springframework.boot.loader.JarLauncher
+
+```
+
+å�‘现`Main-Class`属性指å�‘çš„`Class`为`org.springframework.boot.loader.JarLauncher`ï¼Œè€Œè¯¥ç±»å˜æ”¾åœ¨ jar 包的`org/springframework/boot/loader/`目录下,并且项目的引导类定义在`Start-Class`属性性ä¸ï¼Œè¯¥å±žæ€§å¹¶é�ž java å¹³å�°æ ‡å‡†`META-INF/MANIFEST.MF`属性。
+
+> 注:
+>
+> 1. `org.springframework.boot.loader.JarLauncher`是�执行 jar 的�动器,`org.springframework.boot.loader.WarLauncher`是�执行 war 的�动器。
+>
+>
+> 2. `org.springframework.boot.loader.JarLauncher`所在的 jar 文件的 Maven GAV 信�为`org.springframework.boot:spring-boot-loader:${springboot-version}`,通常情况下,这个�赖没有必�引入 springboot 项目的 pom.xml 文件。
+
+查看`JarLauncher`æº�ç �,如下:
+
+```
+public class JarLauncher extends ExecutableArchiveLauncher {
+
+ static final String BOOT_INF_CLASSES = "BOOT-INF/classes/";
+
+ static final String BOOT_INF_LIB = "BOOT-INF/lib/";
+
+ public JarLauncher() {
+ }
+
+ protected JarLauncher(Archive archive) {
+ super(archive);
+ }
+
+ @Override
+ protected boolean isNestedArchive(Archive.Entry entry) {
+ if (entry.isDirectory()) {
+ return entry.getName().equals(BOOT_INF_CLASSES);
+ }
+ return entry.getName().startsWith(BOOT_INF_LIB);
+ }
+
+ public static void main(String[] args) throws Exception {
+ new JarLauncher().launch(args);
+ }
+
+}
+
+```
+
+å�¯ä»¥å�‘现,`BOOT-INF/classes/`与`BOOT-INF/lib/`分别使用常é‡�`BOOT_INF_CLASSES`å’Œ`BOOT_INF_LIB`表示,并且用于`isNestedArchive(Archive.Entry)`方法判æ–,从该方法的实现分æž�,方法å�‚æ•°`Archive.Entry`看似为 jar 文件ä¸çš„资æº�,比如`application.properties`。
+
+`Archive.Entry`有两ç§�实现,其ä¸ä¸€ç§�为`org.springframework.boot.loader.archive.JarFileArchive.JarFileEntry`,基于`java.util.jar.JarEntry`,表示`FAT JAR`嵌入资æº�,å�¦ä¸€ç§�为`org.springframework.boot.loader.archive.ExplodedArchive.FileEntry`,基于文件系统实现。这也说明了`JarLauncher`支æŒ�`JAR`å’Œ`文件系统`两ç§�å�¯åŠ¨æ–¹å¼�。
+
+> 文件系统�动方�如下:
+>
+> 1. 解压 jar 包到`temp`目录:`unzip springboot-jar-1.0.0.jar -d tmp`
+> 2. 进入`temp`目录,è¿�行命令:`java org.springframework.boot.loader.JarLauncher`å�¯ä»¥çœ‹åˆ°ï¼Œé¡¹ç›®å�Œæ ·èƒ½æ£å¸¸å�¯åŠ¨ã€‚
+
+在`JarLauncher`作为引导类时,当执行`java -jar`命令时,`/META-INF`资�的`Main-Class`属性将调用其`main(String[])`方法,实际上调用的是`JarLauncher#launch(args)`方法,而该方法继承于基类`org.springframework.boot.loader.Launcher`,它们之间的继承关系如下:
+
+* `org.springframework.boot.loader.Launcher`
+ * `org.springframework.boot.loader.ExecutableArchiveLauncher`
+ * `org.springframework.boot.loader.JarLauncher`
+ * `org.springframework.boot.loader.WarLauncher`
+
+简��说,springboot jar �动过程如下:
+
+1. `java -jar xxx.jar`�行的是`JarLauncher`
+2. `JarLauncher#main(String[])`方法会调用`Launcher#launch(String[])`方法,创建 ClassLoader () �调用项目的`main`方法
+ * 项目主类的获�实现�于`ExecutableArchiveLauncher#getMainClass()`,主�是从`/META-INF/MANIFEST.MF`获�`Start-Class`属性
+ * 项目主类的 main () 方法调用�于`MainMethodRunner#run()`,使用�射方�进行调用
+
+### 3.`java -jar`�动 springboot war 包
+
+从上�的分�,我们得到了�动 jar 包的`org.springframework.boot.loader.JarLauncher`以��动 war 包的`org.springframework.boot.loader.WarLauncher`,这里我们�分�下`WarLauncher`上如何工作的。
+
+`WarLauncher`代ç �如下:
+
+```
+public class WarLauncher extends ExecutableArchiveLauncher {
+
+ private static final String WEB_INF = "WEB-INF/";
+
+ private static final String WEB_INF_CLASSES = WEB_INF + "classes/";
+
+ private static final String WEB_INF_LIB = WEB_INF + "lib/";
+
+ private static final String WEB_INF_LIB_PROVIDED = WEB_INF + "lib-provided/";
+
+ public WarLauncher() {
+ }
+
+ protected WarLauncher(Archive archive) {
+ super(archive);
+ }
+
+ @Override
+ public boolean isNestedArchive(Archive.Entry entry) {
+ if (entry.isDirectory()) {
+ return entry.getName().equals(WEB_INF_CLASSES);
+ }
+ else {
+ return entry.getName().startsWith(WEB_INF_LIB)
+ || entry.getName().startsWith(WEB_INF_LIB_PROVIDED);
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ new WarLauncher().launch(args);
+ }
+
+}
+
+```
+
+å�¯ä»¥çœ‹åˆ°ï¼Œ`WEB-INF/classes/`ã€�`WEB-INF/lib/`ã€�`WEB-INF/lib-provided/`å�‡ä¸º`WarLauncher`çš„`Class Path`,其ä¸`WEB-INF/classes/`ã€�`WEB-INF/lib/`æ˜¯ä¼ ç»Ÿçš„ Servlet 应用的 ClassPath 路径,而`WEB-INF/lib-provided/`属性 springboot`WarLauncher`定制实现。那么`WEB-INF/lib-provided/`究竟是干嘛的呢?看到`provided`,我们å�¯ä»¥å¤§èƒ†çŒœæƒ³`WEB-INF/lib-provided/`å˜æ”¾çš„æ˜¯`pom.xml`文件ä¸ï¼Œ`scope`为`provided`çš„ jar。
+
+为了验�以上猜想,修改的 pom.xml 文件如下:
+
+```
+
+
+ 4.0.0
+
+ com.gitee.funcy
+ springboot-war
+ 1.0.0
+
+ war
+ springboot�parent war打包方�
+
+
+ UTF-8
+ UTF-8
+ 1.8
+ 2.1.1.RELEASE
+ 3.8.1
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+ ${spring-boot.version}
+ pom
+ import
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-test
+ provided
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+ ${java.version}
+ ${java.version}
+ ${project.build.sourceEncoding}
+
+
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+
+ 3.2.2
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ ${spring-boot.version}
+
+
+
+ repackage
+
+
+
+
+
+
+
+
+
+```
+
+è¿™é‡Œæˆ‘ä»¬æ·»åŠ äº† springboot 的测试 jar`org.springframework.boot:spring-boot-test`,并将其`scope`设置为`provided`. è¿�行 maven 打包命令`mvn clean install -Dmaven.test.skip=true`,å�¯ä»¥çœ‹åˆ°é¡¹ç›®èƒ½æ£å¸¸æ‰“包。
+
+打包完æˆ�å�Žï¼Œè¿›å…¥`target`目录,è¿�行`java -jar springboot-war-1.0.0.war`,项目能æ£å¸¸å�¯åŠ¨ã€‚
+
+接下�,我们�看看`springboot-war-1.0.0.war`有些啥。首先使用`unzip springboot-war-1.0.0.war -d tmp`命令解压,�使用`tree -h`命令查看文件结构,结果如下
+
+```
+ $ tree -h
+.
+├── [ 128] META-INF
+│ ├── [ 311] MANIFEST.MF
+│ └── [ 96] maven
+│ └── [ 96] com.gitee.funcy
+│ └── [ 128] springboot-war
+│ ├── [ 95] pom.properties
+│ └── [3.3K] pom.xml
+├── [ 160] WEB-INF
+│ ├── [ 96] classes
+│ │ └── [ 96] com
+│ │ └── [ 96] gitee
+│ │ └── [ 96] funcy
+│ │ └── [ 96] maven
+│ │ └── [ 160] war
+│ │ ├── [ 688] Main.class
+│ │ ├── [ 891] StartApplication.class
+│ │ └── [ 96] controller
+│ │ └── [ 646] IndexController.class
+│ ├── [1.2K] lib
+│ │ ├── [ 65K] classmate-1.4.0.jar
+│ │ ├── [1.1M] hibernate-validator-6.0.13.Final.jar
+│ │ ├── [ 65K] jackson-annotations-2.9.0.jar
+│ │ ├── [316K] jackson-core-2.9.7.jar
+│ │ ├── [1.3M] jackson-databind-2.9.7.jar
+│ │ ├── [ 33K] jackson-datatype-jdk8-2.9.7.jar
+│ │ ├── [ 98K] jackson-datatype-jsr310-2.9.7.jar
+│ │ ├── [8.4K] jackson-module-parameter-names-2.9.7.jar
+│ │ ├── [ 26K] javax.annotation-api-1.3.2.jar
+│ │ ├── [ 65K] jboss-logging-3.3.2.Final.jar
+│ │ ├── [4.5K] jul-to-slf4j-1.7.25.jar
+│ │ ├── [258K] log4j-api-2.11.1.jar
+│ │ ├── [ 17K] log4j-to-slf4j-2.11.1.jar
+│ │ ├── [284K] logback-classic-1.2.3.jar
+│ │ ├── [461K] logback-core-1.2.3.jar
+│ │ ├── [ 40K] slf4j-api-1.7.25.jar
+│ │ ├── [294K] snakeyaml-1.23.jar
+│ │ ├── [360K] spring-aop-5.1.3.RELEASE.jar
+│ │ ├── [656K] spring-beans-5.1.3.RELEASE.jar
+│ │ ├── [935K] spring-boot-2.1.1.RELEASE.jar
+│ │ ├── [1.2M] spring-boot-autoconfigure-2.1.1.RELEASE.jar
+│ │ ├── [ 413] spring-boot-starter-2.1.1.RELEASE.jar
+│ │ ├── [ 421] spring-boot-starter-json-2.1.1.RELEASE.jar
+│ │ ├── [ 423] spring-boot-starter-logging-2.1.1.RELEASE.jar
+│ │ ├── [ 422] spring-boot-starter-tomcat-2.1.1.RELEASE.jar
+│ │ ├── [ 421] spring-boot-starter-web-2.1.1.RELEASE.jar
+│ │ ├── [1.0M] spring-context-5.1.3.RELEASE.jar
+│ │ ├── [1.2M] spring-core-5.1.3.RELEASE.jar
+│ │ ├── [274K] spring-expression-5.1.3.RELEASE.jar
+│ │ ├── [ 23K] spring-jcl-5.1.3.RELEASE.jar
+│ │ ├── [1.3M] spring-web-5.1.3.RELEASE.jar
+│ │ ├── [782K] spring-webmvc-5.1.3.RELEASE.jar
+│ │ ├── [3.1M] tomcat-embed-core-9.0.13.jar
+│ │ ├── [244K] tomcat-embed-el-9.0.13.jar
+│ │ ├── [257K] tomcat-embed-websocket-9.0.13.jar
+│ │ └── [ 91K] validation-api-2.0.1.Final.jar
+│ └── [ 96] lib-provided
+│ └── [194K] spring-boot-test-2.1.1.RELEASE.jar
+└── [ 96] org
+ └── [ 96] springframework
+ └── [ 96] boot
+ └── [ 544] loader
+ ├── [3.5K] ExecutableArchiveLauncher.class
+ ├── [1.5K] JarLauncher.class
+ ├── [1.5K] LaunchedURLClassLoader$UseFastConnectionExceptionsEnumeration.class
+ ├── [5.6K] LaunchedURLClassLoader.class
+ ├── [4.6K] Launcher.class
+ ├── [1.5K] MainMethodRunner.class
+ ├── [ 266] PropertiesLauncher$1.class
+ ├── [1.4K] PropertiesLauncher$ArchiveEntryFilter.class
+ ├── [1.9K] PropertiesLauncher$PrefixMatchingArchiveFilter.class
+ ├── [ 19K] PropertiesLauncher.class
+ ├── [1.7K] WarLauncher.class
+ ├── [ 416] archive
+ │ ├── [ 302] Archive$Entry.class
+ │ ├── [ 437] Archive$EntryFilter.class
+ │ ├── [ 945] Archive.class
+ │ ├── [ 273] ExplodedArchive$1.class
+ │ ├── [1.1K] ExplodedArchive$FileEntry.class
+ │ ├── [1.5K] ExplodedArchive$FileEntryIterator$EntryComparator.class
+ │ ├── [3.7K] ExplodedArchive$FileEntryIterator.class
+ │ ├── [5.1K] ExplodedArchive.class
+ │ ├── [1.7K] JarFileArchive$EntryIterator.class
+ │ ├── [1.1K] JarFileArchive$JarFileEntry.class
+ │ └── [7.2K] JarFileArchive.class
+ ├── [ 224] data
+ │ ├── [ 485] RandomAccessData.class
+ │ ├── [ 282] RandomAccessDataFile$1.class
+ │ ├── [2.6K] RandomAccessDataFile$DataInputStream.class
+ │ ├── [3.2K] RandomAccessDataFile$FileAccess.class
+ │ └── [3.9K] RandomAccessDataFile.class
+ ├── [ 768] jar
+ │ ├── [4.9K] AsciiBytes.class
+ │ ├── [ 616] Bytes.class
+ │ ├── [3.0K] CentralDirectoryEndRecord.class
+ │ ├── [5.1K] CentralDirectoryFileHeader.class
+ │ ├── [4.5K] CentralDirectoryParser.class
+ │ ├── [ 540] CentralDirectoryVisitor.class
+ │ ├── [ 345] FileHeader.class
+ │ ├── [ 12K] Handler.class
+ │ ├── [3.5K] JarEntry.class
+ │ ├── [ 299] JarEntryFilter.class
+ │ ├── [2.0K] JarFile$1.class
+ │ ├── [1.2K] JarFile$2.class
+ │ ├── [1.3K] JarFile$JarFileType.class
+ │ ├── [ 15K] JarFile.class
+ │ ├── [1.6K] JarFileEntries$1.class
+ │ ├── [2.0K] JarFileEntries$EntryIterator.class
+ │ ├── [ 14K] JarFileEntries.class
+ │ ├── [ 702] JarURLConnection$1.class
+ │ ├── [4.2K] JarURLConnection$JarEntryName.class
+ │ ├── [9.6K] JarURLConnection.class
+ │ ├── [3.5K] StringSequence.class
+ │ └── [1.8K] ZipInflaterInputStream.class
+ └── [ 96] util
+ └── [5.1K] SystemPropertyUtils.class
+
+22 directories, 93 files
+
+```
+
+相比于`FAT JAR`的解压目录,`War`å¢žåŠ äº†`WEB-INF/lib-provided`,并且该目录仅有一个 jar 文件,å�³`spring-boot-test-2.1.1.RELEASE.jar`ï¼Œè¿™æ£æ˜¯æˆ‘们在 pom.xml 文件ä¸è®¾ç½®çš„`scope`为`provided`çš„ jar 包。
+
+ç”±æ¤å�¯ä»¥å¾—出结论:**`WEB-INF/lib-provided`å˜æ”¾çš„æ˜¯`scope`为`provided`çš„ jar 包**。
+
+我们现�看下`META-INF/MANIFEST.MF`的内容:
+
+```
+$ cat META-INF/MANIFEST.MF
+Manifest-Version: 1.0
+Built-By: fangchengyan
+Start-Class: com.gitee.funcy.maven.war.Main
+Spring-Boot-Classes: WEB-INF/classes/
+Spring-Boot-Lib: WEB-INF/lib/
+Spring-Boot-Version: 2.1.1.RELEASE
+Created-By: Apache Maven 3.6.0
+Build-Jdk: 1.8.0_222
+Main-Class: org.springframework.boot.loader.WarLauncher
+
+```
+
+å�¯ä»¥çœ‹åˆ°ï¼Œè¯¥æ–‡ä»¶ä¸Ž jar 包ä¸çš„`META-INF/MANIFEST.MF`很相似,在文件ä¸å�Œæ ·å®šä¹‰äº†`Main-Class`与`Start-Class`,这也说明了该 war å�¯ä»¥ä½¿ç”¨`java -jar xxx.jar`å’Œ`java org.springframework.boot.loader.WarLauncher`å�¯åŠ¨ï¼Œè¿™ä¹Ÿä¸Žæˆ‘ä»¬çš„éªŒè¯�结果一致。
+
+### 4\. tomcat ç‰å¤–部容器å�¯åЍ war 包
+
+在 springboo åˆšå¼€å§‹æŽ¨å¹¿çš„æ—¶å€™ï¼Œæˆ‘ä»¬è¿˜æ˜¯ä¹ æƒ¯äºŽå°†é¡¹ç›®æ‰“æˆ� war 包,然å�Žéƒ¨ç½²åˆ° tomcat ç‰ web 容器ä¸è¿�行。那 springboot çš„ war 包是如何å�šåˆ°æ—¢èƒ½ç”¨ java 命令å�¯åŠ¨ï¼Œå�ˆèƒ½æ”¾åœ¨ tomcat 容器ä¸å�¯åŠ¨å‘¢ï¼Ÿè¿™å°±æ˜¯ä¹‹å‰�æ��到的`WEB-INF/lib-provided`目录的功能了。
+
+ä¼ ç»Ÿçš„`servlet`应用的`class path`路径仅关注`WEB-INF/classes/`å’Œ`WEB-INF/lib/`,`WEB-INF/lib-provided/`目录下的 jar 包将被`servlet`容器忽略,如`servlet api`,该 api ç”±`servlet`容器æ��供。我们在打包时,å�¯ä»¥æŠŠ`servlet`相关 jar 包的`scope`设置æˆ�`provided`ï¼Œè¿™æ ·å°±å®Œç¾Žå®žçŽ°äº†`servlet`容器å�¯åŠ¨ä¸Ž`java`命令å�¯åŠ¨çš„å…¼å®¹ï¼š
+
+* 当部署到`servlet`容噍䏿—¶ï¼Œ`WEB-INF/lib-provided/`目录下的 jar 包就被容器忽略了(由于`servlet`容器本身就æ��供了`servlet`的相关 jar 包,如果ä¸�忽略,就会出现 jar 包é‡�å¤�引入问题);
+* 当使用`java`å‘½ä»¤æ‰§è¡Œæ—¶ï¼Œæ¤æ—¶æ— `servlet`容器æ��ä¾›`servlet`的相关 jar 包,而`WarLauncher`在è¿�行过程ä¸ä¼šåŠ è½½`WEB-INF/lib-provided/`目录下的 jar 包。
\ No newline at end of file
diff --git "a/docs/Spring\345\205\250\345\256\266\346\241\266/SpringBoot/SpringBoot\347\224\237\344\272\247\347\216\257\345\242\203\345\267\245\345\205\267Actuator.md" "b/docs/Spring\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/SpringBoot/SpringBoot\347\232\204Starter\346\234\272\345\210\266.md" "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringBoot/SpringBoot\347\232\204Starter\346\234\272\345\210\266.md"
new file mode 100644
index 0000000..0318193
--- /dev/null
+++ "b/docs/Spring\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/SpringBoot/SpringBoot\347\232\204\345\211\215\344\270\226\344\273\212\347\224\237.md" "b/docs/Spring\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/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/Spring\345\205\250\345\256\266\346\241\266/SpringBoot/SpringBoot\347\232\204\345\237\272\346\234\254\344\275\277\347\224\250.md" "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringBoot/SpringBoot\347\232\204\345\237\272\346\234\254\344\275\277\347\224\250.md"
new file mode 100644
index 0000000..247e419
--- /dev/null
+++ "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringBoot/SpringBoot\347\232\204\345\237\272\346\234\254\344\275\277\347\224\250.md"
@@ -0,0 +1,108 @@
+# ¿ìËÙ¹¹½¨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\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/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\345\205\250\345\256\266\346\241\266/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/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\345\205\250\345\256\266\346\241\266/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 96%
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\345\205\250\345\256\266\346\241\266/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"
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/Spring\345\205\250\345\256\266\346\241\266/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"
@@ -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/Spring\345\205\250\345\256\266\346\241\266/SpringBoot\346\272\220\347\240\201\350\247\243\346\236\220/@SpringBootApplication\346\263\250\350\247\243.md" "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringBoot\346\272\220\347\240\201\350\247\243\346\236\220/@SpringBootApplication\346\263\250\350\247\243.md"
new file mode 100644
index 0000000..dd72d1f
--- /dev/null
+++ "b/docs/Spring\345\205\250\345\256\266\346\241\266/SpringBoot\346\272\220\347\240\201\350\247\243\346\236\220/@SpringBootApplication\346\263\250\350\247\243.md"
@@ -0,0 +1,382 @@
+springboot ÔÚÆô¶¯ÀàÉÏ»á±ê×¢Ò»¸ö×¢½â£º`@SpringBootApplication`£¬±¾È˽«´ÓÔ´Âë½âÎö·ÖÎöÕâ ¸ö×¢½âµÄ×÷Óá£
+
+`@SpringBootApplication` ´úÂëÈçÏ£º
+
+```
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Inherited
+@SpringBootConfiguration
+@EnableAutoConfiguration
+@ComponentScan(excludeFilters = {
+ @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
+ @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
+public @interface SpringBootApplication {
+
+ /**
+ * ×Ô¶¯×°ÅäÒªÅųýµÄÀ࣬¹¦ÄÜÀ´×ÔÓÚ @EnableAutoConfiguration
+ */
+ @AliasFor(annotation = EnableAutoConfiguration.class)
+ Class>[] exclude() default {};
+
+ /**
+ * ×Ô¶¯×°ÅäÒªÅųýµÄÀàÃû£¬¹¦ÄÜÀ´×ÔÓÚ @EnableAutoConfiguration
+ */
+ @AliasFor(annotation = EnableAutoConfiguration.class)
+ String[] excludeName() default {};
+
+ /**
+ * ÅäÖÃɨÃèµÄ°ü£¬¹¦ÄÜÀ´×ÔÓÚ @ComponentScan
+ */
+ @AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
+ String[] scanBasePackages() default {};
+
+ /**
+ * ÅäÖÃɨÃèµÄclass£¬¸ÃclassËùÔڵİü¶¼»á±»É¨Ã裬¹¦ÄÜÀ´×ÔÓÚ @ComponentScan
+ */
+ @AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
+ Class>[] scanBasePackageClasses() default {};
+
+ /**
+ * ÊÇ·ñÆôÓà @Bean ·½·¨´úÀí£¬¹¦ÄÜÀ´×ÔÓÚ @Configuration
+ */
+ @AliasFor(annotation = Configuration.class)
+ boolean proxyBeanMethods() default true;
+
+}
+
+```
+
+1. `@SpringBootApplication` ÊÇÒ»¸ö×éºÏ×¢½â£¬°üº¬ÁË `@SpringBootConfiguration`¡¢`@EnableAutoConfiguration`¡¢`@ComponentScan` Èý¸ö×¢½âµÄ¹¦ÄÜ£»
+2. `@SpringBootApplication` ÖÐÒ²ÌṩÁËһЩÅäÖÃÊôÐÔ£¬¶øÕâЩÊôÐÔÀ´×ÔÓÚÒÔÉÏÈý¸ö×¢½â¡£
+
+½ÓÏÂÀ´ÎÒÃÇÀ´¿´¿´ÕâÈý¸ö×¢½âµÄ×÷Ó÷ֱðÊÇʲô¡£
+
+### 1. `@SpringBootConfiguration`
+
+½øÈë `@SpringBootConfiguration`£¬´úÂëÈçÏ£º
+
+```
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Configuration
+public @interface SpringBootConfiguration {
+
+ @AliasFor(annotation = Configuration.class)
+ boolean proxyBeanMethods() default true;
+
+}
+
+```
+
+Õâ¸ö×¢½â±È½Ï¼òµ¥£¬ÉÏÃæ±ê¼ÇÁË `@Configuration`£¬È»ºóÊÇÒ»¸öÊôÐÔ `proxyBeanMethods()`£¬ËüÀ´×ÔÓÚ `@Configuration`¡£Òò´Ë£¬`@SpringBootConfiguration` ²¢Ã»ÓÐ×öʲô£¬½ö½öÖ»Êǽ« `@Configuration` ʹÓÃÁË `@Configuration` µÄ¹¦ÄÜ¡£
+
+¹ØÓÚ `@Configuration`£¬ËüÀ´×ÔÓÚ spring£¬Äܱ» spring ʶ±ðΪ `Component`£¬ÇÒ `proxyBeanMethods != false` ʱ£¬»á±» spring ±ê¼ÇΪ `Full` ÅäÖÃÀ࣬ÔÚºóÐø¶ÔÆäÖÐµÄ `@Bean` ·½·¨´¦Àíʱ£¬»á½øÐÐ cglib ´úÀí£¬¹ØÓÚÕâ·½ÃæµÄÄÚÈÝ£¬¿É²Î¿¼ [ConfigurationClassPostProcessor£¨¶þ£©£º´¦Àí @Bean ×¢½â](https://my.oschina.net/funcy/blog/4492878).
+
+### 2. `@EnableAutoConfiguration`
+
+`@EnableAutoConfiguration` Ö÷Òª ÓÃÀ´¿ªÆô×Ô¶¯×°Å书ÄÜ£¬´úÂëÈçÏ£º
+
+```
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Inherited
+// ×Ô¶¯×°ÅäµÄ°ü
+@AutoConfigurationPackage
+// ÒýÈëµÄ×Ô¶¯×°ÅäÀà
+@Import(AutoConfigurationImportSelector.class)
+public @interface EnableAutoConfiguration {
+
+ String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
+
+ /**
+ * ¿É×ÔÐж¨ÒåÅųý×Ô¶¯×°ÅäµÄÀà
+ */
+ Class>[] exclude() default {};
+
+ /**
+ * ¿É×ÔÐж¨ÒåÅųý×Ô¶¯×°ÅäµÄÀàÃû
+ */
+ String[] excludeName() default {};
+
+}
+
+```
+
+´Ó´úÂëÖпÉÒÔ¿´µ½£¬
+
+1. ¸Ã×¢½â×éºÏÁË `@AutoConfigurationPackage` ×¢½âµÄ¹¦ÄÜ£¬¸Ã×¢½âÓÃÀ´Ö¸¶¨×Ô¶¯×°ÅäµÄ°ü£»
+2. ¸Ã×¢½âͨ¹ý `@Import` ×¢½âÒýÈëÁËÒ»¸öÀà `AutoConfigurationImportSelector`£¬Õâ¸öÀàÊÇ×Ô¶¯×°ÅäµÄ¹Ø¼ü£»
+3. ¸Ã×¢½âÌṩÁËÁ½¸öÅäÖã¬ÓÃÀ´ÅųýÖ¸¶¨µÄ×Ô¶¯×°ÅäÀ࣬¿ÉÒÔ¸ù¾ÝÀàÀ´Åųý (`Class` ¶ÔÏó)£¬Ò²¿ÉÒÔ¸ù¾ÝÀàÃû (`°üÃû.ÀàÃû`) Åųý¡£
+
+½ÓÏÂÀ´ÎÒÃÇÀ´¹Ø×¢ `@AutoConfigurationPackage` ¼°ÒýÈëµÄ `AutoConfigurationImportSelector`¡£
+
+#### 2.1 `@AutoConfigurationPackage`
+
+`@AutoConfigurationPackage` Ö¸¶¨ÁË×Ô¶¯×°ÅäµÄ°ü£¬´úÂëÈçÏ£º
+
+```
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Inherited
+@Import(AutoConfigurationPackages.Registrar.class)
+public @interface AutoConfigurationPackage {
+
+}
+
+```
+
+Õâ¸ö×¢½âµÄÄÚÈݷdz£¼òµ¥£¬½öʹÓà `@Import` ×¢½âÒýÈëÁË `AutoConfigurationPackages.Registrar`£¬ÎÒÃÇÀ´¿´ÏÂËüµÄÄÚÈÝ£º
+
+```
+public abstract class AutoConfigurationPackages {
+
+ private static final String BEAN = AutoConfigurationPackages.class.getName();
+
+ static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
+
+ /**
+ * ¸ù¾Ý ImportBeanDefinitionRegistrar µÄ´¦Àí£¬spring½«µ÷Óà registerBeanDefinitions() ×¢²áÄÚÈÝ
+ */
+ @Override
+ public void registerBeanDefinitions(AnnotationMetadata metadata,
+ BeanDefinitionRegistry registry) {
+ register(registry, new PackageImport(metadata).getPackageName());
+ }
+
+ @Override
+ public Set