文章列表

【Midjourney图片转指令】设计麻瓜也能5分钟一张商业海报

作者:微信小助手

<section style="margin: 0px 8px 16px;padding: 0px;color: rgb(51, 51, 51);font-family: mp-quote, -apple-system-font, &quot;system-ui&quot;, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 17px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;white-space: normal;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;text-align: center;" data-mpa-powered-by="yiban.io"> <img class="rich_pages wxw-img" data-cropselx1="0" data-cropselx2="562" data-cropsely1="0" data-cropsely2="134" data-galleryid="" data-ratio="0.23884758364312267" data-s="300,640" src="/upload/597e6bf04cdd0aba575a219540f20551.png" data-type="gif" data-w="1076" style="margin: 0px;padding: 0px;max-width: 100%;vertical-align: bottom;width: 100%;height: auto !important;"> </section> <section style="margin: 0px 8px 0em;padding: 0px;color: rgb(51, 51, 51);font-family: mp-quote, -apple-system-font, &quot;system-ui&quot;, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 17px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;white-space: normal;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;text-align: center;"> <img class="rich_pages wxw-img" data-backh="198" data-backw="562" data-cropselx1="0" data-cropselx2="562" data-cropsely1="0" data-cropsely2="198" data-galleryid="" data-ratio="0.35185185185185186" data-s="300,640" src="/upload/562649a0b5413d07ee440bb6f293b4ce.png" data-type="png" data-w="1080" style="margin: 0px;padding: 0px;max-width: 100%;height: auto;vertical-align: bottom;width: 100%;"> </section> <section style="margin-right: 8px;margin-bottom: 0px;margin-left: 8px;outline: 0px;font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(34, 34, 34);clear: both;min-height: 1em;caret-color: rgb(34, 34, 34);text-size-adjust: inherit;text-align: center;line-height: 27.2px;visibility: visible;"> <br> </section> <section style="margin-right: 8px;margin-bottom: 0px;margin-left: 8px;outline: 0px;font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(34, 34, 34);clear: both;min-height: 1em;caret-color: rgb(34, 34, 34);text-size-adjust: inherit;text-align: center;line-height: 27.2px;visibility: visible;"> <span style="outline: 0px;color: rgb(0, 0, 0);line-height: 27.2px;font-size: 18px;visibility: visible;"><strong mp-original-font-size="17" mp-original-line-height="27.200000762939453" style="outline: 0px;font-size: 17px;line-height: 27.2px;visibility: visible;"><span mp-original-font-size="17" mp-original-line-height="27.200000762939453" style="outline: 0px;font-size: 18px;white-space: pre-wrap;line-height: 27.2px;visibility: visible;">前言</span></strong></span> </section> <section style="margin-right: 8px;margin-bottom: 0px;margin-left: 8px;outline: 0px;font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;color: rgb(62, 62, 62);font-size: 16px;clear: both;min-height: 1em;text-size-adjust: inherit;background-color: rgb(255, 255, 255);text-align: center;line-height: 25.6px;visibility: visible;"> <span mp-original-font-size="20" mp-original-line-height="32" style="outline: 0px;letter-spacing: 0px;font-size: 20px;color: rgb(188, 38, 33);line-height: 32px;visibility: visible;">—</span> </section> <blockquote mp-original-font-size="16" mp-original-line-height="25.600000381469727" style="margin-top: 0px;margin-bottom: 30px;padding: 0.078rem 0.104rem;outline: 0px;border-left-width: 0.026rem;border-left-color: rgb(255, 255, 255);color: var(--weui-FG-1);font-family: system-ui, -apple-system, &quot;system-ui&quot;, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;line-height: 25.6px;text-size-adjust: inherit;quotes: none;background-color: rgb(250, 250, 250);font-style: italic;text-align: left;visibility: visible;"> <p style="margin: 16px;outline: 0px;font-style: normal;text-align: justify;font-size: 16px;color: rgb(102, 102, 102);font-family: &quot;PingFang SC&quot;, &quot;Lantinghei SC&quot;, &quot;Microsoft YaHei&quot;, &quot;HanHei SC&quot;, &quot;Helvetica Neue&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, 微软雅黑, STHeiti, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif;line-height: 1.75em;visibility: visible;"><span style="outline: 0px;color: rgb(62, 62, 62);font-family: PingFangSC-light;letter-spacing: 0.5px;caret-color: rgb(0, 0, 0);font-size: 15px;visibility: visible;">最近AI绘画的热度空前高涨,众多分享平台PO出的AI大作下方,都是清一色留言:“求咒语!”。可大多数童鞋对这苦苦求来的指令,都会产生一个疑惑:“同样的咒语,怎么到我手里画出来的就是一坨shit?难道是我阿瓦达啃大瓜的姿势不够骚?”</span></p> <p style="margin: 0px 16px 30px;outline: 0px;font-style: normal;text-align: justify;font-size: 16px;color: rgb(102, 102, 102);font-family: &quot;PingFang SC&quot;, &quot;Lantinghei SC&quot;, &quot;Microsoft YaHei&quot;, &quot;HanHei SC&quot;, &quot;Helvetica Neue&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, 微软雅黑, STHeiti, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif;line-height: 1.75em;visibility: visible;padding: 0.078rem 0.104rem;border-left-width: 0.026rem;border-left-color: rgb(255, 255, 255);letter-spacing: 0.544px;white-space: normal;text-size-adjust: inherit;quotes: none;background-color: rgb(250, 250, 250);"><span style="outline: 0px;color: rgb(62, 62, 62);font-family: PingFangSC-light;letter-spacing: 0.5px;caret-color: rgb(0, 0, 0);font-size: 15px;visibility: visible;">“一咒难求”、“无法精准施法”是当前Midjourney软件绘画的两大痛点!但就在前几天,Midjourney上线的describe命令,可以将图片反向生成绘画指令,大幅降低了学习咒语的成本,更是让设计麻瓜也能轻松玩转AI绘图!</span></p> </blockquote> <p style="margin-top: 16px;margin-bottom: 16px;outline: 0px;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(102, 102, 102);font-family: &quot;PingFang SC&quot;, &quot;Lantinghei SC&quot;, &quot;Microsoft YaHei&quot;, &quot;HanHei SC&quot;, &quot;Helvetica Neue&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, 微软雅黑, STHeiti, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif;font-size: 16px;line-height: 1.75em;visibility: visible;"><span style="outline: 0px;color: rgb(62, 62, 62);font-family: PingFangSC-light;font-size: 15px;letter-spacing: 0.5px;caret-color: rgb(0, 0, 0);visibility: visible;">接下来,就用一个简单的工作应用:“商业海报”为例,为大家展示一下这条咒语的妙用!就算你是设计小白,也能轻轻松松5分钟,搞定一张商业海报。<br></span></p> <article data-content="[{&quot;type&quot;:&quot;block&quot;,&quot;id&quot;:&quot;8jgo-1680782817495&quot;,&quot;name&quot;:&quot;paragraph&quot;,&quot;data&quot;:{&quot;version&quot;:1},&quot;nodes&quot;:[{&quot;type&quot;:&quot;text&quot;,&quot;id&quot;:&quot;a9dE-1680782817494&quot;,&quot;leaves&quot;:[{&quot;text&quot;:&quot;接下来,就用一个简单的工作应用:“商业海报”为例,为大家展示一下这条咒语的妙用!就算你是设计小白,也能轻轻松松5分钟,搞定一张商业海报。&quot;,&quot;marks&quot;:[{&quot;type&quot;:&quot;color&quot;,&quot;value&quot;:&quot;#525252&quot;},{&quot;type&quot;:&quot;backgroundColor&quot;,&quot;value&quot;:&quot;rgb(255,&nbsp;255,&nbsp;255)&quot;},{&quot;type&quot;:&quot;fontFamily&quot;,&quot;value&quot;:&quot;SimHei&quot;}]}]}]},{&quot;type&quot;:&quot;block&quot;,&quot;id&quot;:&quot;l3iU-1680793856430&quot;,&quot;name&quot;:&quot;paragraph&quot;,&quot;data&quot;:{&quot;version&quot;:1},&quot;nodes&quot;:[{&quot;type&quot;:&quot;text&quot;,&quot;id&quot;:&quot;NJ14-1680793856428&quot;,&quot;leaves&quot;:[{&quot;text&quot;:&quot;下方成果图,小编先干为敬:&quot;,&quot;marks&quot;:[{&quot;type&quot;:&quot;color&quot;,&quot;value&quot;:&quot;#525252&quot;},{&quot;type&quot;:&quot;backgroundColor&quot;,&quot;value&quot;:&quot;rgb(255,&nbsp;255,&nbsp;255)&quot;},{&quot;type&quot;:&quot;fontFamily&quot;,&quot;value&quot;:&quot;SimHei&quot;}]}]}]}]"> <article data-content="[{&quot;type&quot;:&quot;block&quot;,&quot;id&quot;:&quot;8jgo-1680782817495&quot;,&quot;name&quot;:&quot;paragraph&quot;,&quot;data&quot;:{&quot;version&quot;:1},&quot;nodes&quot;:[{&quot;type&quot;:&quot;text&quot;,&quot;id&quot;:&quot;a9dE-1680782817494&quot;,&quot;leaves&quot;:[{&quot;text&quot;:&quot;接下来,就用一个简单的工作应用:“商业海报”为例,为大家展示一下这条咒语的妙用!就算你是设计小白,也能轻轻松松5分钟,搞定一张商业海报。&quot;,&quot;marks&quot;:[{&quot;type&quot;:&quot;color&quot;,&quot;value&quot;:&quot;#525252&quot;},{&quot;type&quot;:&quot;backgroundColor&quot;,&quot;value&quot;:&quot;rgb(255,&nbsp;255,&nbsp;255)&quot;},{&quot;type&quot;:&quot;fontFamily&quot;,&quot;value&quot;:&quot;SimHei&quot;}]}]}]},{&quot;type&quot;:&quot;block&quot;,&quot;id&quot;:&quot;l3iU-1680793856430&quot;,&quot;name&quot;:&quot;paragraph&quot;,&quot;data&quot;:{&quot;version&quot;:1},&quot;nodes&quot;:[{&quot;type&quot;:&quot;text&quot;,&quot;id&quot;:&quot;NJ14-1680793856428&quot;,&quot;leaves&quot;:[{&quot;text&quot;:&quot;下方成果图,小编先干为敬:&quot;,&quot;marks&quot;:[{&quot;type&quot;:&quot;color&quot;,&quot;value&quot;:&quot;#525252&quot;},{&quot;type&quot;:&quot;backgroundColor&quot;,&quot;value&quot;:&quot;rgb(255,&nbsp;255,&nbsp;255)&quot;},{&quot;type&quot;:&quot;fontFamily&quot;,&quot;value&quot;:&quot;SimHei&quot;}]}]}]}]" style="margin-top: 16px;margin-bottom: 16px;outline: 0px;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(102, 102, 102);font-family: &quot;PingFang SC&quot;, &quot;Lantinghei SC&quot;, &quot;Microsoft YaHei&quot;, &quot;HanHei SC&quot;, &quot;Helvetica Neue&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, 微软雅黑, STHeiti, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif;font-size: 16px;line-height: 1.75em;visibility: visible;"> <p style="margin-top: 16px;margin-bottom: 16px;outline: 0px;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(102, 102, 102);font-family: &quot;PingFang SC&quot;, &quot;Lantinghei SC&quot;, &quot;Microsoft YaHei&quot;, &quot;HanHei SC&quot;, &quot;Helvetica Neue&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, 微软雅黑, STHeiti, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif;font-size: 16px;line-height: 1.75em;visibility: visible;"><span style="outline: 0px;color: rgb(62, 62, 62);font-family: PingFangSC-light;font-size: 15px;letter-spacing: 0.5px;caret-color: rgb(0, 0, 0);visibility: visible;">下方成果图,小编先干为敬:</span></p> <p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="1.4768518518518519" data-s="300,640" src="/upload/c16679c15f44d49f7d96f28d084d5cfe.png" data-type="png" data-w="1080" style=""></p> <article data-content="[{&quot;type&quot;:&quot;block&quot;,&quot;id&quot;:&quot;UXjo-1680783456107&quot;,&quot;name&quot;:&quot;heading&quot;,&quot;data&quot;:{&quot;level&quot;:&quot;h3&quot;,&quot;style&quot;:{}},&quot;nodes&quot;:[{&quot;type&quot;:&quot;text&quot;,&quot;id&quot;:&quot;jDWB-1680783456105&quot;,&quot;leaves&quot;:[{&quot;text&quot;:&quot;图片转“咒语”:describe命令的基础操作&quot;,&quot;marks&quot;:[{&quot;type&quot;:&quot;bold&quot;},{&quot;type&quot;:&quot;color&quot;,&quot;value&quot;:&quot;#000000&quot;},{&quot;type&quot;:&quot;backgroundColor&quot;,&quot;value&quot;:&quot;rgb(255,&nbsp;255,&nbsp;255)&quot;},{&quot;type&quot;:&quot;fontFamily&quot;,&quot;value&quot;:&quot;SimHei&quot;}]}]}]},{&quot;type&quot;:&quot;block&quot;,&quot;id&quot;:&quot;BNEz-1680781624256&quot;,&quot;name&quot;:&quot;paragraph&quot;,&quot;data&quot;:{&quot;version&quot;:1},&quot;nodes&quot;:[{&quot;type&quot;:&quot;text&quot;,&quot;id&quot;:&quot;PEI2-1680781624257&quot;,&quot;leaves&quot;:[{&quot;text&quot;:&quot;方法很简单,打开&nbsp;Midjourney应用(不会安装的童鞋请看公众号的上一片文章,详细介绍了Midjourney软件的安装&amp;入门教程)。&quot;,&quot;marks&quot;:[{&quot;type&quot;:&quot;color&quot;,&quot;value&quot;:&quot;#525252&quot;},{&quot;type&quot;:&quot;backgroundColor&quot;,&quot;value&quot;:&quot;rgb(255,&nbsp;255,&nbsp;255)&quot;},{&quot;type&quot;:&quot;fontSize&quot;,&quot;value&quot;:16},{&quot;type&quot;:&quot;fontFamily&quot;,&quot;value&quot;:&quot;SimHei&quot;}]}]}]},{&quot;type&quot;:&quot;block&quot;,&quot;id&quot;:&quot;dPsG-1680784888349&quot;,&quot;name&quot;:&quot;paragraph&quot;,&quot;data&quot;:{&quot;version&quot;:1},&quot;nodes&quot;:[{&quot;type&quot;:&quot;text&quot;,&quot;id&quot;:&quot;qqhk-1680784888347&quot;,&quot;leaves&quot;:[{&quot;text&quot;:&quot;在聊天栏中输入“/describe”命令,就可以得到一个图片上传窗口(图1),上传你选好的参考图(图2),它就会根据图片的内容,分析生成四段不同的prompts(图3)。&quot;,&quot;marks&quot;:[{&quot;type&quot;:&quot;color&quot;,&quot;value&quot;:&quot;#525252&quot;},{&quot;type&quot;:&quot;backgroundColor&quot;,&quot;value&quot;:&quot;rgb(255,&nbsp;255,&nbsp;255)&quot;},{&quot;type&quot;:&quot;fontSize&quot;,&quot;value&quot;:16},{&quot;type&quot;:&quot;fontFamily&quot;,&quot;value&quot;:&quot;SimHei&quot;}]}]}]}]"> <section powered-by="xiumi.us" mp-original-font-size="16" mp-original-line-height="25.600000381469727" style="margin: -10px 0em 0px;outline: 0px;color: rgb(102, 102, 102);font-family: &quot;PingFang SC&quot;, &quot;Lantinghei SC&quot;, &quot;Microsoft YaHei&quot;, &quot;HanHei SC&quot;, &quot;Helvetica Neue&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, 微软雅黑, STHeiti, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif;font-size: 16px;line-height: 25.6px;"> <section mp-original-font-size="28" mp-original-line-height="44.79999923706055" style="margin-right: 0em;margin-left: 0em;outline: 0px;font-size: 28px;line-height: 44.8px;"> <p style="outline: 0px;line-height: 44.8px;"><br></p> <p style="outline: 0px;line-height: 44.8px;"><br></p> <p style="outline: 0px;line-height: 44.8px;"><span style="outline: 0px;color: rgb(0, 0, 0);"><strong style="outline: 0px;">图片转“咒语”:describe命令的基础操作</strong></span><span style="outline: 0px;color: rgb(0, 0, 0);"><strong style="outline: 0px;"><span style="color: rgb(0, 0, 0);font-family: SimHei, STHeiti;font-size: 16px;font-weight: 700;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);"></span></strong></span></p> </section> </section> <section style="margin-bottom: 0px;outline: 0px;color: rgb(102, 102, 102);font-family: &quot;PingFang SC&quot;, &quot;Lantinghei SC&quot;, &quot;Microsoft YaHei&quot;, &quot;HanHei SC&quot;, &quot;Helvetica Neue&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, 微软雅黑, STHeiti, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif;font-size: 16px;transform-origin: left top;line-height: 25.6px;"> <section mp-original-font-size="16" mp-original-line-height="25.600000381469727" style="margin-right: 0em;margin-left: 0em;outline: 0px;text-align: left;justify-content: flex-start;display: flex;flex-flow: row nowrap;line-height: 25.6px;"> <section mp-original-font-size="16" mp-original-line-height="25.600000381469727" style="margin-right: 0em;margin-left: 0em;outline: 0px;display: inline-block;width: 23px;vertical-align: top;flex: 0 0 auto;height: auto;align-self: flex-start;line-height: 25.6px;"> <section powered-by="xiumi.us" mp-original-font-size="16" mp-original-line-height="25.600000381469727" style="margin-right: 0em;margin-bottom: 8px;margin-left: 0em;outline: 0px;line-height: 25.6px;"> <section mp-original-font-size="16" mp-original-line-height="25.600000381469727" style="margin-right: 0em;margin-left: 0em;outline: 0px;background-color: rgb(188, 38, 33);height: 3px;line-height: 25.6px;"> <br> </section> </section> </section> </section> </section> <p style="margin-top: 16px;margin-bottom: 16px;outline: 0px;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(102, 102, 102);font-family: &quot;PingFang SC&quot;, &quot;Lantinghei SC&quot;, &quot;Microsoft YaHei&quot;, &quot;HanHei SC&quot;, &quot;Helvetica Neue&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, 微软雅黑, STHeiti, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif;font-size: 16px;line-height: 1.75em;visibility: visible;"><span style="outline: 0px;color: rgb(62, 62, 62);font-family: PingFangSC-light;font-size: 15px;letter-spacing: 0.5px;caret-color: rgb(0, 0, 0);visibility: visible;">方法很简单,打开 Midjourney应用(不会安装的童鞋请看公众号的上一篇文章,详细介绍了Midjourney软件的安装&amp;入门教程)。</span></p> <p style="margin-top: 16px;margin-bottom: 16px;outline: 0px;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(102, 102, 102);font-family: &quot;PingFang SC&quot;, &quot;Lantinghei SC&quot;, &quot;Microsoft YaHei&quot;, &quot;HanHei SC&quot;, &quot;Helvetica Neue&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, 微软雅黑, STHeiti, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif;font-size: 16px;line-height: 1.75em;visibility: visible;"><span style="outline: 0px;color: rgb(62, 62, 62);font-family: PingFangSC-light;font-size: 15px;letter-spacing: 0.5px;caret-color: rgb(0, 0, 0);visibility: visible;">在聊天栏中输入“/describe”命令,就可以得到一个图片上传窗口(图1),上传你选好的参考图(图2),它就会根据图片的内容,分析生成四段不同的prompts(图3)。</span></p> <p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="1.712962962962963" data-s="300,640" src="/upload/6655328ac7c0895d2751644c82ce1268.png" data-type="png" data-w="1080" style=""></p> <article data-content="[{&quot;type&quot;:&quot;block&quot;,&quot;id&quot;:&quot;Dwqk-1680781882036&quot;,&quot;name&quot;:&quot;paragraph&quot;,&quot;data&quot;:{&quot;version&quot;:1},&quot;nodes&quot;:[{&quot;type&quot;:&quot;text&quot;,&quot;id&quot;:&quot;FlKU-1680781882035&quot;,&quot;leaves&quot;:[{&quot;text&quot;:&quot;接下来,让我们看一下这些指令的品质如何?&quot;,&quot;marks&quot;:[]}]}]},{&quot;type&quot;:&quot;block&quot;,&quot;id&quot;:&quot;FFDr-1680836230982&quot;,&quot;name&quot;:&quot;paragraph&quot;,&quot;data&quot;:{&quot;version&quot;:1},&quot;nodes&quot;:[{&quot;type&quot;:&quot;text&quot;,&quot;id&quot;:&quot;6p49-1680836230980&quot;,&quot;leaves&quot;:[{&quot;text&quot;:&quot;我选中3、4两条,翻译后比较一番,不仅描述了画面内容,连插画风格、画风、模仿的画师风格都表述了出来~选中一条指令即可立即执行绘画。(&quot;,&quot;marks&quot;:[]},{&quot;text&quot;:&quot;不得不说,这玩意儿,可比ChatGPT那个设计门外汉“香”多了……&quot;,&quot;marks&quot;:[{&quot;type&quot;:&quot;color&quot;,&quot;value&quot;:&quot;#525252&quot;},{&quot;type&quot;:&quot;backgroundColor&quot;,&quot;value&quot;:&quot;rgb(255,&nbsp;255,&nbsp;255)&quot;},{&quot;type&quot;:&quot;fontFamily&quot;,&quot;value&quot;:&quot;SimHei&quot;}]},{&quot;text&quot;:&quot;)&quot;,&quot;marks&quot;:[]}]}]}]" style="margin-top: 16px;margin-bottom: 16px;outline: 0px;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(102, 102, 102);font-family: &quot;PingFang SC&quot;, &quot;Lantinghei SC&quot;, &quot;Microsoft YaHei&quot;, &quot;HanHei SC&quot;, &quot;Helvetica Neue&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, 微软雅黑, STHeiti, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif;font-size: 16px;line-height: 1.75em;visibility: visible;"> <p style="margin-top: 16px;margin-bottom: 16px;outline: 0px;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(102, 102, 102);font-family: &quot;PingFang SC&quot;, &quot;Lantinghei SC&quot;, &quot;Microsoft YaHei&quot;, &quot;HanHei SC&quot;, &quot;Helvetica Neue&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, 微软雅黑, STHeiti, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif;font-size: 16px;line-height: 1.75em;visibility: visible;"><span style="outline: 0px;color: rgb(62, 62, 62);font-family: PingFangSC-light;font-size: 15px;letter-spacing: 0.5px;caret-color: rgb(0, 0, 0);visibility: visible;">接下来,让我们看一下这些指令的品质如何?</span></p> <p style="margin-top: 16px;margin-bottom: 16px;outline: 0px;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(102, 102, 102);font-family: &quot;PingFang SC&quot;, &quot;Lantinghei SC&quot;, &quot;Microsoft YaHei&quot;, &quot;HanHei SC&quot;, &quot;Helvetica Neue&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, 微软雅黑, STHeiti, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif;font-size: 16px;line-height: 1.75em;visibility: visible;"><span style="outline: 0px;color: rgb(62, 62, 62);font-family: PingFangSC-light;font-size: 15px;letter-spacing: 0.5px;caret-color: rgb(0, 0, 0);visibility: visible;">我选中3、4两条,翻译后比较一番,不仅描述了画面内容,连插画风格、画风、模仿的画师风格都表述了出来~选中一条指令即可立即执行绘画。(</span><span style="outline: 0px;font-family: PingFangSC-light;font-size: 15px;letter-spacing: 0.5px;caret-color: rgb(0, 0, 0);visibility: visible;color: rgb(136, 136, 136);">不得不说,这玩意儿,可比ChatGPT那个设计门外汉“香”多了……</span><span style="outline: 0px;color: rgb(62, 62, 62);font-family: PingFangSC-light;font-size: 15px;letter-spacing: 0.5px;caret-color: rgb(0, 0, 0);visibility: visible;">)</span></p> <p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.9416666666666667" data-s="300,640" src="/upload/2326e31fc2513995d5f847a99390d913.png" data-type="png" data-w="1080" style=""></p> <section powered-by="xiumi.us" mp-original-font-size="16" mp-original-line-height="25.600000381469727" style="margin: -10px 0em 0px;outline: 0px;color: rgb(102, 102, 102);font-family: &quot;PingFang SC&quot;, &quot;Lantinghei SC&quot;, &quot;Microsoft YaHei&quot;, &quot;HanHei SC&quot;, &quot;Helvetica Neue&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, 微软雅黑, STHeiti, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif;font-size: 16px;line-height: 25.6px;"> <section mp-original-font-size="28" mp-original-line-height="44.79999923706055" style="margin-right: 0em;margin-left: 0em;outline: 0px;font-size: 28px;line-height: 44.8px;"> <p style="outline: 0px;line-height: 44.8px;"><br></p> <p style="outline: 0px;line-height: 44.8px;"><br></p> <p style="outline: 0px;line-height: 44.8px;"><span style="outline: 0px;color: rgb(0, 0, 0);"><strong style="outline: 0px;">精准“调教”:贴图+describe命令</strong></span><span style="outline: 0px;color: rgb(0, 0, 0);"><strong style="outline: 0px;"><span style="font-family: SimHei, STHeiti;font-size: 16px;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);"></span></strong></span></p> </section> </section> <section style="margin-bottom: 0px;outline: 0px;color: rgb(102, 102, 102);font-family: &quot;PingFang SC&quot;, &quot;Lantinghei SC&quot;, &quot;Microsoft YaHei&quot;, &quot;HanHei SC&quot;, &quot;Helvetica Neue&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, 微软雅黑, STHeiti, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif;font-size: 16px;transform-origin: left top;line-height: 25.6px;"> <section mp-original-font-size="16" mp-original-line-height="25.600000381469727" style="margin-right: 0em;margin-left: 0em;outline: 0px;text-align: left;justify-content: flex-start;display: flex;flex-flow: row nowrap;line-height: 25.6px;"> <section mp-original-font-size="16" mp-original-line-height="25.600000381469727" style="margin-right: 0em;margin-left: 0em;outline: 0px;display: inline-block;width: 23px;vertical-align: top;flex: 0 0 auto;height: auto;align-self: flex-start;line-height: 25.6px;"> <section powered-by="xiumi.us" mp-original-font-size="16" mp-original-line-height="25.600000381469727" style="margin-right: 0em;margin-bottom: 8px;margin-left: 0em;outline: 0px;line-height: 25.6px;"> <section mp-original-font-size="16" mp-original-line-height="25.600000381469727" style="margin-right: 0em;margin-left: 0em;outline: 0px;background-color: rgb(188, 38, 33);height: 3px;line-height: 25.6px;"> <br> </section> </section> </section> </section> </section> <article data-content="[{&quot;type&quot;:&quot;block&quot;,&quot;id&quot;:&quot;GSCe-1680783649584&quot;,&quot;name&quot;:&quot;heading&quot;,&quot;data&quot;:{&quot;level&quot;:&quot;h3&quot;,&quot;style&quot;:{}},&quot;nodes&quot;:[{&quot;type&quot;:&quot;text&quot;,&quot;id&quot;:&quot;6B2d-1680783649583&quot;,&quot;leaves&quot;:[{&quot;text&quot;:&quot;精准“调教”:&quot;,&quot;marks&quot;:[{&quot;type&quot;:&quot;bold&quot;},{&quot;type&quot;:&quot;color&quot;,&quot;value&quot;:&quot;#000000&quot;},{&quot;type&quot;:&quot;backgroundColor&quot;,&quot;value&quot;:&quot;rgb(255,&nbsp;255,&nbsp;255)&quot;},{&quot;type&quot;:&quot;fontFamily&quot;,&quot;value&quot;:&quot;SimHei&quot;}]},{&quot;text&quot;:&quot;贴图+describe命令&quot;,&quot;marks&quot;:[{&quot;type&quot;:&quot;bold&quot;},{&quot;type&quot;:&quot;color&quot;,&quot;value&quot;:&quot;#262626&quot;},{&quot;type&quot;:&quot;backgroundColor&quot;,&quot;value&quot;:&quot;rgb(255,&nbsp;255,&nbsp;255)&quot;},{&quot;type&quot;:&quot;fontFamily&quot;,&quot;value&quot;:&quot;SimHei&quot;}]}]}]},{&quot;type&quot;:&quot;block&quot;,&quot;id&quot;:&quot;Ijsk-1680781882504&quot;,&quot;name&quot;:&quot;paragraph&quot;,&quot;data&quot;:{&quot;version&quot;:1},&quot;nodes&quot;:[{&quot;type&quot;:&quot;text&quot;,&quot;id&quot;:&quot;mJ5H-1680781882505&quot;,&quot;leaves&quot;:[{&quot;text&quot;:&quot;上面简单阐述如何操作,接下来才是麻瓜画图的核心打法。看完下文,立马让你“阿瓦达顶呱呱👍”~&quot;,&quot;marks&quot;:[{&quot;type&quot;:&quot;color&quot;,&quot;value&quot;:&quot;#525252&quot;},{&quot;type&quot;:&quot;backgroundColor&quot;,&quot;value&quot;:&quot;rgb(255,&nbsp;255,&nbsp;255)&quot;},{&quot;type&quot;:&quot;fontSize&quot;,&quot;value&quot;:16},{&quot;type&quot;:&quot;fontFamily&quot;,&quot;value&quot;:&quot;SimHei&quot;}]}]}]},{&quot;type&quot;:&quot;block&quot;,&quot;id&quot;:&quot;TnE6-1680785122732&quot;,&quot;name&quot;:&quot;paragraph&quot;,&quot;data&quot;:{&quot;version&quot;:1},&quot;nodes&quot;:[{&quot;type&quot;:&quot;text&quot;,&quot;id&quot;:&quot;hu4k-1680785122731&quot;,&quot;leaves&quot;:[{&quot;text&quot;:&quot;举个Ai画图实际应用的例子,很多设计师工作中会接到商业海报/插画等运营视觉类的需求,那么用上刚才的指令,就会非常高效。&quot;,&quot;marks&quot;:[{&quot;type&quot;:&quot;color&quot;,&quot;value&quot;:&quot;#525252&quot;},{&quot;type&quot;:&quot;backgroundColor&quot;,&quot;value&quot;:&quot;rgb(255,&nbsp;255,&nbsp;255)&quot;},{&quot;type&quot;:&quot;fontSize&quot;,&quot;value&quot;:16},{&quot;type&quot;:&quot;fontFamily&quot;,&quot;value&quot;:&quot;SimHei&quot;}]}]}]},{&quot;type&quot;:&quot;block&quot;,&quot;id&quot;:&quot;OrFj-1680792007855&quot;,&quot;name&quot;:&quot;paragraph&quot;,&quot;data&quot;:{&quot;version&quot;:1},&quot;nodes&quot;:[{&quot;type&quot;:&quot;text&quot;,&quot;id&quot;:&quot;KQd3-1680792007852&quot;,&quot;leaves&quot;:[{&quot;text&quot;:&quot;比方说今天,早上刚一上班老板就让我做一张“立夏”节气应用闪图,他还说要快,下班他就要!这要是在平常,高低我要怼他两句,但这次不一样了,我准备用Midjourney来做……&quot;,&quot;marks&quot;:[{&quot;type&quot;:&quot;color&quot;,&quot;value&quot;:&quot;#525252&quot;},{&quot;type&quot;:&quot;backgroundColor&quot;,&quot;value&quot;:&quot;rgb(255,&nbsp;255,&nbsp;255)&quot;},{&quot;type&quot;:&quot;fontSize&quot;,&quot;value&quot;:16},{&quot;type&quot;:&quot;fontFamily&quot;,&quot;value&quot;:&quot;SimHei&quot;}]}]}]},{&quot;type&quot;:&quot;block&quot;,&quot;id&quot;:&quot;aZRP-1680785337665&quot;,&quot;name&quot;:&quot;paragraph&quot;,&quot;data&quot;:{&quot;version&quot;:1},&quot;nodes&quot;:[{&quot;type&quot;:&quot;text&quot;,&quot;id&quot;:&quot;d7zn-1680785337664&quot;,&quot;leaves&quot;:[{&quot;text&quot;:&quot;第一步就是搜集素材,“立夏”的图片很多,我挑了张我和老板都很满意的荷叶图来做参考。然后按照上面的步骤,通过describe命令,把参考图转化成指令。&quot;,&quot;marks&quot;:[{&quot;type&quot;:&quot;color&quot;,&quot;value&quot;:&quot;#525252&quot;},{&quot;type&quot;:&quot;backgroundColor&quot;,&quot;value&quot;:&quot;rgb(255,&nbsp;255,&nbsp;255)&quot;},{&quot;type&quot;:&quot;fontSize&quot;,&quot;value&quot;:16},{&quot;type&quot;:&quot;fontFamily&quot;,&quot;value&quot;:&quot;SimHei&quot;}]}]}]}]"> <p><span style="color: rgb(62, 62, 62);font-family: PingFangSC-light;font-size: 15px;letter-spacing: 0.5px;caret-color: rgb(0, 0, 0);">上面简单阐述如何操作,接下来才是麻瓜画图的核心打法。</span><span style="color: rgb(62, 62, 62);font-family: PingFangSC-light;font-size: 15px;letter-spacing: 0.5px;caret-color: rgb(0, 0, 0);">看完下文,立马让你“阿瓦达顶呱呱👍”~</span><span style="font-weight: bold;color: rgb(38, 38, 38);background-color: rgb(255, 255, 255);font-family: SimHei, STHeiti;font-size: inherit;"></span></p> <p style="margin-top: 16px;margin-bottom: 16px;outline: 0px;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(102, 102, 102);font-family: &quot;PingFang SC&quot;, &quot;Lantinghei SC&quot;, &quot;Microsoft YaHei&quot;, &quot;HanHei SC&quot;, &quot;Helvetica Neue&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, 微软雅黑, STHeiti, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif;font-size: 16px;line-height: 1.75em;visibility: visible;"><span style="outline: 0px;color: rgb(62, 62, 62);font-family: PingFangSC-light;font-size: 15px;letter-spacing: 0.5px;caret-color: rgb(0, 0, 0);visibility: visible;">举个Ai画图实际应用的例子,很多设计师工作中会接到商业海报/插画等运营视觉类的需求,那么用上刚才的指令,就会非常高效。</span></p> <p style="margin-top: 16px;margin-bottom: 16px;outline: 0px;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(102, 102, 102);font-family: &quot;PingFang SC&quot;, &quot;Lantinghei SC&quot;, &quot;Microsoft YaHei&quot;, &quot;HanHei SC&quot;, &quot;Helvetica Neue&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, 微软雅黑, STHeiti, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif;font-size: 16px;line-height: 1.75em;visibility: visible;"><span style="outline: 0px;color: rgb(62, 62, 62);font-family: PingFangSC-light;font-size: 15px;letter-spacing: 0.5px;caret-color: rgb(0, 0, 0);visibility: visible;">比方说今天,早上刚一上班老板就让我做一张“立夏”节气应用闪图,他还说要快,下班他就要!这要是在平常,高低我要怼他两句,但这次不一样了,我准备用Midjourney来做……</span></p> <p style="margin-top: 16px;margin-bottom: 16px;outline: 0px;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(102, 102, 102);font-family: &quot;PingFang SC&quot;, &quot;Lantinghei SC&quot;, &quot;Microsoft YaHei&quot;, &quot;HanHei SC&quot;, &quot;Helvetica Neue&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, 微软雅黑, STHeiti, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif;font-size: 16px;line-height: 1.75em;visibility: visible;"><span style="outline: 0px;color: rgb(62, 62, 62);font-family: PingFangSC-light;font-size: 15px;letter-spacing: 0.5px;caret-color: rgb(0, 0, 0);visibility: visible;">第一步就是搜集素材,“立夏”的图片很多,我挑了张我和老板都很满意的荷叶图来做参考。然后按照上面的步骤,通过describe命令,把参考图转化成指令。</span></p> <p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.7268518518518519" data-s="300,640" src="/upload/749f91c84d8ed1251f8acf9d1170bec6.png" data-type="png" data-w="1080" style=""></p> <p style="margin-top: 16px;margin-bottom: 16px;outline: 0px;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(102, 102, 102);font-family: &quot;PingFang SC&quot;, &quot;Lantinghei SC&quot;, &quot;Microsoft YaHei&quot;, &quot;HanHei SC&quot;, &quot;Helvetica Neue&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, 微软雅黑, STHeiti, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif;font-size: 16px;line-height: 1.75em;visibility: visible;"><span style="outline: 0px;color: rgb(62, 62, 62);font-family: PingFangSC-light;font-size: 15px;letter-spacing: 0.5px;caret-color: rgb(0, 0, 0);visibility: visible;"></span></p> <article data-content="[{&quot;type&quot;:&quot;block&quot;,&quot;id&quot;:&quot;0OdG-1680836773729&quot;,&quot;name&quot;:&quot;paragraph&quot;,&quot;data&quot;:{&quot;version&quot;:1},&quot;nodes&quot;:[{&quot;type&quot;:&quot;text&quot;,&quot;id&quot;:&quot;7QzU-1680836773727&quot;,&quot;leaves&quot;:[{&quot;text&quot;:&quot;接着就是挑选指令了,按照上面的翻译,我选择了第四条来提交执行,紧接着AI给了我四张图:使我凌乱在风中…&quot;,&quot;marks&quot;:[{&quot;type&quot;:&quot;color&quot;,&quot;value&quot;:&quot;#525252&quot;},{&quot;type&quot;:&quot;backgroundColor&quot;,&quot;value&quot;:&quot;rgb(255,&nbsp;255,&nbsp;255)&quot;},{&quot;type&quot;:&quot;fontSize&quot;,&quot;value&quot;:16},{&quot;type&quot;:&quot;fontFamily&quot;,&quot;value&quot;:&quot;SimHei&quot;}]}]}]}]" style="margin-top: 16px;margin-bottom: 16px;outline: 0px;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(102, 102, 102);font-family: &quot;PingFang SC&quot;, &quot;Lantinghei SC&quot;, &quot;Microsoft YaHei&quot;, &quot;HanHei SC&quot;, &quot;Helvetica Neue&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, 微软雅黑, STHeiti, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif;font-size: 16px;line-height: 1.75em;visibility: visible;"> <p style="margin-top: 16px;margin-bottom: 16px;outline: 0px;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(102, 102, 102);font-family: &quot;PingFang SC&quot;, &quot;Lantinghei SC&quot;, &quot;Microsoft YaHei&quot;, &quot;HanHei SC&quot;, &quot;Helvetica Neue&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, 微软雅黑, STHeiti, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif;font-size: 16px;line-height: 1.75em;visibility: visible;"><span style="outline: 0px;color: rgb(62, 62, 62);font-family: PingFangSC-light;font-size: 15px;letter-spacing: 0.5px;caret-color: rgb(0, 0, 0);visibility: visible;">接着就是挑选指令了,按照上面的翻译,我选择了第四条来提交执行,紧接着AI给了我四张图:使我凌乱在风中…</span></p> </article> <p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="1.9287037037037038" data-s="300,640" src="/upload/b3a8da90c82bd01cfebaff9fe1994691.png" data-type="png" data-w="1080" style=""></p> <article data-content="[{&quot;type&quot;:&quot;block&quot;,&quot;id&quot;:&quot;lCD4-1680836785110&quot;,&quot;name&quot;:&quot;paragraph&quot;,&quot;data&quot;:{&quot;version&quot;:1},&quot;nodes&quot;:[{&quot;type&quot;:&quot;text&quot;,&quot;id&quot;:&quot;DyAC-1680836785109&quot;,&quot;leaves&quot;:[{&quot;text&quot;:&quot;这AI给我扯的有点远,不过没关系,让我们使用贴图大法调教一下,使它天马行空的思绪回归正轨。接下来的骚操作敲黑板!&quot;,&quot;marks&quot;:[{&quot;type&quot;:&quot;color&quot;,&quot;value&quot;:&quot;#525252&quot;},{&quot;type&quot;:&quot;backgroundColor&quot;,&quot;value&quot;:&quot;rgb(255,&nbsp;255,&nbsp;255)&quot;},{&quot;type&quot;:&quot;fontSize&quot;,&quot;value&quot;:16},{&quot;type&quot;:&quot;fontFamily&quot;,&quot;value&quot;:&quot;SimHei&quot;}]}]}]},{&quot;type&quot;:&quot;block&quot;,&quot;id&quot;:&quot;evrP-1680788016310&quot;,&quot;name&quot;:&quot;paragraph&quot;,&quot;data&quot;:{&quot;version&quot;:1},&quot;nodes&quot;:[{&quot;type&quot;:&quot;text&quot;,&quot;id&quot;:&quot;YfKX-1680788016309&quot;,&quot;leaves&quot;:[{&quot;text&quot;:&quot;把刚才的参考图拖进对话框上传,右键复制图片链接。&quot;,&quot;marks&quot;:[{&quot;type&quot;:&quot;bold&quot;},{&quot;type&quot;:&quot;color&quot;,&quot;value&quot;:&quot;#525252&quot;},{&quot;type&quot;:&quot;backgroundColor&quot;,&quot;value&quot;:&quot;rgb(255,&nbsp;255,&nbsp;255)&quot;},{&quot;type&quot;:&quot;fontSize&quot;,&quot;value&quot;:16},{&quot;type&quot;:&quot;fontFamily&quot;,&quot;value&quot;:&quot;SimHei&quot;}]},{&quot;text&quot;:&quot;再使用“/image”指令:“复制图片链接+空格+刚才用的文案指令”,这样ai就会以我的贴图为参考,生成新的画作了。&quot;,&quot;marks&quot;:[{&quot;type&quot;:&quot;color&quot;,&quot;value&quot;:&quot;#525252&quot;},{&quot;type&quot;:&quot;backgroundColor&quot;,&quot;value&quot;:&quot;rgb(255,&nbsp;255,&nbsp;255)&quot;},{&quot;type&quot;:&quot;fontSize&quot;,&quot;value&quot;:16},{&quot;type&quot;:&quot;fontFamily&quot;,&quot;value&quot;:&quot;SimHei&quot;}]}]}]},{&quot;type&quot;:&quot;block&quot;,&quot;id&quot;:&quot;tg2Q-1680788474758&quot;,&quot;name&quot;:&quot;paragraph&quot;,&quot;data&quot;:{},&quot;nodes&quot;:[{&quot;type&quot;:&quot;text&quot;,&quot;id&quot;:&quot;vghT-1680788474759&quot;,&quot;leaves&quot;:[{&quot;text&quot;:&quot;&quot;,&quot;marks&quot;:[]}]}]},{&quot;type&quot;:&quot;block&quot;,&quot;id&quot;:&quot;XFy4-1680836923218&quot;,&quot;name&quot;:&quot;paragraph&quot;,&quot;data&quot;:{},&quot;nodes&quot;:[{&quot;type&quot;:&quot;text&quot;,&quot;id&quot;:&quot;O4pI-1680836923216&quot;,&quot;leaves&quot;:[{&quot;text&quot;:&quot;新一轮的贴图校准结果出来啦!很明显,这波接受参考图“调教”后的ai明显产出优异,每一张都堪称SSR!选中一张最满意的,加上文字排版,5分钟一张商业海报,搞定!&quot;,&quot;marks&quot;:[]}]}]},{&quot;type&quot;:&quot;block&quot;,&quot;id&quot;:&quot;aFN6-1680787810862&quot;,&quot;name&quot;:&quot;paragraph&quot;,&quot;data&quot;:{&quot;version&quot;:1},&quot;nodes&quot;:[{&quot;type&quot;:&quot;text&quot;,&quot;id&quot;:&quot;mKKy-1680787810861&quot;,&quot;leaves&quot;:[{&quot;text&quot;:&quot;&quot;,&quot;marks&quot;:[]}]}]},{&quot;type&quot;:&quot;block&quot;,&quot;id&quot;:&quot;pf5A-1680837204939&quot;,&quot;name&quot;:&quot;paragraph&quot;,&quot;data&quot;:{&quot;version&quot;:1},&quot;nodes&quot;:[{&quot;type&quot;:&quot;text&quot;,&quot;id&quot;:&quot;XtxA-1680837204938&quot;,&quot;leaves&quot;:[{&quot;text&quot;:&quot;如果你的老板很难搞,那就顺手点击“刷新”图标再生成几张。对比我们的原图参考:不能说是一模一样,只能说是毫不相干!这样就不用担心抄袭版权的问题了,nice!👍&quot;,&quot;marks&quot;:[]}]}]},{&quot;type&quot;:&quot;block&quot;,&quot;id&quot;:&quot;c4y2-1680839542191&quot;,&quot;name&quot;:&quot;heading&quot;,&quot;data&quot;:{&quot;level&quot;:&quot;h3&quot;,&quot;style&quot;:{}},&quot;nodes&quot;:[{&quot;type&quot;:&quot;text&quot;,&quot;id&quot;:&quot;TUjS-1680839542189&quot;,&quot;leaves&quot;:[{&quot;text&quot;:&quot;&quot;,&quot;marks&quot;:[]}]}]},{&quot;type&quot;:&quot;block&quot;,&quot;id&quot;:&quot;mtkY-1680844368268&quot;,&quot;name&quot;:&quot;heading&quot;,&quot;data&quot;:{&quot;level&quot;:&quot;h3&quot;,&quot;style&quot;:{}},&quot;nodes&quot;:[{&quot;type&quot;:&quot;text&quot;,&quot;id&quot;:&quot;FYnd-1680844368267&quot;,&quot;leaves&quot;:[{&quot;text&quot;:&quot;结尾彩蛋&quot;,&quot;marks&quot;:[]}]}]},{&quot;type&quot;:&quot;block&quot;,&quot;id&quot;:&quot;kheO-1680791813076&quot;,&quot;name&quot;:&quot;paragraph&quot;,&quot;data&quot;:{&quot;version&quot;:1},&quot;nodes&quot;:[{&quot;type&quot;:&quot;text&quot;,&quot;id&quot;:&quot;Ux9x-1680791813077&quot;,&quot;leaves&quot;:[{&quot;text&quot;:&quot;老板:不错,很高效!既然如此,下班前,给我一套二十四节气吧!记住,要快!&quot;,&quot;marks&quot;:[]}]}]},{&quot;type&quot;:&quot;block&quot;,&quot;id&quot;:&quot;6xFR-1680791861498&quot;,&quot;name&quot;:&quot;paragraph&quot;,&quot;data&quot;:{&quot;version&quot;:1},&quot;nodes&quot;:[{&quot;type&quot;:&quot;text&quot;,&quot;id&quot;:&quot;8yv7-1680791861495&quot;,&quot;leaves&quot;:[{&quot;text&quot;:&quot;我:这要是在以前,我高低要给你两个大逼斗,但是现在…&quot;,&quot;marks&quot;:[]}]}]},{&quot;type&quot;:&quot;block&quot;,&quot;id&quot;:&quot;FGdC-1680839206628&quot;,&quot;name&quot;:&quot;paragraph&quot;,&quot;data&quot;:{&quot;version&quot;:1},&quot;nodes&quot;:[{&quot;type&quot;:&quot;text&quot;,&quot;id&quot;:&quot;L4o4-1680839206626&quot;,&quot;leaves&quot;:[{&quot;text&quot;:&quot;so&nbsp;easy!&quot;,&quot;marks&quot;:[]}]}]},{&quot;type&quot;:&quot;block&quot;,&quot;id&quot;:&quot;PPJC-1680838682007&quot;,&quot;name&quot;:&quot;paragraph&quot;,&quot;data&quot;:{&quot;version&quot;:1},&quot;nodes&quot;:[{&quot;type&quot;:&quot;text&quot;,&quot;id&quot;:&quot;UbmZ-1680838682006&quot;,&quot;leaves&quot;:[{&quot;text&quot;:&quot;&quot;,&quot;marks&quot;:[]}]}]}]" style="margin-top: 16px;margin-bottom: 16px;outline: 0px;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(102, 102, 102);font-family: &quot;PingFang SC&quot;, &quot;Lantinghei SC&quot;, &quot;Microsoft YaHei&quot;, &quot;HanHei SC&quot;, &quot;Helvetica Neue&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, 微软雅黑, STHeiti, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif;font-size: 16px;line-height: 1.75em;visibility: visible;"> <p style="margin-top: 16px;margin-bottom: 16px;outline: 0px;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(102, 102, 102);font-family: &quot;PingFang SC&quot;, &quot;Lantinghei SC&quot;, &quot;Microsoft YaHei&quot;, &quot;HanHei SC&quot;, &quot;Helvetica Neue&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, 微软雅黑, STHeiti, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif;font-size: 16px;line-height: 1.75em;visibility: visible;"><br></p> <p style="margin-top: 16px;margin-bottom: 16px;outline: 0px;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(102, 102, 102);font-family: &quot;PingFang SC&quot;, &quot;Lantinghei SC&quot;, &quot;Microsoft YaHei&quot;, &quot;HanHei SC&quot;, &quot;Helvetica Neue&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, 微软雅黑, STHeiti, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif;font-size: 16px;line-height: 1.75em;visibility: visible;"><span style="outline: 0px;color: rgb(62, 62, 62);font-family: PingFangSC-light;font-size: 15px;letter-spacing: 0.5px;caret-color: rgb(0, 0, 0);visibility: visible;">这AI给我扯的有点远,不过没关系,让我们使用贴图大法调教一下,使它天马行空的思绪回归正轨。接下来的骚操作敲黑板!</span></p> <p style="margin-top: 16px;margin-bottom: 16px;outline: 0px;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(102, 102, 102);font-family: &quot;PingFang SC&quot;, &quot;Lantinghei SC&quot;, &quot;Microsoft YaHei&quot;, &quot;HanHei SC&quot;, &quot;Helvetica Neue&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, 微软雅黑, STHeiti, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif;font-size: 16px;line-height: 1.75em;visibility: visible;"><strong><span style="outline: 0px;color: rgb(62, 62, 62);font-family: PingFangSC-light;font-size: 15px;letter-spacing: 0.5px;caret-color: rgb(0, 0, 0);visibility: visible;">把刚才的参考图拖进对话框上传,右键复制图片链接</span></strong><span style="outline: 0px;color: rgb(62, 62, 62);font-family: PingFangSC-light;font-size: 15px;letter-spacing: 0.5px;caret-color: rgb(0, 0, 0);visibility: visible;">。再使用“/image”指令:“复制图片链接+空格+刚才用的文案指令”,这样ai就会以我的贴图为参考,生成新的画作了。</span></p> <p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.9287037037037037" data-s="300,640" src="/upload/a9a8cd8a5292fb946f2a7adf613cc220.png" data-type="png" data-w="1080" style=""></p> <p style="margin-top: 16px;margin-bottom: 16px;outline: 0px;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(102, 102, 102);font-family: &quot;PingFang SC&quot;, &quot;Lantinghei SC&quot;, &quot;Microsoft YaHei&quot;, &quot;HanHei SC&quot;, &quot;Helvetica Neue&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, 微软雅黑, STHeiti, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif;font-size: 16px;line-height: 1.75em;visibility: visible;"><span style="outline: 0px;color: rgb(62, 62, 62);font-family: PingFangSC-light;font-size: 15px;letter-spacing: 0.5px;caret-color: rgb(0, 0, 0);visibility: visible;"></span></p> <p style="margin-top: 16px;margin-bottom: 16px;outline: 0px;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(102, 102, 102);font-family: &quot;PingFang SC&quot;, &quot;Lantinghei SC&quot;, &quot;Microsoft YaHei&quot;, &quot;HanHei SC&quot;, &quot;Helvetica Neue&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, 微软雅黑, STHeiti, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif;font-size: 16px;line-height: 1.75em;visibility: visible;"><span style="outline: 0px;color: rgb(62, 62, 62);font-family: PingFangSC-light;font-size: 15px;letter-spacing: 0.5px;caret-color: rgb(0, 0, 0);visibility: visible;">新一轮的贴图校准结果出来啦!很明显,这波接受参考图“调教”后的ai明显产出优异,每一张都堪称SSR!选中一张最满意的,加上文字排版,5分钟一张商业海报,搞定!</span></p> <p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.7898148148148149" data-s="300,640" src="/upload/cb8f73515705c233733950c73683e069.png" data-type="png" data-w="1080" style=""></p> <p style="margin-top: 16px;margin-bottom: 16px;outline: 0px;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(102, 102, 102);font-family: &quot;PingFang SC&quot;, &quot;Lantinghei SC&quot;, &quot;Microsoft YaHei&quot;, &quot;HanHei SC&quot;, &quot;Helvetica Neue&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, 微软雅黑, STHeiti, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif;font-size: 16px;line-height: 1.75em;visibility: visible;"><span style="color: rgb(62, 62, 62);font-family: PingFangSC-light;font-size: 15px;letter-spacing: 0.5px;caret-color: rgb(0, 0, 0);">如果你的老板很难搞,那就顺手点击“刷新”图标再生成几张。</span><span style="color: rgb(62, 62, 62);font-family: PingFangSC-light;font-size: 15px;letter-spacing: 0.5px;caret-color: rgb(0, 0, 0);">对比我们的原图参考:</span><span style="color: rgb(62, 62, 62);font-family: PingFangSC-light;font-size: 15px;letter-spacing: 0.5px;caret-color: rgb(0, 0, 0);">不能说是一模一样,只能说是毫不相干!</span><span style="color: rgb(62, 62, 62);font-family: PingFangSC-light;font-size: 15px;letter-spacing: 0.5px;caret-color: rgb(0, 0, 0);">这样就不用担心抄袭版权的问题了,nice!</span><span style="color: rgb(62, 62, 62);font-family: PingFangSC-light;font-size: 15px;letter-spacing: 0.5px;caret-color: rgb(0, 0, 0);">👍</span><span style="outline: 0px;color: rgb(62, 62, 62);font-family: PingFangSC-light;font-size: 15px;letter-spacing: 0.5px;caret-color: rgb(0, 0, 0);visibility: visible;"></span></p> <p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="1.2324074074074074" data-s="300,640" src="/upload/e88144ac67d15865cc53a86fafad4a3e.png" data-type="png" data-w="1080" style=""></p> <p style="margin-top: 16px;margin-bottom: 16px;outline: 0px;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(102, 102, 102);font-family: &quot;PingFang SC&quot;, &quot;Lantinghei SC&quot;, &quot;Microsoft YaHei&quot;, &quot;HanHei SC&quot;, &quot;Helvetica Neue&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, 微软雅黑, STHeiti, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif;font-size: 16px;line-height: 1.75em;visibility: visible;"><br></p> <p style="margin-top: 16px;margin-bottom: 16px;outline: 0px;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(102, 102, 102);font-family: &quot;PingFang SC&quot;, &quot;Lantinghei SC&quot;, &quot;Microsoft YaHei&quot;, &quot;HanHei SC&quot;, &quot;Helvetica Neue&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, 微软雅黑, STHeiti, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif;font-size: 16px;line-height: 1.75em;visibility: visible;"><strong><span style="outline: 0px;color: rgb(62, 62, 62);font-family: PingFangSC-light;font-size: 15px;letter-spacing: 0.5px;caret-color: rgb(0, 0, 0);visibility: visible;">结尾彩蛋</span></strong><span style="outline: 0px;color: rgb(62, 62, 62);font-family: PingFangSC-light;font-size: 15px;letter-spacing: 0.5px;caret-color: rgb(0, 0, 0);visibility: visible;"></span></p> <p style="margin-top: 16px;margin-bottom: 16px;outline: 0px;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(102, 102, 102);font-family: &quot;PingFang SC&quot;, &quot;Lantinghei SC&quot;, &quot;Microsoft YaHei&quot;, &quot;HanHei SC&quot;, &quot;Helvetica Neue&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, 微软雅黑, STHeiti, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif;font-size: 16px;line-height: 1.75em;visibility: visible;"><span style="outline: 0px;color: rgb(62, 62, 62);font-family: PingFangSC-light;font-size: 15px;letter-spacing: 0.5px;caret-color: rgb(0, 0, 0);visibility: visible;">老板:不错,很高效!既然如此,下班前,给我一套二十四节气吧!记住,要快!</span></p> <p style="margin-top: 16px;margin-bottom: 16px;outline: 0px;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(102, 102, 102);font-family: &quot;PingFang SC&quot;, &quot;Lantinghei SC&quot;, &quot;Microsoft YaHei&quot;, &quot;HanHei SC&quot;, &quot;Helvetica Neue&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, 微软雅黑, STHeiti, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif;font-size: 16px;line-height: 1.75em;visibility: visible;"><span style="outline: 0px;color: rgb(62, 62, 62);font-family: PingFangSC-light;font-size: 15px;letter-spacing: 0.5px;caret-color: rgb(0, 0, 0);visibility: visible;">我:这要是在以前,我高低要给你两个大逼斗,但是现在…</span></p> <p style="margin-top: 16px;margin-bottom: 16px;outline: 0px;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(102, 102, 102);font-family: &quot;PingFang SC&quot;, &quot;Lantinghei SC&quot;, &quot;Microsoft YaHei&quot;, &quot;HanHei SC&quot;, &quot;Helvetica Neue&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, 微软雅黑, STHeiti, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif;font-size: 16px;line-height: 1.75em;visibility: visible;"><span style="outline: 0px;color: rgb(62, 62, 62);font-family: PingFangSC-light;font-size: 15px;letter-spacing: 0.5px;caret-color: rgb(0, 0, 0);visibility: visible;">so easy!</span></p> <p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="1.5824074074074075" data-s="300,640" src="/upload/1f8ddb5d0363499a1e5c98bae57705cd.png" data-type="png" data-w="1080" style=""></p> <p style="margin-top: 16px;margin-bottom: 16px;outline: 0px;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(102, 102, 102);font-family: &quot;PingFang SC&quot;, &quot;Lantinghei SC&quot;, &quot;Microsoft YaHei&quot;, &quot;HanHei SC&quot;, &quot;Helvetica Neue&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, 微软雅黑, STHeiti, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif;font-size: 16px;line-height: 1.75em;visibility: visible;"><span style="outline: 0px;color: rgb(62, 62, 62);font-family: PingFangSC-light;font-size: 15px;letter-spacing: 0.5px;caret-color: rgb(0, 0, 0);visibility: visible;"></span></p> </article> <p><br></p> <article data-content="[{&quot;type&quot;:&quot;block&quot;,&quot;id&quot;:&quot;zx1j-1663657181032&quot;,&quot;name&quot;:&quot;paragraph&quot;,&quot;data&quot;:{&quot;version&quot;:1},&quot;nodes&quot;:[{&quot;type&quot;:&quot;text&quot;,&quot;id&quot;:&quot;LQ4f-1663657181031&quot;,&quot;leaves&quot;:[{&quot;text&quot;:&quot;工作中经常有人聊起交互跟产品的差别是什么?交互跟UI的差别是什么?似乎从入行至今,都一直有过这样的声音。互联网红利期的逐步消退,资本紧缩,压缩人力成本似乎成了一件趋之若鹜的事,所以早年阿里提出了全栈设计师、全栈工程师的概念,但本质上各种细分岗位的工作一直都存在,从未消失过,只不过以不同的形式被平摊了,但效果却难以说是好的。下面将去抛砖引玉的探讨交互设计价值点,并聊聊能否被兼并或取代。&quot;,&quot;marks&quot;:[]}]}]},{&quot;type&quot;:&quot;block&quot;,&quot;id&quot;:&quot;secn-1663657208541&quot;,&quot;name&quot;:&quot;paragraph&quot;,&quot;data&quot;:{&quot;style&quot;:{},&quot;version&quot;:1},&quot;nodes&quot;:[{&quot;type&quot;:&quot;text&quot;,&quot;id&quot;:&quot;OOTb-1663657208540&quot;,&quot;leaves&quot;:[{&quot;text&quot;:&quot;&quot;,&quot;marks&quot;:[]}]}]},{&quot;type&quot;:&quot;block&quot;,&quot;id&quot;:&quot;vMKG-1663657615130&quot;,&quot;name&quot;:&quot;heading&quot;,&quot;data&quot;:{&quot;level&quot;:&quot;h2&quot;,&quot;style&quot;:{},&quot;version&quot;:1},&quot;nodes&quot;:[{&quot;type&quot;:&quot;text&quot;,&quot;id&quot;:&quot;NXfa-1663657208542&quot;,&quot;leaves&quot;:[{&quot;text&quot;:&quot;先谈谈交互在做什么?&quot;,&quot;marks&quot;:[]}]}]},{&quot;type&quot;:&quot;block&quot;,&quot;id&quot;:&quot;9fE0-1663657208545&quot;,&quot;name&quot;:&quot;paragraph&quot;,&quot;data&quot;:{&quot;version&quot;:1},&quot;nodes&quot;:[{&quot;type&quot;:&quot;text&quot;,&quot;id&quot;:&quot;1epN-1663657208544&quot;,&quot;leaves&quot;:[{&quot;text&quot;:&quot;借用一句传统设计行业的经典语录,一个好的产品一定是“有用的、好用的、用过还想用的”,有用的主要由产品经理把控,而好用、用过是否还想用就是交互设计的职责和价值了。工作内容,交互大概可以总结为下面这几点&quot;,&quot;marks&quot;:[]}]}]},{&quot;type&quot;:&quot;block&quot;,&quot;id&quot;:&quot;ozx6-1663657208547&quot;,&quot;name&quot;:&quot;paragraph&quot;,&quot;data&quot;:{&quot;version&quot;:1},&quot;nodes&quot;:[{&quot;type&quot;:&quot;text&quot;,&quot;id&quot;:&quot;aURd-1663657208546&quot;,&quot;leaves&quot;:[{&quot;text&quot;:&quot;1、是针对行为的设计,让原本的物理逻辑向用户行为逻辑转化&quot;,&quot;marks&quot;:[]}]}]},{&quot;type&quot;:&quot;block&quot;,&quot;id&quot;:&quot;oQQ5-1663657208549&quot;,&quot;name&quot;:&quot;paragraph&quot;,&quot;data&quot;:{&quot;version&quot;:1},&quot;nodes&quot;:[{&quot;type&quot;:&quot;text&quot;,&quot;id&quot;:&quot;m7bu-1663657208548&quot;,&quot;leaves&quot;:[{&quot;text&quot;:&quot;2、平衡业务价值和用户价值,脑海中永远不要忘记“用户价值”这几个字&quot;,&quot;marks&quot;:[]}]}]},{&quot;type&quot;:&quot;block&quot;,&quot;id&quot;:&quot;kTRJ-1663657208552&quot;,&quot;name&quot;:&quot;paragraph&quot;,&quot;data&quot;:{&quot;version&quot;:1},&quot;nodes&quot;:[{&quot;type&quot;:&quot;text&quot;,&quot;id&quot;:&quot;NpbM-1663657208550&quot;,&quot;leaves&quot;:[{&quot;text&quot;:&quot;3、以目标为导向,保证产品贴合用户心智,用户能更好的理解、使用产品,并获得愉悦的使用体验&quot;,&quot;marks&quot;:[]}]}]},{&quot;type&quot;:&quot;block&quot;,&quot;id&quot;:&quot;j7xR-1663657208554&quot;,&quot;name&quot;:&quot;paragraph&quot;,&quot;data&quot;:{&quot;version&quot;:1},&quot;nodes&quot;:[{&quot;type&quot;:&quot;text&quot;,&quot;id&quot;:&quot;3LNV-1663657208553&quot;,&quot;leaves&quot;:[{&quot;text&quot;:&quot;4、是通过功能架构向信息架构的重组,提升产品框架的扩展性、稳定性等,交互更多的考虑到在不同场景下对可用性的要求,让产品能长久持续的使用下去&quot;,&quot;marks&quot;:[]}]}]},{&quot;type&quot;:&quot;block&quot;,&quot;id&quot;:&quot;ZtJ2-1663657208556&quot;,&quot;name&quot;:&quot;paragraph&quot;,&quot;data&quot;:{&quot;version&quot;:1},&quot;nodes&quot;:[{&quot;type&quot;:&quot;text&quot;,&quot;id&quot;:&quot;RxhE-1663657208555&quot;,&quot;leaves&quot;:[{&quot;text&quot;:&quot;5、是对使用流程设计&quot;,&quot;marks&quot;:[]}]}]},{&quot;type&quot;:&quot;block&quot;,&quot;id&quot;:&quot;h2fc-1663657208558&quot;,&quot;name&quot;:&quot;paragraph&quot;,&quot;data&quot;:{&quot;version&quot;:1},&quot;nodes&quot;:[{&quot;type&quot;:&quot;text&quot;,&quot;id&quot;:&quot;ntTl-1663657208557&quot;,&quot;leaves&quot;:[{&quot;text&quot;:&quot;6、数据分析和用户研究相关的工作,这两者是交互展开工作的基础支撑&quot;,&quot;marks&quot;:[]}]}]},{&quot;type&quot;:&quot;block&quot;,&quot;id&quot;:&quot;XlYa-1663657208560&quot;,&quot;name&quot;:&quot;paragraph&quot;,&quot;data&quot;:{&quot;version&quot;:1},&quot;nodes&quot;:[{&quot;type&quot;:&quot;text&quot;,&quot;id&quot;:&quot;qvw0-1663657208559&quot;,&quot;leaves&quot;:[{&quot;text&quot;:&quot;交互的价值是长期的和可持续的,没有交互,短期内看似不会出现问题,长期来看,对用户留存、用户满意度等会有重大影响,市场环境不同于垄断环境,功能堆砌过多后甚至都无法再动摇产品“难用”这个印象,但凡有类似竞品,放弃产品可能性较大&quot;,&quot;marks&quot;:[{&quot;type&quot;:&quot;bold&quot;}]}]}]},{&quot;type&quot;:&quot;block&quot;,&quot;id&quot;:&quot;fL1B-1663657208562&quot;,&quot;name&quot;:&quot;paragraph&quot;,&quot;data&quot;:{&quot;style&quot;:{},&quot;version&quot;:1},&quot;nodes&quot;:[{&quot;type&quot;:&quot;text&quot;,&quot;id&quot;:&quot;Ky9y-1663657208561&quot;,&quot;leaves&quot;:[{&quot;text&quot;:&quot;&quot;,&quot;marks&quot;:[]}]}]},{&quot;type&quot;:&quot;block&quot;,&quot;id&quot;:&quot;jz70-1663657615131&quot;,&quot;name&quot;:&quot;heading&quot;,&quot;data&quot;:{&quot;level&quot;:&quot;h2&quot;,&quot;style&quot;:{},&quot;version&quot;:1},&quot;nodes&quot;:[{&quot;type&quot;:&quot;text&quot;,&quot;id&quot;:&quot;vc95-1663657208563&quot;,&quot;leaves&quot;:[{&quot;text&quot;:&quot;交互设计的产

SpringCloud 的 25 个面试考点

作者:微信小助手

<section style="display:none;" data-tools="新媒体管家" data-label="powered by xmt.cn" data-mpa-powered-by="yiban.io"> <br> </section> <section data-tool="mdnice编辑器" data-website="https://www.mdnice.com"> <p style="margin-bottom: 0px;outline: 0px;font-size: 16px;white-space: normal;color: rgb(34, 34, 34);letter-spacing: 0.544px;text-align: center;background-color: rgb(255, 255, 255);font-family: sans-serif;text-size-adjust: inherit;caret-color: rgb(51, 51, 51);visibility: visible;"><br></p> <section> <mp-common-profile class="js_uneditable custom_select_card mp_profile_iframe" data-pluginname="mpprofile" data-weui-theme="light" data-id="MzA5MTU0OTY0Ng==" data-headimg="http://mmbiz.qpic.cn/mmbiz_png/zc3KLDBfJlmPt0J5PXYOoiaG8wsQPZrLevbxMZSfgQ0YypNYaicnbS0P9UicluuOySLSP4CjTcRUVHCZzYeXQ9WlA/0?wx_fmt=png" data-nickname="Java派" data-alias="javapai" data-signature="专注Java相关技术栈:Spring全家筒、Docker、k8s、Mysql、集群、微服务、中间件等知识。" data-from="0" data-is_biz_ban="0"></mp-common-profile> </section> <p style="margin-bottom: 0px;"><br></p> <p style="margin-bottom: 0em;outline: 0px;font-size: 16px;white-space: normal;letter-spacing: 0.544px;text-align: left;background-color: rgb(255, 255, 255);color: rgb(0, 0, 0);font-family: sans-serif;text-size-adjust: inherit;caret-color: rgb(51, 51, 51);visibility: visible;"><br></p> <section> <span style="letter-spacing: 0px;"><br></span> </section> <section> <span style="letter-spacing: 0px;">今天给大家分享SpringCloud高频面试题。</span> </section> <h2 data-tool="mdnice编辑器"><span style="display: none;"></span><br mpa-from-tpl="t"></h2> <section data-mpa-template="t" mpa-from-tpl="t"> <section data-mpa-template="t" mpa-from-tpl="t"> <section style="display: flex;justify-content: center;align-items: center;width: 100%;" data-mid="" mpa-from-tpl="t"> <section style="display: flex;justify-content: flex-start;align-items: center;flex-direction: column;" data-mid="" mpa-from-tpl="t"> <section style="z-index: 1;display: flex;justify-content: center;align-items: center;height: 36px;border-width: 1px 0px;border-top-style: dotted;border-bottom-style: dotted;border-top-color: rgb(193, 205, 249);border-bottom-color: rgb(193, 205, 249);border-left-style: initial;border-left-color: initial;border-right-style: initial;border-right-color: initial;" data-mid="" mpa-from-tpl="t"> <section style="width: 7px;height: 9px;" data-mid="" mpa-from-tpl="t"> <img class="rich_pages wxw-img" data-ratio="1.2857142857142858" src="/upload/528d6047c1f8fc974a14ee4f59de28c0.png" data-w="14" style="display: block;"> </section> <section style="padding-right: 12px;padding-left: 12px;text-align: center;" data-mid="" mpa-from-tpl="t"> <p style="font-size: 16px;font-weight: bold;color: rgb(68, 104, 248);line-height: 22px;" data-mid="" mpa-is-content="t"><span style="font-size: 18px;" mpa-is-content="t">Spring Cloud核心知识总结</span></p> </section> <section style="width: 7px;height: 9px;transform: rotate(180deg);" data-mid="" mpa-from-tpl="t"> <img data-ratio="1.2857142857142858" src="/upload/528d6047c1f8fc974a14ee4f59de28c0.png" data-w="14" style="display: block;"> </section> </section> </section> </section> </section> </section> <p><br mpa-from-tpl="t"></p> <h2 data-tool="mdnice编辑器"><br></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">下面是一张Spring Cloud核心组件关系图:<span style="text-align: center;letter-spacing: 0px;"></span></p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <p style="text-align: center;"><img class="rich_pages js_insertlocalimg wxw-img" data-ratio="0.7705882352941177" data-s="300,640" src="/upload/e8a8d49f6e7acdcc8aec23fa749bf4d8.png" data-type="png" data-w="850" style=""></p> <figcaption style="margin-top: 5px;text-align: center;color: #888;font-size: 14px;"> <br> </figcaption> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">从这张图中,其实我们是可以获取很多信息的,希望大家细细品尝。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">话不多说,我们直接开始 Spring Cloud 连环炮。</p> <h2 data-tool="mdnice编辑器"><span style="display: none;"></span></h2> <h2 data-tool="mdnice编辑器"><br mpa-from-tpl="t"></h2> <section data-mpa-template="t" mpa-from-tpl="t"> <section data-mpa-template="t" mpa-from-tpl="t"> <section style="display: flex;justify-content: center;align-items: center;width: 100%;" data-mid="" mpa-from-tpl="t"> <section style="display: flex;justify-content: flex-start;align-items: center;flex-direction: column;" data-mid="" mpa-from-tpl="t"> <section style="z-index: 1;display: flex;justify-content: center;align-items: center;height: 36px;border-width: 1px 0px;border-top-style: dotted;border-bottom-style: dotted;border-top-color: rgb(193, 205, 249);border-bottom-color: rgb(193, 205, 249);border-left-style: initial;border-left-color: initial;border-right-style: initial;border-right-color: initial;" data-mid="" mpa-from-tpl="t"> <section style="width: 7px;height: 9px;" data-mid="" mpa-from-tpl="t"> <img class="rich_pages wxw-img" data-ratio="1.2857142857142858" src="/upload/528d6047c1f8fc974a14ee4f59de28c0.png" data-w="14" style="display: block;"> </section> <section style="padding-right: 12px;padding-left: 12px;text-align: center;" data-mid="" mpa-from-tpl="t"> <p style="font-size: 16px;font-weight: bold;color: rgb(68, 104, 248);line-height: 22px;" data-mid="" mpa-is-content="t"><span style="font-size: 18px;" mpa-is-content="t">连环炮走起</span></p> </section> <section style="width: 7px;height: 9px;transform: rotate(180deg);" data-mid="" mpa-from-tpl="t"> <img data-ratio="1.2857142857142858" src="/upload/528d6047c1f8fc974a14ee4f59de28c0.png" data-w="14" style="display: block;"> </section> </section> </section> </section> </section> </section> <p><br mpa-from-tpl="t"></p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 20px;"><span style="display: none;"></span>1、什么是Spring Cloud ?<span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">Spring cloud 流应用程序启动器是基于 Spring Boot 的 Spring 集成应用程序,提供与外部系统的集成。Spring cloud Task,一个生命周期短暂的微服务框架,用于快速构建执行有限数据处理的应用程序。</p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 20px;"><span style="display: none;"></span>2、什么是微服务?<span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">微服务架构是一种架构模式或者说是一种架构风格,它提倡将单一应用程序划分为一组小的服务,每个服务运行在其独立的自己的进程中,服务之间相互协调、互相配合,为用户提供最终价值。服务之间采用轻量级的通信机制互相沟通(通常是基于HTTP的RESTful API),每个服务都围绕着具体的业务进行构建,并且能够被独立的构建在生产环境、类生产环境等。另外,应避免统一的、集中式的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具对其进行构建,可以有一个非常轻量级的集中式管理来协调这些服务,可以使用不同的语言来编写服务,也可以使用不同的数据存储。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">通俗地来讲:</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">微服务就是一个独立的职责单一的服务应用程序。在 intellij idea 工具里面就是用maven开发的一个个独立的module,具体就是使用springboot 开发的一个小的模块,处理单一专业的业务逻辑,一个模块只做一个事情。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">微服务强调的是服务大小,关注的是某一个点,具体解决某一个问题/落地对应的一个服务应用,可以看做是idea 里面一个 module。</p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 20px;"><span style="display: none;"></span>3、Spring Cloud有什么优势<span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">使用 Spring Boot 开发分布式微服务时,我们面临以下问题</p> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 与分布式系统相关的复杂性-这种开销包括网络问题,延迟开销,带宽问题,安全问题。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 服务发现-服务发现工具管理群集中的流程和服务如何查找和互相交谈。它涉及一个服务目录,在该目录中注册服务,然后能够查找并连接到该目录中的服务。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 冗余-分布式系统中的冗余问题。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 负载平衡 --负载平衡改善跨多个计算资源的工作负荷,诸如计算机,计算机集群,网络链路,中央处理单元,或磁盘驱动器的分布。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 性能-问题 由于各种运营开销导致的性能问题。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 部署复杂性-Devops 技能的要求。 </section></li> </ul> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 20px;"><span style="display: none;"></span>4、微服务之间如何独立通讯的?<span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">同步通信:dubbo通过 RPC 远程过程调用、springcloud通过 REST &nbsp;接口json调用等。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">异步:消息队列,如:<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">RabbitMq</code>、<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">ActiveM</code>、<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">Kafka</code>等消息队列。</p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 20px;"><span style="display: none;"></span>5、<strong>什么是服务熔断?什么是服务降级?</strong><span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">熔断机制是应对雪崩效应的一种微服务链路保护机制。当某个微服务不可用或者响应时间太长时,会进行服务降级,进而熔断该节点微服务的调用,快速返回“错误”的响应信息。当检测到该节点微服务调用响应正常后恢复调用链路。在Spring Cloud框架里熔断机制通过Hystrix实现,Hystrix会监控微服务间调用的状况,当失败的调用到一定阈值,缺省是5秒内调用20次,如果失败,就会启动熔断机制。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">服务降级,一般是从整体负荷考虑。就是当某个服务熔断之后,服务器将不再被调用,此时客户端可以自己准备一个本地的fallback回调,返回一个缺省值。这样做,虽然水平下降,但好歹可用,比直接挂掉强。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;"><code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">Hystrix</code>相关注解<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">@EnableHystrix</code>:开启熔断<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">@HystrixCommand(fallbackMethod=”XXX”)</code>,声明一个失败回滚处理函数<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">XXX</code>,当被注解的方法执行超时(默认是1000毫秒),就会执行<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">fallback</code>函数,返回错误提示。</p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 20px;"><span style="display: none;"></span>6、 请说说Eureka和zookeeper 的区别?<span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">Zookeeper保证了CP,Eureka保证了AP。</p> <blockquote data-tool="mdnice编辑器" style="border-top: none;border-right: none;border-bottom: none;font-size: 0.9em;overflow: auto;color: rgb(106, 115, 125);padding: 10px 10px 10px 20px;margin-bottom: 20px;margin-top: 20px;border-left-color: rgb(239, 112, 96);background: rgb(255, 249, 249);"> <p style="font-size: 16px;padding-top: 8px;padding-bottom: 8px;color: black;line-height: 26px;">A:高可用</p> <p style="font-size: 16px;padding-top: 8px;padding-bottom: 8px;color: black;line-height: 26px;">C:一致性</p> <p style="font-size: 16px;padding-top: 8px;padding-bottom: 8px;color: black;line-height: 26px;">P:分区容错性</p> </blockquote> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">1、当向注册中心查询服务列表时,我们可以容忍注册中心返回的是几分钟以前的信息,但不能容忍直接down掉不可用。也就是说,服务注册功能对高可用性要求比较高,但zk会出现这样一种情况,当master节点因为网络故障与其他节点失去联系时,剩余节点会重新选leader。问题在于,选取leader时间过长,30 ~ 120s,且选取期间zk集群都不可用,这样就会导致选取期间注册服务瘫痪。在云部署的环境下,因网络问题使得zk集群失去master节点是较大概率会发生的事,虽然服务能够恢复,但是漫长的选取时间导致的注册长期不可用是不能容忍的。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">2、Eureka保证了可用性,Eureka各个节点是平等的,几个节点挂掉不会影响正常节点的工作,剩余的节点仍然可以提供注册和查询服务。而Eureka的客户端向某个Eureka注册或发现时发生连接失败,则会自动切换到其他节点,只要有一台Eureka还在,就能保证注册服务可用,只是查到的信息可能不是最新的。除此之外,Eureka还有自我保护机制,如果在15分钟内超过85%的节点没有正常的心跳,那么Eureka就认为客户端与注册中心发生了网络故障,此时会出现以下几种情况:</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">① Eureka不在从注册列表中移除因为长时间没有收到心跳而应该过期的服务。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">② Eureka仍然能够接受新服务的注册和查询请求,但是不会被同步到其他节点上(即保证当前节点仍然可用)</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">③ 当网络稳定时,当前实例新的注册信息会被同步到其他节点。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">因此,Eureka可以很好地应对因网络故障导致部分节点失去联系的情况,而不会像Zookeeper那样使整个微服务瘫痪</p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 20px;"><span style="display: none;"></span>7、SpringBoot和SpringCloud的区别?<span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">SpringBoot专注于快速方便得开发单个个体微服务。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">SpringCloud是关注全局的微服务协调整理治理框架,它将SpringBoot开发的一个个单体微服务整合并管理起来,</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">为各个微服务之间提供,配置管理、服务发现、断路器、路由、微代理、事件总线、全局锁、决策竞选、分布式会话等等集成服务</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">SpringBoot可以离开SpringCloud独立使用开发项目, 但是SpringCloud离不开SpringBoot ,属于依赖的关系.</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">SpringBoot专注于快速、方便得开发单个微服务个体,SpringCloud关注全局的服务治理框架。</p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 20px;"><span style="display: none;"></span>8、负载平衡的意义什么?<span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">在计算中,负载平衡可以改善跨计算机,计算机集群,网络链接,中央处理单元或磁盘驱动器等多种计算资源的工作负载分布。负载平衡旨在优化资源使用,最大化吞吐量,最小化响应时间并避免任何单一资源 的过载。使用多个组件进行负载平衡而不是单个组件可能会通过冗余来提高可靠性和可用性。负载平衡通常涉及专用软件或硬件,例如多层交换机或域名系统服务器进程。</p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 20px;"><span style="display: none;"></span>9、什么是Hystrix?它如何实现容错?<span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">Hystrix是一个延迟和容错库,旨在隔离远程系统,服务和第三方库的访问点,当出现故障是不可避免的故障时,停止级联故障并在复杂的分布式系统中实现弹性。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">通常对于使用微服务架构开发的系统,涉及到许多微服务。这些微服务彼此协作。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">思考一下微服务:</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.5" src="/upload/e934973a0998d789a8983bc7f86c0ed4.jpg" data-type="other" data-w="550" style="display: block;margin: 0px;inset: 0px;"> <figcaption style="text-align: center;font-size: 14px;display: flex;justify-content: center;align-items: center;width: 100%;margin-top: -35px;background: rgba(0,0,0,0.7);color: white;line-height: 35px;z-index: 20;"> <br> </figcaption> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">假设如果上图中的微服务9失败了,那么使用传统方法我们将传播一个异常。但这仍然会导致整个系统崩溃。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">随着微服务数量的增加,这个问题变得更加复杂。微服务的数量可以高达1000。这是hystrix出现的地方 我们将使用Hystrix在这种情况下的Fallback方法功能。我们有两个服务employee-consumer使用由employee-consumer公开的服务。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">简化图如下所示</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.28" src="/upload/cd5f9df7d77ee44c33ec33cfd1981ab.jpg" data-type="other" data-w="550" style="display: block;margin: 0px;inset: 0px;"> <figcaption style="text-align: center;font-size: 14px;display: flex;justify-content: center;align-items: center;width: 100%;margin-top: -35px;background: rgba(0,0,0,0.7);color: white;line-height: 35px;z-index: 20;"> <br> </figcaption> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">现在假设由于某种原因,employee-producer公开的服务会抛出异常。我们在这种情况下使用Hystrix定义了一个回退方法。这种后备方法应该具有与公开服务相同的返回类型。如果暴露服务中出现异常,则回退方法将返回一些值。</p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 20px;"><span style="display: none;"></span>10、什么是Hystrix断路器?我们需要它吗?<span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">由于某些原因,employee-consumer公开服务会引发异常。在这种情况下使用Hystrix我们定义了一个回退方法。如果在公开服务中发生异常,则回退方法返回一些默认值。</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <p style="text-align: center;"><img class="rich_pages js_insertlocalimg wxw-img" data-ratio="0.5055555555555555" data-s="300,640" src="/upload/5c7c28a1a66811140324a69c31d76080.png" data-type="png" data-w="540" style=""></p> <figcaption style="margin-top: 5px;text-align: center;color: #888;font-size: 14px;"> <br> </figcaption> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">如果firstPage method() 中的异常继续发生,则Hystrix电路将中断,并且员工使用者将一起跳过firtsPage方法,并直接调用回退方法。断路器的目的是给第一页方法或第一页方法可能调用的其他方法留出时间,并导致异常恢复。可能发生的情况是,在负载较小的情况下,导致异常的问题有更好的恢复机会 。</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <p style="text-align: center;"><br></p> </figure> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 20px;"><span style="display: none;"></span>11、说说 RPC 的实现原理<span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">首先需要有处理网络连接通讯的模块,负责连接建立、管理和消息的传输。其次需要有编 解码的模块,因为网络通讯都是传输的字节码,需要将我们使用的对象序列化和反序列化。剩下的就是客户端和服务器端的部分,服务器端暴露要开放的服务接口,客户调用服 务接口的一个代理实现,这个代理实现负责收集数据、编码并传输给服务器然后等待结果返回。</p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 20px;"><span style="display: none;"></span>12、eureka自我保护机制是什么?<span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">当Eureka Server 节点在短时间内丢失了过多实例的连接时(比如网络故障或频繁启动关闭客户端)节点会进入自我保护模式,保护注册信息,不再删除注册数据,故障恢复时,自动退出自我保护模式。</p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 20px;"><span style="display: none;"></span>13、什么是Ribbon?<span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">ribbon是一个负载均衡客户端,可以很好地控制htt和tcp的一些行为。<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">feign默认集成了ribbon</code>。</p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 20px;"><span style="display: none;"></span>14、什么是 Netflix Feign?它的优点是什么?<span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">Feign 是受到 Retrofit,JAXRS-2.0 和 WebSocket 启发的 java 客户端联编程序。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">Feign 的第一个目标是将约束分母的复杂性统一到 http apis,而不考虑其稳定性。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">特点:</p> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> Feign 采用的是基于接口的注解 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> Feign 整合了ribbon,具有负载均衡的能力 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 整合了Hystrix,具有熔断的能力 </section></li> </ul> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">使用方式</p> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 添加pom依赖。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 启动类添加 <code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">@EnableFeignClients</code> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 定义一个接口 <code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">@FeignClient(name=“xxx”)</code>指定调用哪个服务 </section></li> </ul> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 20px;"><span style="display: none;"></span>15、 Ribbon和Feign的区别?<span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">1.<strong>启动类注解不同</strong>,Ribbon是@RibbonClient feign的是@EnableFeignClients;2.<strong>服务指定的位置不同</strong>,Ribbon是在@RibbonClient注解上声明,Feign则是在定义抽象方法的接口中使用@FeignClient声明;3.<strong>调用方式不同</strong>,Ribbon需要自己构建http请求,模拟http请求。</p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 20px;"><span style="display: none;"></span>16、Spring Cloud 的核心组件有哪些?<span style="display: none;"></span></h3> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> Eureka:服务注册于发现。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> Feign:基于动态代理机制,根据注解和选择的机器,拼接请求 url 地址,发起请求。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> Ribbon:实现负载均衡,从一个服务的多台机器中选择一台。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> Hystrix:提供线程池,不同的服务走不同的线程池,实现了不同服务调用的隔离,避免了服务雪崩的问题。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> Zuul:网关管理,由 Zuul 网关转发请求给对应的服务。 </section></li> </ul> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 20px;"><span style="display: none;"></span>17、说说Spring Boot和Spring Cloud的关系<span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">Spring Boot是Spring推出用于解决传统框架配置文件冗余,装配组件繁杂的基于Maven的解决方案,旨在快速搭建单个微服务而Spring Cloud专注于解决各个微服务之间的协调与配置,服务之间的通信,熔断,负载均衡等技术维度并相同,并且Spring Cloud是依赖于Spring Boot的,而Spring Boot并不是依赖与Spring Cloud,甚至还可以和Dubbo进行优秀的整合开发</p> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> SpringBoot专注于快速方便的开发单个个体的微服务 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> SpringCloud是关注全局的微服务协调整理治理框架,整合并管理各个微服务,为各个微服务之间提供,配置管理,服务发现,断路器,路由,事件总线等集成服务 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> Spring Boot不依赖于Spring Cloud,Spring Cloud依赖于Spring Boot,属于依赖关系 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> Spring Boot专注于快速,方便的开发单个的微服务个体,Spring Cloud关注全局的服务治理框架 </section></li> </ul> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 20px;"><span style="display: none;"></span>18、说说微服务之间是如何独立通讯的?<span style="display: none;"></span></h3> <h4 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 18px;"><span style="display: none;"></span>远程过程调用(Remote Procedure Invocation)<span style="display: none;"></span></h4> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">也就是我们常说的服务的注册与发现,直接通过远程过程调用来访问别的service。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;"><strong>优点</strong>:简单,常见,因为没有中间件代理,系统更简单</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;"><strong>缺点</strong>:只支持请求/响应的模式,不支持别的,比如通知、请求/异步响应、发布/订阅、发布/异步响应,降低了可用性,因为客户端和服务端在请求过程中必须都是可用的。</p> <h4 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 18px;"><span style="display: none;"></span>消息<span style="display: none;"></span></h4> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">使用异步消息来做服务间通信。服务间通过消息管道来交换消息,从而通信。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;"><strong>优点</strong>:把客户端和服务端解耦,更松耦合,提高可用性,因为消息中间件缓存了消息,直到消费者可以消费, &nbsp; &nbsp; &nbsp; 支持很多通信机制比如通知、请求/异步响应、发布/订阅、发布/异步响应。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;"><strong>缺点</strong>:消息中间件有额外的复杂。</p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 20px;"><span style="display: none;"></span>19、Spring Cloud如何实现服务的注册?<span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">服务发布时,指定对应的服务名,将服务注册到 注册中心(<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">Eureka 、Zookeeper)</code>。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">注册中心加<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">@EnableEurekaServer</code>,服务用<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">@EnableDiscoveryClient</code>,然后用ribbon或feign进行服务直接的调用发现。</p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 20px;"><span style="display: none;"></span>20、什么是服务熔断?<span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">在复杂的分布式系统中,微服务之间的相互调用,有可能出现各种各样的原因导致服务的阻塞,在高并发场景下,服务的阻塞意味着线程的阻塞,导致当前线程不可用,服务器的线程全部阻塞,导致服务器崩溃,由于服务之间的调用关系是同步的,会对整个微服务系统造成服务雪崩</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">为了解决某个微服务的调用响应时间过长或者不可用进而占用越来越多的系统资源引起雪崩效应就需要进行服务熔断和服务降级处理。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">所谓的服务熔断指的是某个服务故障或异常一起类似显示世界中的“保险丝"当某个异常条件被触发就直接熔断整个服务,而不是一直等到此服务超时。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">服务熔断就是相当于我们电闸的保险丝,一旦发生服务雪崩的,就会熔断整个服务,通过维护一个自己的线程池,当线程达到阈值的时候就启动服务降级,如果其他请求继续访问就直接返回fallback的默认值</p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 20px;"><span style="display: none;"></span>21、了解Eureka自我保护机制吗?<span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">当Eureka Server 节点在短时间内丢失了过多实例的连接时(比如网络故障或频繁启动关闭客户端)节点会进入自我保护模式,保护注册信息,不再删除注册数据,故障恢复时,自动退出自我保护模式。</p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 20px;"><span style="display: none;"></span>22、熟悉 Spring Cloud Bus 吗?<span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">spring cloud bus 将分布式的节点用轻量的消息代理连接起来,它可以用于广播配置文件的更改或者服务直接的通讯,也可用于监控。如果修改了配置文件,发送一次请求,所有的客户端便会重新读取配置文件。</p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 20px;"><span style="display: none;"></span>23、Spring Cloud 断路器有什么作用?<span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">当一个服务调用另一个服务由于网络原因或自身原因出现问题,调用者就会等待被调用者的响应,当更多的服务请求到这些资源导致更多的请求等待,发生连锁效应(雪崩效应)。一段时间内 达到一定的次数无法调用 并且多次监测没有恢复的迹象,这时候断路器完全打开 那么下次请求就不会请求到该服务。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">半开:短时间内 有恢复迹象 断路器会将部分请求发给该服务,正常调用时 断路器关闭。关闭:当服务一直处于正常状态 能正常调用。</p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 20px;"><span style="display: none;"></span>24、了解Spring Cloud Config 吗?<span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">在分布式系统中,由于服务数量巨多,为了方便服务配置文件统一管理,实时更新,所以需要分布式配置中心组件。在Spring Cloud中,有分布式配置中心组件<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">Spring Cloud Config</code>,它支持配置服务放在配置服务的内存中(即本地),也支持放在远程Git仓库中。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">在<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">Spring Cloud Config</code>组件中,分两个角色,一是config server,二是config client。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">使用方式:</p> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 添加pom依赖 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 配置文件添加相关配置 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 启动类添加注解@EnableConfigServer </section></li> </ul> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 20px;"><span style="display: none;"></span>25、说说你对Spring Cloud Gateway的理解<span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">Spring Cloud Gateway是Spring Cloud官方推出的第二代网关框架,取代Zuul网关。网关作为流量的,在微服务系统中有着非常作用,网关常见的功能有路由转发、权限校验、限流控制等作用。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">使用了一个RouteLocatorBuilder的bean去创建路由,除了创建路由RouteLocatorBuilder可以让你添加各种predicates和filters,predicates断言的意思,顾名思义就是根据具体的请求的规则,由具体的route去处理,filters是各种过滤器,用来对请求做各种判断和修改。</p> </section>

JVM 日志参数

作者:微信小助手

<section data-mpa-template="t" mpa-paragraph-type="ignored" style="white-space: normal;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);" data-mpa-powered-by="yiban.io"> <section> <mp-common-profile class="js_uneditable custom_select_card mp_profile_iframe" data-pluginname="mpprofile" data-weui-theme="light" data-id="MzA5MTU0OTY0Ng==" data-headimg="http://mmbiz.qpic.cn/mmbiz_png/zc3KLDBfJlmPt0J5PXYOoiaG8wsQPZrLevbxMZSfgQ0YypNYaicnbS0P9UicluuOySLSP4CjTcRUVHCZzYeXQ9WlA/0?wx_fmt=png" data-nickname="Java派" data-alias="javapai" data-signature="专注Java相关技术栈:Spring全家筒、Docker、k8s、Mysql、集群、微服务、中间件等知识。" data-from="0" data-is_biz_ban="0"></mp-common-profile> </section> <p style="margin-bottom: 0px;"><strong style="max-width: 100%;white-space: normal;color: rgb(53, 53, 53);font-size: 16px;letter-spacing: 0.544px;text-align: left;word-spacing: 0.8px;outline: 0px;font-family: 微软雅黑;overflow-wrap: break-word !important;box-sizing: border-box !important;"><span style="max-width: 100%;outline: 0px;font-size: 15px;overflow-wrap: break-word !important;box-sizing: border-box !important;"><strong style="max-width: 100%;letter-spacing: 0.544px;outline: 0px;background-color: rgb(255, 255, 255);font-size: 16px;color: rgb(0, 0, 0);word-spacing: 1.5px;orphans: 4;overflow-wrap: break-word !important;box-sizing: border-box !important;"><span style="max-width: 100%;outline: 0px;font-size: 15px;overflow-wrap: break-word !important;box-sizing: border-box !important;"></span></strong></span></strong></p> </section> <p style="margin-bottom: 0px;outline: 0px;color: rgba(0, 0, 0, 0.9);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: left;visibility: visible;"><span style="outline: 0px;font-size: 15px;visibility: visible;">VM 日志记录一直是 JDK 的一个重要功能,</span><span style="outline: 0px;font-size: 15px;visibility: visible;">通过日志可以分析 bug 和解决性能问题。</span><span style="outline: 0px;font-size: 15px;visibility: visible;">JDK 9 对 VM 日志记录的处理方式进行了几项更新,提升了用户友好性和可配置性。</span><span style="outline: 0px;font-size: 15px;visibility: visible;">本文将介绍如何记录 VM 日志。</span></p> <p style="margin-bottom: 0px;outline: 0px;color: rgba(0, 0, 0, 0.9);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: left;visibility: visible;"><span style="outline: 0px;font-size: 15px;visibility: visible;"><br style="outline: 0px;visibility: visible;"></span></p> <h2 style="outline: 0px;color: rgba(0, 0, 0, 0.9);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: left;visibility: visible;"><span style="outline: 0px;color: rgb(171, 25, 66);visibility: visible;"><strong style="outline: 0px;visibility: visible;"><span style="outline: 0px;font-size: 15px;visibility: visible;">启用和配置日志记录</span></strong></span></h2> <p style="margin-bottom: 0px;outline: 0px;color: rgba(0, 0, 0, 0.9);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: left;visibility: visible;"><br style="outline: 0px;visibility: visible;"></p> <p style="margin-bottom: 0px;outline: 0px;color: rgba(0, 0, 0, 0.9);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: left;visibility: visible;"><span style="outline: 0px;font-size: 15px;visibility: visible;">最基本的方法是在 java 命令中添加&nbsp;-Xlog 来启用 VM 日志记录,使用默认配置启用 VM 日志:</span></p> <p style="margin-bottom: 0px;outline: 0px;color: rgba(0, 0, 0, 0.9);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: left;visibility: visible;"><span style="outline: 0px;font-size: 15px;visibility: visible;"><br style="outline: 0px;visibility: visible;"></span></p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="cpp"><code style="white-space:pre-wrap;outline: 0px;max-width: 1000%;text-align: left;display: flex;font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace;visibility: visible;"><span class="code-snippet_outer" style="outline: 0px;max-width: 1000%;visibility: visible;">-Xlog:all=info:<span class="code-snippet__built_in" style="outline: 0px;max-width: 1000%;visibility: visible;">stdout</span>:uptime,levels,tags</span></code></pre> </section> <p style="margin-bottom: 0px;outline: 0px;color: rgba(0, 0, 0, 0.9);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: left;visibility: visible;"><span style="outline: 0px;font-size: 15px;visibility: visible;"><br style="outline: 0px;visibility: visible;"></span></p> <p style="margin-bottom: 0px;outline: 0px;color: rgba(0, 0, 0, 0.9);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: left;visibility: visible;"><span style="outline: 0px;font-size: 15px;visibility: visible;">上述代码将打开所有类别的 VM 日志记录,以 info 级别在 stdout 中打印 VM 日志。包括 JVM 的正常运行时间、日志语句的级别和与之相关的标签。以下是一个日志语句的示例:</span></p> <p style="margin-bottom: 0px;outline: 0px;color: rgba(0, 0, 0, 0.9);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: left;visibility: visible;"><span style="outline: 0px;font-size: 15px;visibility: visible;"><br style="outline: 0px;visibility: visible;"></span></p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="markdown"><code style="white-space:pre-wrap;outline: 0px;max-width: 1000%;text-align: left;display: flex;font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace;visibility: visible;"><span class="code-snippet_outer" style="outline: 0px;max-width: 1000%;visibility: visible;">[<span class="code-snippet__string" style="outline: 0px;max-width: 1000%;visibility: visible;">1.043s</span>][<span class="code-snippet__symbol" style="outline: 0px;max-width: 1000%;visibility: visible;">info</span>][<span class="code-snippet__string" style="outline: 0px;max-width: 1000%;visibility: visible;">methodhandles&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>]&nbsp;lookup<span class="code-snippet__emphasis" style="outline: 0px;max-width: 1000%;visibility: visible;">_polymorphic_</span>method&nbsp;=&gt;&nbsp;intrinsic&nbsp;{method}&nbsp;{0x000000010a38c880}</span></code></pre> </section> <section style="margin-bottom: 0px;outline: 0px;color: rgba(0, 0, 0, 0.9);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: left;visibility: visible;"> <br style="outline: 0px;visibility: visible;"> </section> <section style="margin-bottom: 0px;outline: 0px;color: rgba(0, 0, 0, 0.9);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: left;visibility: visible;"> <span style="outline: 0px;font-size: 15px;visibility: visible;">在大多数情况下,默认的 VM 日志记录可能过于繁杂可用性不高。幸运的是,VM 日志记录可以进行配置以适应各种需求。</span> </section> <section style="margin-bottom: 0px;outline: 0px;color: rgba(0, 0, 0, 0.9);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: left;visibility: visible;"> <span style="outline: 0px;font-size: 15px;visibility: visible;"><br style="outline: 0px;visibility: visible;"></span> </section> <h3 style="outline: 0px;color: rgba(0, 0, 0, 0.9);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);visibility: visible;"><span style="outline: 0px;color: rgb(171, 25, 66);visibility: visible;"><strong style="outline: 0px;visibility: visible;"><span style="outline: 0px;font-size: 15px;text-align: left;visibility: visible;">配置标签</span></strong></span></h3> <section style="margin-bottom: 0px;outline: 0px;color: rgba(0, 0, 0, 0.9);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);visibility: visible;"> <span style="outline: 0px;font-size: 15px;visibility: visible;"><br style="outline: 0px;visibility: visible;"></span> </section> <section style="margin-bottom: 0px;outline: 0px;color: rgba(0, 0, 0, 0.9);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: left;visibility: visible;"> <span style="outline: 0px;font-size: 15px;visibility: visible;">在启用 VM 日志记录时,开发人员通常会查看特定问题。可以配置 VM 日志记录以仅生成与特定类别匹配的日志,例如垃圾回收&nbsp;(gc)、即时编译器 (jit)、CPU 使用率 (cpu) 等。将日志记录限制在特定分类可以减少噪音并让你专注于自己关心的问题:</span> </section> <p style="margin-bottom: 0px;outline: 0px;color: rgba(0, 0, 0, 0.9);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: left;visibility: visible;"><span style="outline: 0px;font-size: 15px;visibility: visible;"><br style="outline: 0px;visibility: visible;"></span></p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="css"><code style="white-space:pre-wrap;outline: 0px;max-width: 1000%;text-align: left;display: flex;font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace;visibility: visible;"><span class="code-snippet_outer" style="outline: 0px;max-width: 1000%;visibility: visible;"><span class="code-snippet__selector-tag" style="outline: 0px;max-width: 1000%;visibility: visible;">-xlog</span><span class="code-snippet__selector-pseudo" style="outline: 0px;max-width: 1000%;visibility: visible;">:gc</span>,<span class="code-snippet__selector-tag" style="outline: 0px;max-width: 1000%;visibility: visible;">heap</span></span></code></pre> </section> <p style="margin-bottom: 0px;outline: 0px;color: rgba(0, 0, 0, 0.9);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: left;visibility: visible;"><br style="outline: 0px;visibility: visible;"></p> <p style="margin-bottom: 0px;outline: 0px;color: rgba(0, 0, 0, 0.9);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: left;visibility: visible;"><span style="outline: 0px;font-size: 15px;visibility: visible;">上面的例子将限制日志输出仅包含 gc 或 heap 标记的日志语句。你也可以使用以下示例来打印同时包含 gc 和 heap 的日志,并且通过在参数结尾增加&nbsp;* 可以支持打印包含 gc 或 heap 标记的任何日志:</span></p> <p style="margin-bottom: 0px;outline: 0px;color: rgba(0, 0, 0, 0.9);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: left;"><span style="outline: 0px;font-size: 15px;"><br style="outline: 0px;"></span></p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="css"><code style="white-space:pre-wrap;outline: 0px;max-width: 1000%;text-align: left;display: flex;font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="outline: 0px;max-width: 1000%;"><span class="code-snippet__selector-tag" style="outline: 0px;max-width: 1000%;">-xlog</span><span class="code-snippet__selector-pseudo" style="outline: 0px;max-width: 1000%;">:gc+heap</span></span></code><code style="white-space:pre-wrap;outline: 0px;max-width: 1000%;text-align: left;display: flex;font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="outline: 0px;max-width: 1000%;"><span class="code-snippet__selector-tag" style="outline: 0px;max-width: 1000%;">-xlog</span><span class="code-snippet__selector-pseudo" style="outline: 0px;max-width: 1000%;">:gc</span>*,<span class="code-snippet__selector-tag" style="outline: 0px;max-width: 1000%;">heap</span>*</span></code></pre> </section> <p style="margin-bottom: 0px;outline: 0px;color: rgba(0, 0, 0, 0.9);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: left;"><br style="outline: 0px;"></p> <p style="margin-bottom: 0px;outline: 0px;color: rgba(0, 0, 0, 0.9);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: left;"><span style="outline: 0px;font-size: 15px;">标签可以设置为不同级别的日志记录;<span style="outline: 0px;color: rgb(51, 51, 51);letter-spacing: normal;text-decoration-style: solid;text-decoration-color: rgb(51, 51, 51);">&nbsp;off, trace, debug, info, warning, error</span>;例如,如果我想要来自堆的 debug 日志,以及来自 gc 的 error 日志,可以像下面这样设置参数:</span></p> <p style="margin-bottom: 0px;outline: 0px;color: rgba(0, 0, 0, 0.9);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: left;"><span style="outline: 0px;font-size: 15px;"><br style="outline: 0px;"></span></p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="javascript"><code style="white-space:pre-wrap;outline: 0px;max-width: 1000%;text-align: left;display: flex;font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="outline: 0px;max-width: 1000%;">-Xlog:<span class="code-snippet__string" style="outline: 0px;max-width: 1000%;">'gc*=error,heap*=debug'</span></span></code></pre> </section> <h3 style="outline: 0px;color: rgba(0, 0, 0, 0.9);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: left;"><span style="outline: 0px;font-size: 15px;"><br style="outline: 0px;"></span></h3> <h3 style="outline: 0px;color: rgba(0, 0, 0, 0.9);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);"><span style="outline: 0px;color: rgb(171, 25, 66);"><strong style="outline: 0px;"><span style="outline: 0px;font-size: 15px;text-align: left;">配置日志输出位置</span></strong></span></h3> <section style="margin-bottom: 0px;outline: 0px;color: rgba(0, 0, 0, 0.9);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);"> <span style="outline: 0px;font-size: 15px;"><br style="outline: 0px;"></span> </section> <section style="margin-bottom: 0px;outline: 0px;color: rgba(0, 0, 0, 0.9);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: left;"> <span style="outline: 0px;font-size: 15px;">默认情况下,VM 日志将打印到 stdout。但是,这通常不是 VM 日志推荐的位置。在大多数情况下,最好将 VM 日志写入单独的文件。可以按照下面这样设置参数:</span> </section> <section style="margin-bottom: 0px;outline: 0px;color: rgba(0, 0, 0, 0.9);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: left;"> <span style="outline: 0px;font-size: 15px;"><br style="outline: 0px;"></span> </section> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="ruby"><code style="white-space:pre-wrap;outline: 0px;max-width: 1000%;text-align: left;display: flex;font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="outline: 0px;max-width: 1000%;">-<span class="code-snippet__symbol" style="outline: 0px;max-width: 1000%;">Xlog:</span><span class="code-snippet__string" style="outline: 0px;max-width: 1000%;">'gc*,heap*'</span><span class="code-snippet__symbol" style="outline: 0px;max-width: 1000%;">:vm-logging</span>.log</span></code></pre> </section> <p style="margin-bottom: 0px;outline: 0px;color: rgba(0, 0, 0, 0.9);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: left;"><br style="outline: 0px;"></p> <p style="margin-bottom: 0px;outline: 0px;color: rgba(0, 0, 0, 0.9);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: left;"><span style="outline: 0px;font-size: 15px;">在 java 命令中使用多个 Xlog 实例也是有效的,这对于根据类型将 VM 日志写入不同位置非常有用。在下面的示例中,gc 日志语句写入 gc.log,而堆日志语句写入 heap.log。</span></p> <p style="margin-bottom: 0px;outline: 0px;color: rgba(0, 0, 0, 0.9);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: left;"><span style="outline: 0px;font-size: 15px;"><br style="outline: 0px;"></span></p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="ruby"><code style="white-space:pre-wrap;outline: 0px;max-width: 1000%;text-align: left;display: flex;font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="outline: 0px;max-width: 1000%;">-<span class="code-snippet__symbol" style="outline: 0px;max-width: 1000%;">Xlog:</span><span class="code-snippet__string" style="outline: 0px;max-width: 1000%;">'gc*'</span><span class="code-snippet__symbol" style="outline: 0px;max-width: 1000%;">:gc</span>.log&nbsp;-<span class="code-snippet__symbol" style="outline: 0px;max-width: 1000%;">Xlog:</span><span class="code-snippet__string" style="outline: 0px;max-width: 1000%;">`heap*`</span><span class="code-snippet__symbol" style="outline: 0px;max-width: 1000%;">:heap</span>.log</span></code></pre> </section> <h3 style="outline: 0px;color: rgba(0, 0, 0, 0.9);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: left;"><br style="outline: 0px;"></h3> <h3 style="outline: 0px;color: rgba(0, 0, 0, 0.9);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);"><span style="outline: 0px;color: rgb(171, 25, 66);"><strong style="outline: 0px;"><span style="outline: 0px;font-size: 15px;text-align: left;">减少日志性能开销</span></strong></span></h3> <p style="margin-bottom: 0px;outline: 0px;color: rgba(0, 0, 0, 0.9);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: left;"><br style="outline: 0px;"></p> <p style="margin-bottom: 0px;outline: 0px;color: rgba(0, 0, 0, 0.9);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: left;"><span style="outline: 0px;font-size: 15px;">VM 日志记录可能导致 Java 应用程序出现相当大的开销。要解决这个问题,请考虑启用异步日志记录&nbsp;-Xlog: async,它将日志语句写入内存缓冲区,该缓冲区将定期刷新。缓冲区大小可以使用&nbsp;-XX:AsyncLogBufferSize=&lt;bytes&gt;&nbsp;进行配置。例如:</span></p> <p style="margin-bottom: 0px;outline: 0px;color: rgba(0, 0, 0, 0.9);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: left;"><br style="outline: 0px;"></p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="ruby"><code style="white-space:pre-wrap;outline: 0px;max-width: 1000%;text-align: left;display: flex;font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="outline: 0px;max-width: 1000%;">-<span class="code-snippet__symbol" style="outline: 0px;max-width: 1000%;">Xlog:</span><span class="code-snippet__string" style="outline: 0px;max-width: 1000%;">'gc*=trace'</span><span class="code-snippet__symbol" style="outline: 0px;max-width: 1000%;">:gc-trace</span>.log&nbsp;-<span class="code-snippet__symbol" style="outline: 0px;max-width: 1000%;">Xlog:</span>async&nbsp;-<span class="code-snippet__symbol" style="outline: 0px;max-width: 1000%;">XX:</span>AsyncLogBufferSize=<span class="code-snippet__number" style="outline: 0px;max-width: 1000%;">102400</span></span></code></pre> </section> <h2 style="outline: 0px;color: rgba(0, 0, 0, 0.9);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: left;"><br style="outline: 0px;"></h2> <h2 style="outline: 0px;color: rgba(0, 0, 0, 0.9);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);"><span style="outline: 0px;color: rgb(171, 25, 66);"><strong style="outline: 0px;"><span style="outline: 0px;font-size: 15px;text-align: left;">为运行中的 JVM 上配置日志记录</span></strong></span></h2> <section style="margin-bottom: 0px;outline: 0px;color: rgba(0, 0, 0, 0.9);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);"> <span style="outline: 0px;font-size: 15px;"><br style="outline: 0px;"></span> </section> <section style="margin-bottom: 0px;outline: 0px;color: rgba(0, 0, 0, 0.9);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: left;"> <span style="outline: 0px;font-size: 15px;">可以使用 jcmd 和 VM.log 在 JVM 上配置 VM 日志记录。所有 java 命令配置 VM 日志记录时提供的所有配置选项都可使用,但是需要通过 output、output_options、what 和 decorators 参数指定,下面是一个 jcmd 的使用示例:</span> </section> <p style="margin-bottom: 0px;outline: 0px;color: rgba(0, 0, 0, 0.9);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: left;"><span style="outline: 0px;font-size: 15px;"><br style="outline: 0px;"></span></p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="cpp"><code style="white-space:pre-wrap;outline: 0px;max-width: 1000%;text-align: left;display: flex;font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace;"><span class="code-snippet_outer" style="outline: 0px;max-width: 1000%;">jcmd&nbsp;&lt;pid&gt;&nbsp;VM.<span class="code-snippet__built_in" style="outline: 0px;max-width: 1000%;">log</span>&nbsp;output=<span class="code-snippet__string" style="outline: 0px;max-width: 1000%;">"file=heap.log"</span>&nbsp;output_options=<span class="code-snippet__string" style="outline: 0px;max-width: 1000%;">"filecount=5,filesize=10m"</span>&nbsp;what=<span class="code-snippet__string" style="outline: 0px;max-width: 1000%;">"heap=info"</span>&nbsp;decorators=<span class="code-snippet__string" style="outline: 0px;max-width: 1000%;">"time,level"</span></span></code></pre> </section> <h2 style="outline: 0px;color: rgba(0, 0, 0, 0.9);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: left;"><br style="outline: 0px;"></h2> <h2 style="outline: 0px;color: rgba(0, 0, 0, 0.9);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);"><span style="outline: 0px;color: rgb(171, 25, 66);"><strong style="outline: 0px;"><span style="outline: 0px;font-size: 15px;text-align: left;">更多阅读材料</span></strong></span></h2> <p style="margin-bottom: 0px;outline: 0px;color: rgba(0, 0, 0, 0.9);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: left;"><br style="outline: 0px;"></p> <ul class="list-paddingleft-1" style="padding-left: 1.2em;outline: 0px;color: rgba(0, 0, 0, 0.9);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);"> <li style="outline: 0px;font-size: 12px;color: rgb(136, 136, 136);"><p style="outline: 0px;text-align: left;"><span style="outline: 0px;">JEP 158: 统一的 JVM 日志记录:https://openjdk.org/jeps/158]</span></p></li> <li style="outline: 0px;font-size: 12px;color: rgb(136, 136, 136);"><p style="outline: 0px;text-align: left;"><span style="outline: 0px;">JEP 271: 统一的 GC 日志记录:https://openjdk.org/jeps/271</span></p></li> <li style="outline: 0px;font-size: 12px;color: rgb(136, 136, 136);"><p style="outline: 0px;text-align: left;"><span style="outline: 0px;">使用 JVM 统一日志框架启用日志记录:https://docs.oracle.com/en/java/javase/19/docs/specs/man/java.html#enable-logging-with-the-jvm-unified-logging-framework</span></p></li> <li style="outline: 0px;font-size: 12px;color: rgb(136, 136, 136);"><p style="outline: 0px;text-align: left;"><span style="outline: 0px;">jcmd 示例中的日志记录配置:https://gist.github.com/thomasdarimont/f89fc79491241af7a064e1b3ca2757a9</span></p></li> <li style="outline: 0px;font-size: 12px;color: rgb(136, 136, 136);"><p style="outline: 0px;text-align: left;"><span style="outline: 0px;">Xlog:help 的输出:https://gist.github.com/wkorando/be4a0de126371b64c48c7fac83496a53</span></p></li> </ul> <p style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(154, 154, 154);font-size: 15px;"><span style="outline: 0px;font-size: 14px;"></span></p> <blockquote class="js_blockquote_wrap" data-type="2" data-url="" data-author-name="" data-content-utf8-length="58" data-source-title="" style="outline: 0px;color: var(--weui-FG-1);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);"> <section class="js_blockquote_digest" style="outline: 0px;"> <section style="outline: 0px;"> <p style="outline: 0px;color: rgb(154, 154, 154);"><span style="outline: 0px;font-size: 14px;">转自:Billy Korando,</span></p> <p style="outline: 0px;color: rgb(154, 154, 154);"><span style="outline: 0px;font-size: 14px;">链接:https://inside.java/2022/11/07/sip071/</span></p> </section> </section> </blockquote>

vivo全球商城:电商交易平台设计

作者:微信小助手

<section> <mp-common-profile class="js_uneditable custom_select_card mp_profile_iframe" data-pluginname="mpprofile" data-weui-theme="light" data-id="MzI4NjY4MTU5Nw==" data-headimg="http://mmbiz.qpic.cn/mmbiz_png/4g5IMGibSxt45QXJZicZ9gaNU2mRSlvqhQd94MJ7oQh4QFj1ibPV66xnUiaKoicSatwaGXepL5sBDSDLEckicX1ttibHg/0?wx_fmt=png" data-nickname="vivo互联网技术" data-alias="vivoVMIC" data-signature="分享 vivo 互联网技术干货与沙龙活动,推荐最新行业动态与热门会议。" data-from="0" data-is_biz_ban="0"></mp-common-profile> </section> <section style="font-size: 15px;line-height: 1.6;box-sizing: border-box;"> <section style="margin: 10px 0% 8px;text-align: left;justify-content: flex-start;display: flex;flex-flow: row nowrap;box-sizing: border-box;" powered-by="xiumi.us"> <section style="display: inline-block;width: 100%;vertical-align: top;border-left: 3px solid rgb(219, 219, 219);border-bottom-left-radius: 0px;padding-left: 8px;align-self: flex-start;flex: 0 0 auto;box-sizing: border-box;"> <section style="color: rgba(0, 0, 0, 0.5);font-size: 14px;text-align: justify;box-sizing: border-box;" powered-by="xiumi.us"> <p style="white-space: normal;box-sizing: border-box;">作者:vivo 官网商城开发团队 - Cheng Kun、Liu Wei</p> </section> </section> </section> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <section style="margin-top: 10px;margin-bottom: 10px;text-align: center;box-sizing: border-box;" powered-by="xiumi.us"> <section style="display: inline-block;width: 100%;border-width: 1px;border-style: solid;border-color: rgb(160, 160, 160);padding: 10px;box-sizing: border-box;"> <section style="text-align: left;box-sizing: border-box;" powered-by="xiumi.us"> <section style="font-size: 14px;text-align: justify;line-height: 1.8;padding-right: 5px;padding-left: 5px;color: rgb(160, 160, 160);box-sizing: border-box;"> <p style="white-space: normal;box-sizing: border-box;">本文介绍了交易平台的设计理念和关键技术方案,以及实践过程中的思考与挑战。</p> <p style="white-space: normal;box-sizing: border-box;"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;box-sizing: border-box;">点击查阅:<a target="_blank" href="https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzI4NjY4MTU5Nw==&amp;action=getalbum&amp;album_id=1500522652925526016#wechat_redirect" textvalue="《vivo 全球商城》系列文章" linktype="text" imgurl="" imgdata="null" tab="innerlink" data-linktype="2">《vivo 全球商城》系列文章</a></p> </section> </section> <section style="margin-right: 0%;margin-bottom: -5px;margin-left: 0%;text-align: right;line-height: 1;font-size: 5px;transform: translate3d(5px, 0px, 0px);box-sizing: border-box;" powered-by="xiumi.us"> <section style="width: 0px;display: inline-block;vertical-align: top;border-bottom: 0.6em solid rgb(160, 160, 160);border-right: 0.6em solid rgb(160, 160, 160);box-sizing: border-box;border-top: 0.6em solid transparent !important;border-left: 0.6em solid transparent !important;"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> </section> </section> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <section style="margin-top: 10px;margin-bottom: 10px;text-align: center;box-sizing: border-box;" powered-by="xiumi.us"> <section style="padding: 3px;display: inline-block;border-bottom: 1px solid rgb(65, 94, 255);font-size: 17px;color: rgb(65, 94, 255);box-sizing: border-box;"> <p style="box-sizing: border-box;">一、背景</p> </section> </section> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <section style="box-sizing: border-box;" powered-by="xiumi.us"> <p style="white-space: normal;box-sizing: border-box;">vivo官方商城经过了七年的迭代,从单体架构逐步演进到微服务架构,我们的开发团队沉淀了许多宝贵的技术与经验,对电商领域业务也有相当深刻的理解。</p> <p style="white-space: normal;box-sizing: border-box;"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;box-sizing: border-box;">去年初,团队承接了O2O商城的建设任务,还有即将成立的礼品中台,以及官方商城的线上购买线下门店送货需求,都需要搭建底层的商品、交易和库存能力。</p> <p style="white-space: normal;box-sizing: border-box;"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;box-sizing: border-box;">为节约研发与运维成本,避免重复造轮子,我们决定采用平台化的思想来搭建底层系统,以通用能力灵活支撑上层业务的个性化需求。</p> <p style="white-space: normal;box-sizing: border-box;"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;box-sizing: border-box;">包括交易平台、商品平台、库存平台、营销平台在内的一整套电商平台化系统应运而生。</p> <p style="white-space: normal;box-sizing: border-box;"><br></p> </section> <p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.37777777777777777" data-s="300,640" src="/upload/512c80d66f587d6fa1e35d6f917fb09a.jpg" data-type="jpeg" data-w="1080" style=""></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us">本文将介绍交易平台的架构设计理念与实践,以及上线后持续迭代过程中的挑战与思考。</p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <section style="margin-top: 10px;margin-bottom: 10px;text-align: center;box-sizing: border-box;" powered-by="xiumi.us"> <section style="padding: 3px;display: inline-block;border-bottom: 1px solid rgb(65, 94, 255);font-size: 17px;color: rgb(65, 94, 255);box-sizing: border-box;"> <p style="box-sizing: border-box;">二、整体架构</p> </section> </section> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><span style="font-size: 16px;color: rgb(65, 95, 255);box-sizing: border-box;">2.1 架构目标</span></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us">除了高并发、高性能、高可用这三高外,还希望做到:</p> <section style="margin-top: 10px;margin-bottom: 10px;text-align: right;box-sizing: border-box;" powered-by="xiumi.us"> <section style="display: inline-block;width: 100%;border-width: 1px;border-style: solid;border-color: transparent;padding: 10px;background-color: rgb(239, 239, 239);height: auto;box-sizing: border-box;"> <section style="font-size: 14px;text-align: justify;box-sizing: border-box;" powered-by="xiumi.us"> <ol class="list-paddingleft-1" style="padding-left: 40px;list-style-position: outside;"> <li style="box-sizing: border-box;"><p style="box-sizing: border-box;"><strong style="box-sizing: border-box;"><span style="font-size: 15px;box-sizing: border-box;">低成本</span></strong></p><p style="box-sizing: border-box;"><span style="font-size: 15px;box-sizing: border-box;">注重模型与服务的可重用性,灵活支撑各业务的个性化需求,提高开发效率,降低人力成本。</span></p></li> <li style="box-sizing: border-box;"><p style="box-sizing: border-box;"><strong style="box-sizing: border-box;"><span style="font-size: 15px;box-sizing: border-box;">高扩展</span></strong><span style="font-size: 15px;box-sizing: border-box;"> </span></p><p style="box-sizing: border-box;"><span style="font-size: 15px;box-sizing: border-box;">系统架构简单清晰,应用系统间耦合低,容易水平扩展,业务功能增改方便快捷。</span></p></li> </ol> </section> </section> </section> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><span style="font-size: 16px;color: rgb(65, 95, 255);box-sizing: border-box;">2.2 系统架构</span></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><strong style="box-sizing: border-box;">(1)电商平台整体架构中的交易平台</strong></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><strong style="box-sizing: border-box;"><br></strong></p> <p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.9216417910447762" data-s="300,640" src="/upload/6a13636b12e7c5037e651d4cb32f6f9f.png" data-type="png" data-w="804" style=""></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><strong style="box-sizing: border-box;">(2)交易平台系统架构</strong></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.5764462809917356" data-s="300,640" src="/upload/3b75c7ed7a0e67f9e915cb77c2e08acb.png" data-type="png" data-w="968" style=""></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><span style="font-size: 16px;color: rgb(65, 95, 255);box-sizing: border-box;">2.3 数据模型</span></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="1.045945945945946" data-s="300,640" src="/upload/1099ade802763e4000b1ccc411452222.png" data-type="png" data-w="740" style=""></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br></p> <section style="margin-top: 10px;margin-bottom: 10px;text-align: center;box-sizing: border-box;" powered-by="xiumi.us"> <section style="padding: 3px;display: inline-block;border-bottom: 1px solid rgb(65, 94, 255);font-size: 17px;color: rgb(65, 94, 255);box-sizing: border-box;"> <p style="box-sizing: border-box;">三、关键方案设计</p> </section> </section> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><span style="font-size: 16px;color: rgb(65, 95, 255);box-sizing: border-box;">3.1 多租户设计</span></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><strong style="box-sizing: border-box;">(1)背景和目标</strong></p> <section style="margin-top: 10px;margin-bottom: 10px;text-align: right;box-sizing: border-box;" powered-by="xiumi.us"> <section style="display: inline-block;width: 100%;border-width: 1px;border-style: solid;border-color: transparent;padding: 10px;background-color: rgb(239, 239, 239);height: auto;box-sizing: border-box;"> <section style="text-align: justify;box-sizing: border-box;" powered-by="xiumi.us"> <ul class="list-paddingleft-1" style="padding-left: 40px;list-style-position: outside;"> <li style="box-sizing: border-box;"><p style="box-sizing: border-box;">交易平台面向多个租户(业务方),需要能够存储大量订单数据,并提供高可用高性能的服务。</p></li> <li style="box-sizing: border-box;"><p style="box-sizing: border-box;">不同租户的数据量和并发量可能有很大区别,要能根据实际情况灵活分配存储资源。</p></li> </ul> </section> </section> </section> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><strong style="box-sizing: border-box;">(2)设计方案</strong></p> <section style="margin-top: 10px;margin-bottom: 10px;box-sizing: border-box;" powered-by="xiumi.us"> <section style="display: inline-block;width: 100%;border-width: 1px;border-style: solid;border-color: transparent;padding: 10px;background-color: rgb(239, 239, 239);box-sizing: border-box;"> <ul class="list-paddingleft-1" style="padding-left: 40px;list-style-position: outside;" powered-by="xiumi.us"> <li style="box-sizing: border-box;"><p style="box-sizing: border-box;">考虑到交易系统OLTP特性和开发人员熟练程度,采用MySQL作为底层存储、ShardingSphere作为分库分表中间件,将用户标识(userId)作为分片键,保证同一个用户的订单落在同一个库中。</p></li> <li style="box-sizing: border-box;"><p style="box-sizing: border-box;">接入新租户时约定一个租户编码(tenantCode),所有接口都要带上这个参数;租户对数据量和并发量进行评估,分配至少满足未来五年需求的库表数量。</p></li> <li style="box-sizing: border-box;"><p style="box-sizing: border-box;">租户与库表的映射关系:租户编码 -&gt; {库数量,表数量,起始库编号,起始表编号}。</p></li> </ul> </section> </section> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <section style="box-sizing: border-box;" powered-by="xiumi.us"> <p style="white-space: normal;box-sizing: border-box;">通过上面的映射关系,可以为每个租户灵活分配存储资源,数据量很小的租户还能复用已有的库表。</p> <p style="white-space: normal;box-sizing: border-box;"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;box-sizing: border-box;">示例一:</p> </section> <section style="margin: 10px 0% 8px;text-align: left;justify-content: flex-start;display: flex;flex-flow: row nowrap;box-sizing: border-box;" powered-by="xiumi.us"> <section style="display: inline-block;width: 100%;vertical-align: top;border-left: 3px solid rgb(219, 219, 219);border-bottom-left-radius: 0px;padding-left: 8px;align-self: flex-start;flex: 0 0 auto;box-sizing: border-box;"> <section style="color: rgba(0, 0, 0, 0.5);text-align: justify;box-sizing: border-box;" powered-by="xiumi.us"> <p style="white-space: normal;box-sizing: border-box;">新租户接入前已有4库*16表,新租户的订单量少且并发低,直接复用已有的0号库0号表,映射关系是:租户编码-&gt; 1,1,0,0</p> </section> </section> </section> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us">示例二:</p> <section style="margin: 10px 0% 8px;text-align: left;justify-content: flex-start;display: flex;flex-flow: row nowrap;box-sizing: border-box;" powered-by="xiumi.us"> <section style="display: inline-block;width: 100%;vertical-align: top;border-left: 3px solid rgb(219, 219, 219);border-bottom-left-radius: 0px;padding-left: 8px;align-self: flex-start;flex: 0 0 auto;box-sizing: border-box;"> <section style="color: rgba(0, 0, 0, 0.5);text-align: justify;box-sizing: border-box;" powered-by="xiumi.us"> <p style="white-space: normal;box-sizing: border-box;">新租户接入前已有4库*16表,新租户的订单量多但并发低,用原有的0号库中新建8张表来存储,映射关系是:租户编码-&gt; 1,8,0,16</p> </section> </section> </section> <section style="box-sizing: border-box;" powered-by="xiumi.us"> <p style="white-space: normal;box-sizing: border-box;"><br></p> <p style="white-space: normal;box-sizing: border-box;">示例三:</p> </section> <section style="margin: 10px 0% 8px;text-align: left;justify-content: flex-start;display: flex;flex-flow: row nowrap;box-sizing: border-box;" powered-by="xiumi.us"> <section style="display: inline-block;width: 100%;vertical-align: top;border-left: 3px solid rgb(219, 219, 219);border-bottom-left-radius: 0px;padding-left: 8px;align-self: flex-start;flex: 0 0 auto;box-sizing: border-box;"> <section style="color: rgba(0, 0, 0, 0.5);text-align: justify;box-sizing: border-box;" powered-by="xiumi.us"> <p style="white-space: normal;box-sizing: border-box;">新租户接入前已有4库*16表,新租户的订单量多且并发高,用新的4库*8表来存储,映射关系是:租户编码-&gt; 4,8,4,0</p> </section> </section> </section> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.35269709543568467" data-s="300,640" src="/upload/93b1c30b04b9af5914912317cc62fe8e.png" data-type="png" data-w="482" style=""></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us">用户订单所属库表计算公式</p> <section style="margin: 10px 0% 8px;text-align: left;justify-content: flex-start;display: flex;flex-flow: row nowrap;box-sizing: border-box;" powered-by="xiumi.us"> <section style="display: inline-block;width: 100%;vertical-align: top;border-left: 3px solid rgb(219, 219, 219);border-bottom-left-radius: 0px;padding-left: 8px;align-self: flex-start;flex: 0 0 auto;box-sizing: border-box;"> <section style="color: rgba(0, 0, 0, 0.5);text-align: justify;box-sizing: border-box;" powered-by="xiumi.us"> <p style="white-space: normal;box-sizing: border-box;">库序号 = Hash(userId) / 表数量 % 库数量 + 起始库编号<br style="box-sizing: border-box;">表序号 = Hash(userId) % 表数量 + 起始表编号</p> </section> </section> </section> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us">可能有小伙伴会问:为什么计算库序号时要先除以表数量?下面的公式会有什么问题?</p> <section style="margin: 10px 0% 8px;text-align: left;justify-content: flex-start;display: flex;flex-flow: row nowrap;box-sizing: border-box;" powered-by="xiumi.us"> <section style="display: inline-block;width: 100%;vertical-align: top;border-left: 3px solid rgb(219, 219, 219);border-bottom-left-radius: 0px;padding-left: 8px;align-self: flex-start;flex: 0 0 auto;box-sizing: border-box;"> <section style="color: rgba(0, 0, 0, 0.5);text-align: justify;box-sizing: border-box;" powered-by="xiumi.us"> <p style="white-space: normal;box-sizing: border-box;">库序号 = Hash(userId) % 库数量 + 起始库编号<br style="box-sizing: border-box;">表序号 = Hash(userId) % 表数量 + 起始表编号</p> </section> </section> </section> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <section style="box-sizing: border-box;" powered-by="xiumi.us"> <p style="white-space: normal;box-sizing: border-box;">答案是,当库数量和表数量存在公因数时,会存在倾斜问题,先除以表数量就能剔除公因数。</p> <p style="white-space: normal;box-sizing: border-box;"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;box-sizing: border-box;">以2库4表为例,对4取模等于1的数,对2取模也一定等于1,因此0号库的1号表中不会有任何数据,同理,0号库的3号表、1号库的0号表、1号库的2号表中都不会有数据。</p> </section> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us">路由过程如下图所示:</p> <p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="1.1210287443267777" data-s="300,640" src="/upload/2a4e4d360361ce86d982d19005b524ac.png" data-type="png" data-w="661" style=""></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><strong style="box-sizing: border-box;">(3)局限性和应对办法</strong></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <ul class="list-paddingleft-1" style="padding-left: 40px;list-style-position: outside;" powered-by="xiumi.us"> <li style="box-sizing: border-box;"><p style="box-sizing: border-box;"><strong style="box-sizing: border-box;">全局唯一ID</strong><br style="box-sizing: border-box;"></p></li> </ul> <section style="box-sizing: border-box;" powered-by="xiumi.us"> <p style="white-space: normal;box-sizing: border-box;"><strong style="box-sizing: border-box;">问题:</strong>分库分表后,数据库自增主键不再全局唯一,不能作为订单号来使用。且很多内部系统间的交互接口只有订单号,没有用户标识这个分片键。</p> <p style="white-space: normal;box-sizing: border-box;"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;box-sizing: border-box;"><strong style="box-sizing: border-box;">方案:</strong>如下图所示,参考雪花算法来生成全局唯一订单号,同时将库表编号隐含在其中(两个5bit分别存储库表编号),这样就能在没有用户标识的场景下,从订单号中获取库表编号。</p> </section> <p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.2516930022573363" data-s="300,640" src="/upload/127169379478683cd7593b63663a6b42.png" data-type="png" data-w="886" style=""></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br></p> <ul class="list-paddingleft-1" style="padding-left: 40px;list-style-position: outside;" powered-by="xiumi.us"> <li style="box-sizing: border-box;"><p style="box-sizing: border-box;"><strong style="box-sizing: border-box;">全库全表搜索</strong><br style="box-sizing: border-box;"></p></li> </ul> <section style="box-sizing: border-box;" powered-by="xiumi.us"> <p style="white-space: normal;box-sizing: border-box;"><strong style="box-sizing: border-box;">问题:</strong>管理后台需要根据各种筛选条件,分页查询所有满足条件的订单。</p> <p style="white-space: normal;box-sizing: border-box;"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;box-sizing: border-box;"><strong style="box-sizing: border-box;">方案:</strong>将订单数据冗余存储一份到搜索引擎Elasticsearch中,满足各种场景下的快速灵活查询需求。</p> </section> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><span style="font-size: 16px;color: rgb(65, 95, 255);box-sizing: border-box;">3.2 状态机设计</span></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><strong style="box-sizing: border-box;">(1)背景</strong></p> <ul class="list-paddingleft-1" style="padding-left: 40px;list-style-position: outside;" powered-by="xiumi.us"> <li style="box-sizing: border-box;"><p style="box-sizing: border-box;">之前做官方商城时,由于是定制化业务开发,各类型的订单和售后单的状态流转都是写死的,比如常规订单在下单后是待付款,付款后是待发货,发货后是待收货;虚拟商品订单不需要发货,没有待发货状态。</p></li> <li style="box-sizing: border-box;"><p style="box-sizing: border-box;">现在要做的是平台系统,不可能再为每个业务方做定制化开发,否则会导致频繁改动发版,代码错综冗余。</p></li> </ul> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><strong style="box-sizing: border-box;">(2)目标</strong></p> <ul class="list-paddingleft-1" style="padding-left: 40px;list-style-position: outside;" powered-by="xiumi.us"> <li style="box-sizing: border-box;"><p style="box-sizing: border-box;">引入订单状态机,能为每个业务方配置多套差异化的订单流程,类似于流程编排。</p></li> <li style="box-sizing: border-box;"><p style="box-sizing: border-box;">新增订单流程时,尽可能不改动代码,实现状态和操作的可复用性。</p></li> </ul> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><strong style="box-sizing: border-box;">(3)方案</strong></p> <ul class="list-paddingleft-1" style="padding-left: 40px;list-style-position: outside;" powered-by="xiumi.us"> <li style="box-sizing: border-box;"><p style="box-sizing: border-box;">在管理后台为每个租户维护一系列订单类型,数据转化为JSON格式存储在配置中心,或存储在数据库并同步到本地缓存中。</p></li> <li style="box-sizing: border-box;"><p style="box-sizing: border-box;">每个订单类型的配置包括:初始订单状态,以及每个状态下允许的操作和操作之后的目标状态。</p></li> <li style="box-sizing: border-box;"><p style="box-sizing: border-box;">当订单在执行某个动作时,使用订单状态机来修改订单状态。</p><p style="box-sizing: border-box;">订单状态机的公式是:</p><p style="box-sizing: border-box;"><strong>StateMachine(E,S —&gt; A&nbsp;,&nbsp;S’)</strong></p><p style="box-sizing: border-box;">表示订单在事件E的触发下执行动作A,并从原状态S转化为目标状态S’</p></li> <li style="box-sizing: border-box;"><p style="box-sizing: border-box;">每个订单类型配置完成后,生成数据的结构是</p></li> </ul> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="typescript"><code><span class="code-snippet_outer"><span class="code-snippet__comment">/**</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"> * 订单流程配置</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"> **/</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">@Data</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">class</span> OrderFlowConfig <span class="code-snippet__keyword">implements</span> Serializable {</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__comment">/**</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"> * 初始订单状态编码</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"> **/</span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">private</span> <span class="code-snippet__built_in">String</span> initStatus;</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__comment">/**</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"> * 每个订单状态下,可执行的操作及执行操作后的目标状态</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"> * Map&lt;原状态编码, Map&lt;订单操作类型编码, 目标状态编码&gt;&gt;</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"> */</span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">private</span> Map&lt;<span class="code-snippet__built_in">String</span>, Map&lt;<span class="code-snippet__built_in">String</span>, <span class="code-snippet__built_in">String</span>&gt;&gt; operations;</span></code><code><span class="code-snippet_outer">}</span></code></pre> </section> <ul class="list-paddingleft-1" style="padding-left: 40px;list-style-position: outside;" powered-by="xiumi.us"> <li style="box-sizing: border-box;"><p style="box-sizing: border-box;">订单商品行状态机、售后单状态机,也用同样的方式实现</p></li> </ul> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><span style="font-size: 16px;color: rgb(65, 95, 255);box-sizing: border-box;">3.3 通用操作触发器</span></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><strong style="box-sizing: border-box;">(1)背景</strong></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us">业务中通常都会有这样的延时需求,我们之前往往通过定时任务来扫描处理。</p> <ul class="list-paddingleft-1" style="padding-left: 40px;list-style-position: outside;" powered-by="xiumi.us"> <li style="box-sizing: border-box;"><p style="box-sizing: border-box;">下单后多久未支付,自动关闭订单</p></li> <li style="box-sizing: border-box;"><p style="box-sizing: border-box;">申请退款后商家多久未审核,自动同意申请</p></li> <li style="box-sizing: border-box;"><p style="box-sizing: border-box;">订单签收后多久未确认收货,自动确认收货</p></li> </ul> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><strong style="box-sizing: border-box;">(2)目标</strong></p> <ul class="list-paddingleft-1" style="padding-left: 40px;list-style-position: outside;" powered-by="xiumi.us"> <li style="box-sizing: border-box;"><p style="box-sizing: border-box;">业务方有类似的延时需求时,能够有通用的方式轻松实现</p></li> </ul> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><strong style="box-sizing: border-box;">(3)方案</strong></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us">设计通用操作触发器,具体步骤为:</p> <section style="margin-top: 10px;margin-bottom: 10px;box-sizing: border-box;" powered-by="xiumi.us"> <section style="display: inline-block;width: 100%;border-width: 1px;border-style: solid;border-color: transparent;padding: 10px;background-color: rgb(239, 239, 239);box-sizing: border-box;"> <ol class="list-paddingleft-1" style="padding-left: 40px;list-style-position: outside;" powered-by="xiumi.us"> <li style="box-sizing: border-box;"><p style="box-sizing: border-box;">配置触发器,粒度是状态机的流程类型。</p></li> <li style="box-sizing: border-box;"><p style="box-sizing: border-box;">创建订单/售后单时或订单状态变化时,如果有满足条件的触发器,发送延迟消息。</p></li> <li style="box-sizing: border-box;"><p style="box-sizing: border-box;">收到延迟消息后,再次判断执行条件,执行配置的操作。</p></li> </ol> </section> </section> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us">触发器的配置包括:</p> <section style="margin-top: 10px;margin-bottom: 10px;box-sizing: border-box;" powered-by="xiumi.us"> <section style="display: inline-block;width: 100%;border-width: 1px;border-style: solid;border-color: transparent;padding: 10px;background-color: rgb(239, 239, 239);box-sizing: border-box;"> <ol class="list-paddingleft-1" style="padding-left: 40px;list-style-position: outside;" powered-by="xiumi.us"> <li style="box-sizing: border-box;"><p style="box-sizing: border-box;"><strong style="box-sizing: border-box;">注册时间:</strong>可选订单创建时,或订单状态变化时</p></li> <li style="box-sizing: border-box;"><p style="box-sizing: border-box;"><strong style="box-sizing: border-box;">执行时间:</strong>可使用JsonPath表达式选取订单模型中的时间,并可叠加延迟时间</p></li> <li style="box-sizing: border-box;"><p style="box-sizing: border-box;"><strong style="box-sizing: border-box;">注册条件:</strong>使用QLExpress配置,满足条件才注册</p></li> <li style="box-sizing: border-box;"><p style="box-sizing: border-box;"><strong style="box-sizing: border-box;">执行条件:</strong>使用QLExpress配置,满足条件才执行操作</p></li> <li style="box-sizing: border-box;"><p style="box-sizing: border-box;"><strong style="box-sizing: border-box;">执行的操作和参数</strong></p></li> </ol> </section> </section> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><span style="font-size: 16px;color: rgb(65, 95, 255);box-sizing: border-box;">3.4 分布式事务</span></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us">对交易平台而言,分布式事务是一个经典问题,比如:</p> <ul class="list-paddingleft-1" style="padding-left: 40px;list-style-position: outside;" powered-by="xiumi.us"> <li style="box-sizing: border-box;"><p style="box-sizing: border-box;">创建订单时,需要同时扣减库存、占用优惠券,取消订单时则需要进行回退。</p></li> <li style="box-sizing: border-box;"><p style="box-sizing: border-box;">用户支付成功后,需要通知发货系统给用户发货。</p></li> <li style="box-sizing: border-box;"><p style="box-sizing: border-box;">用户确认收货后,需要通知积分系统给用户发放购物奖励的积分。</p></li> </ul> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us">我们是如何保证微服务架构下数据一致性的呢?首先要区分业务场景对一致性的要求。</p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><strong style="box-sizing: border-box;">(1)强一致性场景</strong></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <section style="box-sizing: border-box;" powered-by="xiumi.us"> <p style="white-space: normal;box-sizing: border-box;">比如订单创建和取消时对库存和优惠券系统的调用,如果不能保证强一致,可能导致库存超卖或优惠券重复使用。</p> <p style="white-space: normal;box-sizing: border-box;"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;box-sizing: border-box;">对于强一致性场景,我们采用Seata的AT模式来处理,下面的示意图取自seata官方文档。</p> <p style="white-space: normal;box-sizing: border-box;"><br></p> <p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.5916666666666667" data-s="300,640" src="/upload/3e1bc9b445a25024ae56719028b8d620.png" data-type="png" data-w="1080" style=""></p> <p style="white-space: normal;box-sizing: border-box;"><br></p> </section> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><strong style="box-sizing: border-box;">(2)最终一致性场景</strong></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <section style="box-sizing: border-box;" powered-by="xiumi.us"> <p style="white-space: normal;box-sizing: border-box;">比如支付成功后通知发货系统发货,确认收货后通知积分系统发放积分,只要保证能够通知成功即可,不需要同时成功同时失败。</p> <p style="white-space: normal;box-sizing: border-box;"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;box-sizing: border-box;">对于最终一致性场景,我们采用的是本地消息表方案:在本地事务中将要执行的异步操作记录在消息表中,如果执行失败,可以通过定时任务来补偿。</p> <p style="white-space: normal;box-sizing: border-box;"><br></p> <p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.5201560468140443" data-s="300,640" src="/upload/62d989700f27d7b194d338371553e8d9.png" data-type="png" data-w="769" style=""></p> <p style="white-space: normal;box-sizing: border-box;"><br></p> </section> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><span style="font-size: 16px;color: rgb(65, 95, 255);box-sizing: border-box;">3.5 高可用与安全设计</span></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <section style="box-sizing: border-box;" powered-by="xiumi.us"> <ul class="list-paddingleft-1" style="padding-left: 40px;list-style-position: outside;"> <li style="box-sizing: border-box;"><p style="box-sizing: border-box;"><strong style="box-sizing: border-box;">熔断</strong><br style="box-sizing: border-box;"></p></li> </ul> <p style="white-space: normal;box-sizing: border-box;">使用Hystrix组件,对依赖的外部系统添加熔断保护,防止某个系统故障的影响扩大到整个分布式系统中。</p> </section> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <ul class="list-paddingleft-1" style="padding-left: 40px;list-style-position: outside;" powered-by="xiumi.us"> <li style="box-sizing: border-box;"><p style="box-sizing: border-box;"><strong style="box-sizing: border-box;">限流</strong><br style="box-sizing: border-box;"></p></li> </ul> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us">通过性能测试找出并解决性能瓶颈,掌握系统的吞吐量数据,为限流和熔断的配置提供参考。</p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <ul class="list-paddingleft-1" style="padding-left: 40px;list-style-position: outside;" powered-by="xiumi.us"> <li style="box-sizing: border-box;"><p style="box-sizing: border-box;"><strong style="box-sizing: border-box;">并发锁</strong><br style="box-sizing: border-box;"></p></li> </ul> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us">任何订单更新操作之前,会通过数据库行级锁加以限制,防止出现并发更新。</p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <section style="box-sizing: border-box;" powered-by="xiumi.us"> <ul class="list-paddingleft-1" style="padding-left: 40px;list-style-position: outside;"> <li style="box-sizing: border-box;"><p style="box-sizing: border-box;"><strong style="box-sizing: border-box;">幂等性</strong><br style="box-sizing: border-box;"></p></li> </ul> <p style="white-space: normal;box-sizing: border-box;">所有接口均具备幂等性,上游调用我们接口如果出现超时之类的异常,可以放心重试。</p> <p style="white-space: normal;box-sizing: border-box;"><br style="box-sizing: border-box;"></p> <ul class="list-paddingleft-1" style="padding-left: 40px;list-style-position: outside;"> <li style="box-sizing: border-box;"><p style="box-sizing: border-box;"><strong style="box-sizing: border-box;">网络隔离</strong></p></li> </ul> <p style="white-space: normal;box-sizing: border-box;">只有极少数第三方接口可通过外网访问,且都有白名单、数据加密、签名验证等保护,内部系统交互使用内网域名和RPC接口。</p> <p style="white-space: normal;box-sizing: border-box;"><br style="box-sizing: border-box;"></p> <ul class="list-paddingleft-1" style="padding-left: 40px;list-style-position: outside;"> <li style="box-sizing: border-box;"><p style="box-sizing: border-box;"><strong style="box-sizing: border-box;">监控和告警</strong></p></li> </ul> <p style="white-space: normal;box-sizing: border-box;">通过配置日志平台的错误日志报警、调用链的服务分析告警,再加上公司各中间件和基础组件的监控告警功能,让我们能够能够第一时间发现系统异常。</p> </section> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><span style="font-size: 16px;color: rgb(65, 95, 255);box-sizing: border-box;">3.6 其他考虑</span></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <section style="box-sizing: border-box;" powered-by="xiumi.us"> <ul class="list-paddingleft-1" style="padding-left: 40px;list-style-position: outside;"> <li style="box-sizing: border-box;"><p style="box-sizing: border-box;"><strong style="box-sizing: border-box;">是否用领域驱动设计</strong></p></li> </ul> <p style="white-space: normal;box-sizing: border-box;">考虑到团队非敏捷型组织架构,又缺少领域专家,因此没有采用</p> <p style="white-space: normal;box-sizing: border-box;"><br style="box-sizing: border-box;"></p> <ul class="list-paddingleft-1" style="padding-left: 40px;list-style-position: outside;"> <li style="box-sizing: border-box;"><p style="box-sizing: border-box;"><strong style="box-sizing: border-box;">高峰期性能瓶颈问题</strong></p></li> </ul> <p style="white-space: normal;box-sizing: border-box;">大促和推广期间,特别是爆款抢购时的流量可能会触发限流,导致部分用户被拒之门外。因为无法准确预估流量,难以提前扩容。</p> </section> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <section style="box-sizing: border-box;" powered-by="xiumi.us"> <p style="white-space: normal;box-sizing: border-box;">可以通过主动降级方案增加并发量,比如同步入库切为异步入库、db查询转为cache查询、只能查到最近半年的订单等。</p> <p style="white-space: normal;box-sizing: border-box;"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;box-sizing: border-box;">考虑到业务复杂度和数据量级还处在初期,团队规模也难以支撑,这些设计有远期计划,但暂时还没做。(架构的合适性原则,杀鸡用牛刀,你愿意也行)。</p> </section> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <section style="margin-top: 10px;margin-bottom: 10px;text-align: center;box-sizing: border-box;" powered-by="xiumi.us"> <section style="padding: 3px;display: inline-block;border-bottom: 1px solid rgb(65, 94, 255);font-size: 17px;color: rgb(65, 94, 255);box-sizing: border-box;"> <p style="box-sizing: border-box;">四、总结与展望</p> </section> </section> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <section style="box-sizing: border-box;" powered-by="xiumi.us"> <p style="white-space: normal;box-sizing: border-box;">我们在设计系统时并没有一味追求前沿技术和思想,面对问题时也不是直接采用业界主流的解决方案,而是根据团队和系统的实际状况来选取最合适的办法。好的系统不是在一开始就被大牛设计出来的,而是随着业务的发展和演进逐渐被迭代出来的。</p> <p style="white-space: normal;box-sizing: border-box;"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;box-sizing: border-box;">目前交易平台已上线一年多,接入了三个业务方,系统运行平稳,公司内有交易/商品/库存等需求的新业务,以及存量业务在遇到系统瓶颈需要升级时,都可以复用这块能力。</p> <p style="white-space: normal;box-sizing: border-box;"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;box-sizing: border-box;">上游业务方数量的增加和版本的迭代,对平台系统的需求源源不断,平台的功能得到逐渐完善,架构也在不断演进,我们正在将履约模块从交易平台中剥离出来,进一步解耦,为业务持续发展做好储备。</p> </section> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;box-sizing: border-box;" powered-by="xiumi.us"><br style="box-sizing: border-box;"></p> <section style="margin-right: 0%;margin-bottom: 20px;margin-left: 0%;justify-content: flex-start;display: flex;flex-flow: row nowrap;box-sizing: border-box;" powered-by="xiumi.us"> <section style="display: inline-block;vertical-align: middle;width: 40%;align-self: center;flex: 0 0 auto;box-sizing: border-box;"> <section style="margin-top: 0.5em;margin-bottom: 0.5em;box-sizing: border-box;" powered-by="xiumi.us"> <section style="border-top: 1px dotted rgb(90, 98, 114);box-sizing: border-box;"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> </section> <section style="display: inline-block;vertical-align: middle;width: 20%;align-self: center;flex: 0 0 auto;box-sizing: border-box;"> <section style="text-align: center;color: rgb(45, 66, 87);font-size: 11px;box-sizing: border-box;" powered-by="xiumi.us"> <p style="box-sizing: border-box;">END</p> </section> </section> <section style="display: inline-block;vertical-align: middle;width: 40%;align-self: center;flex: 0 0 auto;box-sizing: border-box;"> <section style="margin-top: 0.5em;margin-bottom: 0.5em;box-sizing: border-box;" powered-by="xiumi.us"> <section style="border-top: 1px dotted rgb(90, 98, 114);box-sizing: border-box;"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> </section> </section> <section style="margin-top: 10px;margin-bottom: 10px;text-align: left;box-sizing: border-box;" powered-by="xiumi.us"> <section style="padding-left: 1em;padding-right: 1em;display: inline-block;text-align: center;box-sizing: border-box;"> <span style="display: inline-block;padding: 0.3em 0.5em;border-radius: 0.5em;background-color: rgb(65, 94, 255);color: rgb(255, 255, 255);box-sizing: border-box;" title="" opera-tn-ra-cell="_$.pages:0.layers:0.comps:140.title1"><p style="box-sizing: border-box;">猜你喜欢</p></span> </section> <section style="border-width: 1px;border-style: solid;border-color: transparent;margin-top: -1em;padding: 20px 10px 10px;background-color: rgb(239, 239, 239);text-align: center;box-sizing: border-box;"> <section style="font-size: 14px;text-align: left;box-sizing: border-box;" powered-by="xiumi.us"> <ul class="list-paddingleft-1" style="padding-left: 40px;list-style-position: outside;"> <li><p><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzI4NjY4MTU5Nw==&amp;mid=2247496259&amp;idx=1&amp;sn=0b1cbc5ae9fb63460b17d56abd81df29&amp;chksm=ebdb82d1dcac0bc753e9eed7ac8b8890d9998813617add0c1cf8d3547afc785073f7d525c29b&amp;scene=21#wechat_redirect" textvalue="vivo全球商城:库存系统架构设计与实践" linktype="text" imgurl="" imgdata="null" data-itemshowtype="0" tab="innerlink" data-linktype="2">vivo全球商城:库存系统架构设计与实践</a></p></li> <li><p><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzI4NjY4MTU5Nw==&amp;mid=2247494907&amp;idx=1&amp;sn=3ac53c4377a3208817ab14142427a49e&amp;chksm=ebdb9c69dcac157f706a0b74522b8b928e2bebcf9c250cf1e689ffa0a4985644db2a826ac686&amp;scene=21#wechat_redirect" textvalue="vivo 全球商城:电商平台通用取货码设计" linktype="text" imgurl="" imgdata="null" data-itemshowtype="0" tab="innerlink" data-linktype="2">vivo 全球商城:电商平台通用取货码设计</a></p></li> <li><p><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzI4NjY4MTU5Nw==&amp;mid=2247493253&amp;idx=2&amp;sn=e82aad1dee7132e61b0553068c764857&amp;chksm=ebdb9617dcac1f0130dab997e97be879b24dcd2deccafdfbdafa0684fc8a68d8e015bee5f8d4&amp;scene=21#wechat_redirect" textvalue="vivo全球商城全球化演进之路—多语言解决方案" linktype="text" imgurl="" imgdata="null" data-itemshowtype="0" tab="innerlink" data-linktype="2">vivo全球商城全球化演进之路—多语言解决方案</a></p></li> </ul> </section> </section> </section> <section> <mp-common-profile class="js_uneditable custom_select_card mp_profile_iframe" data-pluginname="mpprofile" data-weui-theme="light" data-id="MzI4NjY4MTU5Nw==" data-headimg="http://mmbiz.qpic.cn/mmbiz_png/4g5IMGibSxt45QXJZicZ9gaNU2mRSlvqhQd94MJ7oQh4QFj1ibPV66xnUiaKoicSatwaGXepL5sBDSDLEckicX1ttibHg/0?wx_fmt=png" data-nickname="vivo互联网技术" data-alias="vivoVMIC" data-signature="分享 vivo 互联网技术干货与沙龙活动,推荐最新行业动态与热门会议。" data-from="0" data-is_biz_ban="0"></mp-common-profile> </section> </section> <p style="display: none;"> <mp-style-type data-value="3"></mp-style-type></p>

产品中删除真的都需要二次确认吗?

作者:微信小助手

<section style="display:none;" data-tools="新媒体管家" data-label="powered by xmt.cn"> <br> </section> <section> <mp-common-profile class="js_uneditable custom_select_card mp_profile_iframe" data-pluginname="mpprofile" data-weui-theme="light" data-id="MzA3NDQ1Mjc5OQ==" data-headimg="http://mmbiz.qpic.cn/mmbiz_png/CiboI7J6KQxCXETjZzqypQuYpnic08rfYiaFMPrmfolHFrCt5w4OOB45kNrekjGMGt4nJd8jIFJHcD3OgbqHMWUDA/0?wx_fmt=png" data-nickname="互联网产品设计" data-alias="BestWebDesign" data-signature="点击获取大厂产品设计规范及组件库、免商字体、产品数据分析等产品设计资源。[ 互联网产品设计 ] 日常分享产品设计、交互设计精选文章、设计案例、设计趋势等。" data-from="0" data-is_biz_ban="0"></mp-common-profile> </section> <p style="text-align: left;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><span style="color: rgb(35, 37, 52);font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;white-space: pre-wrap;background-color: rgb(255, 255, 255);letter-spacing: 2px;font-size: 16px;">在产品使用过程中,经常遇到二次确认操作。</span></p> <p style="text-align: left;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><span style="color: rgb(35, 37, 52);font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;white-space: pre-wrap;background-color: rgb(255, 255, 255);letter-spacing: 2px;font-size: 16px;">例如 iOS用户删除短信时出现二次确认;微信用户删除联系人时,出现二次确认。</span></p> <p style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><img class="rich_pages wxw-img js_insertlocalimg" data-cropselx1="0" data-cropselx2="578" data-cropsely1="0" data-cropsely2="611" data-ratio="1.0574074074074074" data-s="300,640" src="/upload/d23b050f1ad62f50c6854879feda74cf.png" data-type="png" data-w="1080" style="width: 578px;height: auto !important;"></p> <p style="text-align: left;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><span style="color: rgb(35, 37, 52);font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;white-space: pre-wrap;background-color: rgb(255, 255, 255);letter-spacing: 2px;font-size: 16px;">有些却不需要二次确认,例如:iOS备忘录App,删除一条备忘录,则没有出现二次确认。</span></p> <p style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><img class="rich_pages wxw-img js_insertlocalimg" data-cropselx1="0" data-cropselx2="578" data-cropsely1="0" data-cropsely2="711" data-ratio="1.2307692307692308" data-s="300,640" src="/upload/c8b0bc2245ab7f4810afe6202f034a60.png" data-type="gif" data-w="1079" style="width: 578px;height: auto !important;"></p> <p style="text-align: left;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><span style="color: rgb(35, 37, 52);font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;white-space: pre-wrap;background-color: rgb(255, 255, 255);letter-spacing: 2px;font-size: 16px;">QQ邮箱,用户点击删除按钮,邮件直接从收件箱中删除,这一过程中也没有二次确认。</span></p> <p style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="1.2307692307692308" data-s="300,640" src="/upload/bd12c2c4ac17814ee3a22752f45177f2.png" data-type="gif" data-w="1079" style="height: auto !important;"></p> <p style="text-align: left;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><span style="color: rgb(35, 37, 52);font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;white-space: pre-wrap;background-color: rgb(255, 255, 255);letter-spacing: 2px;font-size: 16px;">为什么有的时候需要二次确认,有的时候不需要二次确认呢?本文大纲如下:</span></p> <p style="text-align: left;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><span style="color: rgb(35, 37, 52);font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;white-space: pre-wrap;background-color: rgb(255, 255, 255);letter-spacing: 2px;font-size: 16px;">1.二次确认的3种形式</span></p> <p style="text-align: left;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><span style="color: rgb(35, 37, 52);font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;white-space: pre-wrap;background-color: rgb(255, 255, 255);letter-spacing: 2px;font-size: 16px;">2.需要二次确认的条件</span></p> <p style="text-align: left;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><span style="color: rgb(35, 37, 52);font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;white-space: pre-wrap;background-color: rgb(255, 255, 255);letter-spacing: 2px;font-size: 16px;">3.C端场景的二次确认</span></p> <p style="text-align: left;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><span style="color: rgb(35, 37, 52);font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;white-space: pre-wrap;background-color: rgb(255, 255, 255);letter-spacing: 2px;font-size: 16px;">4.B端场景的二次确认</span></p> <p style="text-align: left;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><span style="color: rgb(35, 37, 52);font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;white-space: pre-wrap;background-color: rgb(255, 255, 255);letter-spacing: 2px;font-size: 16px;">5.总结</span></p> <p style="white-space: normal;background-color: rgb(255, 255, 255);margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><br></p> <p style="white-space: normal;background-color: rgb(255, 255, 255);margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><img class="rich_pages wxw-img" data-backh="145" data-backw="578" data-galleryid="" data-ratio="0.25" data-s="300,640" src="/upload/a596e7f93783ffcbfc3ef10ecde06484.png" data-type="png" data-w="1080" style="color: rgb(53, 53, 53);font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;font-size: 14px;text-align: left;width: 923.797px;height: auto !important;"><span style="letter-spacing: 2px;"><em style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;text-align: left;"><strong style="outline: 0px;max-width: 100%;font-style: normal;text-align: justify;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="color: rgb(250, 74, 74);font-size: 26px;outline: 0px;max-width: 100%;visibility: visible;white-space: pre-wrap;box-sizing: border-box !important;overflow-wrap: break-word !important;">二次确认的3种形式</span></strong></em></span></p> <p style="text-align: left;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><span style="color: rgb(35, 37, 52);font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;white-space: pre-wrap;background-color: rgb(255, 255, 255);letter-spacing: 2px;font-size: 16px;">二次确认通常有两种形式,一种是底部操作列表,另一种是警示对话框。</span></p> <p style="text-align: left;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><span style="color: rgb(35, 37, 52);font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;white-space: pre-wrap;background-color: rgb(255, 255, 255);letter-spacing: 2px;font-size: 16px;">例如微信的退出登录使用的是底部操作列表,而QQ用的是警示对话框。</span></p> <p style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><img class="rich_pages wxw-img js_insertlocalimg" data-cropselx1="0" data-cropselx2="578" data-cropsely1="0" data-cropsely2="611" data-ratio="1.0574074074074074" data-s="300,640" src="/upload/e7eebe976f98f068bb0b0668aa46395e.png" data-type="png" data-w="1080" style="width: 578px;height: auto !important;"></p> <p style="text-align: left;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><span style="color: rgb(35, 37, 52);font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;white-space: pre-wrap;background-color: rgb(255, 255, 255);letter-spacing: 2px;font-size: 16px;">同样的二次确认,出现两种形式的情况有以下3个原因:</span></p> <p style="text-align: left;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><span style="color: rgb(35, 37, 52);font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;white-space: pre-wrap;background-color: rgb(255, 255, 255);letter-spacing: 2px;font-size: 16px;">1.底部操作列表侧重选择按钮,按钮的功能优先级较高,如微信退出的底部操作列表按钮;</span></p> <p style="text-align: left;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><span style="color: rgb(35, 37, 52);font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;white-space: pre-wrap;background-color: rgb(255, 255, 255);letter-spacing: 2px;font-size: 16px;">2.警示对话框侧重点是提示文字,提示文字的内容优先级较高,如QQ退出警示对话框偏重文案提示;</span></p> <p style="text-align: left;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><span style="color: rgb(35, 37, 52);font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;white-space: pre-wrap;background-color: rgb(255, 255, 255);letter-spacing: 2px;font-size: 16px;">3.具体情况可根据具体产品对待,微信退出登录用的是底部操作列表,原因可能是底部操作列表阻断性不强,对用户的打扰程度较低。</span></p> <p style="text-align: left;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><span style="background-color: rgb(255, 255, 255);color: rgb(35, 37, 52);font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;letter-spacing: 2px;white-space: pre-wrap;font-size: 16px;">除了以上两种形式,还有一种形式是两步操作确认,例如删除微信对话时,在原位置在此出现二次确认。</span></p> <p><img class="rich_pages wxw-img js_insertlocalimg" data-cropselx1="0" data-cropselx2="578" data-cropsely1="0" data-cropsely2="611" data-ratio="1.0574074074074074" data-s="300,640" src="/upload/5eab02df53c468dce97967bc063c5130.png" data-type="png" data-w="1080" style="text-align: center;white-space: normal;width: 578px;height: auto !important;"></p> <p style="text-align: left;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><span style="background-color: rgb(255, 255, 255);color: rgb(35, 37, 52);font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;letter-spacing: 2px;white-space: pre-wrap;font-size: 16px;">微信收藏也采用一样的分步确认,如下图所示:</span></p> <p style="margin-right: 8px;margin-bottom: 0px;margin-left: 8px;text-align: left;white-space: normal;line-height: 1.6em;"><span style="background-color: rgb(255, 255, 255);color: rgb(35, 37, 52);font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;font-size: 15px;letter-spacing: 2px;white-space: pre-wrap;"><img class="rich_pages wxw-img js_insertlocalimg" data-cropselx1="0" data-cropselx2="562" data-cropsely1="0" data-cropsely2="594" data-ratio="1.0574074074074074" data-s="300,640" src="/upload/7fd6a139a5fe65062e1f1060ae967722.png" data-type="png" data-w="1080" style="color: rgb(35, 37, 52);font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;font-size: 15px;letter-spacing: 2px;white-space: normal;text-align: center;width: 562px;height: auto !important;"><br></span></p> <p style="margin-right: 8px;margin-bottom: 0px;margin-left: 8px;text-align: left;white-space: normal;line-height: 1.6em;"><br></p> <p style="margin-right: 8px;margin-bottom: 0px;margin-left: 8px;text-align: left;white-space: normal;line-height: 1.6em;"><span style="background-color: rgb(255, 255, 255);color: rgb(35, 37, 52);font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;letter-spacing: 2px;white-space: pre-wrap;font-size: 16px;">微信这种确认方式,是沿用早期的iOS短信的二次确认方式。后续iOS版本升级,改回了底部操作列表确认。</span></p> <p style="margin-right: 8px;margin-bottom: 0px;margin-left: 8px;text-align: left;white-space: normal;line-height: 1.6em;"><span style="background-color: rgb(255, 255, 255);color: rgb(35, 37, 52);font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;letter-spacing: 2px;white-space: pre-wrap;font-size: 16px;"><br></span></p> <p style="margin-right: 8px;margin-bottom: 0px;margin-left: 8px;text-align: left;white-space: normal;line-height: 1.6em;"><span style="background-color: rgb(255, 255, 255);color: rgb(35, 37, 52);font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;letter-spacing: 2px;white-space: pre-wrap;font-size: 16px;">底部操作列表进行二次确认的优势是可以提供提示语。</span></p> <p style="text-align: left;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><br></p> <p style="white-space: normal;background-color: rgb(255, 255, 255);margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><img class="rich_pages wxw-img" data-backh="145" data-backw="578" data-cropselx1="0" data-cropselx2="562" data-cropsely1="0" data-cropsely2="141" data-galleryid="" data-ratio="0.25" data-s="300,640" src="/upload/a40139c3539bef427597dc72b70de2c6.png" data-type="png" data-w="1080" style="color: rgb(53, 53, 53);font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;font-size: 14px;text-align: left;width: 564px;"><br></p> <p style="white-space: normal;background-color: rgb(255, 255, 255);clear: both;min-height: 1em;text-align: left;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><span style="font-size: 26px;color: rgb(250, 74, 74);letter-spacing: 2px;"><em style="color: rgb(51, 51, 51);font-size: 17px;letter-spacing: normal;text-align: left;"><strong style="outline: 0px;max-width: 100%;font-style: normal;text-align: justify;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="color: rgb(250, 74, 74);outline: 0px;max-width: 100%;visibility: visible;white-space: pre-wrap;box-sizing: border-box !important;overflow-wrap: break-word !important;">需要二次确认的条件</span></strong></em></span></p> <p style="text-align: left;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><span style="letter-spacing: 2px;font-size: 16px;"><strong><span style="letter-spacing: 2px;color: rgb(35, 37, 52);font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;white-space: pre-wrap;background-color: rgb(255, 255, 255);">是否需要二次确认,主要看是否能够恢复。</span></strong></span></p> <p style="text-align: left;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><span style="color: rgb(35, 37, 52);font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;white-space: pre-wrap;background-color: rgb(255, 255, 255);letter-spacing: 2px;font-size: 16px;">这里的恢复指的是用户删除后能否找回来。</span></p> <p style="text-align: left;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><span style="color: rgb(35, 37, 52);font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;white-space: pre-wrap;background-color: rgb(255, 255, 255);letter-spacing: 2px;font-size: 16px;">以iOS的备忘录为例,一条备忘录被删除后,由于没有真正的删除(可以在最近删除的文件夹中找回),所以不需要二次确认。</span></p> <p style="margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><img class="rich_pages wxw-img js_insertlocalimg" data-cropselx1="0" data-cropselx2="578" data-cropsely1="0" data-cropsely2="711" data-ratio="1.2307692307692308" data-s="300,640" src="/upload/c8b0bc2245ab7f4810afe6202f034a60.png" data-type="gif" data-w="1079" style="text-align: center;white-space: normal;width: 578px;height: auto !important;"></p> <p style="text-align: left;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><span style="color: rgb(35, 37, 52);font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;white-space: pre-wrap;background-color: rgb(255, 255, 255);letter-spacing: 2px;font-size: 16px;">而在最近删除文件夹里面,点击删除意味着彻底删除。所以需要二次确认。</span></p> <p style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="1.2305555555555556" data-s="300,640" src="/upload/fee6a5a0e8db595855e26888a04de76a.png" data-type="png" data-w="1080" style="height: auto !important;"></p> <p style="text-align: left;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><span style="color: rgb(35, 37, 52);font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;white-space: pre-wrap;background-color: rgb(255, 255, 255);letter-spacing: 2px;font-size: 16px;">同理,淘宝取消订阅,也没有二次确认。即使用户误操作,也可以点击重新订阅。所以使用二次确认没有意义,还增加用户操作成本。</span></p> <p style="white-space: normal;background-color: rgb(255, 255, 255);margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><span style="color: rgb(35, 37, 52);font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;font-size: 15px;text-align: start;white-space: pre-wrap;letter-spacing: 2px;"><img class="rich_pages wxw-img js_insertlocalimg" data-cropselx1="0" data-cropselx2="562" data-cropsely1="0" data-cropsely2="692" data-ratio="1.2307692307692308" data-s="300,640" src="/upload/1560a796bc387101128aaba4e6dc0140.png" data-type="png" data-w="1079" style="text-align: center;white-space: normal;width: 562px;height: auto !important;"></span></p> <p style="text-align: left;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><span style="color: rgb(35, 37, 52);font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;white-space: pre-wrap;background-color: rgb(255, 255, 255);letter-spacing: 2px;font-size: 16px;">但是国内产品经理有一种说法是:鼓励用户多关注/订阅,通过二次确认,起到挽留的作用。</span></p> <p style="text-align: left;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><span style="color: rgb(35, 37, 52);font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;white-space: pre-wrap;background-color: rgb(255, 255, 255);letter-spacing: 2px;font-size: 16px;">我个人觉得这种论调有问题,用户进行取关,即使做了二次确认,也很难改变用户心意。就算阻碍用户取关,以后feed流还能持续看到不想看到的,也会影响用户的阅读体验,从而降低用户的留存。</span></p> <p style="white-space: normal;background-color: rgb(255, 255, 255);margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><br></p> <article data-content="[{&quot;type&quot;:&quot;block&quot;,&quot;id&quot;:&quot;gVs4-1676879386963&quot;,&quot;name&quot;:&quot;paragraph&quot;,&quot;data&quot;:{},&quot;nodes&quot;:[{&quot;type&quot;:&quot;text&quot;,&quot;id&quot;:&quot;lE8M-1676879386962&quot;,&quot;leaves&quot;:[{&quot;text&quot;:&quot;首先我们需要在&quot;,&quot;marks&quot;:[{&quot;type&quot;:&quot;fontSize&quot;,&quot;value&quot;:16}]},{&quot;text&quot;:&quot;微信红包封面开放平台&quot;,&quot;marks&quot;:[{&quot;type&quot;:&quot;color&quot;,&quot;value&quot;:&quot;#FB8D00&quot;},{&quot;type&quot;:&quot;fontSize&quot;,&quot;value&quot;:16}]},{&quot;text&quot;:&quot;&nbsp;&quot;,&quot;marks&quot;:[{&quot;type&quot;:&quot;fontSize&quot;,&quot;value&quot;:16}]}]},{&quot;type&quot;:&quot;inline&quot;,&quot;id&quot;:&quot;6mOe-1676880854353&quot;,&quot;name&quot;:&quot;link&quot;,&quot;data&quot;:{&quot;href&quot;:&quot;https://cover.weixin.qq.com/&quot;},&quot;nodes&quot;:[{&quot;type&quot;:&quot;text&quot;,&quot;id&quot;:&quot;egxP-1676880854352&quot;,&quot;leaves&quot;:[{&quot;text&quot;:&quot;https://cover.weixin.qq.com/&quot;,&quot;marks&quot;:[{&quot;type&quot;:&quot;fontSize&quot;,&quot;value&quot;:16}]}]}]},{&quot;type&quot;:&quot;text&quot;,&quot;id&quot;:&quot;XXga-1676880854355&quot;,&quot;leaves&quot;:[{&quot;text&quot;:&quot;拿到最新的设计模板,需要注意的是,一定要是最新的设计规范,因为每年微信也会有一些新的设计改版。以往的规范会不适用新的系统机制。另外优秀案例专栏也收集了各行业的往年热门的红包封面设计作品,可以作为设计风格以及设计样式的灵感启发。&quot;,&quot;marks&quot;:[{&quot;type&quot;:&quot;fontSize&quot;,&quot;value&quot;:16}]}]}]}]" style="margin-right: 8px;margin-bottom: 16px;margin-left: 8px;background-color: rgb(255, 255, 255);line-height: normal;font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;text-align: start;"> <p style="color: rgb(53, 53, 53);font-size: 14px;white-space: normal;margin-bottom: 0px;font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;background-color: rgb(255, 255, 255);text-align: left;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><img class="rich_pages wxw-img" data-backh="145" data-backw="578" data-cropselx1="0" data-cropselx2="562" data-cropsely1="0" data-cropsely2="141" data-galleryid="" data-ratio="0.25" data-s="300,640" src="/upload/d05b85d542fea1e9bd7516c2ced514da.png" data-type="png" data-w="1080" style="width: 564px;height: auto !important;"></p> <p style="color: rgb(53, 53, 53);font-size: 14px;white-space: normal;margin-bottom: 16px;background-color: rgb(255, 255, 255);margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><span style="color: rgb(250, 74, 74);font-size: 26px;white-space: pre-wrap;letter-spacing: 2px;"><strong>C端场景的二次确认</strong></span></p> <p style="text-align: left;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><span style="color: rgb(35, 37, 52);font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;white-space: pre-wrap;background-color: rgb(255, 255, 255);letter-spacing: 2px;font-size: 16px;">有些场景,即使可以挽回,有时候也做了二次确认。这里二次确认的作用,是告知用户,操作后会发生什么?并非是为了防止误操作。</span></p> <p style="text-align: left;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><br></p> <p style="text-align: left;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><span style="color: rgb(35, 37, 52);font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;white-space: pre-wrap;background-color: rgb(255, 255, 255);letter-spacing: 2px;font-size: 16px;">例如,微信拉黑联系人时,拉黑后可以关闭开关,恢复之前的效果。但是因为拉黑,会让双方看不到对方的动态和消息,所以才有了二次确认。</span></p> <p style="color: rgb(53, 53, 53);font-size: 14px;white-space: normal;background-color: rgb(255, 255, 255);margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><br></p> <p style="color: rgb(53, 53, 53);font-size: 14px;white-space: normal;text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="1.2305555555555556" data-s="300,640" src="/upload/e1dc3154d84851bf534bcded75631d4e.png" data-type="png" data-w="1080" style="height: auto !important;"></p> <p style="color: rgb(53, 53, 53);font-size: 14px;white-space: normal;background-color: rgb(255, 255, 255);margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><br></p> <p style="background-color: rgb(255, 255, 255);margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><span style="letter-spacing: 2px;color: rgb(35, 37, 52);font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;white-space: pre-wrap;background-color: rgb(255, 255, 255);font-size: 16px;">这里的二次确认更多的是提醒用户操作意味着什么,并非防止误操作。</span></p> <p style="color: rgb(53, 53, 53);font-size: 14px;white-space: normal;margin-right: 8px;margin-left: 8px;background-color: rgb(255, 255, 255);line-height: 1.6em;"><br></p> <p style="color: rgb(53, 53, 53);font-size: 14px;white-space: normal;margin-bottom: 0px;font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;background-color: rgb(255, 255, 255);text-align: left;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><br></p> </article> <p style="margin-bottom: 0px;color: rgb(53, 53, 53);font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;font-size: 14px;white-space: normal;background-color: rgb(255, 255, 255);text-align: left;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><span style="white-space: pre-wrap;color: rgb(99, 99, 109);font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;font-size: 15px;text-align: start;background-color: rgb(255, 255, 255);letter-spacing: 2px;"><br></span></p> <p style="margin-bottom: 0px;white-space: normal;color: rgb(53, 53, 53);font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;font-size: 14px;background-color: rgb(255, 255, 255);text-align: left;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><img class="rich_pages wxw-img" data-backh="145" data-backw="578" data-cropselx1="0" data-cropselx2="562" data-cropsely1="0" data-cropsely2="141" data-galleryid="" data-ratio="0.25" data-s="300,640" src="/upload/dfc630dc639735ea3233ca757a36352b.png" data-type="png" data-w="1080" style="width: 564px;height: auto !important;"></p> <p style="margin-bottom: 16px;white-space: normal;background-color: rgb(255, 255, 255);margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><span style="font-size: 26px;color: rgb(250, 74, 74);letter-spacing: 2px;"><em style="color: rgb(51, 51, 51);font-size: 17px;letter-spacing: normal;text-align: left;"><strong style="outline: 0px;max-width: 100%;font-style: normal;text-align: justify;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="color: rgb(250, 74, 74);outline: 0px;max-width: 100%;visibility: visible;white-space: pre-wrap;box-sizing: border-box !important;overflow-wrap: break-word !important;">B端场景的二次确认</span></strong></em></span></p> <p style="margin-bottom: 0px;color: rgb(53, 53, 53);font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;font-size: 14px;white-space: normal;background-color: rgb(255, 255, 255);text-align: left;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><span style="color: rgb(35, 37, 52);font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;letter-spacing: 2px;white-space: pre-wrap;background-color: rgb(255, 255, 255);font-size: 16px;">B端使用人群,通常是公司员工,而公司员工每天都要进行大量的操作。这种情况下:</span></p> <p style="margin-bottom: 0px;color: rgb(53, 53, 53);font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;font-size: 14px;white-space: normal;background-color: rgb(255, 255, 255);text-align: left;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><span style="color: rgb(35, 37, 52);font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;white-space: pre-wrap;background-color: rgb(255, 255, 255);letter-spacing: 2px;font-size: 16px;"><br></span></p> <p style="margin-bottom: 0px;color: rgb(53, 53, 53);font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;font-size: 14px;white-space: normal;background-color: rgb(255, 255, 255);text-align: left;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><span style="color: rgb(35, 37, 52);white-space: pre-wrap;letter-spacing: 2px;font-size: 16px;">1.如果是可以找回的非毁灭性操作,通常不需要二次确认。</span></p> <p style="margin-bottom: 0px;color: rgb(53, 53, 53);font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;font-size: 14px;white-space: normal;background-color: rgb(255, 255, 255);text-align: left;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><span style="color: rgb(35, 37, 52);white-space: pre-wrap;letter-spacing: 2px;font-size: 16px;"><br></span></p> <p style="background-color: rgb(255, 255, 255);margin-bottom: 16px;font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;text-align: start;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><span style="color: rgb(35, 37, 52);white-space: pre-wrap;letter-spacing: 2px;font-size: 16px;">2.如果操作有一定的逻辑关系,需要提醒给用户,那么可以通过message或者toast告知用户,这样可以提高操作人员的的效率。</span></p> <p style="background-color: rgb(255, 255, 255);margin-bottom: 16px;font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;text-align: start;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><span style="color: rgb(35, 37, 52);letter-spacing: 2px;white-space: pre-wrap;font-size: 16px;">3.当对平台有严重影响时,即使可以迅速找回,也需要二次确认。例如后台设置小程序上线或者下线时,点击开关切换,则需要二次确认。</span></p> <p style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><img class="rich_pages wxw-img js_insertlocalimg" data-cropselx1="0" data-cropselx2="562" data-cropsely1="0" data-cropsely2="692" data-ratio="0.2851851851851852" data-s="300,640" src="/upload/cad5b335de614297ace30b90cf52a887.png" data-type="png" data-w="1080" style="color: rgb(53, 53, 53);font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;font-size: 14px;text-align: center;white-space: normal;background-color: rgb(255, 255, 255);width: 578px;height: auto !important;"></p> <p style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><br></p> <p style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><img class="rich_pages wxw-img" data-cropselx1="0" data-cropselx2="578" data-cropsely1="0" data-cropsely2="145" data-galleryid="" data-ratio="0.25" data-s="300,640" src="/upload/452777c18936ce3f130c1d17c0be9f3b.png" data-type="png" data-w="1080" style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;text-align: justify;outline: 0px;width: 578px;box-sizing: border-box !important;overflow-wrap: break-word !important;visibility: visible !important;"><br></p> <p style="margin-bottom: 16px;background-color: rgb(255, 255, 255);margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><span style="letter-spacing: 2px;color: rgb(250, 74, 74);font-size: 26px;white-space: pre-wrap;"><strong>总结</strong></span></p> <p style="background-color: rgb(255, 255, 255);margin-bottom: 16px;font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;text-align: start;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><span style="color: rgb(35, 37, 52);white-space: pre-wrap;letter-spacing: 2px;font-size: 16px;">1.操作是否需要二次确认,先看是否可以找回。如果可以,那么大概率不需要二次确认。</span></p> <p style="background-color: rgb(255, 255, 255);margin-bottom: 16px;font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;text-align: start;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><span style="color: rgb(35, 37, 52);white-space: pre-wrap;letter-spacing: 2px;font-size: 16px;">2.有一些特殊情况,即使可以找回,由于需要告知用户一些信息,则通过二次确认弹窗告知给用户。这种情况,二次确认弹窗的作用,通常是告知用户信息,而非担心误操作的二次确认。</span></p> <p style="background-color: rgb(255, 255, 255);margin-bottom: 16px;font-family: &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 黑体, Arial, sans-serif;text-align: start;margin-left: 8px;margin-right: 8px;line-height: 1.6em;"><span style="font-size: 16px;"><span style="color: rgb(35, 37, 52);white-space: pre-wrap;letter-spacing: 2px;">3.对于B端用户,对于能找回且需要提醒的场景,通常不用二次确认弹窗,可以通过message或者toast告知用户,这样可以提升操作人员的效率。</span><span style="color: rgb(35, 37, 52);letter-spacing: 2px;white-space: pre-wrap;">但对于某个操作会影响到平台的场景,即使可以找回,也需要二次确认。</span></span></p>

Midjourney最近都更新了啥?重点讲一下Niji 5模式使用方法

作者:微信小助手

<section> <mp-common-profile class="js_uneditable custom_select_card mp_profile_iframe" data-pluginname="mpprofile" data-weui-theme="light" data-id="MjM5MjMzMjE4MA==" data-headimg="http://mmbiz.qpic.cn/mmbiz_png/6tHzAJyhInBu9LYLryBFteHVfsYqZ7VHoK13sGsRd0LhBI1WxsusXgWXqZsU3yic2vTnSnbCpMPRnN2T1T1vVsw/0?wx_fmt=png" data-nickname="UX设计精选" data-alias="UEUXbest" data-signature="精选用户体验、交互设计文章,分享行业动态和工具资源。" data-from="0" data-is_biz_ban="0"></mp-common-profile> </section> <p style="margin-bottom: 24px;"><strong><span style="letter-spacing: 0.5px;font-size: 18px;">前言</span></strong> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);font-size: 16px;">AI每天都在更新,每天都在变化,工具越来越多,有的小伙伴去适应,有的只是觉得好奇,还有的在抵制,希望大家保持初心,该学C4D的还是要学,该学插画的要学完。</span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);font-size: 16px;">可以看到各大厂已经在应用的路上了,目前阶段是结合着去落地,我相信不久会有更全面,更完整的AI项目参与展示出来。</span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><strong><span style="letter-spacing: 0.5px;font-size: 18px;">正文</span></strong> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="letter-spacing: 0.5px;background-color: rgb(0, 0, 0);color: rgb(255, 255, 255);font-size: 16px;">&nbsp;看了几篇推文,Midjourney上周更新的东西大家差不多都知道了,这里我简单的总结一下,以及重点讲一下 Niji 5模式 使用方法。</span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="font-size: 16px;"><strong><span style="letter-spacing: 0.5px;">01.输入 /describe 上传图片识别关键词。</span></strong></span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><img class="rich_pages wxw-img" data-ratio="0.5074074074074074" src="/upload/980a260a54a190b008268c577987de1f.png" data-type="png" data-w="1080" height="306.89889763779524px" style="width: 604.733px;height: 306.899px;" width="604.7333333333333"> <o:p></o:p></p> <p style="margin-bottom: 24px;"><img class="rich_pages wxw-img" data-ratio="0.38333333333333336" src="/upload/a1a77c675bffd45f8b3684f4c15e35be.png" data-type="png" data-w="1080" height="232.0938582677165px" style="width: 604.733px;height: 232.094px;" width="604.7333333333333"> <o:p></o:p></p> <p style="margin-bottom: 24px;"><img class="rich_pages wxw-img" data-ratio="0.43796296296296294" src="/upload/6069b37310ff32ab9c70873a4fd404b.png" data-type="png" data-w="1080" height="264.7751181102362px" style="width: 604.733px;height: 264.775px;" width="604.7333333333333"> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);font-size: 16px;">选择一张要解析的图片,回车,等待识别。</span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><img class="rich_pages wxw-img" data-ratio="0.18703703703703703" src="/upload/36005787e470d73f1a28bcbd23723b5f.png" data-type="png" data-w="1080" height="113.18540682414697px" style="width: 604.733px;height: 113.185px;" width="604.7333333333333"> <o:p></o:p></p> <p style="margin-bottom: 24px;"><img class="rich_pages wxw-img" data-ratio="1.1223175965665235" src="/upload/6a270350b13dd965a62d272848142a0a.png" data-type="png" data-w="932" height="678.7028871391077px" style="width: 604.733px;height: 678.703px;" width="604.7333333333333"> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);font-size: 16px;">可以看到4个选项,对应上方解析的关键词。</span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);font-size: 16px;"><br></span></p> <p style="margin-bottom: 24px;"><span style="font-size: 16px;"><strong><span style="letter-spacing: 0.5px;">02.输入 --repeat + 数字,快速生成批量图。</span></strong></span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><img class="rich_pages wxw-img" data-ratio="0.5092592592592593" src="/upload/cb7cd77888d02a277019c00e0f9e2c36.png" data-type="png" data-w="1080" height="307.887874015748px" style="width: 604.733px;height: 307.888px;" width="604.7333333333333"> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="font-size: 16px;"><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);">在这之前先要打开快速模式(否则应用不了哦),在输入框内</span><span style="letter-spacing: 0.5px;"> <strong>/fast</strong> </span><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);">回车,切换到快速出图模式。</span></span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><img class="rich_pages wxw-img" data-ratio="0.35648148148148145" src="/upload/3890e3b40a663bcc7f4f67d711cd272b.png" data-type="png" data-w="1080" height="215.4028346456693px" style="width: 604.733px;height: 215.403px;" width="604.7333333333333"> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);font-size: 16px;">这里注意一下,公用的账号已经用完了快速出图模式,目前显示需要购买,开启后请谨慎使用。</span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><img class="rich_pages wxw-img" data-ratio="0.15185185185185185" src="/upload/738c2f974a4abab2952056fbd5536ebe.png" data-type="png" data-w="1080" height="91.56850393700786px" style="width: 604.733px;height: 91.5685px;" width="604.7333333333333"> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="font-size: 16px;"><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);">在 /imagine prompt: 关键词 +&nbsp;</span><span style="letter-spacing: 0.5px;"><strong>--repeat + 数字</strong>(</span><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);">最多10)选择yes,即可快速生成5张。目前30美刀用户以支持。</span></span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);font-size: 16px;"><br></span></p> <p style="margin-bottom: 24px;"><span style="font-size: 16px;"><strong><span style="letter-spacing: 0.5px;">03. "{}{}"快速测试功能,比如你想要生成各种动漫风格“{七龙珠,海贼王,进击的巨人,神奇宝贝}{小羊,小猫,人,青蛙}”,就会按照你所要求的批量生成。</span></strong></span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><img class="rich_pages wxw-img" data-ratio="0.12777777777777777" src="/upload/623e8ac17fc24f0af5ce08f92903b632.png" data-type="png" data-w="1080" height="76.99328083989502px" style="width: 604.733px;height: 76.9933px;" width="604.7333333333333"> <o:p></o:p></p> <p style="margin-bottom: 24px;"><img class="rich_pages wxw-img" data-ratio="0.24722222222222223" src="/upload/e3b79969cb9441e49c5a9ce17409114e.png" data-type="png" data-w="1080" height="149.22834645669292px" style="width: 604.733px;height: 149.228px;" width="604.7333333333333"> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);font-size: 16px;">回车后,选择yes,进行输出。这里同样注意,只有快速出图模式下才能使用。</span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);font-size: 16px;"><br></span></p> <p style="margin-bottom: 24px;"><span style="font-size: 16px;"><strong><span style="letter-spacing: 0.5px;">04.重点讲-结尾添加--niji 5,要比以前画风更精细。</span></strong></span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><img class="rich_pages wxw-img" data-ratio="0.4083333333333333" src="/upload/c0e35a3f45337004e0f0a9c95fb65eb3.png" data-type="png" data-w="1080" height="246.68461942257218px" style="width: 604.733px;height: 246.685px;" width="604.7333333333333"> <o:p></o:p></p> <p style="margin-bottom: 24px;"><img class="rich_pages wxw-img" data-ratio="0.2898148148148148" src="/upload/a0e4c3e36954cfa681773cc399647eef.png" data-type="png" data-w="1080" height="175.48629921259842px" style="width: 604.733px;height: 175.486px;" width="604.7333333333333"> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="font-size: 16px;"><strong><span style="letter-spacing: 0.5px;">首先讲一下 Niji 4 和 Niji 5 区别:</span></strong></span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);font-size: 16px;">Midjourney v4 版本下 Niji 无法使用风格化命令“--stylize”。</span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);font-size: 16px;">Midjourney v5 版本下,可以使用风格化命令,且可以引用不同艺术家的设计风格。</span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="letter-spacing: 0.5px;font-size: 16px;"><br></span></p> <p style="margin-bottom: 24px;"><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);font-size: 16px;">测试一下最新版的 Niji 5 ,输入 /settings 回车,打开。</span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><img class="rich_pages wxw-img" data-ratio="0.2962962962962963" src="/upload/a523656303ba3339b9169e009cccffea.png" data-type="png" data-w="1080" height="179.0114435695538px" style="width: 604.733px;height: 179.011px;" width="604.7333333333333"> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="font-size: 16px;"><strong><span style="letter-spacing: 0.5px;">例子测试:</span></strong><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);">一个迷人的皮卡丘,丰满的身材,</span><strong><span style="letter-spacing: 0.5px;color: rgb(0, 0, 0);">克里斯·弗斯风格</span></strong><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);">,超细节,虚幻的渲染 --ar 16:9 </span><span style="letter-spacing: 0.5px;color: rgb(0, 0, 0);"><strong>--s 750 --niji 5</strong></span></span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="font-size: 16px;"><strong><span style="letter-spacing: 0.5px;">翻译测试:</span></strong><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);">An attractive Pikachu, with this plump figure,&nbsp;<strong>Chris Foss style</strong>, hyperdetail, unreal render --ar 16:9</span><span style="letter-spacing: 0.5px;"> <strong>--s 750 --niji 5</strong></span></span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><img class="rich_pages wxw-img" data-ratio="0.5388888888888889" src="/upload/c24657b49e055eb9062c74fde244225.png" data-type="png" data-w="1080" height="325.85879265091864px" style="width: 604.733px;height: 325.859px;display: inline;" width="604.7333333333333"> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);font-size: 16px;">我们换个画师继续测试。</span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="font-size: 16px;"><strong><span style="letter-spacing: 0.5px;">例子测试:</span></strong><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);">一个可爱的女孩,身材苗条,</span><span style="letter-spacing: 0.5px;"><strong>下田光(反乌托邦儿童画)</strong>,</span><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);">超细节,虚幻的渲染 --ar 16:9</span><span style="letter-spacing: 0.5px;"><strong> --s 750 --niji 5</strong></span></span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="font-size: 16px;"><strong><span style="letter-spacing: 0.5px;">翻译测试:</span></strong><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);">A lovely girl, Slim figure,</span><span style="letter-spacing: 0.5px;"> <strong>Hikari Shimoda</strong>, </span><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);">hyperdetail, unreal render --ar 16:9</span><span style="letter-spacing: 0.5px;"> <strong>--s 750 --niji 5</strong></span></span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><img class="rich_pages wxw-img" data-ratio="0.5537037037037037" src="/upload/a0628623b5adb639d5deef2ef6cd51b5.png" data-type="png" data-w="1080" height="334.69522309711283px" style="width: 604.733px;height: 334.695px;display: inline;" width="604.7333333333333"> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);font-size: 16px;">真不错真不错,在继续测试。</span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="font-size: 16px;"><strong><span style="letter-spacing: 0.5px;">例子测试:</span></strong><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);">一个可爱的女孩,身材苗条,</span><span style="letter-spacing: 0.5px;"><strong>杰丝敏·贝基特-格里菲斯</strong>,</span><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);">超细节,虚幻的渲染 --ar 16:9</span><span style="letter-spacing: 0.5px;"><strong>--s 750 --niji 5</strong></span></span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="font-size: 16px;"><strong><span style="letter-spacing: 0.5px;">翻译测试:</span></strong><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);">A lovely girl, Slim figure, </span><span style="letter-spacing: 0.5px;"><strong>Jasmine Becket-Griffith</strong>,</span><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);"> hyperdetail, unreal render --ar 16:9 </span><strong><span style="letter-spacing: 0.5px;">--s 750 --niji 5</span></strong></span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><img class="rich_pages wxw-img" data-ratio="0.5796296296296296" src="/upload/9aedb1d9fd372ca44e04c89f880be5e0.png" data-type="png" data-w="1080" height="350.36136482939634px" style="width: 604.733px;height: 350.361px;" width="604.7333333333333"> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="font-size: 16px;"><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);">这里找不到艺术家风格的,参考结合Chat Gpt那篇:</span><span style="letter-spacing: 0.5px;background-color: rgb(0, 0, 0);color: rgb(255, 255, 255);">https://www.midlibrary.io/categories/illustrators&nbsp;</span></span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);font-size: 16px;">如果调整成 niji 4 版本,还是上面的关键词,会显示不支持风格化。</span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><img class="rich_pages wxw-img" data-ratio="0.549074074074074" src="/upload/9fc34bbcceeea64ef13daab9471f8286.png" data-type="png" data-w="1080" height="331.97343832021px" style="width: 604.733px;height: 331.973px;" width="604.7333333333333"> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);font-size: 16px;">所以 niji 5 模式下,有更大的创作空间。我们继续测试。</span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);font-size: 16px;"><br></span></p> <p style="margin-bottom: 24px;"><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);font-size: 16px;">我们试试之前分享的关键词,看看 niji 5 + 风格化命令 有什么效果。</span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="font-size: 16px;"><strong><span style="letter-spacing: 0.5px;">例子测试:</span></strong><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);">进击巨人里(特定来源)贝尔托特(人物姓名)Q版形象(重要描述词),风格是迪士尼或者皮克斯的(风格),且小巧可爱(描述)。</span></span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="font-size: 16px;"><strong><span style="letter-spacing: 0.5px;">翻译测试:</span></strong><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);">Attack on Titan,Bertolt Hoover,full body, isometric,3d, cute, Little adorable chibi graphics, disney pixar Style,cute mobile game style,Hyper Realistic, cinema lighting</span><span style="color: rgb(119, 119, 119);">&nbsp;</span><span style="letter-spacing: 0.5px;font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;color: rgb(119, 119, 119);">--s 250 --niji 5</span></span></p> <p style="margin-bottom: 24px;"><img class="rich_pages wxw-img" data-ratio="0.9955056179775281" src="/upload/f46d02d84a258abd2f27db2f5374302.png" data-type="png" data-w="890" height="602.0154330708662px" style="width: 604.733px;height: 602.015px;" width="604.7333333333333"> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);font-size: 16px;">我们看到要比之前精致很多,光影很不错,而且更精准。</span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><br></p> <p style="margin-bottom: 24px;"><span style="font-size: 16px;"><strong><span style="letter-spacing: 0.5px;font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;">例子测试:</span></strong><span style="letter-spacing: 0.5px;font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;color: rgb(119, 119, 119);">钢铁侠的设计概念(拆分)</span></span></p> <p style="margin-bottom: 24px;"><span style="font-size: 16px;"><strong><span style="letter-spacing: 0.5px;">翻译测试:</span></strong><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);">knolling Iron Man suit 8K --s 250 --niji 5</span></span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><img class="rich_pages wxw-img" data-ratio="1.012037037037037" src="/upload/5b219114605e502036ab30533c93ad39.png" data-type="png" data-w="1080" height="612.1081364829396px" style="width: 604.733px;height: 612.108px;display: inline;" width="604.7333333333333"> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="font-size: 16px;"><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);">看着雾蒙蒙的,有点神秘,不错~</span></span></p> <p style="margin-bottom: 24px;"><span style="font-size: 16px;"><strong><span style="letter-spacing: 0.5px;">经过上两轮的测试,看到s250的效果非常好。(这里风格化--s是默认<strong style="white-space: normal;"><span style="letter-spacing: 0.5px;">1000&nbsp;</span></strong>)</span></strong></span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="font-size: 16px;"><strong><span style="letter-spacing: 0.5px;"><br></span></strong></span></p> <p style="margin-bottom: 24px;"><span style="font-size: 16px;"><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);">我们试试</span><span style="letter-spacing: 0.5px;"><strong> URL链接+描述+风格化命令,</strong></span><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);">上传一张人物,看能否让人物更像照片人物。</span></span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><img class="rich_pages wxw-img" data-ratio="0.3175925925925926" src="/upload/4c94f4ac50d2227c66a20b22a8172754.png" data-type="png" data-w="1080" height="192.2374803149606px" style="width: 604.733px;height: 192.237px;" width="604.7333333333333"> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);font-size: 16px;">上传一张小姐姐,回车,复制链接来进行喂图操作。</span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);font-size: 16px;"><br></span></p> <p style="margin-bottom: 24px;"><span style="font-size: 16px;"><strong><span style="letter-spacing: 0.5px;">例子测试:</span></strong><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);">一个漂亮的女孩子,头戴黑色无沿帽子,黑色的双马尾,正视图,特写,女仆装。</span></span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="font-size: 16px;"><strong><span style="letter-spacing: 0.5px;">翻译测试:</span></strong><span style="letter-spacing: 0.5px;"><strong>https://s.mj.run/10yov_L9gh4</strong> </span><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);">A pretty girl in a black hat, black double ponytail, Front view, closeup, maid outfit --ar 16:9 --s 250 --niji 5</span></span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><img class="rich_pages wxw-img" data-ratio="0.6092592592592593" src="/upload/5aaefaf516d2dbdde73188a6484058dd.png" data-type="png" data-w="1080" height="368.56041994750655px" style="width: 604.733px;height: 368.56px;display: inline;" width="604.7333333333333"> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="font-size: 16px;"><strong><span style="letter-spacing: 0.5px;">注意:上传人物后,描述要和照片一致,比如这张小姐姐,头戴无沿帽,双马尾,五官端正,(<strong style="white-space: normal;"><span style="letter-spacing: 0.5px;">如果角色有</span></strong>动作,需要和上传照片描述相同动作)。</span></strong></span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);font-size: 16px;">在描述人物的时候,可以添加以下关键词,来更准确的生成相对应的输出图片。</span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="font-size: 16px;"><strong><span style="letter-spacing: 0.5px;">年龄/表情/发型/身材/服装/灯光/背景/画质/视角/风格</span></strong></span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="font-size: 16px;"><strong><span style="letter-spacing: 0.5px;">服装材质: authentic silk/面部描述: exquisite face/发质描述: delicate hair/提升画质: super detailed/皮肤效果: translucent skin/背景描述: hazy background</span></strong></span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="font-size: 16px;"><strong><span style="letter-spacing: 0.5px;"><br></span></strong></span></p> <p style="margin-bottom: 24px;"><span style="font-size: 16px;"><strong><span style="letter-spacing: 0.5px;">我们打开Chat Gpt,根据上上篇文章,给下格式看看。</span></strong></span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);font-size: 16px;">请根据格式生成5组随机命令,请用英文回答。</span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);font-size: 16px;">一个[16-35] 岁的动漫人物,[随机身材] ,穿着[随机] 样式的服装,[随机的表情] ,[随机发色],[随机场景],[随机视角],[随机插画风格] ,[随机照明方式],高质量作品,全身照,超清细节。</span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);font-size: 16px;">这是一段参考文字:18 years old anime girl, with pefect curve,wearing tight jeans and atanktop, smiling, blonde hair, running in the morning, rear view, in the style ofdanbooru dandonfuga, natural lighting,masterpiec,fullbody,ultra detailed --ar 16:9 --niji 5</span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><img class="rich_pages wxw-img" data-ratio="0.5166666666666667" src="/upload/52ac19a03178bd5edfeb561f2c786ce0.png" data-type="png" data-w="1080" height="312.58px" style="width: 604.733px;height: 312.58px;" width="604.733"> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);font-size: 16px;">看到有些内容问题,但是问题不大,还是能生成的。</span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);font-size: 16px;">A 24-year-old anime character with a lean body, dressed in a flowing gown, with a surprised expression, pink hair, standing in a fantasy forest, from a low-angle perspective, in a watercolor illustration style, with soft lighting, high-quality artwork, full body shot, ultra-detailed. --ar 16:9 --niji 5</span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><img class="rich_pages wxw-img" data-ratio="0.5546296296296296" src="/upload/240395e05116d5e14613c03800dc772f.png" data-type="png" data-w="1080" height="335.462px" style="width: 604.733px;height: 335.462px;display: inline;" width="604.733"> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);font-size: 16px;">A 30-year-old anime character with a muscular build, wearing a loose hoodie and shorts, with a fierce expression, green hair, standing in a street alley, from a high-angle perspective, in a graffiti-style illustration, with neon lighting, high-quality artwork, full body shot, ultra-detailed. --ar 16:9 --niji 5</span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><img class="rich_pages wxw-img" data-ratio="0.5564814814814815" src="/upload/b52353e30cb5ae26bf104d136d35fb28.png" data-type="png" data-w="1080" height="336.383px" style="width: 604.733px;height: 336.383px;" width="604.733"> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);font-size: 16px;">A 19-year-old anime character with a curvy figure, dressed in a maid outfit, with a shy expression, black hair, sitting on a sofa, from a mid-angle perspective, in a manga-style illustration, with bright lighting, high-quality artwork, full body shot, ultra-detailed. --ar 16:9 --niji 5</span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><img class="rich_pages wxw-img" data-ratio="0.5574074074074075" src="/upload/9a1ec68ada44203b75888892d2f3338.png" data-type="png" data-w="1080" height="336.804px" style="width: 604.733px;height: 336.804px;display: inline;" width="604.733"> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);font-size: 16px;">A 27-year-old anime character with an average build, wearing a business suit, with a serious expression, brown hair, standing in a modern city, from a low-angle perspective, in a realistic illustration style, with natural lighting, high-quality artwork, full body shot, ultra-detailed. --ar 16:9 --niji 5</span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><img class="rich_pages wxw-img" data-ratio="0.5370370370370371" src="/upload/91817c8022be4847b23150389c690565.png" data-type="png" data-w="1080" height="324.931px" style="width: 604.733px;height: 324.931px;" width="604.733"> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="letter-spacing: 0.5px;color: rgb(119, 119, 119);font-size: 16px;">A 21-year-old anime character with a slim body, wearing a school uniform, with a happy expression, blue hair, sitting on a bench in a park, from a mid-angle perspective, in a sketchy illustration style, with warm lighting, high-quality artwork, full body shot, ultra-detailed. --ar 16:9 --niji 5</span> <o:p></o:p></p> <p style="margin-bottom: 24px;"><img class="rich_pages wxw-img" data-ratio="0.5546296296296296" src="/upload/38bff6696d546d78536f1004ee852553.png" data-type="png" data-w="1080" height="335.29px" style="width: 604.733px;height: 335.29px;" width="604.733"> <o:p></o:p></p> <p style="margin-bottom: 24px;"><span style="letter-spacing: 0.5px;font-size: 16px;">今天测试就到这里。</span></p> <section style="white-space: normal;letter-spacing: 0.544px;text-align: center;background-color: rgb(255, 255, 255);font-size: 16px;color: rgb(62, 62, 62);font-family: -apple-system-font, system-ui, Arial, sans-serif;caret-color: rgb(255, 0, 0);box-sizing: border-box;margin-bottom: 0px;"> <section style="box-sizing: border-box;line-height: 2em;font-family: Optima-Regular, PingFangTC-light;"> <section style="margin-top: 30px;margin-bottom: 30px;display: flex;flex-flow: row nowrap;justify-content: center;box-sizing: border-box;"> <section style="margin-right: -5px;display: inline-block;vertical-align: top;width: 8px;align-self: stretch;flex: 0 0 auto;height: auto;border-style: solid;border-width: 1px;border-radius: 0px;border-color: rgb(62, 62, 62);z-index: 1;background-color: rgb(255, 214, 88);box-sizing: border-box;"> <section powered-by="xiumi.us" style="text-align: justify;box-sizing: border-box;"> <p style="box-sizing: border-box;"><br style="box-sizing: border-box;"></p> </section> </section> <section style="margin-top: -20px;margin-bottom: -20px;padding: 10px 15px;display: inline-block;vertical-align: top;width: 554.875px;border-style: solid;border-width: 1px;border-radius: 0px;border-color: rgb(62, 62, 62);flex: 0 0 auto;height: auto;align-self: flex-start;box-sizing: border-box;"> <section powered-by="xiumi.us" style="text-align: justify;color: rgb(97, 97, 97);box-sizing: border-box;"> <p style="color: rgb(152, 152, 152);font-family: &quot;Microsoft YaHei&quot;, -apple-system-font, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, sans-serif;font-size: 14px;letter-spacing: 1.5px;text-align: start;"><span style="color: rgb(255, 76, 0);font-size: 15px;"><strong>推荐阅读</strong></span><span style="font-size: 12px;color: rgb(128, 128, 128);">(点击标题跳转)</span></p> <p style="color: rgb(152, 152, 152);font-size: 14px;letter-spacing: 1.5px;text-align: start;line-height: 3em;"><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MjM5MjMzMjE4MA==&amp;mid=2649235936&amp;idx=1&amp;sn=0f492766fc3aa04873898632b6a3e94a&amp;chksm=bebb611b89cce80dd88838ff203e97518cc6db1f379ce85f5cca48fa01936778e92bc97ce778&amp;scene=21#wechat_redirect" textvalue="知乎又大改交互,这回挺有创意" linktype="text" imgurl="" imgdata="null" data-itemshowtype="11" tab="innerlink" style="font-size: 15px;text-decoration: underline;" data-linktype="2"><span style="font-size: 15px;">知乎又大改交互,这回挺有创意</span></a><br></p> <p style="color: rgb(152, 152, 152);font-size: 14px;letter-spacing: 1.5px;text-align: start;line-height: 3em;"><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MjM5MjMzMjE4MA==&amp;mid=2649235926&amp;idx=1&amp;sn=047a685420fea17181c3d14a367f0b6e&amp;chksm=bebb612d89cce83bd5e0593b9e7be204eae761785dad42ae7aac4f926bf708f14f4158edd576&amp;scene=21#wechat_redirect" textvalue="淘宝改版体验设计实践" linktype="text" imgurl="" imgdata="null" data-itemshowtype="11" tab="innerlink" style="font-size: 15px;text-decoration: underline;" data-linktype="2"><span style="font-size: 15px;">淘宝改版体验设计实践</span></a><br></p> <p style="color: rgb(152, 152, 152);font-size: 14px;letter-spacing: 1.5px;text-align: start;line-height: 3em;"><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MjM5MjMzMjE4MA==&amp;mid=2649235919&amp;idx=1&amp;sn=0bbf467f3f4ccf771a85b044e8301b69&amp;chksm=bebb613489cce822248d8ea7f79d96063bd4be9e4d9b658757d61b2500c08ffb5e02775a6a01&amp;scene=21#wechat_redirect" textvalue="Midjourney 进阶技巧、关键词补充" linktype="text" imgurl="" imgdata="null" data-itemshowtype="11" tab="innerlink" style="font-size: 15px;text-decoration: underline;" data-linktype="2"><span style="font-size: 15px;">Midjourney 进阶技巧、关键词补充</span></a></p> </section> </section> <section style="margin-left: -5px;display: inline-block;vertical-align: top;width: 8px;align-self: stretch;flex: 0 0 auto;height: auto;border-style: solid;border-width: 1px;border-radius: 0px;border-color: rgb(62, 62, 62);background-color: rgb(255, 214, 88);box-sizing: border-box;"> <section powered-by="xiumi.us" style="text-align: justify;box-sizing: border-box;"> <p style="box-sizing: border-box;"><br style="box-sizing: border-box;"></p> </section> </section> </section> </section> </section> <section style="white-space: normal;letter-spacing: 0.544px;text-align: center;background-color: rgb(255, 255, 255);font-size: 16px;color: rgb(62, 62, 62);caret-color: rgb(255, 0, 0);font-family: Optima-Regular, PingFangTC-light;margin-bottom: 0px;"> <br> </section> <p style="text-align: center;margin-bottom: 0px;"><img class="rich_pages wxw-img" data-galleryid="" data-ratio="0.44375" data-s="300,640" src="/upload/183d627ee93292bff2f73818433cf6cd.jpg" data-type="jpeg" data-w="800" style=""></p> <section style="white-space: normal;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);color: rgb(62, 62, 62);caret-color: rgb(255, 0, 0);text-align: right;font-size: 13px;font-family: Optima-Regular, PingFangTC-light;margin-bottom: 0px;"> <span style="color: rgb(136, 136, 136);font-family: &quot;Microsoft YaHei&quot;, -apple-system-font, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, sans-serif;font-size: 12px;letter-spacing: 1.5px;"><br></span> </section> <section style="white-space: normal;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);color: rgb(62, 62, 62);caret-color: rgb(255, 0, 0);text-align: right;font-size: 13px;font-family: Optima-Regular, PingFangTC-light;margin-bottom: 0px;"> <span style="color: rgb(136, 136, 136);font-family: &quot;Microsoft YaHei&quot;, -apple-system-font, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, sans-serif;font-size: 12px;letter-spacing: 1.5px;">如果你喜欢这篇文章⬇️️</span> </section> <section style="white-space: normal;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);font-size: 16px;color: rgb(62, 62, 62);caret-color: rgb(255, 0, 0);text-align: right;font-family: Optima-Regular, PingFangTC-light;margin-bottom: 0px;"> <span style="font-size: 12px;"><span style="color: rgb(136, 136, 136);font-family: &quot;Microsoft YaHei&quot;, -apple-system-font, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, sans-serif;letter-spacing: 1.5px;">麻烦</span><span style="color: rgb(255, 76, 0);font-family: &quot;Microsoft YaHei&quot;, -apple-system-font, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, sans-serif;letter-spacing: 1.5px;">点赞、在看</span><span style="color: rgb(136, 136, 136);font-family: &quot;Microsoft YaHei&quot;, -apple-system-font, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, sans-serif;letter-spacing: 1.5px;">鼓励一下吧⬇️️</span></span> </section> <p style="display: none;"> <mp-style-type data-value="3"></mp-style-type></p>

为什么不再推荐枚举策略模式?

作者:微信小助手

<section data-mpa-powered-by="yiban.io" style="max-width: 100%;overflow-wrap: break-word !important;box-sizing: border-box !important;margin-bottom: 0px;"> <section powered-by="xiumi.us" style="max-width: 100%;overflow-wrap: break-word !important;box-sizing: border-box !important;"> <section style="max-width: 100%;overflow-wrap: break-word !important;box-sizing: border-box !important;"> <section style="max-width: 100%;overflow-wrap: break-word !important;box-sizing: border-box !important;"> <section powered-by="xiumi.us" style="max-width: 100%;overflow-wrap: break-word !important;box-sizing: border-box !important;"> <section> <section data-tool="mdnice编辑器" data-website="https://www.mdnice.com" data-mpa-powered-by="yiban.io" style="padding-right: 10px;padding-left: 10px;outline: 0px;white-space: normal;background-color: rgb(255, 255, 255);font-size: 16px;color: black;line-height: 1.6;letter-spacing: 0px;word-break: break-word;text-align: left;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;visibility: visible;"> <h1 data-tool="mdnice编辑器" style="margin: 1.2em auto;outline: 0px;font-weight: bold;font-size: 1.8em;color: rgb(0, 150, 136);text-align: center;border-bottom: 1px solid rgb(0, 150, 136);visibility: visible;">一、为什么讲策略模式</h1> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;text-align: justify;visibility: visible;">策略模式,应该是工作中比较常用的设计模式,调用方自己选择用哪一种策略完成对数据的操作,也就是“一个类的行为或其算法可以在运行时更改”</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;text-align: justify;visibility: visible;">我个人的理解是 将一些除了过程不同其他都一样的函数封装成策略,然后调用方自己去选择想让数据执行什么过程策略。常见的例子为根据用户分类推荐不同的排行榜(用户关注点不一样,推荐榜单就不一样)</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;text-align: justify;visibility: visible;">和单例模式一样,随着时间发展,我不再推荐经典策略模式,更推荐简单策略用枚举策略模式,复杂地用工厂策略模式。下面引入一个例子,我们的需求是:对一份股票数据列表,给出低价榜、高价榜、涨幅榜。这其中只有排序条件的区别,比较适合作为策略模式的例子</p> <h1 data-tool="mdnice编辑器" style="margin: 1.2em auto;outline: 0px;font-weight: bold;font-size: 1.8em;color: rgb(0, 150, 136);text-align: center;border-bottom: 1px solid rgb(0, 150, 136);visibility: visible;">二、经典策略模式</h1> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;text-align: justify;visibility: visible;">数据DTO</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;visibility: visible;"><span style="margin-bottom: -7px;outline: 0px;display: block;background: url(&quot;https://mmbiz.qpic.cn/mmbiz_svg/bofA1vl6EUZR9BtL4F0qwlTYcuF5DpkBZwLVYR8ibk3hBfVGkCMUlh72PUIwZS7PJ3a9sdWGhIbrGvTykoGia4S7tE998Y6aV2/640?wx_fmt=svg&quot;) 10px 10px / 40px no-repeat rgb(40, 44, 52);height: 30px;width: 657px;border-radius: 5px;visibility: visible;"></span><code style="padding: 15px 16px 16px;outline: 0px;overflow-x: auto;color: rgb(171, 178, 191);display: -webkit-box;font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;font-size: 12px;background: rgb(40, 44, 52);border-radius: 5px;visibility: visible;"><span style="outline: 0px;color: rgb(97, 174, 238);line-height: 26px;visibility: visible;">@Data</span>&nbsp;&nbsp;<br style="outline: 0px;visibility: visible;"><span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;visibility: visible;">public</span>&nbsp;<span style="outline: 0px;line-height: 26px;visibility: visible;"><span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;visibility: visible;">class</span>&nbsp;<span style="outline: 0px;color: rgb(230, 192, 123);line-height: 26px;visibility: visible;">Stock</span>&nbsp;</span>{&nbsp;&nbsp;<br style="outline: 0px;visibility: visible;">&nbsp;&nbsp;<br style="outline: 0px;visibility: visible;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(92, 99, 112);font-style: italic;line-height: 26px;visibility: visible;">//&nbsp;股票交易代码&nbsp;&nbsp;</span><br style="outline: 0px;visibility: visible;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;visibility: visible;">private</span>&nbsp;String&nbsp;code;&nbsp;&nbsp;<br style="outline: 0px;visibility: visible;">&nbsp;&nbsp;<br style="outline: 0px;visibility: visible;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(92, 99, 112);font-style: italic;line-height: 26px;visibility: visible;">//&nbsp;现价&nbsp;&nbsp;</span><br style="outline: 0px;visibility: visible;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;visibility: visible;">private</span>&nbsp;Double&nbsp;price;&nbsp;&nbsp;<br style="outline: 0px;visibility: visible;">&nbsp;&nbsp;<br style="outline: 0px;visibility: visible;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(92, 99, 112);font-style: italic;line-height: 26px;visibility: visible;">//&nbsp;涨幅&nbsp;&nbsp;</span><br style="outline: 0px;visibility: visible;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;visibility: visible;">private</span>&nbsp;Double&nbsp;rise;&nbsp;&nbsp;<br style="outline: 0px;visibility: visible;">}&nbsp;&nbsp;<br style="outline: 0px;visibility: visible;"></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;text-align: justify;visibility: visible;">抽象得到的策略接口</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;visibility: visible;"><span style="margin-bottom: -7px;outline: 0px;display: block;background: url(&quot;https://mmbiz.qpic.cn/mmbiz_svg/bofA1vl6EUZR9BtL4F0qwlTYcuF5DpkBZwLVYR8ibk3hBfVGkCMUlh72PUIwZS7PJ3a9sdWGhIbrGvTykoGia4S7tE998Y6aV2/640?wx_fmt=svg&quot;) 10px 10px / 40px no-repeat rgb(40, 44, 52);height: 30px;width: 657px;border-radius: 5px;visibility: visible;"></span><code style="padding: 15px 16px 16px;outline: 0px;overflow-x: auto;color: rgb(171, 178, 191);display: -webkit-box;font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;font-size: 12px;background: rgb(40, 44, 52);border-radius: 5px;visibility: visible;"><span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;visibility: visible;">public</span>&nbsp;<span style="outline: 0px;line-height: 26px;visibility: visible;"><span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;visibility: visible;">interface</span>&nbsp;<span style="outline: 0px;color: rgb(230, 192, 123);line-height: 26px;visibility: visible;">Strategy</span>&nbsp;</span>{&nbsp;&nbsp;<br style="outline: 0px;visibility: visible;">&nbsp;&nbsp;<br style="outline: 0px;visibility: visible;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(92, 99, 112);font-style: italic;line-height: 26px;visibility: visible;">/**&nbsp;&nbsp;<br style="outline: 0px;visibility: visible;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;将股票列表排序&nbsp;&nbsp;<br style="outline: 0px;visibility: visible;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;<br style="outline: 0px;visibility: visible;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;visibility: visible;">@param</span>&nbsp;source&nbsp;源数据&nbsp;&nbsp;<br style="outline: 0px;visibility: visible;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">@return</span>&nbsp;排序后的榜单&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span>&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;line-height: 26px;">List&lt;Stock&gt;&nbsp;<span style="outline: 0px;color: rgb(97, 174, 238);line-height: 26px;">sort</span><span style="outline: 0px;line-height: 26px;">(List&lt;Stock&gt;&nbsp;source)</span></span>;&nbsp;&nbsp;<br style="outline: 0px;">}&nbsp;&nbsp;<br style="outline: 0px;"></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;text-align: justify;">实现我们的策略类</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><span style="margin-bottom: -7px;outline: 0px;display: block;background: url(&quot;https://mmbiz.qpic.cn/mmbiz_svg/bofA1vl6EUZR9BtL4F0qwlTYcuF5DpkBZwLVYR8ibk3hBfVGkCMUlh72PUIwZS7PJ3a9sdWGhIbrGvTykoGia4S7tE998Y6aV2/640?wx_fmt=svg&quot;) 10px 10px / 40px no-repeat rgb(40, 44, 52);height: 30px;width: 657px;border-radius: 5px;"></span><code style="padding: 15px 16px 16px;outline: 0px;overflow-x: auto;color: rgb(171, 178, 191);display: -webkit-box;font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;font-size: 12px;background: rgb(40, 44, 52);border-radius: 5px;"><span style="outline: 0px;color: rgb(92, 99, 112);font-style: italic;line-height: 26px;">/**&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;*&nbsp;高价榜&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;*/</span>&nbsp;&nbsp;<br style="outline: 0px;"><span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">public</span>&nbsp;<span style="outline: 0px;line-height: 26px;"><span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">class</span>&nbsp;<span style="outline: 0px;color: rgb(230, 192, 123);line-height: 26px;">HighPriceRank</span>&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">implements</span>&nbsp;<span style="outline: 0px;color: rgb(230, 192, 123);line-height: 26px;">Strategy</span>&nbsp;</span>{&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(97, 174, 238);line-height: 26px;">@Override</span>&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;line-height: 26px;"><span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">public</span>&nbsp;List&lt;Stock&gt;&nbsp;<span style="outline: 0px;color: rgb(97, 174, 238);line-height: 26px;">sort</span><span style="outline: 0px;line-height: 26px;">(List&lt;Stock&gt;&nbsp;source)</span>&nbsp;</span>{&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">return</span>&nbsp;source.stream()&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.sorted(Comparator.comparing(Stock::getPrice).reversed())&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.collect(Collectors.toList());&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br style="outline: 0px;">}&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;<br style="outline: 0px;"><span style="outline: 0px;color: rgb(92, 99, 112);font-style: italic;line-height: 26px;">/**&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;*&nbsp;低价榜&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;*/</span>&nbsp;&nbsp;<br style="outline: 0px;"><span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">public</span>&nbsp;<span style="outline: 0px;line-height: 26px;"><span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">class</span>&nbsp;<span style="outline: 0px;color: rgb(230, 192, 123);line-height: 26px;">LowPriceRank</span>&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">implements</span>&nbsp;<span style="outline: 0px;color: rgb(230, 192, 123);line-height: 26px;">Strategy</span>&nbsp;</span>{&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(97, 174, 238);line-height: 26px;">@Override</span>&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;line-height: 26px;"><span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">public</span>&nbsp;List&lt;Stock&gt;&nbsp;<span style="outline: 0px;color: rgb(97, 174, 238);line-height: 26px;">sort</span><span style="outline: 0px;line-height: 26px;">(List&lt;Stock&gt;&nbsp;source)</span>&nbsp;</span>{&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">return</span>&nbsp;source.stream()&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.sorted(Comparator.comparing(Stock::getPrice))&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.collect(Collectors.toList());&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br style="outline: 0px;">}&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;<br style="outline: 0px;"><span style="outline: 0px;color: rgb(92, 99, 112);font-style: italic;line-height: 26px;">/**&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;*&nbsp;高涨幅榜&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;*/</span>&nbsp;&nbsp;<br style="outline: 0px;"><span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">public</span>&nbsp;<span style="outline: 0px;line-height: 26px;"><span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">class</span>&nbsp;<span style="outline: 0px;color: rgb(230, 192, 123);line-height: 26px;">HighRiseRank</span>&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">implements</span>&nbsp;<span style="outline: 0px;color: rgb(230, 192, 123);line-height: 26px;">Strategy</span>&nbsp;</span>{&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(97, 174, 238);line-height: 26px;">@Override</span>&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;line-height: 26px;"><span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">public</span>&nbsp;List&lt;Stock&gt;&nbsp;<span style="outline: 0px;color: rgb(97, 174, 238);line-height: 26px;">sort</span><span style="outline: 0px;line-height: 26px;">(List&lt;Stock&gt;&nbsp;source)</span>&nbsp;</span>{&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">return</span>&nbsp;source.stream()&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.sorted(Comparator.comparing(Stock::getRise).reversed())&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.collect(Collectors.toList());&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br style="outline: 0px;">}&nbsp;&nbsp;<br style="outline: 0px;"></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;text-align: justify;">经典的Context类,</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><span style="margin-bottom: -7px;outline: 0px;display: block;background: url(&quot;https://mmbiz.qpic.cn/mmbiz_svg/bofA1vl6EUZR9BtL4F0qwlTYcuF5DpkBZwLVYR8ibk3hBfVGkCMUlh72PUIwZS7PJ3a9sdWGhIbrGvTykoGia4S7tE998Y6aV2/640?wx_fmt=svg&quot;) 10px 10px / 40px no-repeat rgb(40, 44, 52);height: 30px;width: 657px;border-radius: 5px;"></span><code style="padding: 15px 16px 16px;outline: 0px;overflow-x: auto;color: rgb(171, 178, 191);display: -webkit-box;font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;font-size: 12px;background: rgb(40, 44, 52);border-radius: 5px;"><span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">public</span>&nbsp;<span style="outline: 0px;line-height: 26px;"><span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">class</span>&nbsp;<span style="outline: 0px;color: rgb(230, 192, 123);line-height: 26px;">Context</span>&nbsp;</span>{&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">private</span>&nbsp;Strategy&nbsp;strategy;&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;line-height: 26px;"><span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">public</span>&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">void</span>&nbsp;<span style="outline: 0px;color: rgb(97, 174, 238);line-height: 26px;">setStrategy</span><span style="outline: 0px;line-height: 26px;">(Strategy&nbsp;strategy)</span>&nbsp;</span>{&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">this</span>.strategy&nbsp;=&nbsp;strategy;&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;line-height: 26px;"><span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">public</span>&nbsp;List&lt;Stock&gt;&nbsp;<span style="outline: 0px;color: rgb(97, 174, 238);line-height: 26px;">getRank</span><span style="outline: 0px;line-height: 26px;">(List&lt;Stock&gt;&nbsp;source)</span>&nbsp;</span>{&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">return</span>&nbsp;strategy.sort(source);&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br style="outline: 0px;">}&nbsp;&nbsp;<br style="outline: 0px;"></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;text-align: justify;">于是 我们顺礼成章地得到调用类--榜单实例RankServiceImpl</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><span style="margin-bottom: -7px;outline: 0px;display: block;background: url(&quot;https://mmbiz.qpic.cn/mmbiz_svg/bofA1vl6EUZR9BtL4F0qwlTYcuF5DpkBZwLVYR8ibk3hBfVGkCMUlh72PUIwZS7PJ3a9sdWGhIbrGvTykoGia4S7tE998Y6aV2/640?wx_fmt=svg&quot;) 10px 10px / 40px no-repeat rgb(40, 44, 52);height: 30px;width: 657px;border-radius: 5px;"></span><code style="padding: 15px 16px 16px;outline: 0px;overflow-x: auto;color: rgb(171, 178, 191);display: -webkit-box;font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;font-size: 12px;background: rgb(40, 44, 52);border-radius: 5px;"><span style="outline: 0px;color: rgb(97, 174, 238);line-height: 26px;">@Service</span>&nbsp;&nbsp;<br style="outline: 0px;"><span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">public</span>&nbsp;<span style="outline: 0px;line-height: 26px;"><span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">class</span>&nbsp;<span style="outline: 0px;color: rgb(230, 192, 123);line-height: 26px;">RankServiceImpl</span>&nbsp;</span>{&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(92, 99, 112);font-style: italic;line-height: 26px;">/**&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;dataService.getSource()&nbsp;提供原始的股票数据&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span>&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(97, 174, 238);line-height: 26px;">@Resource</span>&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">private</span>&nbsp;DataService&nbsp;dataService;&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(92, 99, 112);font-style: italic;line-height: 26px;">/**&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;前端传入榜单类型,&nbsp;返回排序完的榜单&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">@param</span>&nbsp;rankType&nbsp;榜单类型&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">@return</span>&nbsp;榜单数据&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span>&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;line-height: 26px;"><span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">public</span>&nbsp;List&lt;Stock&gt;&nbsp;<span style="outline: 0px;color: rgb(97, 174, 238);line-height: 26px;">getRank</span><span style="outline: 0px;line-height: 26px;">(String&nbsp;rankType)</span>&nbsp;</span>{&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(92, 99, 112);font-style: italic;line-height: 26px;">//&nbsp;创建上下文&nbsp;&nbsp;</span><br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Context&nbsp;context&nbsp;=&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">new</span>&nbsp;Context();&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(92, 99, 112);font-style: italic;line-height: 26px;">//&nbsp;这里选择策略&nbsp;&nbsp;</span><br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">switch</span>&nbsp;(rankType)&nbsp;{&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">case</span>&nbsp;<span style="outline: 0px;color: rgb(152, 195, 121);line-height: 26px;">"HighPrice"</span>:&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;context.setStrategy(<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">new</span>&nbsp;HighPriceRank());&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">break</span>;&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">case</span>&nbsp;<span style="outline: 0px;color: rgb(152, 195, 121);line-height: 26px;">"LowPrice"</span>:&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;context.setStrategy(<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">new</span>&nbsp;LowPriceRank());&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">break</span>;&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">case</span>&nbsp;<span style="outline: 0px;color: rgb(152, 195, 121);line-height: 26px;">"HighRise"</span>:&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;context.setStrategy(<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">new</span>&nbsp;HighRiseRank());&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">break</span>;&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">default</span>:&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">throw</span>&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">new</span>&nbsp;IllegalArgumentException(<span style="outline: 0px;color: rgb(152, 195, 121);line-height: 26px;">"rankType&nbsp;not&nbsp;found"</span>);&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(92, 99, 112);font-style: italic;line-height: 26px;">//&nbsp;然后执行策略&nbsp;&nbsp;</span><br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">return</span>&nbsp;context.getRank(dataService.getSource());&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br style="outline: 0px;">}&nbsp;&nbsp;<br style="outline: 0px;"></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;text-align: justify;">我们可以看到经典方法,创建了一个接口、三个策略类,还是比较啰嗦的。调用类的实现也待商榷,新增一个策略类还要修改榜单实例(可以用抽象工厂解决,但是复杂度又上升了)。加之我们有更好的选择,所以此处不再推荐经典策略模式</p> <h1 data-tool="mdnice编辑器" style="margin: 1.2em auto;outline: 0px;font-weight: bold;font-size: 1.8em;color: rgb(0, 150, 136);text-align: center;border-bottom: 1px solid rgb(0, 150, 136);">三、基于枚举的策略模式</h1> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;text-align: justify;">这里对这种简单的策略,推荐用枚举进行优化。枚举的本质是创建了一些静态类的集合。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;text-align: justify;">我下面直接给出例子,大家可以直观感受一下</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;text-align: justify;">枚举策略类</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><span style="margin-bottom: -7px;outline: 0px;display: block;background: url(&quot;https://mmbiz.qpic.cn/mmbiz_svg/bofA1vl6EUZR9BtL4F0qwlTYcuF5DpkBZwLVYR8ibk3hBfVGkCMUlh72PUIwZS7PJ3a9sdWGhIbrGvTykoGia4S7tE998Y6aV2/640?wx_fmt=svg&quot;) 10px 10px / 40px no-repeat rgb(40, 44, 52);height: 30px;width: 657px;border-radius: 5px;"></span><code style="padding: 15px 16px 16px;outline: 0px;overflow-x: auto;color: rgb(171, 178, 191);display: -webkit-box;font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;font-size: 12px;background: rgb(40, 44, 52);border-radius: 5px;"><span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">public</span>&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">enum</span>&nbsp;RankEnum&nbsp;{&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(92, 99, 112);font-style: italic;line-height: 26px;">//&nbsp;以下三个为策略实例&nbsp;&nbsp;</span><br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;HighPrice&nbsp;{&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(97, 174, 238);line-height: 26px;">@Override</span>&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;line-height: 26px;"><span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">public</span>&nbsp;List&lt;Stock&gt;&nbsp;<span style="outline: 0px;color: rgb(97, 174, 238);line-height: 26px;">sort</span><span style="outline: 0px;line-height: 26px;">(List&lt;Stock&gt;&nbsp;source)</span>&nbsp;</span>{&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">return</span>&nbsp;source.stream()&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.sorted(Comparator.comparing(Stock::getPrice).reversed())&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.collect(Collectors.toList());&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;},&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;LowPrice&nbsp;{&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(97, 174, 238);line-height: 26px;">@Override</span>&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;line-height: 26px;"><span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">public</span>&nbsp;List&lt;Stock&gt;&nbsp;<span style="outline: 0px;color: rgb(97, 174, 238);line-height: 26px;">sort</span><span style="outline: 0px;line-height: 26px;">(List&lt;Stock&gt;&nbsp;source)</span>&nbsp;</span>{&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">return</span>&nbsp;source.stream()&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.sorted(Comparator.comparing(Stock::getPrice))&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.collect(Collectors.toList());&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;},&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;HighRise&nbsp;{&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(97, 174, 238);line-height: 26px;">@Override</span>&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;line-height: 26px;"><span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">public</span>&nbsp;List&lt;Stock&gt;&nbsp;<span style="outline: 0px;color: rgb(97, 174, 238);line-height: 26px;">sort</span><span style="outline: 0px;line-height: 26px;">(List&lt;Stock&gt;&nbsp;source)</span>&nbsp;</span>{&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">return</span>&nbsp;source.stream()&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.sorted(Comparator.comparing(Stock::getRise).reversed())&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.collect(Collectors.toList());&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;};&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(92, 99, 112);font-style: italic;line-height: 26px;">//&nbsp;这里定义了策略接口&nbsp;&nbsp;</span><br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;line-height: 26px;"><span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">public</span>&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">abstract</span>&nbsp;List&lt;Stock&gt;&nbsp;<span style="outline: 0px;color: rgb(97, 174, 238);line-height: 26px;">sort</span><span style="outline: 0px;line-height: 26px;">(List&lt;Stock&gt;&nbsp;source)</span></span>;&nbsp;&nbsp;<br style="outline: 0px;">}&nbsp;&nbsp;<br style="outline: 0px;"></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;text-align: justify;">对应的调用类也得以优化,榜单实例RankServiceImpl</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><span style="margin-bottom: -7px;outline: 0px;display: block;background: url(&quot;https://mmbiz.qpic.cn/mmbiz_svg/bofA1vl6EUZR9BtL4F0qwlTYcuF5DpkBZwLVYR8ibk3hBfVGkCMUlh72PUIwZS7PJ3a9sdWGhIbrGvTykoGia4S7tE998Y6aV2/640?wx_fmt=svg&quot;) 10px 10px / 40px no-repeat rgb(40, 44, 52);height: 30px;width: 657px;border-radius: 5px;"></span><code style="padding: 15px 16px 16px;outline: 0px;overflow-x: auto;color: rgb(171, 178, 191);display: -webkit-box;font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;font-size: 12px;background: rgb(40, 44, 52);border-radius: 5px;"><span style="outline: 0px;color: rgb(97, 174, 238);line-height: 26px;">@Service</span>&nbsp;&nbsp;<br style="outline: 0px;"><span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">public</span>&nbsp;<span style="outline: 0px;line-height: 26px;"><span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">class</span>&nbsp;<span style="outline: 0px;color: rgb(230, 192, 123);line-height: 26px;">RankServiceImpl</span>&nbsp;</span>{&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(92, 99, 112);font-style: italic;line-height: 26px;">/**&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;dataService.getSource()&nbsp;提供原始的股票数据&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span>&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(97, 174, 238);line-height: 26px;">@Resource</span>&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">private</span>&nbsp;DataService&nbsp;dataService;&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(92, 99, 112);font-style: italic;line-height: 26px;">/**&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;前端传入榜单类型,&nbsp;返回排序完的榜单&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">@param</span>&nbsp;rankType&nbsp;榜单类型&nbsp;形似&nbsp;RankEnum.HighPrice.name()&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">@return</span>&nbsp;榜单数据&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span>&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;line-height: 26px;"><span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">public</span>&nbsp;List&lt;Stock&gt;&nbsp;<span style="outline: 0px;color: rgb(97, 174, 238);line-height: 26px;">getRank</span><span style="outline: 0px;line-height: 26px;">(String&nbsp;rankType)</span>&nbsp;</span>{&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(92, 99, 112);font-style: italic;line-height: 26px;">//&nbsp;获取策略,这里如果未匹配会抛&nbsp;IllegalArgumentException异常&nbsp;&nbsp;</span><br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RankEnum&nbsp;rank&nbsp;=&nbsp;RankEnum.valueOf(rankType);&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(92, 99, 112);font-style: italic;line-height: 26px;">//&nbsp;然后执行策略&nbsp;&nbsp;</span><br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">return</span>&nbsp;rank.sort(dataService.getSource());&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br style="outline: 0px;">}&nbsp;&nbsp;<br style="outline: 0px;"></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;text-align: justify;">可以看到,如果策略简单的话,基于枚举的策略模式优雅许多,调用方也做到了0修改,但正确地使用枚举策略模式需要额外考虑以下几点。</p> <ul data-tool="mdnice编辑器" class="list-paddingleft-1" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;outline: 0px;"> <li style="outline: 0px;"> <section style="margin-top: 5px;margin-bottom: 5px;outline: 0px;line-height: 26px;color: rgb(1, 1, 1);"> <p style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;color: black;text-align: justify;">枚举的策略类是公用且静态,这意味着这个策略过程不能引入非静态的部分,扩展性受限</p> </section></li> <li style="outline: 0px;"> <section style="margin-top: 5px;margin-bottom: 5px;outline: 0px;line-height: 26px;color: rgb(1, 1, 1);"> <p style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;color: black;text-align: justify;">策略模式的目标之一,是优秀的扩展性和可维护性,最好能新增或修改某一策略类时,对其他类是无改动的。而枚举策略如果过多或者过程复杂,维护是比较困难的,可维护性受限</p> </section></li> </ul> <h1 data-tool="mdnice编辑器" style="margin: 1.2em auto;outline: 0px;font-weight: bold;font-size: 1.8em;color: rgb(0, 150, 136);text-align: center;border-bottom: 1px solid rgb(0, 150, 136);">四、基于工厂的策略模式</h1> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;text-align: justify;">为了解决良好的扩展性和可维护性,我更推荐以下利用spring自带beanFactory的优势,实现一个基于工厂的策略模式。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;text-align: justify;">策略类改动只是添加了@Service注解,并指定了Service的value属性</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><span style="margin-bottom: -7px;outline: 0px;display: block;background: url(&quot;https://mmbiz.qpic.cn/mmbiz_svg/bofA1vl6EUZR9BtL4F0qwlTYcuF5DpkBZwLVYR8ibk3hBfVGkCMUlh72PUIwZS7PJ3a9sdWGhIbrGvTykoGia4S7tE998Y6aV2/640?wx_fmt=svg&quot;) 10px 10px / 40px no-repeat rgb(40, 44, 52);height: 30px;width: 657px;border-radius: 5px;"></span><code style="padding: 15px 16px 16px;outline: 0px;overflow-x: auto;color: rgb(171, 178, 191);display: -webkit-box;font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;font-size: 12px;background: rgb(40, 44, 52);border-radius: 5px;"><span style="outline: 0px;color: rgb(92, 99, 112);font-style: italic;line-height: 26px;">/**&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;*&nbsp;高价榜&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;*&nbsp;注意申明&nbsp;Service.value&nbsp;=&nbsp;HighPrice,他是我们的key,下同&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;*/</span>&nbsp;&nbsp;<br style="outline: 0px;"><span style="outline: 0px;color: rgb(97, 174, 238);line-height: 26px;">@Service</span>(<span style="outline: 0px;color: rgb(152, 195, 121);line-height: 26px;">"HighPrice"</span>)&nbsp;&nbsp;<br style="outline: 0px;"><span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">public</span>&nbsp;<span style="outline: 0px;line-height: 26px;"><span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">class</span>&nbsp;<span style="outline: 0px;color: rgb(230, 192, 123);line-height: 26px;">HighPriceRank</span>&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">implements</span>&nbsp;<span style="outline: 0px;color: rgb(230, 192, 123);line-height: 26px;">Strategy</span>&nbsp;</span>{&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(97, 174, 238);line-height: 26px;">@Override</span>&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;line-height: 26px;"><span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">public</span>&nbsp;List&lt;Stock&gt;&nbsp;<span style="outline: 0px;color: rgb(97, 174, 238);line-height: 26px;">sort</span><span style="outline: 0px;line-height: 26px;">(List&lt;Stock&gt;&nbsp;source)</span>&nbsp;</span>{&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">return</span>&nbsp;source.stream()&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.sorted(Comparator.comparing(Stock::getPrice).reversed())&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.collect(Collectors.toList());&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br style="outline: 0px;">}&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;<br style="outline: 0px;"><span style="outline: 0px;color: rgb(92, 99, 112);font-style: italic;line-height: 26px;">/**&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;*&nbsp;低价榜&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;*/</span>&nbsp;&nbsp;<br style="outline: 0px;"><span style="outline: 0px;color: rgb(97, 174, 238);line-height: 26px;">@Service</span>(<span style="outline: 0px;color: rgb(152, 195, 121);line-height: 26px;">"LowPrice"</span>)&nbsp;&nbsp;<br style="outline: 0px;"><span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">public</span>&nbsp;<span style="outline: 0px;line-height: 26px;"><span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">class</span>&nbsp;<span style="outline: 0px;color: rgb(230, 192, 123);line-height: 26px;">LowPriceRank</span>&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">implements</span>&nbsp;<span style="outline: 0px;color: rgb(230, 192, 123);line-height: 26px;">Strategy</span>&nbsp;</span>{&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(97, 174, 238);line-height: 26px;">@Override</span>&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;line-height: 26px;"><span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">public</span>&nbsp;List&lt;Stock&gt;&nbsp;<span style="outline: 0px;color: rgb(97, 174, 238);line-height: 26px;">sort</span><span style="outline: 0px;line-height: 26px;">(List&lt;Stock&gt;&nbsp;source)</span>&nbsp;</span>{&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">return</span>&nbsp;source.stream()&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.sorted(Comparator.comparing(Stock::getPrice))&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.collect(Collectors.toList());&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br style="outline: 0px;">}&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;<br style="outline: 0px;"><span style="outline: 0px;color: rgb(92, 99, 112);font-style: italic;line-height: 26px;">/**&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;*&nbsp;高涨幅榜&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;*/</span>&nbsp;&nbsp;<br style="outline: 0px;"><span style="outline: 0px;color: rgb(97, 174, 238);line-height: 26px;">@Service</span>(<span style="outline: 0px;color: rgb(152, 195, 121);line-height: 26px;">"HighRise"</span>)&nbsp;&nbsp;<br style="outline: 0px;"><span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">public</span>&nbsp;<span style="outline: 0px;line-height: 26px;"><span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">class</span>&nbsp;<span style="outline: 0px;color: rgb(230, 192, 123);line-height: 26px;">HighRiseRank</span>&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">implements</span>&nbsp;<span style="outline: 0px;color: rgb(230, 192, 123);line-height: 26px;">Strategy</span>&nbsp;</span>{&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(97, 174, 238);line-height: 26px;">@Override</span>&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;line-height: 26px;"><span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">public</span>&nbsp;List&lt;Stock&gt;&nbsp;<span style="outline: 0px;color: rgb(97, 174, 238);line-height: 26px;">sort</span><span style="outline: 0px;line-height: 26px;">(List&lt;Stock&gt;&nbsp;source)</span>&nbsp;</span>{&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">return</span>&nbsp;source.stream()&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.sorted(Comparator.comparing(Stock::getRise).reversed())&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.collect(Collectors.toList());&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br style="outline: 0px;">}&nbsp;&nbsp;<br style="outline: 0px;"></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;text-align: justify;">调用类修改较大,接入借助spring工厂特性,完成策略类</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><span style="margin-bottom: -7px;outline: 0px;display: block;background: url(&quot;https://mmbiz.qpic.cn/mmbiz_svg/bofA1vl6EUZR9BtL4F0qwlTYcuF5DpkBZwLVYR8ibk3hBfVGkCMUlh72PUIwZS7PJ3a9sdWGhIbrGvTykoGia4S7tE998Y6aV2/640?wx_fmt=svg&quot;) 10px 10px / 40px no-repeat rgb(40, 44, 52);height: 30px;width: 657px;border-radius: 5px;"></span><code style="padding: 15px 16px 16px;outline: 0px;overflow-x: auto;color: rgb(171, 178, 191);display: -webkit-box;font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;font-size: 12px;background: rgb(40, 44, 52);border-radius: 5px;"><span style="outline: 0px;color: rgb(97, 174, 238);line-height: 26px;">@Service</span>&nbsp;&nbsp;<br style="outline: 0px;"><span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">public</span>&nbsp;<span style="outline: 0px;line-height: 26px;"><span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">class</span>&nbsp;<span style="outline: 0px;color: rgb(230, 192, 123);line-height: 26px;">RankServiceImpl</span>&nbsp;</span>{&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(92, 99, 112);font-style: italic;line-height: 26px;">/**&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;dataService.getSource()&nbsp;提供原始的股票数据&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span>&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(97, 174, 238);line-height: 26px;">@Resource</span>&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">private</span>&nbsp;DataService&nbsp;dataService;&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(92, 99, 112);font-style: italic;line-height: 26px;">/**&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;利用注解<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">@Resource</span>和<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">@Autowired</span>特性,直接获取所有策略类&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;key&nbsp;=&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">@Service</span>的value&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span>&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(97, 174, 238);line-height: 26px;">@Resource</span>&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">private</span>&nbsp;Map&lt;String,&nbsp;Strategy&gt;&nbsp;rankMap;&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(92, 99, 112);font-style: italic;line-height: 26px;">/**&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;前端传入榜单类型,&nbsp;返回排序完的榜单&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">@param</span>&nbsp;rankType&nbsp;榜单类型&nbsp;和Service注解的value属性一致&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">@return</span>&nbsp;榜单数据&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span>&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;line-height: 26px;"><span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">public</span>&nbsp;List&lt;Stock&gt;&nbsp;<span style="outline: 0px;color: rgb(97, 174, 238);line-height: 26px;">getRank</span><span style="outline: 0px;line-height: 26px;">(String&nbsp;rankType)</span>&nbsp;</span>{&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(92, 99, 112);font-style: italic;line-height: 26px;">//&nbsp;判断策略是否存在&nbsp;&nbsp;</span><br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">if</span>&nbsp;(!rankMap.containsKey(rankType))&nbsp;{&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">throw</span>&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">new</span>&nbsp;IllegalArgumentException(<span style="outline: 0px;color: rgb(152, 195, 121);line-height: 26px;">"rankType&nbsp;not&nbsp;found"</span>);&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(92, 99, 112);font-style: italic;line-height: 26px;">//&nbsp;获得策略实例&nbsp;&nbsp;</span><br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Strategy&nbsp;rank&nbsp;=&nbsp;rankMap.get(rankType);&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(92, 99, 112);font-style: italic;line-height: 26px;">//&nbsp;执行策略&nbsp;&nbsp;</span><br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">return</span>&nbsp;rank.sort(dataService.getSource());&nbsp;&nbsp;<br style="outline: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br style="outline: 0px;">}&nbsp;&nbsp;<br style="outline: 0px;"></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;text-align: justify;">若读者使用的不是Spring,也可以找找对应框架的工厂模式实现,或者自己实现一个抽象工厂。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;text-align: justify;">工厂策略模式会比枚举策略模式啰嗦,但也更加灵活、易扩展性和易维护。故简单策略推荐枚举策略模式,复杂策略才推荐工厂策略模式。</p> </section> <section data-tool="mdnice编辑器" data-website="https://www.mdnice.com" style="margin-bottom: 0px;padding-right: 10px;padding-left: 10px;outline: 0px;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;text-align: left;line-height: 1.6;word-break: break-word;font-size: 15px;color: rgb(89, 89, 89);"> <section style="outline: 0px;"> <blockquote data-type="2" data-url="" data-author-name="" data-content-utf8-length="121" data-source-title="" style="outline: 0px;"> <section style="outline: 0px;"> <section style="outline: 0px;"> <span style="outline: 0px;font-size: 11px;"><em style="outline: 0px;">感谢阅读,希望对你有所帮助&nbsp;:)&nbsp; &nbsp;</em></span> </section> <section style="outline: 0px;"> <em style="outline: 0px;font-size: 11px;letter-spacing: 0.544px;">来源:toutiao.com/article/7080135241830302212</em> </section> </section> </blockquote> </section> </section> </section> </section> </section> </section> </section> </section>

开源部分组内实用运维shell脚本模版

作者:微信小助手

<section data-mpa-powered-by="yiban.io"> <section> <section> <section data-tool="编辑器" data-website="https://jsjson.com"> <section> <section> <section> <section powered-by="xiumi.us"> <s

Spring Boot 如何让你的 bean 在其他 bean 之前完成加载 ?

作者:微信小助手

<section class="mp_profile_iframe_wrp" data-mpa-powered-by="yiban.io"> <mp-common-profile class="js_uneditable custom_select_card mp_profile_iframe" data-pluginname="mpprofile" data-weui-theme="light" data-id="MzAwMTk4NjM1MA==" data-headimg="http://mmbiz.qpic.cn/mmbiz_png/PxMzT0Oibf4gcBzLSUNh2cgXUsuLIsvQYJE1lzZd74qpC3iciaM6gcYIfOVV0KjDDkeN4CTLTn4ETPtaHOAuTWSWA/0?wx_fmt=png" data-nickname="JAVA日知录" data-alias="javadaily" data-signature="写代码的架构师,做架构的程序员! 实战、源码、数据库、架构...只要你来,你想了解的这里都有!" data-from="0" data-is_biz_ban="0"></mp-common-profile> </section> <section style="font-size: 15px;margin-bottom: 24px;"> <section style="margin-top: 10px;margin-bottom: 10px;text-align: center;" powered-by="xiumi.us"> <section style="padding: 3px;display: inline-block;border-bottom: 5px solid rgb(255, 129, 36);color: rgb(255, 129, 36);font-size: 16px;"> <p><span style="color: rgb(255, 104, 39);">问题</span></p> </section> </section> </section> <section style="line-height: 1.75em;margin-bottom: 24px;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">今天有个小伙伴给我出了一个难题:在 SpringBoot 中如何让自己的某个指定的 Bean 在其他 Bean 前完成被 Spring 加载?我听到这个问题的第一反应是,为什么会有这样奇怪的需求?</span> </section> <section style="min-height: 24px;line-height: 1.75em;margin-bottom: 24px;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">Talk is cheap,show me the code,这里列出了那个想做最先加载的“天选 Bean” 的代码,我们来分析一下:</span> </section> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="typescript"><code><span class="code-snippet_outer"><span class="code-snippet__comment">/**</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"> * 系统属性服务</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment">**/</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">@Service</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">class</span> SystemConfigService {</span></code><code><span class="code-snippet_outer"><br></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__comment">// 访问 db 的 mapper</span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">private</span> final SystemConfigMapper systemConfigMapper;</span></code><code><span class="code-snippet_outer"><br></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__comment">// 存放一些系统配置的缓存 map</span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">private</span> <span class="code-snippet__keyword">static</span> Map&lt;<span class="code-snippet__built_in">String</span>, <span class="code-snippet__built_in">String</span>&gt;&gt; SYS_CONF_CACHE = <span class="code-snippet__keyword">new</span> HashMap&lt;&gt;()</span></code><code><span class="code-snippet_outer"><br></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__comment">// 使用构造方法完成依赖注入</span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">public</span> SystemConfigServiceImpl(SystemConfigMapper systemConfigMapper) {</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">this</span>.systemConfigMapper = systemConfigMapper;</span></code><code><span class="code-snippet_outer"> }</span></code><code><span class="code-snippet_outer"><br></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__comment">// Bean 的初始化方法,捞取数据库中的数据,放入缓存的 map 中</span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__meta">@PostConstruct</span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">public</span> <span class="code-snippet__built_in">void</span> init() {</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__comment">// systemConfigMapper 访问 DB,捞取数据放入缓存的 map 中</span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__comment">// SYS_CONF_CACHE.put(key, value);</span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__comment">// ...</span></span></code><code><span class="code-snippet_outer"> }</span></code><code><span class="code-snippet_outer"><br></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__comment">// 对外提供获得系统配置的 static 工具方法</span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">static</span> <span class="code-snippet__built_in">String</span> getSystemConfig(<span class="code-snippet__built_in">String</span> key) {</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">return</span> SYS_CONF_CACHE.get(key);</span></code><code><span class="code-snippet_outer"> }</span></code><code><span class="code-snippet_outer"><br></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__comment">// 省略了从 DB 更新缓存的代码</span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__comment">// ...</span></span></code><code><span class="code-snippet_outer">}</span></code></pre> </section> <p style="min-height: 24px;line-height: 1.75em;margin-top: 24px;margin-bottom: 24px;"><span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 15px;letter-spacing: 0.034em;color: rgb(62, 62, 62);">看过了上面的代码后,很容易就理解了为什么会标题中的需求了。</span></p> <section style="margin-bottom: 24px;"> <span style="font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">SystemConfigService</span> <span style="color: rgb(62, 62, 62);font-size: 15px;">&nbsp;是一个提供了查询系统属性的服务,系统属性存放在 DB 中并且读多写少,在 Bean 创建的时候,通过</span> <span style="font-size: 15px;color: rgb(136, 136, 136);">&nbsp;</span> <span style="font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">@PostConstruct</span> <span style="font-size: 15px;color: rgb(136, 136, 136);">&nbsp;</span> <span style="color: rgb(62, 62, 62);font-size: 15px;">注解的 init() 方法完成了数据加载到缓存中,最关键的是,由于是系统属性,所以需要在很多地方都想使用,尤其需要在很多 bean <strong>启动的时候使用</strong><strong>,</strong>为了方便就提供了 static 方法来方便调用,这样其他的 bean 不需要依赖注入就可以直接调用,但问题是系统属性是存在 db 里面的,这就导致了不能把</span> <span style="font-size: 15px;color: rgb(136, 136, 136);">&nbsp;</span> <span style="font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">SystemConfigService</span> <span style="font-size: 15px;color: rgb(62, 62, 62);">做成一个纯「工具类」,它必须要被 Spring 托管起来,完成 mapper 的注入才能正常工作。因此这样一来就比较麻烦,其他的类或者 Bean 如果想安全的使用&nbsp;</span> <span style="font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">SystemConfigService#getSystemConfig</span> <span style="font-size: 15px;color: rgb(136, 136, 136);">&nbsp;</span> <span style="font-size: 15px;color: rgb(62, 62, 62);">中的获取配置的静态方法,就必须等</span> <span style="font-size: 15px;color: rgb(136, 136, 136);">&nbsp;</span> <span style="font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">SystemConfigService</span> <span style="font-size: 15px;color: rgb(136, 136, 136);">&nbsp;</span> <span style="font-size: 15px;color: rgb(62, 62, 62);">先被 Spring 创建加载起来,完成</span> <span style="font-size: 15px;color: rgb(136, 136, 136);">&nbsp;</span> <span style="font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">init()</span> <span style="font-size: 15px;color: rgb(136, 136, 136);">&nbsp;</span> <span style="font-size: 15px;color: rgb(62, 62, 62);">方法后才可以。</span> </section> <section style="min-height: 24px;line-height: 1.75em;margin-bottom: 24px;"> <span style="color: rgb(62, 62, 62);font-size: 15px;font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;">所以才有了最开头提到的问题,如何让这个 Bean 在其他的 Bean 之前加载。</span> <br> </section> <section style="font-size: 15px;margin-bottom: 24px;"> <section style="margin-top: 10px;margin-bottom: 10px;text-align: center;" powered-by="xiumi.us"> <section style="padding: 3px;display: inline-block;border-bottom: 5px solid rgb(255, 129, 36);color: rgb(255, 129, 36);font-size: 16px;"> <p><span style="color: rgb(255, 104, 39);">SpringBoot 官方文档推荐做法</span></p> </section> </section> </section> <h3 style="margin-top: 16px;margin-bottom: 5px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(62, 62, 62);"></span></h3> <section style="min-height: 24px;line-height: 1.75em;margin-bottom: 24px;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">这里引用了一段 Spring Framework 官方文档的原文:</span> </section> <blockquote style="outline: 0px;font-family: system-ui, -apple-system, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);"> <section style="letter-spacing: 0.578px;white-space: normal;min-height: 24px;line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(136, 136, 136);">Constructor-based or setter-based DI?&nbsp;</span> </section> <section style="letter-spacing: 0.578px;white-space: normal;min-height: 24px;line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(136, 136, 136);">Since you can mix constructor-based and setter-based DI, it is a good rule of thumb to use constructors for mandatory dependencies and setter methods or configuration methods for optional dependencies. Note that use of the @Autowired annotation on a setter method can be used to make the property be a required dependency; however, constructor injection with programmatic validation of arguments is preferable.</span> </section> </blockquote> <section style="min-height: 24px;line-height: 1.75em;margin-bottom: 24px;"> <span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(62, 62, 62);">可以看到 Spring 对于依赖注入更推荐(is preferable)使用构造函数来注入必须的依赖,用 setter 方法来注入可选的依赖。至于我们平时工作中更多采用的</span> <span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">&nbsp;@Autowired&nbsp;</span> <span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(62, 62, 62);">注解 + 属性的注入方式是不推荐的,这也是为什么你用 Idea 集成开发环境的时候会给你一个警告。</span> <span style="color: rgb(62, 62, 62);font-size: 15px;font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;"></span> </section> <section style="min-height: 24px;line-height: 1.75em;margin-bottom: 24px;"> <span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(62, 62, 62);">按照 Spring 的文档,我们应该直接去掉</span> <span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">&nbsp;getSystemConfig&nbsp;</span> <span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(62, 62, 62);">的 static 修饰,让&nbsp;</span> <span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">getSystemConfig&nbsp;</span> <span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(62, 62, 62);">变成一个实例方法,让每个需要依赖的</span> <span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">&nbsp;SystemConfigService&nbsp;</span> <span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(62, 62, 62);">的 Bean 通过构造函数完成依赖注入,这样 Spring 会保证每个 Bean 在创建之前会先把它所有的依赖创建并初始化完成。</span> <br> </section> <section style="min-height: 24px;line-height: 1.75em;margin-bottom: 24px;"> <span style="color: rgb(62, 62, 62);font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 15px;letter-spacing: 0.034em;">看来我们还是要想一些其他的方法来达成我们的目的。</span> </section> <section style="font-size: 15px;margin-bottom: 24px;"> <section style="margin-top: 10px;margin-bottom: 10px;text-align: center;" powered-by="xiumi.us"> <section style="padding: 3px;display: inline-block;border-bottom: 5px solid rgb(255, 129, 36);color: rgb(255, 129, 36);font-size: 16px;"> <p><span style="color: rgb(255, 104, 39);">尝试解决问题的一些方法</span></p> </section> </section> </section> <h3 style="margin-top: 16px;margin-bottom: 5px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(62, 62, 62);"></span></h3> <section style="font-size: 15px;margin-bottom: 24px;"> <section style="text-align: left;justify-content: flex-start;margin: 10px 0%;display: flex;flex-flow: row nowrap;" powered-by="xiumi.us"> <section style="display: inline-block;vertical-align: bottom;width: auto;align-self: flex-end;flex: 0 0 0%;height: auto;line-height: 0;"> <section style="text-align: right;" powered-by="xiumi.us"> <section style="display: inline-block;width: 18px;height: 18px;vertical-align: top;overflow: hidden;background-color: rgb(255, 129, 36);"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> </section> <section style="display: inline-block;vertical-align: bottom;width: auto;min-width: 10%;flex: 0 0 auto;height: auto;align-self: flex-end;"> <section style="color: rgb(62, 62, 62);font-size: 14px;padding-right: 4px;padding-left: 4px;line-height: 1;text-align: justify;" powered-by="xiumi.us"> <p style="text-align: left;white-space: normal;"><br></p> <p style="text-align: left;white-space: normal;"><strong><span style="font-size: 15px;">@Order 注解或者实现 org.springframework.core.Ordered</span></strong></p> </section> </section> <section style="display: inline-block;vertical-align: middle;width: auto;align-self: center;min-width: 10%;flex: 0 0 auto;height: auto;line-height: 0;"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> </section> <h4 style="margin-top: 10px;margin-bottom: 5px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(62, 62, 62);"></span></h4> <section style="min-height: 24px;line-height: 1.75em;margin-bottom: 24px;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">最先想到的就是 Spring 提供的 Order 相关的注解和接口,实际上测试下来不可行。Order 相关的方法一般用来控制 Spring 自身组件相关 Bean 的顺序,比如 ApplicationListener,RegistrationBean 等,对于我们自己使用 @Service @Compont 注解注册的业务相关的 bean 没有排序的效果。</span> </section> <section style="font-size: 15px;margin-bottom: 24px;"> <section style="text-align: left;justify-content: flex-start;margin: 10px 0%;display: flex;flex-flow: row nowrap;" powered-by="xiumi.us"> <section style="display: inline-block;vertical-align: bottom;width: auto;align-self: flex-end;flex: 0 0 0%;height: auto;line-height: 0;"> <section style="text-align: right;" powered-by="xiumi.us"> <section style="display: inline-block;width: 18px;height: 18px;vertical-align: top;overflow: hidden;background-color: rgb(255, 129, 36);"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> </section> <section style="display: inline-block;vertical-align: bottom;width: auto;min-width: 10%;flex: 0 0 auto;height: auto;align-self: flex-end;"> <section style="color: rgb(62, 62, 62);font-size: 14px;padding-right: 4px;padding-left: 4px;line-height: 1;text-align: justify;" powered-by="xiumi.us"> <p style="text-align: left;white-space: normal;"><br></p> <p style="white-space: normal;"><strong><span style="font-size: 15px;">@AutoConfigureOrder/@AutoConfigureAfter/@AutoConfigureBefore 注解</span></strong></p> </section> </section> <section style="display: inline-block;vertical-align: middle;width: auto;align-self: center;min-width: 10%;flex: 0 0 auto;height: auto;line-height: 0;"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> </section> <h4 style="margin-top: 10px;margin-bottom: 5px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(62, 62, 62);"></span></h4> <section style="min-height: 24px;line-height: 1.75em;margin-bottom: 24px;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">测试下来这些注解也是不可行,它们和 Ordered 一样都是针对 Spring 自身组件 Bean 的顺序。</span> </section> <section style="font-size: 15px;margin-bottom: 24px;"> <section style="text-align: left;justify-content: flex-start;margin: 10px 0%;display: flex;flex-flow: row nowrap;" powered-by="xiumi.us"> <section style="display: inline-block;vertical-align: bottom;width: auto;align-self: flex-end;flex: 0 0 0%;height: auto;line-height: 0;"> <section style="text-align: right;" powered-by="xiumi.us"> <section style="display: inline-block;width: 18px;height: 18px;vertical-align: top;overflow: hidden;background-color: rgb(255, 129, 36);"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> </section> <section style="display: inline-block;vertical-align: bottom;width: auto;min-width: 10%;flex: 0 0 auto;height: auto;align-self: flex-end;"> <section style="color: rgb(62, 62, 62);font-size: 14px;padding-right: 4px;padding-left: 4px;line-height: 1;text-align: justify;" powered-by="xiumi.us"> <p style="text-align: left;white-space: normal;"><br></p> <p style="white-space: normal;"><strong><span style="font-size: 15px;">@DependsOn 注解</span></strong></p> </section> </section> <section style="display: inline-block;vertical-align: middle;width: auto;align-self: center;min-width: 10%;flex: 0 0 auto;height: auto;line-height: 0;"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> </section> <h4 style="margin-top: 10px;margin-bottom: 5px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(62, 62, 62);"></span></h4> <section style="min-height: 24px;line-height: 1.75em;margin-bottom: 24px;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">接下来是尝试加上 @DependsOn 注解:</span> </section> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="java"><code><span class="code-snippet_outer"><span class="code-snippet__meta">@Service</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">@DependsOn</span>({<span class="code-snippet__string">"systemConfigService"</span>})</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">public</span> <span class="code-snippet__class"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">BizService</span> </span>{</span></code><code><span class="code-snippet_outer"><br></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__title">BizService</span><span class="code-snippet__params">()</span> </span>{</span></code><code><span class="code-snippet_outer"> String xxValue = SystemConfigService.getSystemConfig(<span class="code-snippet__string">"xxKey"</span>);</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__comment">// 可行</span></span></code><code><span class="code-snippet_outer"> }</span></code><code><span class="code-snippet_outer">}</span></code></pre> </section> <p style="min-height: 24px;line-height: 1.75em;margin-top: 24px;margin-bottom: 24px;"><span style="font-size: 15px;color: rgb(62, 62, 62);">这样测试下来是可以是可以的,就是操作起来也太麻烦了,需要让每个每个依赖&nbsp;</span><span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">SystemConfigService</span><span style="font-size: 15px;color: rgb(62, 62, 62);">的 Bean 都改代码加上注解,那有没有一种默认就让&nbsp;</span><span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">SystemConfigService</span><span style="font-size: 15px;color: rgb(62, 62, 62);">&nbsp;提前的方法?</span></p> <section style="min-height: 24px;line-height: 1.75em;margin-bottom: 24px;"> <span style="color: rgb(62, 62, 62);font-size: 15px;font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;">上面提到的方法都不好用,那我们只能利用 spring 给我们提供的扩展点来做文章了。</span> </section> <section style="font-size: 15px;margin-bottom: 24px;"> <section style="margin-top: 10px;margin-bottom: 10px;text-align: center;" powered-by="xiumi.us"> <section style="padding: 3px;display: inline-block;border-bottom: 5px solid rgb(255, 129, 36);color: rgb(255, 129, 36);font-size: 16px;"> <p><span style="color: rgb(255, 104, 39);">Spring 中 Bean 创建的相关知识</span></p> </section> </section> </section> <h3 style="margin-top: 16px;margin-bottom: 5px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(62, 62, 62);"></span></h3> <section style="min-height: 24px;line-height: 1.75em;margin-bottom: 24px;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">首先要明白一点,Bean 创建的顺序是怎么来的,如果你对 Spring 的源码比较熟悉,你会知道在&nbsp;</span> <span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">AbstractApplicationContext</span> <span style="font-size: 15px;color: rgb(62, 62, 62);">&nbsp;里面有个 refresh 方法, Bean 创建的大部分逻辑都在 refresh 方法里面,在 refresh 末尾的&nbsp;</span> <span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">finishBeanFactoryInitialization(beanFactory)</span> <span style="font-size: 15px;color: rgb(62, 62, 62);">&nbsp;方法调用中,会调用&nbsp;</span> <span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">beanFactory.preInstantiateSingletons()</span> <span style="font-size: 15px;color: rgb(62, 62, 62);">,在这里对所有的 beanDefinitionNames 一一遍历,进行 bean 实例化和组装:</span> </section> <section style="min-height: 24px;line-height: 1.75em;text-align: center;margin-bottom: 24px;"> <img class="rich_pages wxw-img" data-ratio="0.9314814814814815" src="/upload/ec5e6f66c6c2a7dc55cf1119de7e01b6.png" data-type="png" data-w="1080" style="height: auto !important;" width="718.5"> </section> <section style="min-height: 24px;line-height: 1.75em;margin-bottom: 24px;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">这个 beanDefinitionNames 列表的顺序就决定了 Bean 的创建顺序,那么这个 beanDefinitionNames 列表又是怎么来的?答案是&nbsp;</span> <span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">ConfigurationClassPostProcessor</span> <span style="font-size: 15px;color: rgb(62, 62, 62);">&nbsp;通过扫描你的代码和注解生成的,将 Bean 扫描解析成 Bean 定义(BeanDefinition),同时将 Bean 定义(BeanDefinition)注册到 BeanDefinitionRegistry 中,才有了 beanDefinitionNames 列表。</span> </section> <section style="font-size: 15px;margin-bottom: 24px;"> <section style="text-align: left;justify-content: flex-start;margin: 10px 0%;display: flex;flex-flow: row nowrap;" powered-by="xiumi.us"> <section style="display: inline-block;vertical-align: bottom;width: auto;align-self: flex-end;flex: 0 0 0%;height: auto;line-height: 0;"> <section style="text-align: right;" powered-by="xiumi.us"> <section style="display: inline-block;width: 18px;height: 18px;vertical-align: top;overflow: hidden;background-color: rgb(255, 129, 36);"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> </section> <section style="display: inline-block;vertical-align: bottom;width: auto;min-width: 10%;flex: 0 0 auto;height: auto;align-self: flex-end;"> <section style="color: rgb(62, 62, 62);font-size: 14px;padding-right: 4px;padding-left: 4px;line-height: 1;text-align: justify;" powered-by="xiumi.us"> <p style="text-align: left;white-space: normal;"><br></p> <p style="white-space: normal;"><strong><span style="font-size: 15px;">ConfigurationClassPostProcessor 的介绍</span></strong></p> </section> </section> <section style="display: inline-block;vertical-align: middle;width: auto;align-self: center;min-width: 10%;flex: 0 0 auto;height: auto;line-height: 0;"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> </section> <h4 style="margin-top: 10px;margin-bottom: 5px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(62, 62, 62);"></span></h4> <section style="min-height: 24px;line-height: 1.75em;margin-bottom: 24px;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">这里提到了</span> <span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">&nbsp;ConfigurationClassPostProcessor</span> <span style="font-size: 15px;color: rgb(62, 62, 62);">,实现了&nbsp;</span> <span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">BeanDefinitionRegistryPostProcessor</span> <span style="font-size: 15px;color: rgb(62, 62, 62);">&nbsp;接口。它是一个非常非常重要的类,甚至可以说它是 Spring boot 提供的扫描你的注解并解析成 BeanDefinition 最重要的组件。我们在使用 SpringBoot 过程中用到的&nbsp;</span> <span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">@Configuration</span> <span style="font-size: 15px;color: rgb(62, 62, 62);">、</span> <span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">@ComponentScan</span> <span style="font-size: 15px;color: rgb(62, 62, 62);">、</span> <span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">@Import</span> <span style="font-size: 15px;color: rgb(62, 62, 62);">、</span> <span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">@Bean</span> <span style="font-size: 15px;color: rgb(62, 62, 62);">&nbsp;这些注解的功能都是通过&nbsp;</span> <span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">ConfigurationClassPostProcessor</span> <span style="font-size: 15px;color: rgb(62, 62, 62);">&nbsp;注解实现的,这里找了一篇文件介绍,就不多说了。</span> <span style="font-size: 15px;color: rgb(62, 62, 62);">https://juejin.cn/post/6844903944146124808</span> </section> <section style="font-size: 15px;margin-bottom: 24px;"> <section style="text-align: left;justify-content: flex-start;margin: 10px 0%;display: flex;flex-flow: row nowrap;" powered-by="xiumi.us"> <section style="display: inline-block;vertical-align: bottom;width: auto;align-self: flex-end;flex: 0 0 0%;height: auto;line-height: 0;"> <section style="text-align: right;" powered-by="xiumi.us"> <section style="display: inline-block;width: 18px;height: 18px;vertical-align: top;overflow: hidden;background-color: rgb(255, 129, 36);"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> </section> <section style="display: inline-block;vertical-align: bottom;width: auto;min-width: 10%;flex: 0 0 auto;height: auto;align-self: flex-end;"> <section style="color: rgb(62, 62, 62);font-size: 14px;padding-right: 4px;padding-left: 4px;line-height: 1;text-align: justify;" powered-by="xiumi.us"> <p style="text-align: left;white-space: normal;"><br></p> <p style="white-space: normal;"><strong><span style="font-size: 15px;">BeanDefinitionRegistryPostProcessor 相关接口的介绍</span></strong></p> </section> </section> <section style="display: inline-block;vertical-align: middle;width: auto;align-self: center;min-width: 10%;flex: 0 0 auto;height: auto;line-height: 0;"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> </section> <h4 style="margin-top: 10px;margin-bottom: 5px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(62, 62, 62);"></span></h4> <section style="min-height: 24px;line-height: 1.75em;margin-bottom: 24px;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">接下来还要介绍 Spring 中提供的一些扩展,它们在 Bean 的创建过程中起到非常重要的作用。</span> </section> <section style="min-height: 24px;line-height: 1.75em;margin-bottom: 24px;"> <span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">BeanFactoryPostProcessor&nbsp;</span> <span style="font-size: 15px;color: rgb(62, 62, 62);">它的作用:</span> </section> <ul class="list-paddingleft-1" style="padding-left: 23px;"> <li style="font-size: 15px;color: rgb(62, 62, 62);"><p style="line-height: 1.75em;margin-bottom: 8px;"><span style="font-size: 15px;color: rgb(62, 62, 62);">在 BeanFactory 初始化之后调用,来定制和修改 BeanFactory 的内容</span></p></li> <li style="font-size: 15px;color: rgb(62, 62, 62);"><p style="line-height: 1.75em;margin-bottom: 8px;"><span style="font-size: 15px;color: rgb(62, 62, 62);">所有的 Bean 定义(BeanDefinition)已经保存加载到 beanFactory,但是 Bean 的实例还未创建</span></p></li> <li style="font-size: 15px;color: rgb(62, 62, 62);"> <section style="line-height: 1.75em;margin-bottom: 24px;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">方法的入参是 ConfigurrableListableBeanFactory,意思是你可以调整 ConfigurrableListableBeanFactory 的配置</span> </section></li> </ul> <section style="min-height: 24px;line-height: 1.75em;margin-bottom: 24px;"> <span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">BeanDefinitionRegistryPostProcessor</span> <span style="font-size: 15px;color: rgb(62, 62, 62);">&nbsp;它的作用:</span> </section> <ul class="list-paddingleft-1" style="padding-left: 23px;"> <li style="font-size: 15px;color: rgb(62, 62, 62);"><p style="line-height: 1.75em;margin-bottom: 8px;"><span style="font-size: 15px;color: rgb(62, 62, 62);">是 BeanFactoryPostProcessor 的子接口</span></p></li> <li style="font-size: 15px;color: rgb(62, 62, 62);"><p style="line-height: 1.75em;margin-bottom: 8px;"><span style="font-size: 15px;color: rgb(62, 62, 62);">在所有 Bean 定义(BeanDefinition)信息将要被加载,Bean 实例还未创建的时候加载</span></p></li> <li style="font-size: 15px;color: rgb(62, 62, 62);"><p style="line-height: 1.75em;margin-bottom: 8px;"><span style="font-size: 15px;color: rgb(62, 62, 62);">优先于 BeanFactoryPostProcessor 执行,利用 BeanDefinitionRegistryPostProcessor 可以给 Spring 容器中自定义添加 Bean&nbsp;</span></p></li> <li style="font-size: 15px;color: rgb(62, 62, 62);"> <section style="line-height: 1.75em;margin-bottom: 24px;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">方法入参是 BeanDefinitionRegistry,意思是你可以调整 BeanDefinitionRegistry 的配置</span> </section></li> </ul> <section style="min-height: 24px;line-height: 1.75em;margin-bottom: 24px;"> <span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(62, 62, 62);">还有一个类似的&nbsp;</span> <span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">BeanPostProcessor</span> <span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(62, 62, 62);">&nbsp;它的作用:</span> <span style="color: rgb(62, 62, 62);font-size: 15px;font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;"></span> </section> <ul class="list-paddingleft-1" style="padding-left: 23px;"> <li style="font-size: 15px;color: rgb(62, 62, 62);"><p style="line-height: 1.75em;margin-bottom: 8px;"><span style="font-size: 15px;color: rgb(62, 62, 62);">在 Bean 实例化之后执行的</span></p></li> <li style="font-size: 15px;color: rgb(62, 62, 62);"><p style="line-height: 1.75em;margin-bottom: 8px;"><span style="font-size: 15px;color: rgb(62, 62, 62);">执行顺序在 BeanFactoryPostProcessor 之后</span></p></li> <li style="font-size: 15px;color: rgb(62, 62, 62);"> <section style="line-height: 1.75em;margin-bottom: 24px;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">方法入参是 Object bean,意思是你可以调整 bean 的配置</span> </section></li> </ul> <section style="min-height: 24px;line-height: 1.75em;margin-bottom: 24px;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">搞明白了以上的内容,下面我们可以直接动手写代码了。</span> </section> <section style="font-size: 15px;margin-bottom: 24px;"> <section style="margin-top: 10px;margin-bottom: 10px;text-align: center;" powered-by="xiumi.us"> <section style="padding: 3px;display: inline-block;border-bottom: 5px solid rgb(255, 129, 36);color: rgb(255, 129, 36);font-size: 16px;"> <p><span style="color: rgb(255, 104, 39);">最终答案</span></p> </section> </section> </section> <h3 style="margin-top: 16px;margin-bottom: 5px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(62, 62, 62);"></span></h3> <section style="min-height: 24px;line-height: 1.75em;margin-bottom: 24px;"> <span style="font-size: 15px;color: rgb(62, 62, 62);"><strong>第一步:通过 spring.factories 扩展来注册一个 ApplicationContextInitializer:</strong></span> </section> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="apache"><code><span class="code-snippet_outer"><span class="code-snippet__comment"># 注册 ApplicationContextInitializer</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">org</span>.springframework.context.ApplicationContextInitializer=com.antbank.demo.bootstrap.MyApplicationContextInitializer</span></code></pre> </section> <p style="min-height: 24px;line-height: 1.75em;margin-top: 24px;margin-bottom: 24px;"><span style="font-size: 15px;color: rgb(62, 62, 62);">注册&nbsp;</span><span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">ApplicationContextInitializer</span><span style="font-size: 15px;color: rgb(62, 62, 62);">&nbsp;的目的其实是为了接下来注册&nbsp;</span><span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">BeanDefinitionRegistryPostProcessor</span><span style="font-size: 15px;color: rgb(62, 62, 62);">&nbsp;到 Spring 中,我没有找到直接使用 spring.factories 来注册&nbsp;</span><span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">BeanDefinitionRegistryPostProcessor</span><span style="font-size: 15px;color: rgb(62, 62, 62);">&nbsp;的方式,猜测是不支持的:</span></p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="java"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">public</span> <span class="code-snippet__class"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">MyApplicationContextInitializer</span> <span class="code-snippet__keyword">implements</span> <span class="code-snippet__title">ApplicationContextInitializer</span>&lt;<span class="code-snippet__title">ConfigurableApplicationContext</span>&gt; </span>{</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer"> <span class="code-snippet__meta">@Override</span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">initialize</span><span class="code-snippet__params">(ConfigurableApplicationContext applicationContext)</span> </span>{</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__comment">// 注意,如果你同时还使用了 spring cloud,这里需要做个判断,要不要在 spring cloud applicationContext 中做这个事</span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__comment">// 通常 spring cloud 中的 bean 都和业务没关系,是需要跳过的</span></span></code><code><span class="code-snippet_outer"> applicationContext.addBeanFactoryPostProcessor(<span class="code-snippet__keyword">new</span> MyBeanDefinitionRegistryPostProcessor());</span></code><code><span class="code-snippet_outer"> }</span></code><code><span class="code-snippet_outer">}</span></code></pre> </section> <p style="min-height: 24px;line-height: 1.75em;margin-top: 24px;margin-bottom: 24px;"><span style="font-size: 15px;color: rgb(62, 62, 62);">除了使用 spring 提供的 SPI 来注册&nbsp;</span><span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">ApplicationContextInitializer</span><span style="font-size: 15px;color: rgb(62, 62, 62);">,你也可以用&nbsp;</span><span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">SpringApplication.addInitializers</span><span style="font-size: 15px;color: rgb(62, 62, 62);">&nbsp;的方式直接在 main 方法中直接注册一个 ApplicationContextInitializer 结果都是可以的:</span></p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="java"><code><span class="code-snippet_outer"><span class="code-snippet__meta">@SpringBootApplication</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">public</span> <span class="code-snippet__class"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">SpringBootDemoApplication</span> </span>{</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">main</span><span class="code-snippet__params">(String[] args)</span> </span>{</span></code><code><span class="code-snippet_outer"> SpringApplication application = <span class="code-snippet__keyword">new</span> SpringApplication(SpringBootDemoApplication.class);</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__comment">// 通过 SpringApplication 注册 ApplicationContextInitializer</span></span></code><code><span class="code-snippet_outer"> application.addInitializers(<span class="code-snippet__keyword">new</span> MyApplicationContextInitializer());</span></code><code><span class="code-snippet_outer"> application.run(args);</span></code><code><span class="code-snippet_outer"> }</span></code><code><span class="code-snippet_outer">}</span></code></pre> </section> <p style="min-height: 24px;line-height: 1.75em;margin-top: 24px;margin-bottom: 24px;"><span style="font-size: 15px;color: rgb(62, 62, 62);">当然了,通过 Spring 的事件机制也可以做到注册&nbsp;</span><span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">BeanDefinitionRegistryPostProcessor</span><span style="font-size: 15px;color: rgb(62, 62, 62);">,选择实现合适的&nbsp;</span><span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">ApplicationListener</span><span style="font-size: 15px;color: rgb(62, 62, 62);">&nbsp;事件,可以通过&nbsp;</span><span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">ApplicationContextEvent</span><span style="font-size: 15px;color: rgb(62, 62, 62);">&nbsp;获得&nbsp;</span><span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">ApplicationContext</span><span style="font-size: 15px;color: rgb(62, 62, 62);">,即可注册&nbsp;</span><span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">BeanDefinitionRegistryPostProcessor</span><span style="font-size: 15px;color: rgb(62, 62, 62);">,这里就不多展开了。</span></p> <section style="min-height: 24px;line-height: 1.75em;margin-bottom: 24px;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">这里需要注意一点,为什么需要用&nbsp;</span> <span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">ApplicationContextInitializer</span> <span style="font-size: 15px;color: rgb(62, 62, 62);">&nbsp;来注册&nbsp;</span> <span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">BeanDefinitionRegistryPostProcessor</span> <span style="font-size: 15px;color: rgb(62, 62, 62);">,能不能用&nbsp;</span> <span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">@Component</span> <span style="font-size: 15px;color: rgb(62, 62, 62);">&nbsp;或者其他的注解的方式注册?</span> </section> <section style="min-height: 24px;line-height: 1.75em;margin-bottom: 24px;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">答案是不能的。</span> <span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">@Component</span> <span style="font-size: 15px;color: rgb(62, 62, 62);">&nbsp;注解的方式注册能注册上的前提是能被&nbsp;</span> <span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">ConfigurationClassPostProcessor</span> <span style="font-size: 15px;color: rgb(62, 62, 62);">&nbsp;扫描到,也就是说用&nbsp;</span> <span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">@Component&nbsp;</span> <span style="font-size: 15px;color: rgb(62, 62, 62);">注解的方式来注册,注册出来的 Bean 一定不可能排在&nbsp;</span> <span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">ConfigurationClassPostProcessor</span> <span style="font-size: 15px;color: rgb(62, 62, 62);">&nbsp;前面,而我们的目的就是在所有的 Bean 扫描前注册你需要的 Bean,这样才能排在其他所有 Bean 前面,所以这里的场景下是不能用注解注册的,这点需要额外注意。</span> </section> <section style="min-height: 24px;line-height: 1.75em;margin-bottom: 24px;"> <span style="font-size: 15px;color: rgb(62, 62, 62);"><strong>第二步:实现 BeanDefinitionRegistryPostProcessor,注册目标 bean:</strong></span> </section> <section style="min-height: 24px;line-height: 1.75em;margin-bottom: 24px;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">用&nbsp;</span> <span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">MyBeanDefinitionRegistryPostProcessor</span> <span style="font-size: 15px;color: rgb(62, 62, 62);">&nbsp;在&nbsp;</span> <span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">ConfigurationClassPostProcessor</span> <span style="font-size: 15px;color: rgb(62, 62, 62);">&nbsp;扫描前注册你需要的目标 bean 的 BeanDefinition 即可。</span> </section> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="java"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">public</span> <span class="code-snippet__class"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">MyBeanDefinitionRegistryPostProcessor</span> <span class="code-snippet__keyword">implements</span> <span class="code-snippet__title">BeanDefinitionRegistryPostProcessor</span> </span>{</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer"> <span class="code-snippet__meta">@Override</span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">postProcessBeanDefinitionRegistry</span><span class="code-snippet__params">(BeanDefinitionRegistry registry)</span> <span class="code-snippet__keyword">throws</span> BeansException </span>{</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__comment">// 手动注册一个 BeanDefinition</span></span></code><code><span class="code-snippet_outer"> registry.registerBeanDefinition(<span class="code-snippet__string">"systemConfigService"</span>, <span class="code-snippet__keyword">new</span> RootBeanDefinition(SystemConfigService.class));</span></code><code><span class="code-snippet_outer"> }</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer"> <span class="code-snippet__meta">@Override</span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">postProcessBeanFactory</span><span class="code-snippet__params">(ConfigurableListableBeanFactory beanFactory)</span> <span class="code-snippet__keyword">throws</span> BeansException </span>{}</span></code><code><span class="code-snippet_outer">}</span></code></pre> </section> <p style="min-height: 24px;line-height: 1.75em;margin-top: 24px;margin-bottom: 24px;"><span style="font-size: 15px;color: rgb(62, 62, 62);">当然你也可以使用一个类同时实现&nbsp;</span><span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">ApplicationContextInitializer</span><span style="font-size: 15px;color: rgb(62, 62, 62);">&nbsp;和</span><span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">BeanDefinitionRegistryPostProcessor</span></p> <section style="min-height: 24px;line-height: 1.75em;margin-bottom: 24px;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">通过 applicationContext#addBeanFactoryPostProcessor 注册的&nbsp;</span> <span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">BeanDefinitionRegistryPostProcessor</span> <span style="font-size: 15px;color: rgb(62, 62, 62);">,比 Spring 自带的优先级要高,所以这里就不需要再实现 Ordered 接口提升优先级就可以排在&nbsp;</span> <span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.034em;font-size: 15px;color: rgb(136, 136, 136);background-color: rgb(245, 245, 245);">ConfigurationClassPostProcessor</span> <span style="font-size: 15px;color: rgb(62, 62, 62);">&nbsp;前面:</span> </section> <section style="min-height: 24px;line-height: 1.75em;text-align: center;margin-bottom: 24px;"> <img class="rich_pages wxw-img" data-ratio="0.825" src="/upload/4a2e0b97699c9ce300953f83745f3fd8.png" data-type="png" data-w="1080" style="height: auto !important;" width="1133"> </section> <section style="min-height: 24px;line-height: 1.75em;margin-bottom: 24px;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">经过测试发现,上面的方式可行的,SystemConfigService 被排在第五个 Bean 进行实例化,排在前面的四个都是 Spring 自己内部的 Bean 了,也没有必要再提前了。</span> </section>

Spring循环依赖那些事儿(含Spring详细流程图)

作者:微信小助手

<p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.625" data-s="300,640" data-type="jpeg" data-w="1024" style="height: auto !important;" src="/upload/21d0922272ed91552a825e649fb471d6.jpg"></p> <section style="font-size: 15px;"> <section style="text-align: left;justify-content: flex-start;display: flex;flex-flow: row nowrap;margin-top: 10px;margin-bottom: 10px;" powered-by="xiumi.us"> <section style="display: inline-block;width: 100%;vertical-align: top;align-self: flex-start;flex: 0 0 auto;background-color: rgba(62, 62, 62, 0.04);padding: 31px;"> <section style="text-align: center;justify-content: center;display: flex;flex-flow: row nowrap;margin-bottom: 10px;" powered-by="xiumi.us"> <section style="display: inline-block;vertical-align: top;width: 33.33%;"> <section style="margin-top: 11px;margin-bottom: 8px;" powered-by="xiumi.us"> <section style="background-color: rgba(62, 62, 62, 0.66);height: 1px;"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> </section> <section style="display: inline-block;vertical-align: top;width: auto;align-self: flex-start;flex: 0 0 auto;min-width: 5%;height: auto;padding-right: 14px;padding-left: 14px;"> <section style="text-align: justify;font-size: 11px;color: rgba(62, 62, 62, 0.66);" powered-by="xiumi.us"> <p style="white-space: normal;">阿里妹导读</p> </section> <section style="transform: rotateZ(45deg);" powered-by="xiumi.us"> <section style="transform: translate3d(-6px, 0px, 0px);margin-top: 6px;"> <section style="display: inline-block;width: 15px;height: 15px;vertical-align: top;overflow: hidden;border-style: solid;border-width: 0px 3px 3px 0px;border-color: rgb(195, 5, 3) rgb(255, 129, 36) rgb(255, 129, 36) rgb(195, 5, 3);"> <section style="text-align: justify;" powered-by="xiumi.us"> <p style="white-space: normal;"><br></p> </section> </section> </section> </section> </section> <section style="display: inline-block;vertical-align: top;width: 33.33%;"> <section style="margin-top: 11px;margin-bottom: 8px;" powered-by="xiumi.us"> <section style="background-color: rgba(62, 62, 62, 0.66);height: 1px;"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> </section> </section> <section style="text-align: center;" powered-by="xiumi.us"> <section style="font-size: 14px;text-align: justify;"> <p style="white-space: normal;"><span style="color: rgb(136, 136, 136);">本篇不仅仅是介绍Spring循环依赖的原理,而且给出Spring不能支持的循环依赖场景与案例,对其进行详细解析,同时给出解决建议与方案,以后出现此问题可以少走弯路。</span></p> </section> </section> </section> </section> </section> <section style="font-size: 15px;"> <section style="margin-top: 10px;margin-bottom: 10px;text-align: center;" powered-by="xiumi.us"> <section style="padding: 3px;display: inline-block;border-bottom: 5px solid rgb(255, 129, 36);color: rgb(255, 129, 36);font-size: 16px;"> <p>背景</p> </section> </section> </section> <section style="font-size: 15px;"> <section style="text-align: left;justify-content: flex-start;margin: 10px 0%;display: flex;flex-flow: row nowrap;" powered-by="xiumi.us"> <section style="display: inline-block;vertical-align: bottom;width: auto;align-self: flex-end;flex: 0 0 0%;height: auto;line-height: 0;"> <section style="text-align: right;" powered-by="xiumi.us"> <section style="display: inline-block;width: 18px;height: 18px;vertical-align: top;overflow: hidden;background-color: rgb(255, 129, 36);"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> </section> <section style="display: inline-block;vertical-align: bottom;width: auto;min-width: 10%;flex: 0 0 auto;height: auto;align-self: flex-end;"> <section style="color: rgb(62, 62, 62);font-size: 14px;padding-right: 4px;padding-left: 4px;line-height: 1;text-align: justify;" powered-by="xiumi.us"> <p style="white-space: normal;"><strong><span style="font-size: 15px;">1、循环依赖异常信息</span></strong></p> </section> </section> <section style="display: inline-block;vertical-align: middle;width: auto;align-self: center;min-width: 10%;flex: 0 0 auto;height: auto;line-height: 0;"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> </section> <ul class="list-paddingleft-1" style="list-style-type: revert;"> <li style="font-size: 15px;color: rgb(62, 62, 62);"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">应用时间时间久</span> </section></li> <li style="font-size: 15px;color: rgb(62, 62, 62);"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">应用多人同时并行开发</span> </section></li> <li style="font-size: 15px;color: rgb(62, 62, 62);"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">应用保证迭代进度</span> </section></li> </ul> <p style="line-height: 1.75em;margin-top: 24px;"><span style="font-size: 15px;color: rgb(62, 62, 62);">经常出现启动时出现循环依赖异常</span></p> <pre> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(62, 62, 62);"></span> </section></pre> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="sql"><code><span class="code-snippet_outer">Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean <span class="code-snippet__keyword">with</span> <span class="code-snippet__keyword">name</span> <span class="code-snippet__string">'taskPunchEvent'</span>: Injection <span class="code-snippet__keyword">of</span> <span class="code-snippet__keyword">resource</span> dependencies <span class="code-snippet__keyword">failed</span>; nested exception is org.</span></code><code><span class="code-snippet_outer">springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean <span class="code-snippet__keyword">with</span> <span class="code-snippet__keyword">name</span> <span class="code-snippet__string">'playContentService'</span>: Bean <span class="code-snippet__keyword">with</span> <span class="code-snippet__keyword">name</span> <span class="code-snippet__string">'playContentService'</span> has been injected <span class="code-snippet__keyword">into</span> other be</span></code><code><span class="code-snippet_outer">ans [toVoConvertor] <span class="code-snippet__keyword">in</span> its <span class="code-snippet__keyword">raw</span> <span class="code-snippet__keyword">version</span> <span class="code-snippet__keyword">as</span> part <span class="code-snippet__keyword">of</span> a circular <span class="code-snippet__keyword">reference</span>, but has eventually been wrapped. This means that said other beans <span class="code-snippet__keyword">do</span> <span class="code-snippet__keyword">not</span> <span class="code-snippet__keyword">use</span> the <span class="code-snippet__keyword">final</span> <span class="code-snippet__keyword">version</span> <span class="code-snippet__keyword">of</span> the bean. Thi</span></code><code><span class="code-snippet_outer">s <span class="code-snippet__keyword">is</span> often the <span class="code-snippet__keyword">result</span> <span class="code-snippet__keyword">of</span> <span class="code-snippet__keyword">over</span>-eager <span class="code-snippet__keyword">type</span> matching - <span class="code-snippet__keyword">consider</span> <span class="code-snippet__keyword">using</span> <span class="code-snippet__string">'getBeanNamesOfType'</span> <span class="code-snippet__keyword">with</span> the <span class="code-snippet__string">'allowEagerInit'</span> flag turned <span class="code-snippet__keyword">off</span>, <span class="code-snippet__keyword">for</span> example.</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">at</span> org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessProperties(CommonAnnotationBeanPostProcessor.java:<span class="code-snippet__number">325</span>)</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">at</span> org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:<span class="code-snippet__number">1404</span>)</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">at</span> org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:<span class="code-snippet__number">592</span>)</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">at</span> org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:<span class="code-snippet__number">515</span>)</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">at</span> org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$<span class="code-snippet__number">0</span>(AbstractBeanFactory.java:<span class="code-snippet__number">320</span>)</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">at</span> org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:<span class="code-snippet__number">222</span>)</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">at</span> org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:<span class="code-snippet__number">318</span>)</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">at</span> org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:<span class="code-snippet__number">199</span>)</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">at</span> org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:<span class="code-snippet__number">277</span>)</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">at</span> org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:<span class="code-snippet__number">1255</span>)</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">at</span> org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:<span class="code-snippet__number">1175</span>)</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">at</span> org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:<span class="code-snippet__number">595</span>)</span></code><code><span class="code-snippet_outer"> ... <span class="code-snippet__number">40</span> more</span></code><code><span class="code-snippet_outer">Caused <span class="code-snippet__keyword">by</span>: org.springframework.beans.factory.BeanCurrentlyInCreationException: <span class="code-snippet__keyword">Error</span> creating bean <span class="code-snippet__keyword">with</span> <span class="code-snippet__keyword">name</span> <span class="code-snippet__string">'playContentService'</span>: Bean <span class="code-snippet__keyword">with</span> <span class="code-snippet__keyword">name</span> <span class="code-snippet__string">'playContentService'</span> has been injecte</span></code><code><span class="code-snippet_outer">d <span class="code-snippet__keyword">into</span> other beans [toVoConvertor] <span class="code-snippet__keyword">in</span> its <span class="code-snippet__keyword">raw</span> <span class="code-snippet__keyword">version</span> <span class="code-snippet__keyword">as</span> part <span class="code-snippet__keyword">of</span> a circular <span class="code-snippet__keyword">reference</span>, but has eventually been wrapped. This means that said other beans <span class="code-snippet__keyword">do</span> <span class="code-snippet__keyword">not</span> <span class="code-snippet__keyword">use</span> the <span class="code-snippet__keyword">final</span> <span class="code-snippet__keyword">version</span> o</span></code><code><span class="code-snippet_outer">f the bean. This <span class="code-snippet__keyword">is</span> often the <span class="code-snippet__keyword">result</span> <span class="code-snippet__keyword">of</span> <span class="code-snippet__keyword">over</span>-eager <span class="code-snippet__keyword">type</span> matching - <span class="code-snippet__keyword">consider</span> <span class="code-snippet__keyword">using</span> <span class="code-snippet__string">'getBeanNamesOfType'</span> <span class="code-snippet__keyword">with</span> the <span class="code-snippet__string">'allowEagerInit'</span> flag turned <span class="code-snippet__keyword">off</span>, <span class="code-snippet__keyword">for</span> example.</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">at</span> org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:<span class="code-snippet__number">622</span>)</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">at</span> org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:<span class="code-snippet__number">515</span>)</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">at</span> org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$<span class="code-snippet__number">0</span>(AbstractBeanFactory.java:<span class="code-snippet__number">320</span>)</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">at</span> org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:<span class="code-snippet__number">222</span>)</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">at</span> org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:<span class="code-snippet__number">318</span>)</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">at</span> org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:<span class="code-snippet__number">204</span>)</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">at</span> org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.resolveBeanByName(AbstractAutowireCapableBeanFactory.java:<span class="code-snippet__number">452</span>)</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">at</span> org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:<span class="code-snippet__number">527</span>)</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">at</span> org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:<span class="code-snippet__number">497</span>)</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">at</span> org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:<span class="code-snippet__number">637</span>)</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">at</span> org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:<span class="code-snippet__number">180</span>)</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">at</span> org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:<span class="code-snippet__number">90</span>)</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">at</span> org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessProperties(CommonAnnotationBeanPostProcessor.java:<span class="code-snippet__number">322</span>)</span></code><code><span class="code-snippet_outer"> ... <span class="code-snippet__number">51</span> more</span></code></pre> </section> <pre> <section style="text-align: left;justify-content: flex-start;margin: 10px 0%;display: flex;flex-flow: row nowrap;" powered-by="xiumi.us"> <section style="display: inline-block;vertical-align: bottom;width: auto;align-self: flex-end;flex: 0 0 0%;height: auto;line-height: 0;"> <section style="text-align: right;" powered-by="xiumi.us"> <section style="display: inline-block;width: 18px;height: 18px;vertical-align: top;overflow: hidden;background-color: rgb(255, 129, 36);"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> </section> <section style="display: inline-block;vertical-align: bottom;width: auto;min-width: 10%;flex: 0 0 auto;height: auto;align-self: flex-end;"> <section style="color: rgb(62, 62, 62);font-size: 14px;padding-right: 4px;padding-left: 4px;line-height: 1;text-align: justify;" powered-by="xiumi.us"> <p style="white-space: normal;"><br></p> <p style="white-space: normal;"><strong><span style="font-size: 15px;">2、依赖关系</span></strong></p> </section> </section> <section style="display: inline-block;vertical-align: middle;width: auto;align-self: center;min-width: 10%;flex: 0 0 auto;height: auto;line-height: 0;"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section></pre> <section style="line-height: 1.75em;margin-bottom: 24px;margin-top: 24px;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">先不关注其他不规范问题,看现象</span> </section> <section style="line-height: 1.75em;margin-bottom: 24px;margin-top: 24px;text-align: center;"> <span style="font-size: 15px;color: rgb(62, 62, 62);"><br style="box-sizing: inherit;"></span> <img class="rich_pages wxw-img" data-ratio="0.3138888888888889" data-type="png" data-w="1080" style="box-sizing: inherit;border: 0px;display: inline;height: auto !important;" src="/upload/53b90129bd8871279fc5368c839b2331.png"> <br style="box-sizing: inherit;"> <img class="rich_pages wxw-img" data-ratio="0.35" data-type="png" data-w="1080" style="box-sizing: inherit;border: 0px;display: inline;height: auto !important;" src="/upload/d0b80992cecbd812eb0e07f58829353d.png"> </section> <section style="font-size: 15px;"> <section style="text-align: left;justify-content: flex-start;margin: 10px 0%;display: flex;flex-flow: row nowrap;" powered-by="xiumi.us"> <section style="display: inline-block;vertical-align: bottom;width: auto;align-self: flex-end;flex: 0 0 0%;height: auto;line-height: 0;"> <section style="text-align: right;" powered-by="xiumi.us"> <section style="display: inline-block;width: 18px;height: 18px;vertical-align: top;overflow: hidden;background-color: rgb(255, 129, 36);"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> </section> <section style="margin-top: 24px;"> <section style="display: inline-block;vertical-align: bottom;width: auto;min-width: 10%;flex: 0 0 auto;height: auto;a