浣滆€咃細灏忎粯鍝ュ崥瀹細https://bugstack.cn娌夋穩锛屽垎浜紝鎴愰暱锛岃鑷繁鍜屼粬浜烘湁鎵€鏀惰幏锛侌煒勬渶杩戝緢鎰熷叴瓒g粨鍚圛DEAPlugin鐨勫紑鍙戣兘鍔涳紝鎵╁睍鍚勭鍔熻兘銆備篃浠ユ涓哄熀纭€锛岄€氳繃涓嶅悓鐨勬渚嬫潵鎺㈢储IDEAPlugin鎻掍欢寮€鍙戞妧鏈€傚笇鏈涜繖鏍风郴缁熺殑瀛︿範楠岃瘉鎬荤粨锛屽彲浠ュ府鍔╁埌鏇村闇€瑕佽鎶€鏈殑灏忎紮浼淬€傛簮鐮佸湴鍧€锛歨ttps://github.com/fuzhengwei/CodeGuide#1-%E6%BA%90%E7%A0%811.鍓嶈█鐮斿彂锛屽垏蹇岃嚜鎴戞斁绾碉紒浣犲仛杩欎欢浜嬬殑浠峰€兼槸浠€涔堬紵鏈夌珵浜夌爺绌跺悧锛熻兘涓轰紒涓氳祴鑳藉悧锛熼偅宸茬粡鏈夌被浼肩殑浜嗭紝涓轰粈涔堣繕瑕佽嚜宸遍€犺疆瀛愶紵浣犳槸涓嶆槸涔熻闂埌杩欐牱鐨勯棶棰橈紝鐢氳嚦鏈変簺澶寸柤銆備絾鏄垜鍋氱殑鏃跺€欓潪甯稿叴濂嬨€傜爺绌舵妧鏈湡鏄お鍒烘縺浜嗭紝绔熺劧杩樿惤鍦颁簡銆備絾鍦ㄤ环鍊间笂锛屼技涔庝竴鏃跺崐浼氫綋鐜颁笉鍑烘潵锛岃兘涓嶈兘涓轰笟鍔¤祴鑳戒篃涓嶄竴瀹氥€備絾鏄皝鑳戒繚璇佷互鍚庡氨涓嶅彲鑳藉憿锛熸妧鏈偣灏辨槸鍘诲厠鏈嶏紝涓€涓竴涓幓灏濊瘯锛屾繁鍏ュ涔犱箣鍚庢墠鏈夋満浼氭妸杩欎簺鍐呭鑱旂郴鍦ㄤ竴璧凤紝灏卞儚鍗曠嫭璋堟按娌欐偿涓€鏍枫€備技涔庡苟娌℃湁浠€涔堜笉濡ャ€備絾鏄紝濡傛灉鎶婂畠浠斁鍦ㄤ竴璧锋斁鐏紝瀹冧滑灏变細琚儳鎴愮爾锛岀爾浼氬爢鎴愬锛屽浼氱洊鎴愭埧瀛愩€?.闇€姹傜洰鐨勬湰绔犳垜浠粨鍚坒reemarker鑳藉姏鍜孖DEAPlugin鎻掍欢鑳藉姏锛屽紑鍙戜竴涓狣DD鑴氭墜鏋禝DEA鎻掍欢銆備篃璁镐綘浼氭兂涓轰粈涔堣鎶婅剼鎵嬫灦寮€鍙戞垚鎻掍欢锛熸湁娌℃湁宸茬粡鎴愬瀷鐨勮剼鎵嬫灦鍙互浣跨敤锛熼鍏堬紝鐩墠鎴戜滑鐪嬪埌鐨勮剼鎵嬫灦鍩烘湰閮芥槸web鐗堢殑锛屽氨鏄垱寤轰竴涓伐绋嬶紝涓€娆℃€т娇鐢ㄣ€備絾鏄紝鎴戜滑鍦ㄥ疄闄呬娇鐢ㄧ殑鏃跺€欙紝涔熷笇鏈涙暟鎹簱銆丒S銆丷edis绛夊湪椤圭洰鍒涘缓杩囩▼涓敓鎴愮浉搴旂殑ORM浠g爜銆傚噺灏戝紑鍙戝伐浣滈噺銆傚苟涓斿湪浣跨敤宸ョ▼楠ㄦ灦鐨勮繃绋嬩腑锛屼篃甯屾湜鑳藉闅忕潃寮€鍙戠殑闇€瑕侊紝澧炲姞鏂扮殑鍔熻兘銆傝繖涓椂鍊檞eb鐗堢殑鑴氭墜鏋跺氨涓嶈兘寰堝ソ鐨勬敮鎸佷簡銆傚彟澶栵紝涓€浜涘ぇ鍘傛湁鑷繁鐨勬妧鏈綋绯伙紝浣跨敤甯傞潰涓婄殑鑴氭墜鏋跺熀鏈緢闅炬弧瓒宠嚜宸辩殑闇€姹傦紝鎵€浠ラ渶瑕佹湁閫傚悎鑷繁鍦烘櫙鐨勮剼鎵嬫灦銆傞偅涔堬紝鏈珷鎴戜滑灏嗘妸鑴氭墜鏋剁殑寮€鍙戞斁鍒癐DEA鎻掍欢寮€鍙戜腑銆備竴鏂归潰锛屾垜浠皢瀛︿範鎼缓鑴氭墜鏋讹紝鍙︿竴鏂归潰锛屾垜浠皢瀛︿範濡備綍鏇存敼椤圭洰鍚戝锛屽垱寤烘垜浠渶瑕佺殑DDD缁撴瀯鑴氭墜鏋躲€備笁銆佹渚嬪紑鍙?銆侀」鐩粨鏋刧uide-idea-plugin-鑴氭墜鏋垛敎鈹€鈹€.gradle鈹斺攢鈹€src鈹溾攢鈹€main鈹傗敂鈹€鈹€java鈹傗敂鈹€鈹€cn.bugstack.guide.idea.plugin鈹傗敎鈹€鈹€鍩熲攤鈹溾攢鈹€妯″瀷鈹傗攤鈹傗敂鈹€鈹€ProjectConfigVO.java鈹傗攤鈹斺攢鈹€鏈嶅姟鈹傗攤鈹溾攢鈹€impl鈹傗攤鈹傗敂鈹€鈹€ProjectGeneratorImpl.java鈹傗攤鈹溾攢鈹€AbstractProjectGenerator.鈹俲ava鈹傗攤FreemarkerConfiguration.java鈹傗攤鈹斺攢鈹€IProjectGenerator.java鈹傗敎鈹€鈹€宸ュ巶鈹傗攤鈹斺攢鈹€TemplateFactory.java鈹傗敎鈹€鈹€鍩虹璁炬柦鈹傗敎鈹€鈹€DataSetting.java鈹傗敎鈹€鈹€DataState.java鈹傗攤鈹溾攢鈹€ICONS.java鈹傗攤鈹斺攢鈹€MsgBundle.java鈹傗敎鈹€鈹€妯″潡鈹傗攤鈹溾攢鈹€DDDModuleBuilder.java鈹傗攤鈹斺攢鈹€DDDModuleConfigStep.java鈹傗敂鈹€鈹€ui鈹傗敎鈹€鈹€ProjectConfigUI.java鈹傗敂鈹€鈹€ProjectConfigUI.form鈹溾攢鈹€璧勬簮鈹傗敎鈹€鈹€META-INF鈹傗敂鈹€鈹€plugin.xml鈹傗敂鈹€鈹€妯℃澘鈹傗敎鈹€鈹€pom.ftl鈹傗敂鈹€鈹€yml.ftl鈹溾攢鈹€build.gradle鈹斺攢鈹€gradle.properties婧愮爜鑾峰彇锛?鍏紬鍙?bugstack铏礊鏍堝洖澶嶏細idea鍙互涓嬭浇鎵€鏈塈DEA鎻掍欢寮€鍙憇ourcecodeat鏈琁DEA鎻掍欢椤圭洰涓昏鍒嗕负5涓尯鍩燂細domain锛氶鍩熷眰锛屾彁渚涘垱寤篋DD妯℃澘椤圭洰鐨勬湇鍔°€傚叾瀹炶繖閮ㄥ垎涓昏鏄敤鍒癴reemarkerfactory锛氬伐鍘傚眰锛屾彁渚涘伐绋嬪垱寤烘ā鏉裤€傝灞傜殑浣滅敤鏄垜浠湪IDEA涓柊寤哄伐绋嬫椂锛屽彲浠ユ坊鍔犺嚜宸辩殑鍐呭锛屽嵆鍒涘缓鎴戜滑瀹氫箟鐨凞DD宸ョ▼缁撴瀯鍩虹璁炬柦锛氬熀纭€灞傦紝鎻愪緵鏁版嵁瀛樺偍銆佸浘鐗囧姞杞姐€佷俊鎭瓑鍔熻兘鏄犲皠銆俶odule锛氭ā鍧楀眰鎻愪緵浜嗗垱寤篋DD妯℃澘椤圭洰鐨勫叿浣撴搷浣滃拰姝ラ銆備篃灏辨槸璇达紝鎴戜滑鍦ㄥ垱寤洪」鐩殑鏃跺€欙紝鏄竴姝ユ閫夋嫨鐨勩€傛偍鍙互鏍规嵁闇€瑕佹坊鍔犺嚜宸辩殑姝ラ椤甸潰锛岃鐢ㄦ埛閫夋嫨鍜屾坊鍔犱粬浠渶瑕佺殑鍐呭銆傛瘮濡傞渶瑕佽繛鎺ュ簱锛岄€夋嫨琛紝娣诲姞椤圭洰闇€瑕佺殑鎶€鏈爤绛夈€倁i锛氱晫闈㈠眰锛屾彁渚汼wing寮€鍙戠殑UI鐣岄潰锛屼緵鐢ㄦ埛鍥惧舰閫夋嫨鍜屽垱寤恒€?.UI椤圭洰閰嶇疆琛ㄥ崟publicclassProjectConfigUI{privateJPanelmainPanel;绉佹湁JTextFieldgroupIdField锛涚鏈塉TextFieldartifactIdField锛涚鏈塉TextField鐗堟湰瀛楁锛涚鏈塉TextField鍖呭瓧娈碉紱鍒涘缓鍙互鐩存帴鎷栨斁銆傚湪杩欎釜UI琛ㄥ崟涓紝鎴戜滑涓昏闇€瑕侊紱roupId銆乤rtifactId銆佺増鏈€乸ackage3銆傞厤缃」鐩楠ゅ垱寤?.1鏁版嵁瀛樺偍cn.bugstack.guide.idea.plugin.infrastructure.DataSetting@State(name="DataSetting",storages=@Storage("plugin.xml"))publicclassDataSettingimplementsPersistentStateComponent{绉佷汉鏁版嵁鐘舵€佺姸鎬?鏂版暟鎹姸鎬侊紙锛夛紱publicstaticDataSettinggetInstance(){returnServiceManager.getService(DataSetting.class);}@Nullable@OverridepublicDataStategetState(){杩斿洖鐘舵€侊紱}@OverridepublicvoidloadState(@NotNullDataStatestate){this.state=state;}publicProjectConfigVOgetProjectConfig(){returnstate.getProjectConfigVO();}}鍦ㄥ熀纭€灞係ervice鎻愪緵鏁版嵁瀛樺偍锛屽垱寤洪」鐩殑閰嶇疆淇℃伅瀛樺偍鍦⊿ervice涓紝璁剧疆鍜岃幏鍙栨洿鏂逛究銆?.2鎵╁睍姝ラcn.bugstack.guide.idea.plugin.module.DDDModuleConfigSteppublicclassDDDModuleConfigStepextendsModuleWizardStep{privateProjectConfigUIprojectConfigUI;publicDDDModuleConfigStep(ProjectConfigUIprojectConfigUI){this.projectConfigUI=projectConfigUI;}@OverridepublicJComponentgetComponent(){returnprojectConfigUI.getComponent();}@Overridepublicbooleanvalidate()throwsConfigurationException{//鑾峰彇閰嶇疆淇℃伅锛屽啓鍏ataSettingProjectConfigVOprojectConfig=DataSetting.getInstance().getProjectConfig();projectConfig.set_groupId(projectConfigUI.getGroupIdField().getText());projectConfig.set_artifactId(projectConfigUI.getArtifactIdField().getText());projectConfig.set_version(projectConfigUI.getVersionField().getText());projectConfig.set_package(projectConfigUI.getPackageField().getText());杩斿洖super.validate();}}缁ф壙ModuleWizardStep寮€鍙戞垜浠渶瑕佺殑涓€涓楠わ紝褰撴垜浠柊寤轰竴涓」鐩紝鍦ㄩ噸鍐欑殑validate鏂规硶涓紝灏嗛」鐩厤缃甎I琛ㄥ崟鑾峰彇鐨勪俊鎭啓鍏ユ暟鎹厤缃枃浠舵椂锛屽氨浼氬嚭鐜拌繖涓楠ゃ€?.3閰嶇疆姝ラcn.bugstack.guide.idea.plugin.module.DDDModuleBuilderpublicclassDDDModuleBuilderextendsModuleBuilder{privateIProjectGeneratorprojectGenerator=newProjectGeneratorImpl();@OverridepublicIcongetNodeIcon(){returnICONS.SPRING_BOOT;}/***閲嶅啓builderId鎸傝浇鑷畾涔夋ā鏉?/@Nullable@OverridepublicStringgetBuilderId(){returngetClass().getName();}@OverridepublicModuleWizardStep[]createWizardSteps(@NotNullWizardContextwizardContext,@NotNullModulesProvidermodulesProvider){//娣诲姞Project閰嶇疆姝ラ锛屽彲浠ヨ嚜宸卞畾涔夐渶瑕佺殑姝ラ锛屽鏋滄湁澶氫釜锛屽彲浠ユ坊鍔燚DDModuleConfigStepmoduleConfigStep=newDDDModuleConfigStep锛堟柊椤圭洰閰嶇疆鐣岄潰锛堬級锛夛紱杩斿洖鏂扮殑ModuleWizardStep[]{moduleConfigStep}锛泒}鍦╟reateWizardSteps鏂规硶涓紝鎴戜滑宸茬粡鍒涘缓濂戒簡DDDModuleConfigStep娣诲姞椤圭洰閰嶇疆姝ラ锛岄渶瑕佺殑姝ラ鍙互鑷繁瀹氫箟锛屽鏋滄湁澶氫釜锛屽彲浠ヤ竴涓竴涓坊鍔犮€傚悓鏃堕渶瑕佹敞鎰忕殑鏄紝鏂板鐨勫悜瀵兼楠ら渶瑕侀噸鍐檊etBuilderId()鏂规硶鍚庢墠鑳界敓鏁堛€?.寮€鍙戣剼鎵嬫灦鏈嶅姟cn.bugstack.guide.idea.plugin.domain.service.AbstractProjectGeneratorpublicabstractclassAbstractProjectGeneratorextendsFreemarkerConfigurationimplementsIProjectGenerator{@OverridepublicvoiddoGenerator(Projectproject,StringentryPath,ProjectConfigVOcreateproject){//ConfMainPOM鏂囦欢generateProjectPOM(project,entryPath,projectConfig);//2.鍒涘缓鍥涘眰鏋舵瀯generateProjectDDD(project,entryPath,projectConfig);//3.鍒涘缓搴旂敤绋嬪簭generateApplication(project,entryPath,projectConfig);//4.鍒涘缓YmlgenerateYml(project,entryPath,projectConfig);//5.鍒涘缓閫氱敤generateCommon(project,entryPath,projectConfig);}}娣诲姞FreeMarker鏈嶅姟锛岀敤浜庡湪domain鍩熷眰鍒涘缓鑴氭墜鏋舵鏋讹紝瀹冩槸涓€涓ā鏉垮紩鎿庯細涓€涓熀浜庢ā鏉垮拰鏁版嵁鐢熸垚杈撳嚭鏂囨湰锛圚TML缃戦〉銆佺數瀛愰偖浠躲€侀厤缃枃浠躲€佹簮浠g爜绛夛級鐨勯€氱敤宸ュ叿琚敼鍙樸€侳reeMarker鍦ㄧ嚎鎵嬪唽锛歨ttp://freemarker.foofun.cn鏍规嵁DDD鐨勯」鐩粨鏋勶紝灞傛鍖呮嫭锛歛pplication,domain,infrastructure,interfaces锛岀劧鍚庢垜浠妸杩欎簺鍒涘缓杩囩▼鎶借薄鎴愭ā鏉挎柟娉曪紝鍏蜂綋浜ょ粰鍒涘缓瀛愮被銆?.璋冪敤鑴氭墜鏋舵湇鍔n.bugstack.guide.idea.plugin.module.DDDModuleBuilderpublicclassDDDModuleBuilderextendsModuleBuilder{privateIProjectGeneratorprojectGenerator=newProjectGeneratorImpl();@OverridepublicIcongetNodeIcon(){returnICONS.SPRING_BOOT;}@OverridepublicvoidsetupRootModel(@NotNullModifiableRootModelrootModel)throwsConfigurationException{//璁剧疆JDKif(null!=this.myJdk){rootModel.setSdk(this.myJdk);}else{rootModel.inheritSdk();}//鐢熸垚宸ョ▼璺緞Stringpath=FileUtil.toSystemIndependentName(Objects.requireNonNull(getContentEntryPath()));鏂版枃浠讹紙璺緞锛?mkdirs锛堬級锛沄irtualFilevirtualFile=LocalFileSystem.getInstance().refreshAndFindFileByPath(path);rootModel.addContentEntry锛堣櫄鎷熸枃浠讹級锛涢」鐩畃roject=rootModel.getProject();//鍒涘缓宸ョ▼缁撴瀯Runnabler=()->newWriteCommandAction(project){@Overrideprotectedvoidrun(@NotNullResultresult)throwsThrowable{projectGenerator.doGenerator(project,getContentEntryPath(),DataSetting.getInstance().getProjectConfig());}}銆傛墽琛岋紙锛?}}鍦―DDModuleBuilder#setupRootModel涓紝娣诲姞鍒涘缓DDD椤圭洰妗嗘灦鐨勬湇鍔★紝projectGenerator.doGenerator(project,getContentEntryPath(),DataSetting.getInstance().getProjectConfig());鍙﹀锛岃繖閲岄渶瑕佺敤鍒癐DEA鎻愪緵鐨勭嚎绋嬭皟鐢ㄦ柟娉曘€俷ewWriteCommandAction鍙互姝e父鍒涘缓6銆侀厤缃ā鏉垮伐绋?.1妯℃澘宸ュ巶cn.bugstack.guide.idea.plugin.factory.TemplateFactorypublicclassTemplateFactoryextendsProjectTemplatesFactory{@NotNull@OverridepublicString[]getGroups(){returnnewString[]{"DDD鑴氭墜鏋?};}@OverridepublicIcongetGroupIcon(Stringgroup){returnICONS.DDD;}@NotNull@OverridepublicProjectTemplate[]createTemplates(@NullableStringgroup,WizardContextcontext){returnnewProjectTemplate[]{newBuilderBasedTemplate(newDDDModuleBuilder())};}}妯℃澘宸ュ巶鐨勬牳蹇冩槸灏嗘垜浠垱寤篋DD鐨勬楠ゆ坊鍔犲埌createTemplates鏂规硶涓紝浠庤€屼覆鑱斿畬鎴愬垱寤鸿嚜瀹氫箟鑴氭墜鏋堕」鐩殑鏁翠釜閾炬潯銆?.2鏂囦欢閰嶇疆plugin.xmlcn.bugstack.guide.idea.plugin.guide-idea-plugin-scaffolding鑴氭墜鏋?/name>灏忓鍝?/vendor>com.intellij.modules.platform鎺ヤ笅鏉ラ渶瑕佹坊鍔犳垜浠垱寤虹殑椤圭洰妯℃澘鍜屾暟鎹湇鍔″湪plugin.xml涓繘琛岄厤缃紝杩欐牱鎻掍欢鍚姩鐨勬椂鍊欐垜浠氨鍙互鍚姩鑷繁鐨勬彃浠朵簡銆?銆佹祴璇曢獙璇佺偣鍑籔lugin鍚姩IDEA鎻掍欢锛岀劧鍚庡垱寤哄伐绋嬪涓嬶細鎷挎潵璇曡瘯锛屽惎鍔ㄦ彃浠讹紝鐐瑰嚮CreateProject锛屽偦鐡滃紡鐐瑰嚮锛屽氨鍙互鍒涘缓DDD浜嗛」鐩粨鏋勩€?.鎬荤粨瀛︿範浣跨敤IDEAPlugin寮€鍙戞妧鏈紝鏇存敼椤圭洰鍒涘缓鍚戝锛屾坊鍔犱綘闇€瑕佺殑椤圭洰鍒涘缓妯℃澘锛岃繖鏍蜂綘灏卞彲浠ュ垱寤轰竴涓狣DD鑴氭墜鏋堕」鐩鏋讹紝鐒跺悗浣犲氨鍙互缁撳悎浣犵殑瀹為檯娣诲姞浣犻渶瑕佺殑涓氬姟鍦烘櫙涓€浜涙妧鏈爢鍙犲埌鑴氭墜鏋朵腑銆傚鏋滀綘鎰挎剰灏濊瘯锛屽彲浠ュ湪椤圭洰鍒涘缓鏃堕摼鎺ユ暟鎹簱锛屽皢鏁版嵁搴撲腑瀵瑰簲鐨勮〃鐢熸垚Java浠g爜锛岃繖鏍蜂竴浜涚畝鍗曠殑閰嶇疆銆佹煡璇€佹槧灏勫氨涓嶇敤鑷繁鍐欎簡銆傚紑鍙慏DD鑴氭墜鏋剁殑婧愮爜涓繕鏄湁涓€浜涜缁嗙殑杩囩▼锛屽寘鎷浘鏍囧睍绀猴紝澶嶅埗淇℃伅锛孎reemarker浣跨敤缁嗚妭绛夈€備綘鍙互鍦ㄦ簮鐮佷腑瀛︿範璋冭瘯楠岃瘉杩欎簺銆?銆佺郴鍒楁帹鑽愪娇鐢‵reemarker鎼缓SpringBoot鑴氭墜鏋讹紝鍙戝竷Jar鍖呭埌Maven涓ぎ浠撳簱锛堜负寮€鍙戝紑婧愪腑闂翠欢鍋氬噯澶囷級銆侱DD棰嗗煙灞傚喅绛栬鍒欐爲鏈嶅姟璁捐鍋氫簡涓や笁骞翠簡锛岀湅涓嶆噦鏋舵瀯鍥炬槸浠€涔堬紵CodeGuideGithub瀛樺偍搴撶幇宸插紑婧愶紒