<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Posts on Janson's Blog</title><link>http://www.jansonblog.com/post/</link><description>Recent content in Posts on Janson's Blog</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Sat, 26 Oct 2024 00:00:00 +0000</lastBuildDate><atom:link href="http://www.jansonblog.com/post/index.xml" rel="self" type="application/rss+xml"/><item><title>2024年10月26日</title><link>http://www.jansonblog.com/p/2024-10-26/</link><pubDate>Sat, 26 Oct 2024 00:00:00 +0000</pubDate><guid>http://www.jansonblog.com/p/2024-10-26/</guid><description>&lt;img src="http://www.jansonblog.com/p/2024-10-26/nagoya.jpg" alt="Featured image of post 2024年10月26日" /&gt;&lt;h2 id="内省"&gt;内省
&lt;/h2&gt;&lt;p&gt;  这是我来日本的第五年。毕业以后“顺利”进入一家公司工作，今天为止刚好满一年零一个月。&lt;br&gt;
  他，亦父亦友。为了见他，坐着电车穿过一片片农田，坐着电车。来回五个小时的车程。
  同为在日本制造业工作的社畜，我的经历他深有感触。日企的体制，通过没必要的压迫告诉你：&lt;strong&gt;他们也是这样过来的，他们吃过的苦你一定要吃&lt;/strong&gt;
  日企也好，父亲也罢。它们都在告诉你，想要达到他们的高度，你一定要跟他们一样饱受苦难，&lt;br&gt;
  但，正如他所说，你可以选择一条直线的人生，也可以在生生落落的人生中成长、历练。&lt;br&gt;
  公司里有人工作了五年、十年、二十年，依然接受现在的生活。但，这不是我想要的生活，这是我今晚给自己的答案。&lt;br&gt;
  思考自己的价值，思考自己想做什么，然后行动——转职，去体验不一样的生活，去新的地方生存、成长。&lt;br&gt;
  保持年轻，不畏风险。在大风大浪中去闯，而不是患得患失。&lt;br&gt;
  去闯，去学习，去思考。&lt;/p&gt;</description></item><item><title>2024年10月22日</title><link>http://www.jansonblog.com/p/2024-10/</link><pubDate>Tue, 22 Oct 2024 00:00:00 +0000</pubDate><guid>http://www.jansonblog.com/p/2024-10/</guid><description>&lt;img src="http://www.jansonblog.com/p/2024-10/10.JPG" alt="Featured image of post 2024年10月22日" /&gt;&lt;h2 id="高铁"&gt;高铁
&lt;/h2&gt;&lt;p&gt; 2024年10月21日一个沿海的小县城通了高铁。&lt;/p&gt;
&lt;p&gt; 北京，北京，北京。 北京是旧时代人心中的圣地，是新时代人痛并快乐的舞台。等到高铁通到了北京那天，可能我会下定决心回到中国，那时候我想跟她一起去。&lt;/p&gt;
&lt;p&gt; 这是她的梦，不可以是我的遗憾。&lt;/p&gt;
&lt;h2 id="工作相关的牢骚"&gt;工作相关的牢骚
&lt;/h2&gt;&lt;p&gt; 同事都很好，但是对于这个体制，我不喜欢。它每天都在警告你，用它几十年不变的权威告诉你该怎么做，该学什么。&lt;/p&gt;
&lt;p&gt; 对于工作，虽然还有很多不懂的东西。但是在这个体制内，你能一眼看到尽头。有些人喜欢人生能看到尽头带来的踏实感，但我讨厌。好比你一生下来，就有人告诉你你会死，但是人还是会勇敢的成长，生存，冒险。&lt;/p&gt;
&lt;p&gt; 我现在对于人生的感悟是：体验。我们被生下来就是为了体验喜怒哀乐，感悟世间百态。&lt;/p&gt;
&lt;p&gt; &lt;strong&gt;要永远奔跑，永远保持一颗好奇的童心去探索，去冒险。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.jansonblog.com/p/2024-10/14.JPG"
width="5568"
height="3712"
srcset="http://www.jansonblog.com/p/2024-10/14_hu_eb40d1b7c777e7e2.JPG 480w, http://www.jansonblog.com/p/2024-10/14_hu_e80248c8c9d49747.JPG 1024w"
loading="lazy"
alt="白浜"
class="gallery-image"
data-flex-grow="150"
data-flex-basis="360px"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.jansonblog.com/p/2024-10/8.JPG"
width="5568"
height="3712"
srcset="http://www.jansonblog.com/p/2024-10/8_hu_ad5c99e80538a8a2.JPG 480w, http://www.jansonblog.com/p/2024-10/8_hu_7e8156019a234e1c.JPG 1024w"
loading="lazy"
alt="琵琶湖"
class="gallery-image"
data-flex-grow="150"
data-flex-basis="360px"
&gt;&lt;img src="http://www.jansonblog.com/p/2024-10/12.jpg"
width="5250"
height="3500"
srcset="http://www.jansonblog.com/p/2024-10/12_hu_e7bf7dbf93c3dddc.jpg 480w, http://www.jansonblog.com/p/2024-10/12_hu_4241d2976ddbbded.jpg 1024w"
loading="lazy"
alt="京都"
class="gallery-image"
data-flex-grow="150"
data-flex-basis="360px"
&gt;&lt;/p&gt;</description></item><item><title>宇治</title><link>http://www.jansonblog.com/p/uji/</link><pubDate>Sun, 26 May 2024 00:00:00 +0000</pubDate><guid>http://www.jansonblog.com/p/uji/</guid><description>&lt;img src="http://www.jansonblog.com/p/uji/DSC_0480.jpg" alt="Featured image of post 宇治" /&gt;&lt;h2 id="平等院"&gt;平等院
&lt;/h2&gt;&lt;p&gt;&lt;img src="http://www.jansonblog.com/p/uji/DSC_0480.jpg"
width="5568"
height="3712"
srcset="http://www.jansonblog.com/p/uji/DSC_0480_hu_98171393c9a54d03.jpg 480w, http://www.jansonblog.com/p/uji/DSC_0480_hu_1fec33dd097ed70b.jpg 1024w"
loading="lazy"
alt="1"
class="gallery-image"
data-flex-grow="150"
data-flex-basis="360px"
&gt;
&lt;img src="http://www.jansonblog.com/p/uji/DSC_0484.jpg"
width="5568"
height="3712"
srcset="http://www.jansonblog.com/p/uji/DSC_0484_hu_d1b37585ce62dc0d.jpg 480w, http://www.jansonblog.com/p/uji/DSC_0484_hu_d14dcf2a16df0705.jpg 1024w"
loading="lazy"
alt="2"
class="gallery-image"
data-flex-grow="150"
data-flex-basis="360px"
&gt; &lt;img src="http://www.jansonblog.com/p/uji/DSC_0489.jpg"
width="5568"
height="3712"
srcset="http://www.jansonblog.com/p/uji/DSC_0489_hu_c597596a476cead4.jpg 480w, http://www.jansonblog.com/p/uji/DSC_0489_hu_5bd5fed4dff6baca.jpg 1024w"
loading="lazy"
alt="3"
class="gallery-image"
data-flex-grow="150"
data-flex-basis="360px"
&gt;&lt;/p&gt;
&lt;h2 id="平等院周边1"&gt;平等院周边1
&lt;/h2&gt;&lt;p&gt;&lt;img src="http://www.jansonblog.com/p/uji/DSC_0497.jpg"
width="3712"
height="5568"
srcset="http://www.jansonblog.com/p/uji/DSC_0497_hu_5119b08d59f095d7.jpg 480w, http://www.jansonblog.com/p/uji/DSC_0497_hu_95b16234269e5ab0.jpg 1024w"
loading="lazy"
alt="4"
class="gallery-image"
data-flex-grow="66"
data-flex-basis="160px"
&gt; &lt;img src="http://www.jansonblog.com/p/uji/DSC_0501.jpg"
width="3712"
height="5568"
srcset="http://www.jansonblog.com/p/uji/DSC_0501_hu_1c20d7a7ca787a2d.jpg 480w, http://www.jansonblog.com/p/uji/DSC_0501_hu_29eac6714940bb7b.jpg 1024w"
loading="lazy"
alt="5"
class="gallery-image"
data-flex-grow="66"
data-flex-basis="160px"
&gt;
&lt;img src="http://www.jansonblog.com/p/uji/DSC_0503.jpg"
width="3712"
height="5568"
srcset="http://www.jansonblog.com/p/uji/DSC_0503_hu_8e8429ae8381d0fc.jpg 480w, http://www.jansonblog.com/p/uji/DSC_0503_hu_51900c72bd0d648f.jpg 1024w"
loading="lazy"
alt="6"
class="gallery-image"
data-flex-grow="66"
data-flex-basis="160px"
&gt; &lt;img src="http://www.jansonblog.com/p/uji/DSC_0506.jpg"
width="3712"
height="5568"
srcset="http://www.jansonblog.com/p/uji/DSC_0506_hu_89e8e4f949a651e2.jpg 480w, http://www.jansonblog.com/p/uji/DSC_0506_hu_f1c505b1bccf482f.jpg 1024w"
loading="lazy"
alt="7"
class="gallery-image"
data-flex-grow="66"
data-flex-basis="160px"
&gt;&lt;/p&gt;
&lt;h2 id="平等院周边2"&gt;平等院周边2
&lt;/h2&gt;&lt;p&gt;&lt;img src="http://www.jansonblog.com/p/uji/DSC_0513.jpg"
width="3712"
height="5568"
srcset="http://www.jansonblog.com/p/uji/DSC_0513_hu_63152221fe698ec9.jpg 480w, http://www.jansonblog.com/p/uji/DSC_0513_hu_720abeb4838a4d62.jpg 1024w"
loading="lazy"
alt="8"
class="gallery-image"
data-flex-grow="66"
data-flex-basis="160px"
&gt;
&lt;img src="http://www.jansonblog.com/p/uji/DSC_0517.jpg"
width="3712"
height="5568"
srcset="http://www.jansonblog.com/p/uji/DSC_0517_hu_461650a022868b03.jpg 480w, http://www.jansonblog.com/p/uji/DSC_0517_hu_2ea7b41f00df5669.jpg 1024w"
loading="lazy"
alt="9"
class="gallery-image"
data-flex-grow="66"
data-flex-basis="160px"
&gt;&lt;/p&gt;
&lt;h2 id="宇治川1"&gt;宇治川1
&lt;/h2&gt;&lt;p&gt;&lt;img src="http://www.jansonblog.com/p/uji/DSC_0530.jpg"
width="3712"
height="5568"
srcset="http://www.jansonblog.com/p/uji/DSC_0530_hu_20541de2e227b5cf.jpg 480w, http://www.jansonblog.com/p/uji/DSC_0530_hu_80e932e8259dffa1.jpg 1024w"
loading="lazy"
alt="10"
class="gallery-image"
data-flex-grow="66"
data-flex-basis="160px"
&gt; &lt;img src="http://www.jansonblog.com/p/uji/DSC_0525.jpg"
width="3712"
height="5568"
srcset="http://www.jansonblog.com/p/uji/DSC_0525_hu_a49c75de286c9b12.jpg 480w, http://www.jansonblog.com/p/uji/DSC_0525_hu_c0b10b1e969db3f5.jpg 1024w"
loading="lazy"
alt="11"
class="gallery-image"
data-flex-grow="66"
data-flex-basis="160px"
&gt;
&lt;img src="http://www.jansonblog.com/p/uji/DSC_0523.jpg"
width="3712"
height="5568"
srcset="http://www.jansonblog.com/p/uji/DSC_0523_hu_9517f3a38ed4bb95.jpg 480w, http://www.jansonblog.com/p/uji/DSC_0523_hu_cfe1e8b558467702.jpg 1024w"
loading="lazy"
alt="12"
class="gallery-image"
data-flex-grow="66"
data-flex-basis="160px"
&gt; &lt;img src="http://www.jansonblog.com/p/uji/DSC_0535.jpg"
width="3712"
height="5568"
srcset="http://www.jansonblog.com/p/uji/DSC_0535_hu_d1647167dd80cbff.jpg 480w, http://www.jansonblog.com/p/uji/DSC_0535_hu_64cbdc7d9462b7b9.jpg 1024w"
loading="lazy"
alt="13"
class="gallery-image"
data-flex-grow="66"
data-flex-basis="160px"
&gt;&lt;/p&gt;
&lt;h2 id="宇治川2"&gt;宇治川2
&lt;/h2&gt;&lt;p&gt;&lt;img src="http://www.jansonblog.com/p/uji/DSC_0526.jpg"
width="5568"
height="3712"
srcset="http://www.jansonblog.com/p/uji/DSC_0526_hu_4e6c18e67a62cb5c.jpg 480w, http://www.jansonblog.com/p/uji/DSC_0526_hu_d9ad79265f375733.jpg 1024w"
loading="lazy"
alt="14"
class="gallery-image"
data-flex-grow="150"
data-flex-basis="360px"
&gt; &lt;img src="http://www.jansonblog.com/p/uji/DSC_0536.jpg"
width="5568"
height="3712"
srcset="http://www.jansonblog.com/p/uji/DSC_0536_hu_6ffff5027abd7b2f.jpg 480w, http://www.jansonblog.com/p/uji/DSC_0536_hu_de60199034b51420.jpg 1024w"
loading="lazy"
alt="15"
class="gallery-image"
data-flex-grow="150"
data-flex-basis="360px"
&gt;&lt;/p&gt;</description></item><item><title>神户</title><link>http://www.jansonblog.com/p/kobe/</link><pubDate>Sat, 18 May 2024 00:00:00 +0000</pubDate><guid>http://www.jansonblog.com/p/kobe/</guid><description>&lt;img src="http://www.jansonblog.com/p/kobe/DSC_0469.jpg" alt="Featured image of post 神户" /&gt;&lt;h2 id="六甲山"&gt;六甲山
&lt;/h2&gt;&lt;p&gt;&lt;img src="http://www.jansonblog.com/p/kobe/DSC_0400.jpg"
width="5568"
height="3712"
srcset="http://www.jansonblog.com/p/kobe/DSC_0400_hu_8f479e0d2805a23d.jpg 480w, http://www.jansonblog.com/p/kobe/DSC_0400_hu_5e538340db0488d4.jpg 1024w"
loading="lazy"
alt="4"
class="gallery-image"
data-flex-grow="150"
data-flex-basis="360px"
&gt; &lt;img src="http://www.jansonblog.com/p/kobe/DSC_0404.jpg"
width="5568"
height="3712"
srcset="http://www.jansonblog.com/p/kobe/DSC_0404_hu_956b02c41a498e92.jpg 480w, http://www.jansonblog.com/p/kobe/DSC_0404_hu_1d322442493874c1.jpg 1024w"
loading="lazy"
alt="5"
class="gallery-image"
data-flex-grow="150"
data-flex-basis="360px"
&gt;
&lt;img src="http://www.jansonblog.com/p/kobe/DSC_0410.jpg"
width="3712"
height="5568"
srcset="http://www.jansonblog.com/p/kobe/DSC_0410_hu_715bfb00c8fafa9e.jpg 480w, http://www.jansonblog.com/p/kobe/DSC_0410_hu_4428bdc1f4067188.jpg 1024w"
loading="lazy"
alt="6"
class="gallery-image"
data-flex-grow="66"
data-flex-basis="160px"
&gt;&lt;/p&gt;
&lt;h2 id="海边"&gt;海边
&lt;/h2&gt;&lt;p&gt;&lt;img src="http://www.jansonblog.com/p/kobe/DSC_0427.jpg"
width="5568"
height="3712"
srcset="http://www.jansonblog.com/p/kobe/DSC_0427_hu_196d43a728245787.jpg 480w, http://www.jansonblog.com/p/kobe/DSC_0427_hu_5182834dfdf5f8bb.jpg 1024w"
loading="lazy"
alt="7"
class="gallery-image"
data-flex-grow="150"
data-flex-basis="360px"
&gt; &lt;img src="http://www.jansonblog.com/p/kobe/DSC_0436.jpg"
width="5568"
height="3712"
srcset="http://www.jansonblog.com/p/kobe/DSC_0436_hu_f9dfb95f2bd18889.jpg 480w, http://www.jansonblog.com/p/kobe/DSC_0436_hu_4bc9a929bd30ca79.jpg 1024w"
loading="lazy"
alt="8"
class="gallery-image"
data-flex-grow="150"
data-flex-basis="360px"
&gt;&lt;/p&gt;
&lt;h2 id="神户塔"&gt;神户塔
&lt;/h2&gt;&lt;p&gt;&lt;img src="http://www.jansonblog.com/p/kobe/DSC_0477.jpg"
width="3712"
height="5568"
srcset="http://www.jansonblog.com/p/kobe/DSC_0477_hu_af35c8d9d92aa033.jpg 480w, http://www.jansonblog.com/p/kobe/DSC_0477_hu_f88d17dc93b996d5.jpg 1024w"
loading="lazy"
alt="10"
class="gallery-image"
data-flex-grow="66"
data-flex-basis="160px"
&gt;&lt;/p&gt;
&lt;h2 id="kobe"&gt;KOBE
&lt;/h2&gt;&lt;p&gt;&lt;img src="http://www.jansonblog.com/p/kobe/DSC_0469.jpg"
width="5568"
height="3712"
srcset="http://www.jansonblog.com/p/kobe/DSC_0469_hu_b7a6fd424af2c4cb.jpg 480w, http://www.jansonblog.com/p/kobe/DSC_0469_hu_95e2094665addf47.jpg 1024w"
loading="lazy"
alt="11"
class="gallery-image"
data-flex-grow="150"
data-flex-basis="360px"
&gt;&lt;/p&gt;
&lt;h2 id="中日友好建筑抽象"&gt;中日友好建筑（抽象
&lt;/h2&gt;&lt;p&gt;&lt;img src="http://www.jansonblog.com/p/kobe/DSC_0472.jpg"
width="3712"
height="5568"
srcset="http://www.jansonblog.com/p/kobe/DSC_0472_hu_76355c424dabd309.jpg 480w, http://www.jansonblog.com/p/kobe/DSC_0472_hu_1359dfbbb838bca2.jpg 1024w"
loading="lazy"
alt="12"
class="gallery-image"
data-flex-grow="66"
data-flex-basis="160px"
&gt;&lt;/p&gt;
&lt;h2 id="黄昏"&gt;黄昏
&lt;/h2&gt;&lt;p&gt;&lt;img src="http://www.jansonblog.com/p/kobe/DSC_0474.jpg"
width="5568"
height="3712"
srcset="http://www.jansonblog.com/p/kobe/DSC_0474_hu_1633cdce37c52e6d.jpg 480w, http://www.jansonblog.com/p/kobe/DSC_0474_hu_1373ddb85d04a862.jpg 1024w"
loading="lazy"
alt="13"
class="gallery-image"
data-flex-grow="150"
data-flex-basis="360px"
&gt;&lt;/p&gt;</description></item><item><title>2024年黄金周</title><link>http://www.jansonblog.com/p/goldenweek/</link><pubDate>Tue, 30 Apr 2024 00:00:00 +0000</pubDate><guid>http://www.jansonblog.com/p/goldenweek/</guid><description>&lt;img src="http://www.jansonblog.com/p/goldenweek/DSC_0028.jpg" alt="Featured image of post 2024年黄金周" /&gt;&lt;h2 id="430-56"&gt;4.30-5.6
&lt;/h2&gt;&lt;p&gt;&lt;img src="http://www.jansonblog.com/p/goldenweek/DSC_0028.jpg"
width="5568"
height="3712"
srcset="http://www.jansonblog.com/p/goldenweek/DSC_0028_hu_640e81c3270151db.jpg 480w, http://www.jansonblog.com/p/goldenweek/DSC_0028_hu_269d276b82b7de9c.jpg 1024w"
loading="lazy"
alt="关西机场"
class="gallery-image"
data-flex-grow="150"
data-flex-basis="360px"
&gt;
&lt;img src="http://www.jansonblog.com/p/goldenweek/DSC_0051.jpg"
width="3712"
height="5568"
srcset="http://www.jansonblog.com/p/goldenweek/DSC_0051_hu_c7aeab32f35ffad1.jpg 480w, http://www.jansonblog.com/p/goldenweek/DSC_0051_hu_77589edcb41d531.jpg 1024w"
loading="lazy"
alt="大疆总部"
class="gallery-image"
data-flex-grow="66"
data-flex-basis="160px"
&gt; &lt;img src="http://www.jansonblog.com/p/goldenweek/DSC_0068.jpg"
width="3712"
height="5568"
srcset="http://www.jansonblog.com/p/goldenweek/DSC_0068_hu_4c4afc1070e4e8a5.jpg 480w, http://www.jansonblog.com/p/goldenweek/DSC_0068_hu_a213e19582d7f7b4.jpg 1024w"
loading="lazy"
alt="母子"
class="gallery-image"
data-flex-grow="66"
data-flex-basis="160px"
&gt;&lt;/p&gt;
&lt;h2 id="公园"&gt;公园
&lt;/h2&gt;&lt;p&gt;&lt;img src="http://www.jansonblog.com/p/goldenweek/DSC_0071.jpg"
width="3712"
height="5568"
srcset="http://www.jansonblog.com/p/goldenweek/DSC_0071_hu_dc810ffe88bda591.jpg 480w, http://www.jansonblog.com/p/goldenweek/DSC_0071_hu_70034669a6eec3a6.jpg 1024w"
loading="lazy"
alt="1"
class="gallery-image"
data-flex-grow="66"
data-flex-basis="160px"
&gt; &lt;img src="http://www.jansonblog.com/p/goldenweek/DSC_0074.jpg"
width="3712"
height="5568"
srcset="http://www.jansonblog.com/p/goldenweek/DSC_0074_hu_fd4647baae277e8e.jpg 480w, http://www.jansonblog.com/p/goldenweek/DSC_0074_hu_5afac9dc2a9b6b87.jpg 1024w"
loading="lazy"
alt="2"
class="gallery-image"
data-flex-grow="66"
data-flex-basis="160px"
&gt;
&lt;img src="http://www.jansonblog.com/p/goldenweek/DSC_0081.jpg"
width="3712"
height="5568"
srcset="http://www.jansonblog.com/p/goldenweek/DSC_0081_hu_6a1c835fdc83f03e.jpg 480w, http://www.jansonblog.com/p/goldenweek/DSC_0081_hu_6cbe76679aa6ea6d.jpg 1024w"
loading="lazy"
alt="3"
class="gallery-image"
data-flex-grow="66"
data-flex-basis="160px"
&gt; &lt;img src="http://www.jansonblog.com/p/goldenweek/DSC_0097.jpg"
width="3712"
height="5568"
srcset="http://www.jansonblog.com/p/goldenweek/DSC_0097_hu_dbe298abe879a285.jpg 480w, http://www.jansonblog.com/p/goldenweek/DSC_0097_hu_d9811298050c598b.jpg 1024w"
loading="lazy"
alt="4"
class="gallery-image"
data-flex-grow="66"
data-flex-basis="160px"
&gt;&lt;/p&gt;
&lt;h2 id="毛毛"&gt;毛毛
&lt;/h2&gt;&lt;p&gt;&lt;img src="http://www.jansonblog.com/p/goldenweek/DSC_0121.jpg"
width="3712"
height="5568"
srcset="http://www.jansonblog.com/p/goldenweek/DSC_0121_hu_c2e2285293c2a750.jpg 480w, http://www.jansonblog.com/p/goldenweek/DSC_0121_hu_9320a66d0947d690.jpg 1024w"
loading="lazy"
alt="5"
class="gallery-image"
data-flex-grow="66"
data-flex-basis="160px"
&gt;
&lt;img src="http://www.jansonblog.com/p/goldenweek/DSC_0149.jpg"
width="5568"
height="3712"
srcset="http://www.jansonblog.com/p/goldenweek/DSC_0149_hu_644cbae32b8443d7.jpg 480w, http://www.jansonblog.com/p/goldenweek/DSC_0149_hu_9fbf9f00dbd1c56e.jpg 1024w"
loading="lazy"
alt="毛毛1"
class="gallery-image"
data-flex-grow="150"
data-flex-basis="360px"
&gt; &lt;img src="http://www.jansonblog.com/p/goldenweek/DSC_0150.jpg"
width="5568"
height="3712"
srcset="http://www.jansonblog.com/p/goldenweek/DSC_0150_hu_6960df7e300892a8.jpg 480w, http://www.jansonblog.com/p/goldenweek/DSC_0150_hu_a8dc7a01d2f0bb20.jpg 1024w"
loading="lazy"
alt="毛毛2"
class="gallery-image"
data-flex-grow="150"
data-flex-basis="360px"
&gt;&lt;/p&gt;
&lt;h2 id="国潮"&gt;国潮
&lt;/h2&gt;&lt;p&gt;&lt;img src="http://www.jansonblog.com/p/goldenweek/DSC_0181.jpg"
width="3712"
height="5568"
srcset="http://www.jansonblog.com/p/goldenweek/DSC_0181_hu_e24198aac8c68177.jpg 480w, http://www.jansonblog.com/p/goldenweek/DSC_0181_hu_6b19c0bfad431abc.jpg 1024w"
loading="lazy"
alt="6"
class="gallery-image"
data-flex-grow="66"
data-flex-basis="160px"
&gt; &lt;img src="http://www.jansonblog.com/p/goldenweek/DSC_0192.jpg"
width="3712"
height="5568"
srcset="http://www.jansonblog.com/p/goldenweek/DSC_0192_hu_b08bac09a58d1d37.jpg 480w, http://www.jansonblog.com/p/goldenweek/DSC_0192_hu_9d14358c81b22391.jpg 1024w"
loading="lazy"
alt="7"
class="gallery-image"
data-flex-grow="66"
data-flex-basis="160px"
&gt;&lt;/p&gt;
&lt;h2 id="大疆"&gt;大疆
&lt;/h2&gt;&lt;p&gt;&lt;img src="http://www.jansonblog.com/p/goldenweek/DSC_0209.jpg"
width="5568"
height="3712"
srcset="http://www.jansonblog.com/p/goldenweek/DSC_0209_hu_1530b25d4ddde3be.jpg 480w, http://www.jansonblog.com/p/goldenweek/DSC_0209_hu_475b2dc691d0b66b.jpg 1024w"
loading="lazy"
alt="8"
class="gallery-image"
data-flex-grow="150"
data-flex-basis="360px"
&gt;
&lt;img src="http://www.jansonblog.com/p/goldenweek/DSC_0219.jpg"
width="3712"
height="5568"
srcset="http://www.jansonblog.com/p/goldenweek/DSC_0219_hu_32a45f9a508ce45b.jpg 480w, http://www.jansonblog.com/p/goldenweek/DSC_0219_hu_42c47d60b5081cc7.jpg 1024w"
loading="lazy"
alt="9"
class="gallery-image"
data-flex-grow="66"
data-flex-basis="160px"
&gt;&lt;/p&gt;
&lt;h2 id="世界之窗抽象"&gt;世界之窗（抽象
&lt;/h2&gt;&lt;p&gt;&lt;img src="http://www.jansonblog.com/p/goldenweek/DSC_0221.jpg"
width="3712"
height="5568"
srcset="http://www.jansonblog.com/p/goldenweek/DSC_0221_hu_9570152247c12b8b.jpg 480w, http://www.jansonblog.com/p/goldenweek/DSC_0221_hu_e78d200839d8f1ed.jpg 1024w"
loading="lazy"
alt="10"
class="gallery-image"
data-flex-grow="66"
data-flex-basis="160px"
&gt;&lt;/p&gt;
&lt;h2 id="香港"&gt;香港
&lt;/h2&gt;&lt;p&gt;&lt;img src="http://www.jansonblog.com/p/goldenweek/DSC_0224.jpg"
width="3712"
height="5568"
srcset="http://www.jansonblog.com/p/goldenweek/DSC_0224_hu_82485b529573fb6c.jpg 480w, http://www.jansonblog.com/p/goldenweek/DSC_0224_hu_d9e34e461800fa1e.jpg 1024w"
loading="lazy"
alt="11"
class="gallery-image"
data-flex-grow="66"
data-flex-basis="160px"
&gt; &lt;img src="http://www.jansonblog.com/p/goldenweek/DSC_0246.jpg"
width="5568"
height="3712"
srcset="http://www.jansonblog.com/p/goldenweek/DSC_0246_hu_6c978e1aaa34fb09.jpg 480w, http://www.jansonblog.com/p/goldenweek/DSC_0246_hu_96fb1433bc56f15b.jpg 1024w"
loading="lazy"
alt="雨天拍的高糊维港"
class="gallery-image"
data-flex-grow="150"
data-flex-basis="360px"
&gt;
&lt;img src="http://www.jansonblog.com/p/goldenweek/DSC_0251.jpg"
width="5568"
height="3712"
srcset="http://www.jansonblog.com/p/goldenweek/DSC_0251_hu_f48fcac930d439da.jpg 480w, http://www.jansonblog.com/p/goldenweek/DSC_0251_hu_61ea1b2278f637a1.jpg 1024w"
loading="lazy"
alt="13"
class="gallery-image"
data-flex-grow="150"
data-flex-basis="360px"
&gt;&lt;/p&gt;</description></item><item><title>2023年10月18日</title><link>http://www.jansonblog.com/p/2023-10/</link><pubDate>Wed, 18 Oct 2023 00:00:00 +0000</pubDate><guid>http://www.jansonblog.com/p/2023-10/</guid><description>&lt;img src="http://www.jansonblog.com/p/2023-10/1.jpg" alt="Featured image of post 2023年10月18日" /&gt;&lt;h2 id="学业"&gt;学业
&lt;/h2&gt;&lt;p&gt;  半年的折磨，每日每夜跑实验采集数据。自己选的课题，哭着也要做完。&lt;/p&gt;
&lt;p&gt;  论文老师和博士看完很满意。赶在学会投稿截止日期前，投上了(投完发现有个图注释配反了)。
&lt;img src="http://www.jansonblog.com/p/2023-10/1.jpg"
width="4032"
height="3024"
srcset="http://www.jansonblog.com/p/2023-10/1_hu_d12f6d1094cd0b19.jpg 480w, http://www.jansonblog.com/p/2023-10/1_hu_fd41b1e5d8c1b840.jpg 1024w"
loading="lazy"
alt="IEICE"
class="gallery-image"
data-flex-grow="133"
data-flex-basis="320px"
&gt;&lt;/p&gt;
&lt;h2 id="工作"&gt;工作
&lt;/h2&gt;&lt;p&gt;  3月和4月两个月，拿到了3家offer。一家国内银行，一家在日本的中国人公司，一家京都的半导体公司。&lt;/p&gt;
&lt;p&gt;最后选择了那家半导体公司。&lt;/p&gt;
&lt;h2 id="反省"&gt;反省
&lt;/h2&gt;&lt;p&gt; 自制力比以前好了，但是没半年前阳光了。&lt;/p&gt;</description></item><item><title>格雷码（Gray code）</title><link>http://www.jansonblog.com/p/graycode/</link><pubDate>Thu, 23 Feb 2023 00:00:00 +0000</pubDate><guid>http://www.jansonblog.com/p/graycode/</guid><description>&lt;img src="http://www.jansonblog.com/p/graycode/1.jpg" alt="Featured image of post 格雷码（Gray code）" /&gt;&lt;h2 id="简介--原理"&gt;简介 &amp;amp; 原理
&lt;/h2&gt;&lt;p&gt; 格雷码（Gray code）是由贝尔实验室的Frank Gray在1940年提出，用于在PCM（脉冲编码调变）方法传送讯号时防止出错。&lt;br&gt;
 格雷码是一个数列集合，相邻两数间&lt;strong&gt;只有一个位元&lt;/strong&gt;改变，为无权数码，且格雷码的顺序不是唯一的。&lt;br&gt;
 原理：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt; 传统的二进位系统，例如数字3的表示法为011，要切换为邻近的数字4，也就是100时，装置中的三个位元都得要转换，因此于未完全转换的过程时装置会经历短暂的，010,001,101,110,111等其中数种状态，也就是代表着2、1、5、6、7，因此此种数字编码方法于邻近数字转换时有比较大的误差可能范围。
格雷码的发明即是用来将误差之可能性缩减至最小，编码的方式定义为每个邻近数字都只相差一个位元，因此也称为最小差异码，可以使装置做数字步进时只更动最少的位元数以提高稳定性。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="代码实现"&gt;代码实现
&lt;/h2&gt;&lt;p&gt; 用&lt;code&gt;G&lt;/code&gt;代表格雷码：&lt;br&gt;
 例如3位数的格雷码序列为：&lt;code&gt;000&lt;/code&gt;,&lt;code&gt;001&lt;/code&gt;,&lt;code&gt;011&lt;/code&gt;,&lt;code&gt;010&lt;/code&gt;,&lt;code&gt;110&lt;/code&gt;,&lt;code&gt;111&lt;/code&gt;,&lt;code&gt;101&lt;/code&gt;,&lt;code&gt;100&lt;/code&gt;。&lt;code&gt;111&lt;/code&gt;可以用&lt;code&gt;G(4) = 6&lt;/code&gt;来表示。&lt;/p&gt;
&lt;p&gt; &lt;em&gt;&lt;strong&gt;公式：&lt;/strong&gt;&lt;/em&gt;&lt;code&gt;G(n) = n ^ (n &amp;gt;&amp;gt; 1)&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;int g (int n) {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; return n ^ (n &amp;gt;&amp;gt; 1);
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="例题"&gt;例题
&lt;/h3&gt;&lt;p&gt;&lt;a class="link" href="https://leetcode.com/problems/circular-permutation-in-binary-representation/description/" title="1238. Circular Permutation in Binary Representation"
target="_blank" rel="noopener"
&gt;[medium]1238. Circular Permutation in Binary Representation&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;如有遗漏或错误，欢迎补充纠正&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>GCD算法（最大公因数算法）</title><link>http://www.jansonblog.com/p/gcd/</link><pubDate>Wed, 01 Feb 2023 00:00:00 +0000</pubDate><guid>http://www.jansonblog.com/p/gcd/</guid><description>&lt;img src="http://www.jansonblog.com/p/gcd/1.jpg" alt="Featured image of post GCD算法（最大公因数算法）" /&gt;&lt;h2 id="欧几里得算法辗转相除法"&gt;欧几里得算法（辗转相除法）
&lt;/h2&gt;&lt;h3 id="递归实现"&gt;递归实现
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;gcd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;gcd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="迭代实现"&gt;迭代实现
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;gcd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="例题"&gt;例题
&lt;/h3&gt;&lt;p&gt;&lt;a class="link" href="https://leetcode.com/problems/greatest-common-divisor-of-strings/description/" title="1071. Greatest Common Divisor of Strings"
target="_blank" rel="noopener"
&gt;[easy]1071. Greatest Common Divisor of Strings&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;如有遗漏或错误，欢迎补充纠正&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>Spring学习之路（六）</title><link>http://www.jansonblog.com/p/spring6/</link><pubDate>Fri, 16 Dec 2022 00:00:00 +0000</pubDate><guid>http://www.jansonblog.com/p/spring6/</guid><description>&lt;img src="http://www.jansonblog.com/p/spring6/1.jpg" alt="Featured image of post Spring学习之路（六）" /&gt;&lt;p&gt; &lt;/p&gt;
&lt;h2 id="创建自己的配置属性"&gt;创建自己的配置属性
&lt;/h2&gt;&lt;p&gt; 这章讲的有点啰嗦，主要就讲了一个注解：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;@ConfigurationProperties&lt;/code&gt;：&lt;br&gt;
Spring Boot提供的支持配置属性的注入注释。放到Spring bean上后，它会为该bean中那些能够根据Spring环境注入值的属性赋值。&lt;br&gt;
 &lt;code&gt;@ConfigurationProperties&lt;/code&gt;实际上通常会放到⼀种特定类型的bean中，这种bean的⽬的就是持有配置数据。这样的话，特定的配置细节就能从控制器和其他应⽤程序类中抽离出来，多个bean也能更容易地共享⼀些通⽤的配置。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;注：Pageable是Spring Data根据页号和每页数量选取结果的子集的一种方法。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="spring-profile搭建特定环境的配置"&gt;Spring profile搭建特定环境的配置
&lt;/h2&gt;&lt;p&gt; profile是⼀种条件化的配置，在运⾏时，根据哪些profile处于激活状态，可以使⽤或忽略不同的bean、配置类和配置属性&lt;/p&gt;
&lt;h3 id="定义特定profile"&gt;定义特定profile
&lt;/h3&gt;&lt;p&gt; 定义特定profile相关的属性的⼀种⽅式就是创建另外⼀个YAML或属性⽂件，其中只包含⽤于⽣产环境的属性。&lt;br&gt;
 ⽂件的名称要遵守如下的约定：&lt;code&gt;application-{profile名}.yml&lt;/code&gt;或 &lt;code&gt;application-{profile名}.properties&lt;/code&gt;。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;方法1&lt;br&gt;
新建名为application-prod.yml的文件，包含以下属性：&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spring&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;datasource&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;jdbc:mysql://localhost/tacocloud&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;tacouser&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;tacopassword&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;level&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tacos&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;WARN&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ol start="2"&gt;
&lt;li&gt;方法2&lt;br&gt;
将特定的profile和非特定profile的属性都放到application.yml中，二者之间使用三个中线【&amp;mdash;】进行分隔，并且使用spring.profiles属性来命名profile。application.yml如下所示：&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;level&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tacos&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;DEBUG&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spring&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;profiles&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;prod&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;datasource&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;jdbc:mysql://localhost/tacocloud&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;tacouser&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;tacopassword&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;level&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tacos&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;WARN&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt; 该文件通过中划线(&amp;mdash;)分成两部分。第二部分制定了spring.profiles值，代表&lt;strong&gt;后面的属性适用于prod profile&lt;/strong&gt;。&lt;br&gt;
 第一部分没有指定&lt;strong&gt;spring.profiles&lt;/strong&gt;，所以是&lt;strong&gt;所有profiles通用&lt;/strong&gt;的，如果当前激活的profiles没有设置这些属性，它们会作为默认值。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;解释：&lt;br&gt;
 在上述例子，不管程序运行的时候哪个profile处于激活状态，根据&lt;strong&gt;默认profile&lt;/strong&gt;，包的日志级别都会设为DEBUG。&lt;br&gt;
 但是如果名为prod的profile激活，&lt;code&gt;logging.level.tacos&lt;/code&gt;属性会被重写为&lt;strong&gt;WARN&lt;/strong&gt;。同理，如果prod profile处于激活状态，数据源相关属性会被设置为使用外部的MySQL数据库。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="激活profile三个方法"&gt;激活profile（三个方法）
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;需要将profile名称的列表赋值给&lt;code&gt;spring.profiles.active&lt;/code&gt;属性。例如，在&lt;code&gt;application.yml&lt;/code&gt;文件中：&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spring&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;profiles&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;active&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;prod&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt; 如果这么激活，这个profile就会成为&lt;strong&gt;默认profile&lt;/strong&gt;。体验不到使用profile将生产环境和开发环境属性分开的好处。
2. &lt;code&gt;% export SPRING_PROFILES_ACTIVE=prod&lt;/code&gt;
3. 以JAR文件形式运行，可以以&lt;strong&gt;命令行参数&lt;/strong&gt;的形式设置要激活的profile：&lt;br&gt;
&lt;code&gt;% java -jar taco-cloud.jar --spring.profiles.active=prod&lt;/code&gt;&lt;/p&gt;
&lt;h4 id="设置多个profile两个方法"&gt;设置多个profile(两个方法)
&lt;/h4&gt;&lt;ol&gt;
&lt;li&gt;YAML中：&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spring&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;profiles&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;active&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;prod&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;audit&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;ha&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ol start="2"&gt;
&lt;li&gt;&lt;code&gt;% export SPRING_PROFILES_ACTIVE=prod,audit,ha&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id="如果使用cloud-foundry"&gt;如果使用Cloud Foundry
&lt;/h4&gt;&lt;p&gt; Spring应用部署在Cloud Foundry，会自动激活名为&lt;strong&gt;cloud&lt;/strong&gt;的profile，只需将生产环境相关的配置放到cloud profile下。&lt;/p&gt;
&lt;h2 id="使用profile条件化地创建bean"&gt;使用profile条件化地创建bean
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;@Profile&lt;/code&gt;注解可以将某些bean设置为仅适用于给定的profile，例如：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@Bean&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@Profile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;dev&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CommandLineRunner&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;dataLoader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IngredientRepository&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UserRepository&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;userRepo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PasswordEncoder&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;encoder&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;用法&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;@Profile(&amp;quot;dev&amp;quot;)&lt;/code&gt;:在dev profile激活时创建该bean&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@Profile({&amp;quot;dev&amp;quot;, &amp;quot;qa&amp;quot;})&lt;/code&gt;：dev&lt;strong&gt;或&lt;/strong&gt;qa profile激活的时候创建该bean&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@Profile(&amp;quot;!prod&amp;quot;)&lt;/code&gt;：prod profile不激活就创建该bean&lt;/li&gt;
&lt;li&gt;与&lt;code&gt;@Configuration&lt;/code&gt;注解一起使用：&lt;br&gt;
将 &lt;code&gt;CommandLineRunner&lt;/code&gt;抽取到一个名为&lt;code&gt;DevelopmentConfig&lt;/code&gt;的配置类中：&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;span class="lnt"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@Profile&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;!prod&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;!qa&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@Configuration&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DevelopmentConfig&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Bean&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CommandLineRunner&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;dataLoader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IngredientRepository&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UserRepository&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;userRepo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PasswordEncoder&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;encoder&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;只有prod和qa&lt;strong&gt;均&lt;/strong&gt;没有激活的情况下才创建该bean。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;本章完。&lt;br&gt;
如有遗漏或错误，欢迎补充纠正&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>vscode中ctrl+左键不跳转</title><link>http://www.jansonblog.com/p/tips-1/</link><pubDate>Thu, 15 Dec 2022 00:00:00 +0000</pubDate><guid>http://www.jansonblog.com/p/tips-1/</guid><description>&lt;img src="http://www.jansonblog.com/p/tips-1/1.png" alt="Featured image of post vscode中ctrl+左键不跳转" /&gt;&lt;p&gt; 我一直是ssh远程操作的，之前ctrl+鼠标左键一直好用，可以跳转到对应函数的位置。&lt;br&gt;
 但是最近突然不好用了，解决方法很简单：&lt;/p&gt;
&lt;h1 id="vscode里重装cc拓展"&gt;vscode里重装C/C++拓展
&lt;/h1&gt;&lt;p&gt; 先是尝试了在本地运行一个简单的.c文件，结果提示&lt;code&gt;找不到类型为“cppdbg”的调试适配器&lt;/code&gt;。&lt;br&gt;
然后&lt;strong&gt;卸载重装远程C/C++拓展&lt;/strong&gt;，问题解决！&lt;/p&gt;</description></item><item><title>Spring学习之路（五）</title><link>http://www.jansonblog.com/p/spring5/</link><pubDate>Wed, 14 Dec 2022 00:00:00 +0000</pubDate><guid>http://www.jansonblog.com/p/spring5/</guid><description>&lt;img src="http://www.jansonblog.com/p/spring5/1.jpg" alt="Featured image of post Spring学习之路（五）" /&gt;&lt;p&gt; 第六章内容第五版与第六版几乎相同。本章介绍了自动配置bean；创建自己的配置属性；使用profile进行配置。&lt;/p&gt;
&lt;h1 id="自动配置"&gt;自动配置：
&lt;/h1&gt;&lt;h2 id="细粒度的自动配置"&gt;细粒度的自动配置
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;两种不同但相关的配置&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Bean wiring（装配bean）：声明在Spring应⽤上下⽂中创建哪些应⽤组件以及它们应该如何相互注入。&lt;/li&gt;
&lt;li&gt;Property injection（依赖注入）声明在Spring应⽤上下⽂中创建哪些应⽤组件以及它们应该如何相互注入。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt; 在Spring的XML和Java配置中，这两种类型的配置通常在同一个地方&lt;strong&gt;显式声明&lt;/strong&gt;。&lt;br&gt;
 在Java配置中，带@bean注解的方法很可能既实例化一个bean，又给它的属性赋值。举例来说，@Bean方法为H2数据库声明一个数据源：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@Bean&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;DataSource&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;dataSource&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;EmbeddedDatabaseBuilder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;H2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addScript&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;taco_schema.sql&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addScripts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;user_data.sql&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;ingredient_data.sql&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;addScript()&lt;/code&gt; 和 &lt;code&gt;addScripts()&lt;/code&gt;方法通过设置String属性来确定数据源——&lt;strong&gt;这是不使用Spring Boot的配置方法。&lt;/strong&gt;&lt;br&gt;
 如果在运行时类路径中能够找到H2依赖，那么&lt;strong&gt;Spring Boot会自动在Spring应用上下文中创建对应的DataSource bean&lt;/strong&gt;。这个bean会运行名为&lt;code&gt;schema.sql&lt;/code&gt;和&lt;code&gt;data.sql&lt;/code&gt;的脚本。&lt;/p&gt;
&lt;h2 id="spring的环境抽象"&gt;Spring的环境抽象
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Spring的环境抽象&lt;/strong&gt;&lt;br&gt;
 Spring环境会拉取多个属性源：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;JVM系统属性&lt;/li&gt;
&lt;li&gt;操作系统环境变量&lt;/li&gt;
&lt;li&gt;命令行参数&lt;/li&gt;
&lt;li&gt;应用属性配置文件&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt; 将这些属性聚合到一个源中，通过这个源可以注入到spring的bean中。如下图所示：
&lt;img src="http://www.jansonblog.com/p/spring5/img.png"
width="1288"
height="767"
srcset="http://www.jansonblog.com/p/spring5/img_hu_20feca64762622ee.png 480w, http://www.jansonblog.com/p/spring5/img_hu_a8063e58c3571e0f.png 1024w"
loading="lazy"
alt="img.png"
class="gallery-image"
data-flex-grow="167"
data-flex-basis="403px"
&gt;
 Spring boot自动配置的bean都可以通过spring环境提取的属性进行配置.&lt;br&gt;
例如，希望底层Servlet容器使用另一个端口监听，有以下四个不同的方法：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;“src/main/resources/application.properties”将server.port设置成一个不同的端口：server.port = 9090&lt;/li&gt;
&lt;li&gt;“src/main/resources/application.yml”中: server : port : 9090&lt;/li&gt;
&lt;li&gt;命令行参数启动时指定端口：$ java -jar tacocloud-0.0.5-SNAPSHOT.jar &amp;ndash;server.port=9090&lt;/li&gt;
&lt;li&gt;操作系统环境变量进行一次配置：$ export SERVER_PORT=9090（Spring能自动挑选环境变量名，将其解析）&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="配置数据源"&gt;配置数据源
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;显示配置自己的datasource&lt;/strong&gt;:&lt;br&gt;
在&lt;code&gt;application.yml&lt;/code&gt;配置：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spring&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;datasource&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;jdbc:mysql://localhost/tacocloud&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;tacodb&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;tacopassword&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt; &lt;strong&gt;尽管我们需要将对应的JDBC驱动添加到构建⽂件中，但是我们不需要指定JDBC驱动类。Spring Boot会根据数据库URL的结构推算出来。&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="设置jdbc驱动类"&gt;设置JDBC驱动类
&lt;/h3&gt;&lt;p&gt; 然⽽，我们依然可以通过&lt;code&gt;spring.datasource.driver-class-name&lt;/code&gt;属性来进⾏设置JDBC驱动类：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spring&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;datasource&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;jdbc:mysql://localhost/tacocloud&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;tacodb&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;tacopassword&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;driver-class-name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;com.mysql.jdbc.Driver&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt; Spring boot自动化配置DataSource bean的时候，会使用该连接。如果类路径存在&lt;code&gt;HikariCP&lt;/code&gt;的连接池，会使用该连接池。否则在类路径查找并使用以下连接池：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Tomcat JDBC Connection Pool&lt;/li&gt;
&lt;li&gt;Apache Commons DBCP 2&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;注：旧版默认连接池是Tomcat的JDBC连接池，新版默认连接池已经变成HikariCP，因为它够快，代码量少，稳定。&lt;/p&gt;
&lt;h2 id="配置嵌入式服务器"&gt;配置嵌入式服务器
&lt;/h2&gt;&lt;p&gt; 如果在配置servlet容器端口时，将端口设为0，即：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;server:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Port : 0
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;会发生什么？&lt;br&gt;
 虽然显式设为0，但是服务器不会在端口0上启动。而是任选一个可用的端口。这在运行自动化集成测试的时候，非常有用：因为可以保证并发运行的测试不会与硬编码的端口号冲突。&lt;/p&gt;
&lt;h3 id="配置使其处理https请求"&gt;配置使其处理HTTPS请求
&lt;/h3&gt;&lt;p&gt; 底层服务器配置不仅局限于一个端口，底层容器最常见的一项设置是让它处理HTTPS请求。&lt;br&gt;
 为了实现，需要使用JDK的keytool命令行工具生成keystore：&lt;br&gt;
&lt;code&gt;$ keytool -keystore mykeys.jks -genkey -alias tomcat -keyalg RSA&lt;/code&gt;&lt;/p&gt;
&lt;p&gt; 接下来，为了在嵌入式服务器中启用HTTPS，需要设置属性：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;可以在命令行中设置，但是不方便&lt;/li&gt;
&lt;li&gt;可以通过&lt;code&gt;application.properties&lt;/code&gt;或&lt;code&gt;application.yml&lt;/code&gt;文件来声明配置：&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;server&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;8443&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ssl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;key-store&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;file:/ / /path/to/mykeys.jks&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;key-store-password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;letmein&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;key-password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;letmein&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt; 解释：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;端口设为&lt;strong&gt;8443&lt;/strong&gt;（开发阶段HTTPS服务器的常用选择）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;server.ssl.key-store&lt;/code&gt;设置为所创建的&lt;code&gt;keystore&lt;/code&gt;路径&lt;/li&gt;
&lt;li&gt;&lt;code&gt;server.ssl.key-store-password&lt;/code&gt;和&lt;code&gt;server.ssl.key-password&lt;/code&gt;属性设置为创建&lt;code&gt;keystore&lt;/code&gt;所设置的密码&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;属性准备就绪后，应用会监听8443端口的HTTPS请求。&lt;/p&gt;
&lt;h2 id="配置日志"&gt;配置日志
&lt;/h2&gt;&lt;p&gt; 默认情况下，Spring Boot通过Logback配置日志，日志以INFO级别写入到控制台&lt;br&gt;
 为了完全控制日志的配置，可以在类路径的根目录下&lt;code&gt;src/main/resources&lt;/code&gt;创建&lt;code&gt;logback.xml&lt;/code&gt;文件。&lt;br&gt;
简单样例：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-xml" data-lang="xml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;appender&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;STDOUT&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;ch.qos.logback.core.ConsoleAppender&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;encoder&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;pattern&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/pattern&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/encoder&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/appender&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;logger&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;root&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;level=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;INFO&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;root&lt;/span&gt; &lt;span class="na"&gt;level=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;INFO&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;appender-ref&lt;/span&gt; &lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;STDOUT&amp;#34;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/root&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt; 这个&lt;code&gt;Logback&lt;/code&gt;和没有&lt;code&gt;logback.xml&lt;/code&gt;文件时的默认行为是几乎完全相同的。但是编辑&lt;code&gt;logback.xml&lt;/code&gt;文件，可以完全控制应用的日志文件。&lt;/p&gt;
&lt;p&gt; 日志配置中最常见变更是&lt;strong&gt;修改日志级别&lt;/strong&gt;和&lt;strong&gt;指定日志写入到某个文件&lt;/strong&gt;，Spring Boot的配置属性功能如何实现？&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;设置日志级别：&lt;br&gt;
在&lt;code&gt;application.yml&lt;/code&gt;中添加条目，例如：&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;level&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;root&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;WARN&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;org.springframework.security&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;DEBUG&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;以上配置将&lt;code&gt;root logging&lt;/code&gt;设置为&lt;strong&gt;WARN&lt;/strong&gt;级别，spring security的日志级别设为&lt;strong&gt;DEBUG&lt;/strong&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;将日志条目写入指定文件：
如要将日志条目写入到&amp;quot;&lt;code&gt;/var/logs/&lt;/code&gt;&amp;ldquo;中的TacoCloud文件中&lt;code&gt;logging.path&lt;/code&gt;和&lt;code&gt;logging.file&lt;/code&gt;文件可以如下配置：&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;span class="lnt"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/var/logs/&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;TacoCloud.log&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;level&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;root&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;WARN&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;org&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;springframework&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;security&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;DEBUG&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt; 如果应用具有指定目录的写入权限，日志条目会被写入到指定目录。&lt;br&gt;
 默认情况下，日志文件达到&lt;strong&gt;10MB&lt;/strong&gt;就会轮换。&lt;/p&gt;
&lt;h2 id="使用特定的属性值"&gt;使用特定的属性值
&lt;/h2&gt;&lt;p&gt; 设置属性不局限于将值设置为硬编码的String或数值，可以从其他的&lt;strong&gt;配置属性派生值&lt;/strong&gt;：&lt;br&gt;
 假设我们想要设置⼀个名为&lt;code&gt;greeting.welcome&lt;/code&gt;的属性，它的值来源于名为&lt;code&gt;spring.application.name&lt;/code&gt;的另⼀个属性：
 在设置&lt;code&gt;greeting.welcome&lt;/code&gt;的时候，可以使用&lt;code&gt;${}&lt;/code&gt;占位符标记：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;greeting&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;welcome&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;${spring.application.name}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt; 甚至可以将&lt;code&gt;${}&lt;/code&gt;占位符嵌入到其他文本中：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;greeting&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;welcome&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;You are using ${spring.application.name}.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt; 在配置Spring⾃⼰的组件时，使⽤配置属性可以很容易地将值注⼊这些组件属性中，并且可以细粒度地调整⾃动配置功能。&lt;br&gt;
 配置属性并不专属于Spring创建的bean。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;如有遗漏或错误，欢迎补充纠正&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>2022年总结</title><link>http://www.jansonblog.com/p/2022/</link><pubDate>Tue, 06 Dec 2022 00:00:00 +0000</pubDate><guid>http://www.jansonblog.com/p/2022/</guid><description>&lt;img src="http://www.jansonblog.com/p/2022/1.jpg" alt="Featured image of post 2022年总结" /&gt;&lt;p&gt;&lt;strong&gt;生活总结：&lt;/strong&gt;&lt;br&gt;
  那天我们都喝醉了，也都哭了，互相说了许多肝胆相照的话，真是难忘的一夜。&lt;/p&gt;
&lt;h2 id="2022被牢日本的第三年"&gt;2022——被“牢”日本的第三年
&lt;/h2&gt;&lt;h3 id="冬ふゆ"&gt;冬(ふゆ)
&lt;/h3&gt;&lt;p&gt;&lt;img src="http://www.jansonblog.com/p/2022/4.jpg"
width="1280"
height="960"
srcset="http://www.jansonblog.com/p/2022/4_hu_bd2654e1a1ef70d3.jpg 480w, http://www.jansonblog.com/p/2022/4_hu_c44b7111a8a43916.jpg 1024w"
loading="lazy"
alt="冬"
class="gallery-image"
data-flex-grow="133"
data-flex-basis="320px"
&gt;&lt;/p&gt;
&lt;h3 id="春はる"&gt;春(はる)
&lt;/h3&gt;&lt;p&gt;&lt;img src="http://www.jansonblog.com/p/2022/6.jpg"
width="960"
height="1280"
srcset="http://www.jansonblog.com/p/2022/6_hu_8f438cf07a58a62f.jpg 480w, http://www.jansonblog.com/p/2022/6_hu_2000c8cc41e3f115.jpg 1024w"
loading="lazy"
alt="春"
class="gallery-image"
data-flex-grow="75"
data-flex-basis="180px"
&gt;&lt;/p&gt;
&lt;h4 id="掘金"&gt;掘金
&lt;/h4&gt;&lt;p&gt;  4月报名掘金青训营&lt;/p&gt;
&lt;h5 id="礼盒周边"&gt;礼盒+周边
&lt;/h5&gt;&lt;p&gt;&lt;img src="http://www.jansonblog.com/p/2022/3.jpg"
width="1276"
height="1702"
srcset="http://www.jansonblog.com/p/2022/3_hu_4e42159de3dcdbb0.jpg 480w, http://www.jansonblog.com/p/2022/3_hu_a45b9b2cad7586ae.jpg 1024w"
loading="lazy"
alt="掘金礼盒"
class="gallery-image"
data-flex-grow="74"
data-flex-basis="179px"
&gt;&lt;/p&gt;
&lt;h3 id="夏なつ"&gt;夏(なつ)
&lt;/h3&gt;&lt;p&gt;&lt;img src="http://www.jansonblog.com/p/2022/img.png"
width="2050"
height="1537"
srcset="http://www.jansonblog.com/p/2022/img_hu_84849f44dc41c095.png 480w, http://www.jansonblog.com/p/2022/img_hu_21a4464acb53ed39.png 1024w"
loading="lazy"
alt="夏"
class="gallery-image"
data-flex-grow="133"
data-flex-basis="320px"
&gt;
  夏天，一个学长毕业了，也是山东人。生活和学习都给了我很多帮助。
  外表冷酷坚强的学长，临别那天像个泪人。然后说好到最近车站送他，结果一直陪他坐电车坐了一个多小时，一直送到大阪站。&lt;br&gt;
  那天离我表弟很近，包里带着一个钱包，坐了一个小时车去他家住了一个周，算不上是一次&amp;quot;说走就走的旅行&amp;quot;，但是也不知道怎么就突然离开自己的出租屋这么久。
&lt;img src="http://www.jansonblog.com/p/2022/11.jpg"
width="960"
height="1280"
srcset="http://www.jansonblog.com/p/2022/11_hu_7301f942ec8dbdbe.jpg 480w, http://www.jansonblog.com/p/2022/11_hu_2d080e1078125a40.jpg 1024w"
loading="lazy"
alt="夏"
class="gallery-image"
data-flex-grow="75"
data-flex-basis="180px"
&gt;&lt;/p&gt;
&lt;h3 id="秋あき"&gt;秋(あき)
&lt;/h3&gt;&lt;p&gt;&lt;img src="http://www.jansonblog.com/p/2022/8.jpg"
width="1280"
height="960"
srcset="http://www.jansonblog.com/p/2022/8_hu_51eb58573a68f0c3.jpg 480w, http://www.jansonblog.com/p/2022/8_hu_9e8250d71a04c3df.jpg 1024w"
loading="lazy"
alt="秋"
class="gallery-image"
data-flex-grow="133"
data-flex-basis="320px"
&gt;&lt;/p&gt;
&lt;h4 id="掘友们"&gt;掘友们
&lt;/h4&gt;&lt;p&gt;  最有收获的属于游戏圈组织的那一次王者荣耀比赛的活动了——抱着纯纯凑热闹的心理，找了个队混替补，结果发现群里的人全都很nice。&lt;br&gt;
  队长是山东老乡，大概是当时圈子里唯一剩下的朋友了
&lt;img src="http://www.jansonblog.com/p/2022/12.jpg"
width="1280"
height="960"
srcset="http://www.jansonblog.com/p/2022/12_hu_3e955fb5d2555fb8.jpg 480w, http://www.jansonblog.com/p/2022/12_hu_f09fb0a4b22e826e.jpg 1024w"
loading="lazy"
alt="秋"
class="gallery-image"
data-flex-grow="133"
data-flex-basis="320px"
&gt;
 &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;  2022年过去了，我很怀念它。&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>Spring学习之路（四）</title><link>http://www.jansonblog.com/p/spring4/</link><pubDate>Wed, 16 Nov 2022 00:00:00 +0000</pubDate><guid>http://www.jansonblog.com/p/spring4/</guid><description>&lt;img src="http://www.jansonblog.com/p/spring4/1.jpg" alt="Featured image of post Spring学习之路（四）" /&gt;&lt;p&gt; 本文是Spring Security系列最后一篇总结。&lt;/p&gt;
&lt;h2 id="对oauth20的支持"&gt;对OAuth2.0的支持
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;OAuth2.0是什么？&lt;/strong&gt;&lt;br&gt;
 举个例子，就是网站中常见的第三方登录，登录某个网站支持使用Facebook，Google账号登录。微信网页授权也是基于OAuth2.0。同时1.0版本也已经被2.0完全取代了。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Spring Security支持Fackbook,Google,GitHub,Okta第三方登录&lt;/li&gt;
&lt;li&gt;书中没有详细的配置教学：“ 通过OAuth2/OpenID连接客户端，你需要设置以下属性:”&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;span class="lnt"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;spring:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; security:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; oauth2:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; client:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; registration:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;lt;oauth2 or openid provider name&amp;gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; clientId: &amp;lt;client id&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; clientSecret: &amp;lt;client secret&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; scope: &amp;lt;comma-separated list of requested scopes&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt; 如果要启用OAuth2.0登录，需要在&lt;em&gt;&lt;strong&gt;Spring Security配置类&lt;/strong&gt;&lt;/em&gt;中添加&lt;code&gt;.and().oauth2Login()&lt;/code&gt;方法。&lt;br&gt;
 同时提供传统用户名-密码登录方式和第三方登录：&lt;code&gt;.and().oauth2Login().loginPage(&amp;quot;/login&amp;quot;)&lt;/code&gt;
 启用logout登出功能：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cm"&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; * 启用logout登出:点击logout时，session被清空，同时登出
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; * logoutSuccessUrl()方法：登出后，重定向到指定路径页面
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; */&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;and&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;logout&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;logoutSuccessUrl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;/&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="阻止跨站请求伪造-csrfcross-site-request-forgery"&gt;阻止跨站请求伪造 (CSRF:Cross-site request forgery)：
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Spring Security含有&lt;strong&gt;内置的CSRF保护&lt;/strong&gt;，而且是&lt;strong&gt;默认启用&lt;/strong&gt;的，所以只需确保应用程序提交的任何表单都包含一个名为&lt;code&gt;_csrf&lt;/code&gt;的字段，该字段包含CSRF令牌。&lt;/li&gt;
&lt;li&gt;Spring Security通过将CSRF令牌放在名为&lt;code&gt;_csrf&lt;/code&gt;的请求属性中来简化这一点。因此，在一个&lt;strong&gt;Thymeleaf模板&lt;/strong&gt;中，可以用下面的代码在一个隐藏字段中呈现CSRF令牌:&lt;br&gt;
 &lt;code&gt;&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;_csrf&amp;quot; th:value=&amp;quot;${_csrf.token}&amp;quot;/&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;如果使用Spring MVC表单标签库（Spring MVC’s JSP tag library）或spring security安全方言，内置CSRF令牌的隐藏字段会&lt;strong&gt;自动显示&lt;/strong&gt;。
&lt;ul&gt;
&lt;li&gt;在静态模板Thymeleaf 中，只需要确保&lt;form&gt;元素作为Thymeleaf的前缀，例如：
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;form method=&amp;quot;POST&amp;quot; th:action=&amp;quot;@{/login}&amp;quot; id=&amp;quot;loginForm&amp;quot;&amp;gt;&lt;/code&gt;，&lt;code&gt;th:action&lt;/code&gt; 在Thymeleaf会为开发者渲染隐藏字段。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;作者极其不推荐，但是还是教了这个歪门邪道：&lt;br&gt;
 禁用内置CSRF支持：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;.and().csrf().disable()&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="方法级安全控制"&gt;方法级安全控制
&lt;/h2&gt;&lt;h3 id="preauthorize注解"&gt;&lt;code&gt;@PreAuthorize&lt;/code&gt;注解
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;
&lt;h4 id="作用"&gt;作用
&lt;/h4&gt; &lt;code&gt;@PreAuthorize&lt;/code&gt;注解根据SpEL表达式进行判断，如果表达式值为&lt;code&gt;false&lt;/code&gt;，则不会调用方法： &lt;br&gt;
 &lt;code&gt;@PreAuthorize&lt;/code&gt;如果阻止了调用，SpringSecurity抛出&lt;strong&gt;AccessDeniedException&lt;/strong&gt;未检查的异常，不需要进行捕捉。除非想对其进行自定义处理。如果不进行捕获:
&lt;ul&gt;
&lt;li&gt; 异常会被SpringSecurity的过滤器捕捉，要么显示&lt;strong&gt;HTTP403&lt;/strong&gt;错误；&lt;/li&gt;
&lt;li&gt; 要么如果用户没登录的话，被重定向到登录界面；&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h4 id="用法"&gt;用法
&lt;/h4&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@PreAuthorize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;hasRole(&amp;#39;ADMIN&amp;#39;)&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;deleteAllOrders&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;orderRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;deleteAll&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ol start="3"&gt;
&lt;li&gt;
&lt;h4 id="注意"&gt;&lt;strong&gt;注意&lt;/strong&gt;
&lt;/h4&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt; &lt;del&gt;在以前的用法中，使用&lt;code&gt;@EnableGlobalMethodSecurity&lt;/code&gt;注解，并扩展&lt;code&gt;WebSecurityConfigurerAdapter&lt;/code&gt;类并且覆盖配置&lt;code&gt;HttpSecurity&lt;/code&gt;和&lt;code&gt;WebSecurity&lt;/code&gt;的方法；&lt;/del&gt;&lt;br&gt;
 &lt;strong&gt;现在，&lt;code&gt;WebSecurityConfigurerAdapter&lt;/code&gt;在SpringSecurity5.7.1以上或SpringBoot2.7.0以上会出现已被弃用的警告!&lt;/strong&gt;**
 在新的用法中，我们得分别声明类型为&lt;code&gt;SecurityFilterChain&lt;/code&gt;和&lt;code&gt;WebSecurityCustomizer&lt;/code&gt;的bean，例如：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Bean&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SecurityFilterChain&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;filterChain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpSecurityhttp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;throws&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Bean&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;WebSecurityCustomizer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;webSecurityCustomizer&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="postauthorize注解"&gt;&lt;code&gt;@PostAuthorize&lt;/code&gt;注解
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;
&lt;h4 id="作用-1"&gt;作用
&lt;/h4&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt; &lt;code&gt;@PostAuthorize&lt;/code&gt;注解的工作方式几乎与&lt;code&gt;@PreAuthorize&lt;/code&gt;注解相同，只是它的表达式在&lt;strong&gt;调用目标方法并返回之前&lt;/strong&gt;不会被计算。表达式可以根据方法的返回值来决定是否允许调用方法。&lt;br&gt;
 抛出异常与&lt;code&gt;@PreAuthorize&lt;/code&gt;注解相同，为&lt;strong&gt;AccessDeniedException&lt;/strong&gt;未检查的异常。&lt;/p&gt;
&lt;ol start="2"&gt;
&lt;li&gt;
&lt;h4 id="用法-1"&gt;用法
&lt;/h4&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@PostAuthorize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;hasRole(&amp;#39;ADMIN&amp;#39;) || &amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;returnObject.user.username == authentication.name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;TacoOrder&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;getOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;long&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="spring-security判断经过身份验证用户的方法"&gt;Spring Security判断经过身份验证用户的方法：
&lt;/h2&gt;&lt;h3 id="方法一"&gt;方法一
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;在控制器方法中添加&lt;strong&gt;java.security.Principal&lt;/strong&gt;对象：
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@PostMapping&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;processOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@Valid&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;TacoOrder&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Errors&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SessionStatus&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sessionStatus&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Principal&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;principal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;userRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findByUsername&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;principal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getName&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="方法二"&gt;方法二
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;在控制器方法中添加&lt;strong&gt;org.springframework.security.core.Authentication&lt;/strong&gt;对象：
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;* 调用getPrincipal()方法得到主要对象（例子为User）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;* getPrincipal()方法返回java.util.Object，所以将其转换为User
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;*/&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@PostMapping&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;processOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@Valid&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;TacoOrder&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Errors&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SessionStatus&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sessionStatus&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Authentication&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;authentication&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;authentication&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getPrincipal&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="方法三"&gt;方法三
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;注入一个带&lt;code&gt;@AuthenticationPrincipal&lt;/code&gt;注解的方法参数。（该注解来自Spring Security的&lt;strong&gt;org.springframework.security.core.annotation&lt;/strong&gt;包）：
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@PostMapping&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;processOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@Valid&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;TacoOrder&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Errors&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SessionStatus&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sessionStatus&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@AuthenticationPrincipal&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hasErrors&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;orderForm&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;orderRepo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sessionStatus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setComplete&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;redirect:/&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;优点：
&lt;ul&gt;
&lt;li&gt;不需要对对象进行映射&lt;/li&gt;
&lt;li&gt;它将特定于安全性的代码限制为注释本身&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="方法四"&gt;方法四
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;还有另一种方法可以识别经过身份验证的用户是谁，虽然有点混乱，因为它使用了大量特定于安全的代码。可以从安全上下文中获取一个身份验证对象，然后像这样请求它的主体：
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Authentication&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;authentication&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SecurityContextHolder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getContext&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getAuthentication&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;authentication&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getPrincipal&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;缺点：
&lt;ul&gt;
&lt;li&gt;有大量安全相关的代码&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;优点：
&lt;ul&gt;
&lt;li&gt;可以在应用程序中的任何地方使用，而不仅仅是在控制器的处理程序方法中。（这使得它适合在较低级别的代码中使用）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;本章完&lt;br&gt;
如有遗漏或错误，欢迎补充纠正&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>并查集（Union-find）[Java]</title><link>http://www.jansonblog.com/p/union-find/</link><pubDate>Mon, 14 Nov 2022 00:00:00 +0000</pubDate><guid>http://www.jansonblog.com/p/union-find/</guid><description>&lt;img src="http://www.jansonblog.com/p/union-find/1.jpg" alt="Featured image of post 并查集（Union-find）[Java]" /&gt;&lt;h2 id="什么是并查集"&gt;什么是并查集？
&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;  并查集(Disjoint-set data structure)是一种数据结构，用于解决&lt;strong&gt;不交集&lt;/strong&gt;问题的合并及查询问题。它还有几个英文名叫：Union-find data structure / merge–find set(中文就是：合并-查找数据结构)。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;  为什么叫&lt;strong&gt;合并-查询数据结构&lt;/strong&gt;？因为并查集有三个功能：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;添加&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;合并&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;查询&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;  以维基百科的例子为例:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;现在有数字1-8共八个元素，每个元素是一个集合：
&lt;img src="http://www.jansonblog.com/p/union-find/2-1.jpg"
width="1920"
height="175"
srcset="http://www.jansonblog.com/p/union-find/2-1_hu_6604bf29050fe65c.jpg 480w, http://www.jansonblog.com/p/union-find/2-1_hu_b4a6ec6af89aa47a.jpg 1024w"
loading="lazy"
alt="2-1"
class="gallery-image"
data-flex-grow="1097"
data-flex-basis="2633px"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;合并&lt;/strong&gt;操作几次后，一些集合合并到了一起：
&lt;img src="http://www.jansonblog.com/p/union-find/2-2.jpg"
width="1920"
height="175"
srcset="http://www.jansonblog.com/p/union-find/2-2_hu_6f43f0604a13490.jpg 480w, http://www.jansonblog.com/p/union-find/2-2_hu_4c5d6996e83e6a58.jpg 1024w"
loading="lazy"
alt="2-2"
class="gallery-image"
data-flex-grow="1097"
data-flex-basis="2633px"
&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;  这就是并查集，其实很简单。其主要的作用就是&lt;strong&gt;合并&lt;/strong&gt;和&lt;strong&gt;查找&lt;/strong&gt;。&lt;br&gt;
  其最常见的实现是不交集森林。但是为了方便解释，接下来用一个数组实现的力扣题目来说明。&lt;/p&gt;
&lt;h2 id="力扣990题"&gt;&lt;a class="link" href="https://leetcode.cn/problems/satisfiability-of-equality-equations/" title="力扣990.等式方程的可满足性"
target="_blank" rel="noopener"
&gt;力扣990题&lt;/a&gt;
&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;题目：&lt;strong&gt;等式方程的可满足性&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt; 给定一个由表示变量之间关系的字符串方程组成的数组，每个字符串方程 equations[i] 的长度为 4，并采用两种不同的形式之一：&amp;ldquo;a==b&amp;rdquo; 或 &amp;ldquo;a!=b&amp;rdquo;。在这里，a 和 b 是小写字母（不一定不同），表示单字母变量名。&lt;br&gt;
 只有当可以将整数分配给变量名，以便满足所有给定的方程时才返回 true，否则返回 false。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;示例1：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;输入：&lt;/strong&gt; [&amp;ldquo;a==b&amp;rdquo;,&amp;ldquo;b!=a&amp;rdquo;]&lt;br&gt;
&lt;strong&gt;输出：&lt;/strong&gt; false&lt;br&gt;
&lt;strong&gt;解释：&lt;/strong&gt; 如果我们指定，a = 1 且 b = 1，那么可以满足第一个方程，但无法满足第二个方程。没有办法分配变量同时满足这两个方程。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;示例2：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;输入：&lt;/strong&gt; [&amp;ldquo;b==a&amp;rdquo;,&amp;ldquo;a==b&amp;rdquo;]&lt;br&gt;
&lt;strong&gt;输出：&lt;/strong&gt; true&lt;br&gt;
&lt;strong&gt;解释：&lt;/strong&gt; 我们可以指定 a = 1 且 b = 1 以满足满足这两个方程。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="题解java-感谢lee215大佬提供的题解"&gt;题解[Java] (感谢Lee215大佬提供的题解)：
&lt;/h2&gt;&lt;p&gt; 990这道题由于最大只有26个小写字母，所以可以使用数组来实现&lt;strong&gt;并查集&lt;/strong&gt;。&lt;br&gt;
 具体思路（并查集的三个功能）：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;添加：&lt;/strong&gt; 建立大小为26的int数组,名为uf；得到大小为26的数组，并让每个位置对应一个英文字母，即：&lt;br&gt;
 从&lt;code&gt;'a'-'z'&lt;/code&gt;对应&lt;code&gt;uf[0] - uf[25]&lt;/code&gt;，即：&lt;code&gt;uf[0] = 0&lt;/code&gt;，&lt;code&gt;uf[1] = 1&lt;/code&gt;……&lt;code&gt;uf[25]=25&lt;/code&gt;分别代表26个字母，也得到了26个集合。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;合并：&lt;/strong&gt; 将符合 &lt;code&gt;==&lt;/code&gt;关系的合并到一个集合中，实现：&lt;br&gt;
  例如，我们想将&lt;code&gt;'a'&lt;/code&gt;对应的集合&lt;code&gt;uf[0]&lt;/code&gt;与&lt;code&gt;'b'&lt;/code&gt;对应的集合&lt;code&gt;uf[1]&lt;/code&gt;合并，只需让：&lt;code&gt;uf[0] = 1&lt;/code&gt;&lt;br&gt;
  这样当我们查看&lt;code&gt;'a'&lt;/code&gt;对应的&lt;code&gt;uf[0]&lt;/code&gt;的值时，即可发现集合&lt;code&gt;'a'&lt;/code&gt;与集合&lt;code&gt;'b'&lt;/code&gt;是合并的。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;查找：&lt;/strong&gt; 查找只需要从数组uf的一个位置开始，便可以知道该位置对应的字母与哪些字母合并过。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt; 在建立并查集后，本题只需要查看所有&lt;code&gt;!=&lt;/code&gt;关系中的字母，是否在并查集中被合并到了一个集合。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Solution&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;uf&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;26&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;boolean&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;equationsPossible&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;equations&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;//添加并查集；uf[0]到uf[25]分别对应从&amp;#39;a&amp;#39;到&amp;#39;z&amp;#39;的26个小写字母&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;26&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;uf&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;//合并；合并“==”关系的字母：使用find()方法查询到集合的最后一个字母，将其合并&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;equations&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;charAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sc"&gt;&amp;#39;=&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;uf&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;charAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sc"&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;charAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sc"&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;//遍历并查集，使用find()方法找到每个集合最尾端的字母，&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;//判断最尾端字母是否相同来判断“!=”两边的字母是否位于一个集合内&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;equations&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;charAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sc"&gt;&amp;#39;!&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uf&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;charAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sc"&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;uf&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;charAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sc"&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;//查找；寻找属于同一集合的最尾端的字母，将其返回&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uf&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;uf&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uf&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;uf&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;如有遗漏或错误，欢迎补充纠正&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>KMP算法（字符串匹配算法）</title><link>http://www.jansonblog.com/p/kmp/</link><pubDate>Thu, 03 Nov 2022 00:00:00 +0000</pubDate><guid>http://www.jansonblog.com/p/kmp/</guid><description>&lt;img src="http://www.jansonblog.com/p/kmp/1.png" alt="Featured image of post KMP算法（字符串匹配算法）" /&gt;&lt;h2 id="kmpknuth-morris-pratt算法"&gt;KMP(Knuth-Morris-Pratt)算法：
&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt; 字符串查找算法（简称为KMP算法）可在一个字符串S内查找一个词W的出现位置。一个词在不匹配时本身就包含足够的信息来确定下一个匹配可能的开始位置，此算法利用这一特性以避免重重复查找之前出现的字符。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt; 我对MKP的认识：其归属于DP问题，核心的思想在于对要查找的字符串进行处理——寻找最长的前缀。然后通过记忆化数组的方式，跳过不可能成功匹配的字符串位置，从下一个可能的位置进行搜索。利用要查找字符串的特性，利用其前缀和后缀的共同部分来简化搜索过程。&lt;/p&gt;
&lt;h2 id="算法原理"&gt;算法原理：
&lt;/h2&gt;&lt;p&gt; 简单的暴力搜索无非就是从每个可能的index开始，与要查找的字符串进行比较。
 而KMP则会跳过已经匹配的部分，以维基百科的说明为例，简单概括过程：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;blockquote&gt;
&lt;p&gt;要查找的字符串W=&amp;ldquo;ABCDABD&amp;rdquo;，&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;blockquote&gt;
&lt;p&gt;给定字符串S=&amp;ldquo;ABC ABCDAB ABCDABCDABDE&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;为例说明查找过程：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;S: &lt;strong&gt;ABC&lt;/strong&gt; ABCDAB ABCDABCDABDE&lt;br&gt;
W: &lt;strong&gt;ABC&lt;/strong&gt;DABD&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;S[3]（=&amp;rsquo; &amp;rsquo;)与W[3]（=&amp;lsquo;D&amp;rsquo;）不匹配，所以跳过；从S[4]开始，与W[0]进行比较。&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;S:ABC &lt;strong&gt;ABCDAB&lt;/strong&gt; ABCDABCDABDE&lt;br&gt;
W:&lt;strong&gt;ABCDAB&lt;/strong&gt;D&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;从S[4]开始比较，当位于S[10]（=&amp;rsquo; &amp;rsquo;）时，与W对应的字符不匹配；但是此时可以注意到，&amp;quot;&lt;strong&gt;AB&lt;/strong&gt;&amp;ldquo;在“ABCD&lt;strong&gt;AB&lt;/strong&gt;&amp;ldquo;的头尾处均有出现——这意味着，尾部的“AB”可以作为下一次比较的起点。&lt;/li&gt;
&lt;li&gt;所以下次从index = 8的位置：&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;S:ABC ABCD&lt;strong&gt;A&lt;/strong&gt;B ABCDABCDABDE&lt;br&gt;
W:ABCD&lt;strong&gt;A&lt;/strong&gt;BD&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;即&lt;strong&gt;A&lt;/strong&gt;开始进行匹配。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="应用题目实战"&gt;应用题目实战:
&lt;/h2&gt;&lt;p&gt;&lt;a class="link" href="https://leetcode.com/problems/find-the-index-of-the-first-occurrence-in-a-string/" title="LeetCode 28. Find the Index of the First Occurrence in a String"
target="_blank" rel="noopener"
&gt;LeetCode 28. Find the Index of the First Occurrence in a String&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;题目实战日后补充说明&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;同时推荐一个算法可视化工具：&lt;br&gt;
&lt;a class="link" href="https://algorithm-visualizer.org/dynamic-programming/knuth-morris-pratts-string-search" title="algorithm-visualizer_KMP"
target="_blank" rel="noopener"
&gt;algorithm-visualizer_KMP&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;如有遗漏或错误，欢迎补充纠正&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>Spring学习之路（三）</title><link>http://www.jansonblog.com/p/spring3/</link><pubDate>Wed, 02 Nov 2022 00:00:00 +0000</pubDate><guid>http://www.jansonblog.com/p/spring3/</guid><description>&lt;img src="http://www.jansonblog.com/p/spring3/1.jpg" alt="Featured image of post Spring学习之路（三）" /&gt;&lt;ul&gt;
&lt;li&gt;Spring实战第五版中使用的WebSecurityConfigurerAdapter已被弃用 （还没学过就被弃用了&amp;hellip;）&lt;/li&gt;
&lt;li&gt;第五章开始，使用最新的Spring实战第六版进行学习&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="spring-security的密码编译器"&gt;Spring Security的密码编译器
&lt;/h2&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: center"&gt;密码编译器&lt;/th&gt;
&lt;th style="text-align: center"&gt;加密方法&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;BCryptPasswordEncoder&lt;/td&gt;
&lt;td style="text-align: center"&gt;应用 bcrypt 加强哈希加密&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;NoOpPasswordEncoder&lt;/td&gt;
&lt;td style="text-align: center"&gt;不应用任何编码&lt;br/&gt;（对测试有用，不适合生产使用）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;Pbkdf2PasswordEncoder&lt;/td&gt;
&lt;td style="text-align: center"&gt;应用 PBKDF2 加密&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;SCryptPasswordEncoder&lt;/td&gt;
&lt;td style="text-align: center"&gt;应用 scrypt 哈希加密&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;StandardPasswordEncoder&lt;/td&gt;
&lt;td style="text-align: center"&gt;应用 SHA-256 哈希加密&lt;br/&gt;（被认为不够安全，已经被弃用）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt; 数据库中密码被加密；&lt;br&gt;
 用户在login输入的密码使用相同的算法进行编码，在数据库使用PasswordEncoder的matches()方法进行比较。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt; ps：关于为什么认为StandardPasswordEncoder是不安全的：&lt;br&gt;
 目前有说法是认为SHA-256不够安全，因为SHA-256算法本身效率高，速度快，所以暴力破解门槛低。&lt;br&gt;
而bcrypt算法可以通过参数调节计算速度，计算速度慢，所以大幅提高了暴力破解的门槛，安全性也就高了&lt;br&gt;
（但是目前SHA-256还未被成功破解过……？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="userdetailsservice实现"&gt;UserDetailsService实现：
&lt;/h2&gt;&lt;p&gt;Spring Security提供了几个开箱即用的UserDetailsService实现：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;基于内存的用户存储&lt;/li&gt;
&lt;li&gt;基于JDBC的用户存储&lt;/li&gt;
&lt;li&gt;由LDAP支持的用户存储&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;span class="lnt"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;/*&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;loadUserByUsername&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="err"&gt;方法接受用户名并使用它查找&lt;/span&gt;&lt;span class="n"&gt;UserDetails对象&lt;/span&gt;&lt;span class="err"&gt;。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="err"&gt;如果找不到给定用户名的用户，则抛出&lt;/span&gt;&lt;span class="n"&gt;UsernameNotFoundException异常&lt;/span&gt;&lt;span class="err"&gt;。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;*/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;public&lt;/span&gt; &lt;span class="n"&gt;interface&lt;/span&gt; &lt;span class="n"&gt;UserDetailsService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;UserDetails&lt;/span&gt; &lt;span class="n"&gt;loadUserByUsername&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ne"&gt;String&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;throws&lt;/span&gt; &lt;span class="n"&gt;UsernameNotFoundException&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="securing-web-requests"&gt;Securing web requests
&lt;/h2&gt;&lt;p&gt; authorizeRequests()返回(ExpressionUrlAuthorizationConfigurer.ExpressionInterceptUrlRegistry)对象，允许指定URL路径和模式，以及路径对应的安全要求：&lt;br&gt;
 书中项目的代码实现如下：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/*
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; *保证对于/design 和 /orders路径的请求只对认证的用户有效；
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; *其他路径对于所有的用户有效；
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; */
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;@Bean
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; return http
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; .authorizeRequests()
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; .antMatchers(&amp;#34;/design&amp;#34;, &amp;#34;/orders&amp;#34;).hasRole(&amp;#34;USER&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; .antMatchers(&amp;#34;/&amp;#34;, &amp;#34;/**&amp;#34;).permitAll()
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; .and()
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; .build();
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt; Spring web requests的配置方法，以及如何保护路径如下：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: center"&gt;方法&lt;/th&gt;
&lt;th style="text-align: center"&gt;作用&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;access(String)&lt;/td&gt;
&lt;td style="text-align: center"&gt;如果给定的Spring Expression Language(SpEL)表达式求值为true，允许访问&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;anonymous()&lt;/td&gt;
&lt;td style="text-align: center"&gt;允许匿名用户访问&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;authenticated()&lt;/td&gt;
&lt;td style="text-align: center"&gt;允许通过验证的用户访问&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;denyAll()&lt;/td&gt;
&lt;td style="text-align: center"&gt;无条件拒绝所有访问&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;fullyAuthenticated()&lt;/td&gt;
&lt;td style="text-align: center"&gt;允许通过完全身份验证的用户访问（不推荐）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;hasAnyAuthority(String&amp;hellip;)&lt;/td&gt;
&lt;td style="text-align: center"&gt;如果用户具有任何一个给定的权限，则允许访问（可代替hasAnyRole(String)方法）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;hasAnyRole(String…)&lt;/td&gt;
&lt;td style="text-align: center"&gt;如果用户具有任何给定的角色，则允许访问&lt;br/&gt; （自动加 ROLE_ 的前缀）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;hasAuthority(String)&lt;/td&gt;
&lt;td style="text-align: center"&gt;如果用户具有指定的权限，则允许访问&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;hasRole(String)&lt;/td&gt;
&lt;td style="text-align: center"&gt;如果用户具有指定的角色，则允许访问&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;hasIpAddress(String)&lt;/td&gt;
&lt;td style="text-align: center"&gt;如果用户具有指定的IP地址，则允许访问&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;not()&lt;/td&gt;
&lt;td style="text-align: center"&gt;否定任何其他认证方法的效果&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;permitAll()&lt;/td&gt;
&lt;td style="text-align: center"&gt;无条件允许访问&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;rememberMe()&lt;/td&gt;
&lt;td style="text-align: center"&gt;允许通过 remember-me 进行身份验证的用户访问&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;这其中值得注意的事，hasRole()方法可以被hasAuthority()代替：hasRole()方法自动补足 &lt;strong&gt;ROLE_&lt;/strong&gt; 的前缀。&lt;/li&gt;
&lt;li&gt;设计上来看，一个是权限，一个是角色，角色是权限的集合体。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="spring-security对于spel表达式的扩展"&gt;Spring Security对于SpEL表达式的扩展
&lt;/h2&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: center"&gt;Security expression&lt;/th&gt;
&lt;th style="text-align: center"&gt;SpEL的计算结果&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;authentication&lt;/td&gt;
&lt;td style="text-align: center"&gt;用户的认证对象&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;denyAll&lt;/td&gt;
&lt;td style="text-align: center"&gt;恒为false&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;hasAnyAuthority(String&amp;hellip;authorities)&lt;/td&gt;
&lt;td style="text-align: center"&gt;如果用户被授予所有权限中的某一个，则为true&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;hasAnyRole(String&amp;hellip;roles)&lt;/td&gt;
&lt;td style="text-align: center"&gt;如果用户有给定的roles中的某一个，则为true&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;hasAnyAuthority(String authority)&lt;/td&gt;
&lt;td style="text-align: center"&gt;如果用户被授予指定的权限，则为true&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;hasPermission(Object target, Object permission)&lt;/td&gt;
&lt;td style="text-align: center"&gt;如果用户能以给定的权限访问指定的目标对象，则为true&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;hasRole(String role)&lt;/td&gt;
&lt;td style="text-align: center"&gt;如果用户有给定的role，则为true&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;hasIpAddress(String ipAddress)&lt;/td&gt;
&lt;td style="text-align: center"&gt;如果请求来自指定ip，则为true&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;isAnnoymous()&lt;/td&gt;
&lt;td style="text-align: center"&gt;如果用户是匿名的，则为true&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;isAuthenticated()&lt;/td&gt;
&lt;td style="text-align: center"&gt;如果用户已认证，则为true&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;isFullyAuthenticated()&lt;/td&gt;
&lt;td style="text-align: center"&gt;如果用户经过完全身份验证(没有使用remember-me进行身份验证)，则为true&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;isRememberMe()&lt;/td&gt;
&lt;td style="text-align: center"&gt;如果用户使用remeber-me进行身份验证，则为true&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;permitAll()&lt;/td&gt;
&lt;td style="text-align: center"&gt;恒为true&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;principal&lt;/td&gt;
&lt;td style="text-align: center"&gt;用户的主要对象&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;remember-me（记住我）认证，就是常见的记住我：下次登录时，使用cookie导致自动登录发生。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/*
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;*所以上面一节中的方法，可以用access()方法+security表达式的方式来实现；
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;*/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;@Bean
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; return http
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; .authorizeRequests()
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; .antMatchers(&amp;#34;/design&amp;#34;, &amp;#34;/orders&amp;#34;).access(&amp;#34;hasRole(&amp;#39;USER&amp;#39;)&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; .antMatchers(&amp;#34;/&amp;#34;, &amp;#34;/**&amp;#34;).access(&amp;#34;permitAll()&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; .and()
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; .build();
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;如有遗漏或错误，欢迎补充纠正&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>2022年10月20日</title><link>http://www.jansonblog.com/p/2022-10/</link><pubDate>Thu, 20 Oct 2022 00:00:00 +0000</pubDate><guid>http://www.jansonblog.com/p/2022-10/</guid><description>&lt;img src="http://www.jansonblog.com/p/2022-10/1.jpg" alt="Featured image of post 2022年10月20日" /&gt;&lt;h2 id="近况"&gt;近况
&lt;/h2&gt;&lt;p&gt;  两个月没有更新博客，把最近的一些事，漫无目的的记录下来。&lt;/p&gt;
&lt;h2 id="1力扣"&gt;1.力扣
&lt;/h2&gt;&lt;p&gt; 力扣依旧在每日刷题，现在基本上看到题可以判断出是什么题型，但是最近对于做题仿佛失去了一些思考。明知道只做出来是不对的，但是还是懒得去思考。或许是因为研究过于不顺，导致自己每天没有余力去探索。&lt;br&gt;
 跟狗人和阿毛一起报名了力扣的一个什么比赛，六道题目，好像一个人四个小时。我和阿毛10分钟不到做完了1，2题，后面知道是dp但是没想出公式，加上那天后背的粉瘤爆炸，下午不得不赶在医院关门前去诊所，最后排名也就只能1000+的样子。&lt;br&gt;
 好消息：比赛赚了1k积分，能换力扣全家桶了。&lt;/p&gt;
&lt;h2 id="2学习"&gt;2.学习
&lt;/h2&gt;&lt;p&gt; LoRa网关真的很难搞，研究室没有人能帮，只能自己硬着头皮，顶着压力一点一点来。&lt;br&gt;
 今天抱着试试的态度跟一个台湾的公司联络了一下，居然一个小时就收到了回信，虽然很简短，但是给了看起来有用的文档。看了一眼文档，前路漫漫，比想象中的要困难。进度一拖再拖，没有进展。&lt;/p&gt;
&lt;h2 id="3掘金"&gt;3.掘金
&lt;/h2&gt;&lt;p&gt; 最大的收获应该是认识了掘金的小伙伴。安安，小安，小鱼，鑫，master。一个很不错的小圈子。&lt;br&gt;
 其中印象最深，聊的最多的是安安。安安是莱州的老乡。安安看着外表搞笑坚强，但是自述有些抑郁。我呢？我应该并不抑郁，不过在日本留学这几年，我内心也是孤独的，我似乎能体会到她和阿毛当时考研时的孤独。她的经历我周围有很多人跟她相似，但是她是一个非常外向的人，内心痛苦会释放。&lt;/p&gt;
&lt;h2 id="4独白"&gt;4.独白
&lt;/h2&gt;&lt;p&gt; 安安是一个让我有时候会羡慕的人，因为她知道自己喜欢什么。而我，像王小波说的那样，原文我并不记得了，大概意思是：20岁是最迷茫的年龄，因为一个人要决定自己以后做什么。&lt;br&gt;
 我又想做什么呢？自学了Java或许是出于一种喜爱，又或是承诺的履行？因为好像是有人跟我说可以学Java，但是我可能又是羡慕大一花旗那个保研清北的学长，因为在他口中Java是那么有趣。或许我确实对Java
有自己的喜爱，才能在尝试过那么多语言后选择Java。&lt;br&gt;
 总之，想起来一个亲戚跟我说的话：“现在的年轻人迷茫是因为可以选的路太多了，她们那个年代，没有那么多路，大家不知不觉进了一条路就坚持走到了最后”。所以尽量不去想自己的选择，做出了选择就不要后悔。&lt;/p&gt;</description></item><item><title>2022年8月生活日记</title><link>http://www.jansonblog.com/p/2022-08/</link><pubDate>Thu, 25 Aug 2022 00:00:00 +0000</pubDate><guid>http://www.jansonblog.com/p/2022-08/</guid><description>&lt;img src="http://www.jansonblog.com/p/2022-08/title.jpg" alt="Featured image of post 2022年8月生活日记" /&gt;&lt;h2 id="毕业季"&gt;毕业季
&lt;/h2&gt;&lt;p&gt; 学长要去LINE福冈工作了，走之前前一夜只睡了2个两小时，看着那状态实在不放心，陪他坐车到了新大阪去换乘新干线（最后还是等错了站台，改了票…）&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.jansonblog.com/p/2022-08/2.jpg"
width="1172"
height="1333"
srcset="http://www.jansonblog.com/p/2022-08/2_hu_7c492dc3e1350e1a.jpg 480w, http://www.jansonblog.com/p/2022-08/2_hu_1adc1f4e5552ca97.jpg 1024w"
loading="lazy"
alt="祝好"
class="gallery-image"
data-flex-grow="87"
data-flex-basis="211px"
&gt;&lt;/p&gt;
&lt;p&gt; 那会我跟学长都很喜欢吃咖喱&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.jansonblog.com/p/2022-08/15.jpg"
width="4032"
height="3024"
srcset="http://www.jansonblog.com/p/2022-08/15_hu_d3e4bf20e0daeddf.jpg 480w, http://www.jansonblog.com/p/2022-08/15_hu_879e95e699b93e29.jpg 1024w"
loading="lazy"
alt="经常去的一家印度咖喱店"
class="gallery-image"
data-flex-grow="133"
data-flex-basis="320px"
&gt;&lt;/p&gt;
&lt;h2 id="flag"&gt;flag！
&lt;/h2&gt;&lt;p&gt; 跟学长约定，我拿到offer或者回国之前一定会去福冈找他。&lt;br&gt;
 用了很久的头像，是福冈县神社的照片&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.jansonblog.com/p/2022-08/dream.jpg"
width="800"
height="534"
srcset="http://www.jansonblog.com/p/2022-08/dream_hu_99b681bdba94799a.jpg 480w, http://www.jansonblog.com/p/2022-08/dream_hu_deba01840ace0373.jpg 1024w"
loading="lazy"
alt="宮地嶽神社-福津市"
class="gallery-image"
data-flex-grow="149"
data-flex-basis="359px"
&gt; &lt;img src="http://www.jansonblog.com/p/2022-08/QQ.jpg"
width="639"
height="640"
srcset="http://www.jansonblog.com/p/2022-08/QQ_hu_ce041f4239ee66e1.jpg 480w, http://www.jansonblog.com/p/2022-08/QQ_hu_85c3e6a90ecc5726.jpg 1024w"
loading="lazy"
alt="用了四五年的头像"
class="gallery-image"
data-flex-grow="99"
data-flex-basis="239px"
&gt;&lt;/p&gt;
&lt;h2 id="大阪万博纪念公园"&gt;大阪万博纪念公园
&lt;/h2&gt;&lt;p&gt; 在送学长去大阪的路上临时决定要去大阪的表弟家玩几天，表弟刚考完阪大修士，也算是说走就走的旅行了。
&lt;img src="http://www.jansonblog.com/p/2022-08/3.jpg"
width="1280"
height="960"
srcset="http://www.jansonblog.com/p/2022-08/3_hu_83611d9d32449c0b.jpg 480w, http://www.jansonblog.com/p/2022-08/3_hu_3b97149e24dc1cc0.jpg 1024w"
loading="lazy"
alt="超大河豚"
class="gallery-image"
data-flex-grow="133"
data-flex-basis="320px"
&gt; &lt;img src="http://www.jansonblog.com/p/2022-08/4.jpg"
width="1280"
height="960"
srcset="http://www.jansonblog.com/p/2022-08/4_hu_e2819c23b7c1c6e9.jpg 480w, http://www.jansonblog.com/p/2022-08/4_hu_61d8154d9ce3d86e.jpg 1024w"
loading="lazy"
alt="万博公园的摩天轮夜景"
class="gallery-image"
data-flex-grow="133"
data-flex-basis="320px"
&gt;&lt;/p&gt;
&lt;h2 id="天王寺あべのハルカス"&gt;天王寺——あべのハルカス
&lt;/h2&gt;&lt;p&gt; 天王寺的「あべのハルカス」是现在关西最高的ビル，入门券1500。&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.jansonblog.com/p/2022-08/14.jpg"
width="960"
height="1280"
srcset="http://www.jansonblog.com/p/2022-08/14_hu_4f2d155331ba2287.jpg 480w, http://www.jansonblog.com/p/2022-08/14_hu_107758a9c5b1ae10.jpg 1024w"
loading="lazy"
alt="あべのハルカス"
class="gallery-image"
data-flex-grow="75"
data-flex-basis="180px"
&gt; &lt;img src="http://www.jansonblog.com/p/2022-08/9.jpg"
width="1280"
height="960"
srcset="http://www.jansonblog.com/p/2022-08/9_hu_c8a53742684221b5.jpg 480w, http://www.jansonblog.com/p/2022-08/9_hu_7fb555d8c0e0d9ff.jpg 1024w"
loading="lazy"
alt="看到海就想家了"
class="gallery-image"
data-flex-grow="133"
data-flex-basis="320px"
&gt;&lt;/p&gt;
&lt;p&gt; 看了个日落和夜景。&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.jansonblog.com/p/2022-08/7.jpg"
width="1280"
height="960"
srcset="http://www.jansonblog.com/p/2022-08/7_hu_81ff2fc4a1f4439c.jpg 480w, http://www.jansonblog.com/p/2022-08/7_hu_cbae7ea973bb2b3e.jpg 1024w"
loading="lazy"
alt="白天"
class="gallery-image"
data-flex-grow="133"
data-flex-basis="320px"
&gt; &lt;img src="http://www.jansonblog.com/p/2022-08/8.jpg"
width="960"
height="1280"
srcset="http://www.jansonblog.com/p/2022-08/8_hu_1f8fa52f7e475143.jpg 480w, http://www.jansonblog.com/p/2022-08/8_hu_1d7b2bf684b1ff81.jpg 1024w"
loading="lazy"
alt="夜景"
class="gallery-image"
data-flex-grow="75"
data-flex-basis="180px"
&gt;&lt;/p&gt;
&lt;p&gt; 之前研究室日本人曾经跟我说过，大阪北部和南部差别很大，南边犯罪率高，治安很差&lt;br&gt;
 北边高楼耸立，南边除了几个大型公园，几乎没有高层建筑(照片可能拍的位置不太对）&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.jansonblog.com/p/2022-08/10.jpg"
width="1280"
height="960"
srcset="http://www.jansonblog.com/p/2022-08/10_hu_ce1b02ce35e0e4f3.jpg 480w, http://www.jansonblog.com/p/2022-08/10_hu_3efa413488b6cc28.jpg 1024w"
loading="lazy"
alt="应该是大阪南部"
class="gallery-image"
data-flex-grow="133"
data-flex-basis="320px"
&gt; &lt;img src="http://www.jansonblog.com/p/2022-08/11.jpg"
width="1280"
height="960"
srcset="http://www.jansonblog.com/p/2022-08/11_hu_8c439958f765f8a8.jpg 480w, http://www.jansonblog.com/p/2022-08/11_hu_cdd35e9d79ecb5d.jpg 1024w"
loading="lazy"
alt="这个应该是西边"
class="gallery-image"
data-flex-grow="133"
data-flex-basis="320px"
&gt;&lt;/p&gt;
&lt;p&gt; 非常经典的一幕，天王寺动物园车站北侧有一个看着很怪的会馆，应该是基督教会馆，但这外观看着像个邪教…&lt;br&gt;
 车站南侧更诡异，走过来的时候路上很吓人，照片都没好意思拍，也可能那边的人看着吓人吧。不过在动物园周围看到了很多涂鸦的垃圾箱和流浪汉…在日本有涂鸦的话，治安应该是很差的…&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.jansonblog.com/p/2022-08/5.jpg"
width="1280"
height="960"
srcset="http://www.jansonblog.com/p/2022-08/5_hu_bae7fff5177d045a.jpg 480w, http://www.jansonblog.com/p/2022-08/5_hu_c4f8fd4995ff4343.jpg 1024w"
loading="lazy"
alt="奇怪的会馆"
class="gallery-image"
data-flex-grow="133"
data-flex-basis="320px"
&gt;&lt;/p&gt;
&lt;h2 id="小动物"&gt;小动物
&lt;/h2&gt;&lt;p&gt;&lt;img src="http://www.jansonblog.com/p/2022-08/6.jpg"
width="1280"
height="960"
srcset="http://www.jansonblog.com/p/2022-08/6_hu_f7ba362e2b7518be.jpg 480w, http://www.jansonblog.com/p/2022-08/6_hu_7d0720fdd5cc36a6.jpg 1024w"
loading="lazy"
alt="小家伙虽然可恨，但是也蛮可爱的"
class="gallery-image"
data-flex-grow="133"
data-flex-basis="320px"
&gt; &lt;img src="http://www.jansonblog.com/p/2022-08/18.jpg"
width="4032"
height="3024"
srcset="http://www.jansonblog.com/p/2022-08/18_hu_af08db71a775813b.jpg 480w, http://www.jansonblog.com/p/2022-08/18_hu_d843b7bf597a9916.jpg 1024w"
loading="lazy"
alt="带眼妆的鱼"
class="gallery-image"
data-flex-grow="133"
data-flex-basis="320px"
&gt;&lt;/p&gt;
&lt;h2 id="姬路城"&gt;姬路城
&lt;/h2&gt;&lt;p&gt; 最后一天去了姬路城，路上有一段靠海，风景很不错&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.jansonblog.com/p/2022-08/13.jpg"
width="1280"
height="960"
srcset="http://www.jansonblog.com/p/2022-08/13_hu_1081e1c011bb72a6.jpg 480w, http://www.jansonblog.com/p/2022-08/13_hu_77099fd75c01c271.jpg 1024w"
loading="lazy"
alt="明石海峡大桥"
class="gallery-image"
data-flex-grow="133"
data-flex-basis="320px"
&gt; &lt;img src="http://www.jansonblog.com/p/2022-08/17.jpg"
width="4032"
height="3024"
srcset="http://www.jansonblog.com/p/2022-08/17_hu_f64f6210ce4bcc53.jpg 480w, http://www.jansonblog.com/p/2022-08/17_hu_bedffe5277316dc4.jpg 1024w"
loading="lazy"
alt="最喜欢的一张照片"
class="gallery-image"
data-flex-grow="133"
data-flex-basis="320px"
&gt;&lt;/p&gt;
&lt;p&gt; 姬路城确实比关西其他城堡好玩很多&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.jansonblog.com/p/2022-08/12.jpg"
width="1280"
height="960"
srcset="http://www.jansonblog.com/p/2022-08/12_hu_f1ba8af2d8a9993a.jpg 480w, http://www.jansonblog.com/p/2022-08/12_hu_63e1944b7b2179d6.jpg 1024w"
loading="lazy"
alt="城里有六层，很壮观"
class="gallery-image"
data-flex-grow="133"
data-flex-basis="320px"
&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;不愿清醒，宁愿一直沉迷放纵。不知归路，宁愿一世无悔追逐。&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>Spring学习之路（二）</title><link>http://www.jansonblog.com/p/spring2/</link><pubDate>Mon, 15 Aug 2022 00:00:00 +0000</pubDate><guid>http://www.jansonblog.com/p/spring2/</guid><description>&lt;img src="http://www.jansonblog.com/p/spring2/1.jpg" alt="Featured image of post Spring学习之路（二）" /&gt;&lt;h2 id="模板引擎"&gt;模板引擎
&lt;/h2&gt;&lt;p&gt;书中总结了以下模板：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: center"&gt;模板&lt;/th&gt;
&lt;th style="text-align: center"&gt;Spring Boot starter依赖&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;JavaServer Pages(JSP)&lt;/td&gt;
&lt;td style="text-align: center"&gt;无(由Tomcat或Jetty提供)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;FreeMarker&lt;/td&gt;
&lt;td style="text-align: center"&gt;spring-boot-starter-freemarker&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;Groovy Templates&lt;/td&gt;
&lt;td style="text-align: center"&gt;spring-boot-starter-groovy-templates&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;Mustache&lt;/td&gt;
&lt;td style="text-align: center"&gt;spring-boot-starter-mustache&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;Thymeleaf&lt;/td&gt;
&lt;td style="text-align: center"&gt;spring-boot-starter-thymeleaf&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;其中，JSP不需要依赖的原因:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;是因为Servlet容器本身（默认是Tomcat）会实现JSP，因此不需要额外的依赖。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;使用JSP问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Java Servlet容器包括嵌入式的Tomcat和Jetty容器，通常会在“/WEB-INF”目录下寻找JSP。如果将应用构建成一个可执行的JAR文件，就无法满足这种需求；&lt;strong&gt;只有在将应用构建成WAR文件并部署到Servlet容器中时&lt;/strong&gt;，才能选择JSP方案。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="模板缓存"&gt;模板缓存
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;默认情况下，模板只有在&lt;strong&gt;第⼀次使用的时候解析⼀次&lt;/strong&gt;，解析的结果会被后续的请求所使⽤。开发期缓存存在时，想要看到变更效果，必须重新启动应用，非常不方便&lt;/li&gt;
&lt;li&gt;禁用模板缓存：将相关缓存属性设成false:在application.properties中添加：
&lt;code&gt;spring.thymeleaf.cache=false&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: center"&gt;模板&lt;/th&gt;
&lt;th style="text-align: center"&gt;启用缓存的属性&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;FreeMarker&lt;/td&gt;
&lt;td style="text-align: center"&gt;spring.freemarker.cache&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;Groovy Templates&lt;/td&gt;
&lt;td style="text-align: center"&gt;spring.groovy.template.cache&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;Mustache&lt;/td&gt;
&lt;td style="text-align: center"&gt;spring.mustache.cache&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;Thymeleaf&lt;/td&gt;
&lt;td style="text-align: center"&gt;spring.thymeleaf.cache&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="thymeleaf模板"&gt;Thymeleaf模板
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Thymeleaf 模板只是 HTML 与一些额外的元素属性，指导模板在渲染请求数据。&lt;/p&gt;
&lt;p&gt; &lt;em&gt;例如，如果有一个请求属性，它的键是 “message”，你希望它被Thymeleaf渲染成一个&lt;code&gt;HTML&amp;lt;p&amp;gt;&lt;/code&gt;标签，你可以在你的Thymeleaf模板中写以下内容：&lt;/em&gt;&lt;br&gt;
&lt;code&gt;&amp;lt;p th:text=&amp;quot;${message}&amp;quot;&amp;gt;placeholder message&amp;lt;/p&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Thymeleaf 提供了一个内置的field.hasErrors方法，该方法根据给定字段是否存在任何错误返回一个布尔值。&lt;br&gt;
 例如要在一个信用卡号字段上显示验证错误：&lt;br&gt;
&lt;code&gt;&amp;lt;label for=&amp;quot;ccNumber&amp;quot;&amp;gt;Credit Card #: &amp;lt;/label&amp;gt;·&lt;/code&gt;&lt;br&gt;
&lt;code&gt;&amp;lt;input type=&amp;quot;text&amp;quot; th:field=&amp;quot;*{ccNumber}&amp;quot;/&amp;gt;&lt;/code&gt;&lt;br&gt;
&lt;code&gt;&amp;lt;span class=&amp;quot;validationError&amp;quot;&lt;/code&gt; &lt;br&gt;
&lt;code&gt;th:if=&amp;quot;${#fields.hasErrors('ccNumber')}&amp;quot;&lt;/code&gt; &lt;br&gt;
&lt;code&gt;th:errors=&amp;quot;*{ccNumber}&amp;quot;&amp;gt;CC Num Error&amp;lt;/span&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;如有遗漏或错误，欢迎补充纠正&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>Spring学习之路（一）</title><link>http://www.jansonblog.com/p/spring1/</link><pubDate>Sat, 13 Aug 2022 00:00:00 +0000</pubDate><guid>http://www.jansonblog.com/p/spring1/</guid><description>&lt;img src="http://www.jansonblog.com/p/spring1/1.jpg" alt="Featured image of post Spring学习之路（一）" /&gt;&lt;h2 id="前言"&gt;前言
&lt;/h2&gt;&lt;p&gt; 学习路程是按照&lt;a class="link" href="https://zh.jp1lib.org/book/18238678/2d772e" title="Spring实战（第五版）"
target="_blank" rel="noopener"
&gt;Spring实战（第五版）&lt;/a&gt;进行，本系列只针对笔者自己进行内容总结，用于加深学习以及日后回顾使用。如感兴趣，推荐阅读参考图书进行学习。&lt;/p&gt;
&lt;p&gt; 书中有较多地方描述比较不清楚，实战时，存在很多问题。&lt;a class="link" href="https://github.com/habuma/spring-in-action-5-samples" title="spring-in-action-5-samples"
target="_blank" rel="noopener"
&gt;spring-in-action-5-samples&lt;/a&gt;对书中每一章项目进行了汇总，对照此仓库学习更容易理解。&lt;/p&gt;
&lt;h2 id="spring项目结构"&gt;Spring项目结构
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;mvnw和mvnw.cmd：这是Maven包装器（wrapper）脚本，借助脚本，即使没有安装Maven也可以构建项目&lt;/li&gt;
&lt;li&gt;pom.xml： Maven构建规范，用于引入依赖等&lt;/li&gt;
&lt;li&gt;Application.java：SpringBoot主类&lt;/li&gt;
&lt;li&gt;application.properties：初始为空，用来指定配置属性&lt;/li&gt;
&lt;li&gt;static：初始为空，用于存放静态内容（图片，样式表，JavaScript等）&lt;/li&gt;
&lt;li&gt;templates：初始为空，用于存放渲染内容到浏览器的模板文件&lt;/li&gt;
&lt;li&gt;ApplicationTests.java：简单的测试类，确保Spring应用上下文成功加载&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="springbootapplication组合注解"&gt;@SpringBootApplication组合注解
&lt;/h2&gt;&lt;p&gt;@SpringBootApplication是一个组合注解，它组合了3个其他的注释：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;@SpringBootConfiguration：将该类声明为配置类。尽管这个类⽬前还没有太多的配置，但是后续我们可以按需添加基于Java的Spring框架配置。这个注解实际上是@Configuration注解的特殊形式。&lt;/li&gt;
&lt;li&gt;@EnableAutoConfiguration：启⽤Spring Boot的⾃动配置。我们随后会介绍⾃动配置的更多功能。就现在来说，我们只需要知道这个注解会告诉Spring Boot⾃动配置它认为我们会⽤到的组件。&lt;/li&gt;
&lt;li&gt;@ComponentScan：启⽤组件扫描。这样我们能够通过像@Component、 @Controller、@Service这样的注解声明其他类，Spring会⾃动发现它们并将它们注册为Spring应⽤上下⽂中的组件&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="spring的一些重点项目"&gt;Spring的一些重点项目：
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Spring MVC——Spring的Web框架：可以边写控制器处理Web请求；创建REST API，生成非HTML的输出&lt;/li&gt;
&lt;li&gt;Spring Boot：starter依赖和自动配置；Actuator能洞察应用运行时的内部工作状况；灵活的环境属性规范；在核心框架的测试辅助功能之上提供了对测试的额外支持&lt;/li&gt;
&lt;li&gt;Spring Data：将应用程序数据repository定义为java接口，定义驱动存储和检索数据的方法时使用一种命名约定即可；能够处理不同类型的数据库，包括关系型数据库（JPA）、文档数据库（Mongo）、图数据库（Neo4j）等&lt;/li&gt;
&lt;li&gt;Spring Security：Spring的安全框架，解决了身份验证、授权和API安全性等安全性需求&lt;/li&gt;
&lt;li&gt;Spring Integration：解决实时集成问题，数据在可用时马上就会得到处理&lt;/li&gt;
&lt;li&gt;Spring Batch：批处理集成问题——数据收集一段时间，直到触发触发器，才进行批处理&lt;/li&gt;
&lt;li&gt;Spring Cloud：使用Spring开发云原生应用程序的项目&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;如有遗漏或错误，欢迎补充纠正&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>如何使用git</title><link>http://www.jansonblog.com/p/git/</link><pubDate>Tue, 09 Aug 2022 00:00:00 +0000</pubDate><guid>http://www.jansonblog.com/p/git/</guid><description>&lt;img src="http://www.jansonblog.com/p/git/git.jpg" alt="Featured image of post 如何使用git" /&gt;&lt;h2 id="基本操作"&gt;基本操作
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git init // 初始化仓库，生成.git目录
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git status // 查看仓库的状态，显示目前分支，以及有没有可疑提交的内容
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git add 要添加的文件 // 向暂存区添加文件
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git commit // 执行启动编辑器，可以记述更加详细的信息
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git commit -m &amp;#34;本次的提交注释&amp;#34;// 添加对提交的概述；
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git commit --amend // 修改上一条提交信息
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git log // 查看提交日志
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git log --pretty=short // 显示第一行简述信息
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git log 文件名或目录名 //显示指定文件的日志
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git log -p // 查看提交带来的变动，显示文件前后差别
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git log -p 文件名或目录名 //查看指定文件的变动
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git reflog // 查看当前仓库执行过的操作的日志
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git diff // 查看当前工作树与暂存区的差别
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git diff HEAD // 查看与最新提交的差别，在git commit前执行这条命令是个好习惯
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="分支的操作"&gt;分支的操作
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git branch // 显示分支一览表
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git checkout -b 新分支名 // 创建并切换到新的分支；
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/以上命令与“git branch 新分支名”，再执行“git git checkout 新分支名”效果相同/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git checkout 分支名 // 切换到分支
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git checkout - // 切换到上一个分支
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git merge // 合并分支
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git merge --no-ff A // 将分支A合并到当前分支，并启动编辑器录入合并提交的信息
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git log --graph // 以图表形式查看分支
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="更改提交的操作"&gt;更改提交的操作
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/使用git reflog 查看仓库日志，第一列为时间哈希值/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git reset // 回溯历史版本
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git reset --hard 目标时间点的哈希值 // 恢复到时间点的状态，
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="推送至远程仓库"&gt;推送至远程仓库
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;span class="lnt"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;// 将远程仓库的名称设置为origin（标识符）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git remote add origin git@github.com:用户名/git-tutorial.git
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git remote -v // 查看当前远程仓库
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git push // 推送至远程仓库
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git push -u origin master // 将当前分支内容推送给远程仓库origin的master分支；
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;// -u参数在推送的同时，将origin仓库的master分支设置为本地仓库当前分支的upstream（上游）,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;// 运行git pull 命令，本地仓库的这个分支可以直接从origin的master分支获取内容
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="从远程仓库获取"&gt;从远程仓库获取
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git clone // 将github仓库clone到本地，注意不要与之前操作的仓库在同一目录下
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git checkout -b A origin/A //以远程仓库分支A为来源，在本地新建分支A
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git pull // 获取最新的远程仓库分支
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="其他深入理解git的资料"&gt;其他深入理解Git的资料
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Pro Git (零基础的git学习资料)&lt;/li&gt;
&lt;li&gt;LearnGitBranching (学习git基本操作的网站)&lt;/li&gt;
&lt;li&gt;tryGit (只有英文版的网站)&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;如有遗漏或错误，欢迎补充纠正&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>2022年7月散记</title><link>http://www.jansonblog.com/p/2022-07/</link><pubDate>Thu, 04 Aug 2022 00:00:00 +0000</pubDate><guid>http://www.jansonblog.com/p/2022-07/</guid><description>&lt;img src="http://www.jansonblog.com/p/2022-07/1.jpg" alt="Featured image of post 2022年7月散记" /&gt;&lt;h2 id="美景"&gt;美景
&lt;/h2&gt;&lt;p&gt;&lt;img src="http://www.jansonblog.com/p/2022-07/1.jpg"
width="1280"
height="960"
srcset="http://www.jansonblog.com/p/2022-07/1_hu_805871bae47c9f2d.jpg 480w, http://www.jansonblog.com/p/2022-07/1_hu_3ba5c6d79b81d89c.jpg 1024w"
loading="lazy"
alt="周末骑车去了琵琶湖"
class="gallery-image"
data-flex-grow="133"
data-flex-basis="320px"
&gt; &lt;img src="http://www.jansonblog.com/p/2022-07/2.jpg"
width="1280"
height="960"
srcset="http://www.jansonblog.com/p/2022-07/2_hu_52d5aa1d8c0091.jpg 480w, http://www.jansonblog.com/p/2022-07/2_hu_c7e389f7220871f2.jpg 1024w"
loading="lazy"
alt="大津市长雕像旁边的名言"
class="gallery-image"
data-flex-grow="133"
data-flex-basis="320px"
&gt;&lt;/p&gt;
&lt;h2 id="研究室那些事儿"&gt;研究室那些事儿
&lt;/h2&gt;&lt;p&gt;&lt;img src="http://www.jansonblog.com/p/2022-07/6.jpg"
width="720"
height="1280"
srcset="http://www.jansonblog.com/p/2022-07/6_hu_551bdc21a7e1c36e.jpg 480w, http://www.jansonblog.com/p/2022-07/6_hu_6e0120e9c2738f85.jpg 1024w"
loading="lazy"
alt="裤子上挂伞，日本人真有你的"
class="gallery-image"
data-flex-grow="56"
data-flex-basis="135px"
&gt; &lt;img src="http://www.jansonblog.com/p/2022-07/7.jpg"
width="960"
height="1280"
srcset="http://www.jansonblog.com/p/2022-07/7_hu_51c5863c64ddfbdf.jpg 480w, http://www.jansonblog.com/p/2022-07/7_hu_e8abb9747134049d.jpg 1024w"
loading="lazy"
alt="教授办公室门前的仙人掌是真的长~"
class="gallery-image"
data-flex-grow="75"
data-flex-basis="180px"
&gt;&lt;/p&gt;
&lt;h2 id="又吃啥了"&gt;又吃啥了
&lt;/h2&gt;&lt;p&gt;&lt;img src="http://www.jansonblog.com/p/2022-07/4.jpg"
width="1280"
height="960"
srcset="http://www.jansonblog.com/p/2022-07/4_hu_eeb4fe9371b41552.jpg 480w, http://www.jansonblog.com/p/2022-07/4_hu_ca2d03ed117352de.jpg 1024w"
loading="lazy"
alt="什么梅子冷面，看着好看，但是味道很一般"
class="gallery-image"
data-flex-grow="133"
data-flex-basis="320px"
&gt; &lt;img src="http://www.jansonblog.com/p/2022-07/5.jpg"
width="1280"
height="960"
srcset="http://www.jansonblog.com/p/2022-07/5_hu_83bad04510663b2a.jpg 480w, http://www.jansonblog.com/p/2022-07/5_hu_1117d4d5051e2b72.jpg 1024w"
loading="lazy"
alt="印度人开的咖喱店，店里不开空调又热的够呛"
class="gallery-image"
data-flex-grow="133"
data-flex-basis="320px"
&gt;&lt;/p&gt;
&lt;h2 id="生活"&gt;生活
&lt;/h2&gt;&lt;p&gt;&lt;img src="http://www.jansonblog.com/p/2022-07/8.jpg"
width="591"
height="1280"
srcset="http://www.jansonblog.com/p/2022-07/8_hu_6c39bf0ae9a26219.jpg 480w, http://www.jansonblog.com/p/2022-07/8_hu_eec9c12fdce8b7f0.jpg 1024w"
loading="lazy"
alt="周董新专辑！"
class="gallery-image"
data-flex-grow="46"
data-flex-basis="110px"
&gt; &lt;img src="http://www.jansonblog.com/p/2022-07/9.jpg"
width="591"
height="1280"
srcset="http://www.jansonblog.com/p/2022-07/9_hu_13c3a548307253.jpg 480w, http://www.jansonblog.com/p/2022-07/9_hu_f5e1292497b4f9cd.jpg 1024w"
loading="lazy"
alt="记录一下历史，21世纪了还能有政客被枪杀"
class="gallery-image"
data-flex-grow="46"
data-flex-basis="110px"
&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;祝你今天愉快，你明天的愉快留着我明天再祝。&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>动态规划(Dynamic programming)问题解法</title><link>http://www.jansonblog.com/p/dp/</link><pubDate>Fri, 27 May 2022 00:00:00 +0000</pubDate><guid>http://www.jansonblog.com/p/dp/</guid><description>&lt;img src="http://www.jansonblog.com/p/dp/PascalTriangleFibanacci.jpg" alt="Featured image of post 动态规划(Dynamic programming)问题解法" /&gt;&lt;p&gt;动态规划实现有两种方法：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;自下而上        (制表)&lt;/li&gt;
&lt;li&gt;自上而下        (记忆化)&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="自下而上"&gt;自下而上
&lt;/h2&gt;&lt;p&gt;自下而上是通过 &lt;em&gt;迭代&lt;/em&gt; 实现的&lt;/p&gt;
&lt;p&gt;以&lt;strong&gt;斐波那契数列&lt;/strong&gt;为例，F(0)=0, F(1)=1。通过F(0)和F(1)计算F(2)，然后使用计算结果计算F(3)…&lt;/p&gt;
&lt;p&gt;以此类推，一直计算F(n)&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;// 伪代码如下:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;F = array of length (n + 1)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;F[0] = 0
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;F[1] = 1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;for i from 2 to n:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; F[i] = F[i - 1] + F[i - 2]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="自上而下"&gt;自上而下
&lt;/h2&gt;&lt;p&gt;自上而下通过 &lt;em&gt;递归&lt;/em&gt; 实现，并且通过 &lt;em&gt;记忆化&lt;/em&gt; 提高效率(之后解释记忆化概念)&lt;/p&gt;
&lt;p&gt;如果我们想知道斐波那契数列F(n)，需要找到F(n-1)和F(n-2)…通过递归求出F(0)和F(1)&lt;/p&gt;
&lt;p&gt;缺点也很明显，在计算中存在大量的 重复计算 ，导致效率不高&lt;/p&gt;
&lt;p&gt;而解决方法也很简单，用空间换时间，也就是 &lt;em&gt;记忆化&lt;/em&gt; ：将函数调用的结果存储在哈希图或数组中，这样当再次进行相同的函数调用时，我们可以简单地返回记忆的结果，而不是重新计算结果。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;span class="lnt"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;//伪代码如下:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;memo = hashmap
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Function F(integer i):
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; if i is 0 or 1:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; return i
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; if i doesn&amp;#39;t exist in memo:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; memo[i] = F(i - 1) + F(i - 2)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; return memo[i]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="总结"&gt;总结
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;所以，这两个算法哪个更好呢？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;DP(动态规划问题)可以用任意一种方法实现&lt;/p&gt;
&lt;p&gt;每个方法都有一个突出的优点:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;自下而上的运行速度更快    (递归效率低)&lt;/li&gt;
&lt;li&gt;自上而下的实现更简单        (因为对于递归来说，我们不用在意子问题的逻辑顺序，而对于自下而上的方法来说，我们需要解决子问题的逻辑顺序)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;比较简单而且经典的题目：&lt;a class="link" href="https://leetcode.cn/problems/unique-paths/" title="《力扣 62.不同路径》"
target="_blank" rel="noopener"
&gt;《力扣 62.不同路径》&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;学习资料如下:&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://leetcode.com/explore/learn/card/dynamic-programming/630/an-introduction-to-dynamic-programming/4035/" title="Explore - LeetCode"
target="_blank" rel="noopener"
&gt;Explore - LeetCode&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;如有遗漏或错误，欢迎补充纠正&lt;/p&gt;
&lt;/blockquote&gt;</description></item></channel></rss>