成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

選定對象批量織入“x.set(y.get)”代碼,自動生成vo2dto

開發 前端
這些年從事編程開發以來,我好像發現了大部分研發那些不愿意干的事,都成就了別人。就像部署服務麻煩,有了Docker、簡單CRUD不想開發,有了低代碼、給方法代碼加監控繁瑣、有了非入侵的全鏈路監控。

[[440440]]

本文轉載自微信公眾號「bugstack蟲洞棧」,作者小傅哥。轉載本文請聯系bugstack蟲洞棧公眾號。

一、前言

給你機會,你也不中用啊

這些年從事編程開發以來,我好像發現了大部分研發那些不愿意干的事,都成就了別人。就像部署服務麻煩,有了Docker、簡單CRUD不想開發,有了低代碼、給方法代碼加監控繁瑣、有了非入侵的全鏈路監控。

而這些原本你也在干的事情,因為沒有想法、沒有創新、沒有思考,也可能是沒有能力,所以一直都是在搬磚、碼磚、砌磚,反反復復、來來回回。鍵盤敲的是越來越快了,代碼搞的是越來越爛了。薪資沒搞上去,頭發是越來越少了。

對于想走技術路線的碼農,千萬不要只是停留在業務功能的邏輯開發上,只有當你有了共性凝練的邏輯思維,才會逐步思考怎么把一件重復的事做成一個通用的服務或者組件,而這些東西的落地不僅需要你會寫代碼,還要會思考更要會去索引一些你需要的技術,并用自學的方式來補充這部分技能。

二、需求目的

你想寫對象間的get、set嗎?煩,煩死了,尤其是在DDD四層架構下,有了多層防污處理,一會一個vo2dto、一會一個vo2do、一會一個do2po,雖然有很多工具的操作,但還是得寫呀。

怎么辦?不要慌,這是機會呀,我們做個插件搞定它,讓它可以自動的給我生成get、set代碼,在IDEA Plugin的處理下,選擇好需要生成對象代碼的錨點,復制下轉換對象,自動織入代碼,1s鐘搞定!效果視頻

三、案例開發

1. 工程結構

  1. guide-idea-plugin-vo2dto 
  2. ├── .gradle 
  3. └── src 
  4.     ├── main 
  5.     │   └── java 
  6.     │    └── cn.bugstack.guide.idea.plugin  
  7.     │        ├── action 
  8.     │        │   └── Vo2DtoGenerateAction.java      
  9.     │        ├── application 
  10.     │        │   └── IGenerateVo2Dto.java       
  11.     │        ├── domain 
  12.     │        │   ├── model 
  13.     │        │   │   ├── GenerateContext.java      
  14.     │        │   │   ├── GetObjConfigDO.java       
  15.     │        │   │   └── SetObjConfigDO.java        
  16.     │        │   └── service    
  17.     │        │       ├── impl      
  18.     │        │       │   └── GenerateVo2DtoImpl.java     
  19.     │        │       └── AbstractGenerateVo2Dto.java       
  20.     │        └── infrastructure    
  21.     │            └── Utils.java     
  22.     ├── resources 
  23.     │   └── META-INF 
  24.     │       └── plugin.xml  
  25.     ├── build.gradle   
  26.     └── gradle.properties 

在此 IDEA 插件工程中,主要分為4塊區域:

action:提供菜單欄窗體,在插件中我們把這個菜單欄配置到 Generate 下,也就是通常你生成 get、set、constructor 方法的地方。

application:應用層定義接口,這里定義了一個用于生成代碼并織入到錨點的方法接口。

domian:領域層專門處理代碼的生成和織入動作,這一層把代碼的中錨點位置獲取、剪切板信息復制、應用上下文、類中get、set的解析,以及最終把生成代碼織入到錨點后的操作。

infrastructure:在基礎層提供了工具類,用于獲取剪切板信息和錨點位置判斷等操作。

2. 織入代碼接口

cn.bugstack.guide.idea.plugin.application.IGenerateVo2Dto

  1. public interface IGenerateVo2Dto { 
  2.  
  3.     void doGenerate(Project project, DataContext dataContext); 
  4.  

定義接口其實非常重要的一步,因為這樣一步就把生成的標準定義下來了,所有的生成動作都要從這個接口發起。學習源碼也一樣,你要找到一個核心的入口點,才能更好的開始學習

3. 定義模板方法

因為生成代碼并織入錨點位置的操作,整個來看其實也是一套流程操作,因為在這個過程需要;獲取上下文信息(也就是工程對象)、給當前錨點位置的類提取 set 方法集合、之后在給Ctrl+C剪切板上的信息讀取出來提取 get 方法集合,第四步把set、get進行組合并織入代碼到錨點位置。整體過程如下:

那么在使用模板方法后,就可以非常容易的把寫在一個類里的成片的代碼按照職責進行拆分。

同時因為有了模板的定義,也就定義出了整個一套標準流程,在流程規范下執行代碼,后續再補充邏輯迭代功能也會更加容易。

4. 代碼織入錨點

關于代碼織入錨點前,我們在模板類中定義的方法,需要實現接口進行處理,重點包括:

  • 通過 CommonDataKeys.EDITOR.getData(dataContext)、CommonDataKeys.PSI_ELEMENT.getData(dataContext) 封裝 GenerateContext 對象上下文信息,也就是一些類、錨點位置、文檔編輯的對象。
  • 通過 PsiClass 獲取光標位置對應的 Class 類信息,在通過 psiClass.getMethods() 讀取對象方法,把 set 方法過濾出來,封裝到集合中。
  • 通過 Toolkit.getDefaultToolkit().getSystemClipboard() 獲取剪切板信息,也就是你在錨點位置給對象生成 x.set(y.get) 時,復制的 Y y 對象,并開始提取 get 方法,同樣封裝到集合中。
  • 那么最后就是代碼的組裝和織入動作了,這部分我們的代碼如下;

cn.bugstack.guide.idea.plugin.domain.service.impl.GenerateVo2DtoImpl

  1. @Override 
  2. protected void weavingSetGetCode(GenerateContext generateContext, SetObjConfigDO setObjConfigDO, GetObjConfigDO getObjConfigDO) { 
  3.     Application application = ApplicationManager.getApplication(); 
  4.     // 獲取空格位置長度 
  5.     int distance = Utils.getWordStartOffset(generateContext.getEditorText(), generateContext.getOffset()) - generateContext.getStartOffset(); 
  6.     application.runWriteAction(() -> { 
  7.         StringBuilder blankSpace = new StringBuilder(); 
  8.         for (int i = 0; i < distance; i++) { 
  9.             blankSpace.append(" "); 
  10.         } 
  11.         int lineNumberCurrent = generateContext.getDocument().getLineNumber(generateContext.getOffset()) + 1; 
  12.         List<String> setMtdList = setObjConfigDO.getParamList(); 
  13.         for (String param : setMtdList) { 
  14.             int lineStartOffset = generateContext.getDocument().getLineStartOffset(lineNumberCurrent++); 
  15.             new WriteCommandAction(generateContext.getProject()) { 
  16.                 @Override 
  17.                 protected void run(@NotNull Result result) throws Throwable { 
  18.                     generateContext.getDocument().insertString(lineStartOffset, blankSpace + setObjConfigDO.getClazzParamName() + "." + setObjConfigDO.getParamMtdMap().get(param) + "(" + (null == getObjConfigDO.getParamMtdMap().get(param) ? "" : getObjConfigDO.getClazzParam() + "." + getObjConfigDO.getParamMtdMap().get(param) + "()") + ");\n"); 
  19.                     generateContext.getEditor().getCaretModel().moveToOffset(lineStartOffset + 2); 
  20.                     generateContext.getEditor().getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); 
  21.                 } 
  22.             }.execute(); 
  23.         } 
  24.     }); 
  • 織入代碼的流程動作,主要是對set方法集合進行遍歷,把對應的x.set(y.get)通過 document.insertString 到具體的位置和代碼。
  • 最終所有生成的代碼方法織入完成,即完成了整個 x.set(y.get) 的過程。

5. 配置菜單入口

plugin.xml

  1. <actions> 
  2.     <!-- Add your actions here --> 
  3.     <action id="Vo2DtoGenerateAction" class="cn.bugstack.guide.idea.plugin.action.Vo2DtoGenerateAction" 
  4.             text="Vo2Dto - 小傅哥" description="Vo2Dto generate util" icon="/icons/logo.png"
  5.         <add-to-group group-id="GenerateGroup" anchor="last"/> 
  6.         <keyboard-shortcut keymap="$default" first-keystroke="ctrl shift K"/> 
  7.     </action
  8. </actions> 

 

 

這次我們給生成 x.set(y.get) 代碼的操作加個快捷鍵,可以讓我們更加方便的進行操作。

四、測試驗證

點擊 Plugin 啟動 IDEA 插件,之后有2步操作;

  • 復制你需要被轉換的對象,因為復制以后就可以被插件獲取到剪切板信息了,也就能提取到get方法集合。
  • 把鼠標定義到需要轉換設置值的對象,之后鼠標右鍵,選擇 Generate -> Vo2Dto - 小傅哥

1. 復制對象

2. 生成對象

3. 最終效果

最終你就可以看到已經把你全部的對象轉換,自動生成出來代碼了,是不是很香。

如果你直接使用快捷鍵 Ctrl + Shift + K 也是可以自動生成的。

五、擴展接口

   
獲取當前編輯的文件, 通過PsiFile可獲得PsiClass, PsiField等 PsiFile psiFile = e.getData(LangDataKeys.PSI_FILE);
獲取當前的project對象 Project project = e.getProject();
獲取數據上下文 DataContext dataContext = e.getDataContext();
獲取到數據上下文后,通過CommonDataKeys對象可以獲得該File的所有信息 Editor editor = CommonDataKeys.EDITOR.getData(dataContext);<br />PsiFile psiFile = CommonDataKeys.PSI_FILE.getData(dataContext);<br />VirtualFile virtualFile = CommonDataKeys.VIRTUAL_FILE.getData(dataContext);
GlobalSearchScope中有Project域,Moudule域,File域等等 PsiFile[] psiFiles = FilenameIndex.getFilesByName(project, name, GlobalSearchScope);
類似于IDE中的Find Usages操作 Query<PsiReference> search = ReferencesSearch.search(PsiElement);
重命名 RenameRefactoring newName = RefactoringFactory.getInstance(Project).createRename(PsiElement, "newName");
搜索一個類的所有子類,重載方法較多,具體不再一一列出 Query<PsiClass> search = ClassInheritorsSearch.search(PsiClass);
根據類的全限定名查詢PsiClass,下面這個方法是查詢Project域 PsiClass psiClass = JavaPsiFacade.getInstance(project).findClass(classQualifiedName, GlobalSearchScope.projectScope(project));
獲取Java類所在的Package PsiPackage psiPackage = JavaPsiFacade.getInstance(Project).findPackage(classQualifiedName);
查找被特定方法重寫的方法 Query<PsiMethod> search = OverridingMethodsSearch.search(PsiMethod);

六、總結

本章節中我們涉及了不少對工程對象的類和方法進行操作的處理,這些內容的實踐也非常適合你在其他場景使用,比如給工程的接口生成一些自動化API的操作。

在給對象生成 x.set(y.get) 的時候,我也在思考該怎么更合理的把轉換對象代入到插件的代碼邏輯中,可能會想到是通過彈窗配置或者代碼掃描到上一行,但這樣的方式終究是不舒服的,考慮到實際自己編碼的習慣操作,其實我們做這步的時候,復制是第一步動作,為了更好的體驗,所以這里選擇了用復制來處理這塊的連接性問題。

本系列的 IDEA Plugin 開發都以遵循 DDD 工程結構思想為設計和實現,雖然整體內容看上去也不復雜,但希望這些框架的沉淀可以為 DDD 落地鋪路,讓更多的工程研發人員適應 DDD 結構。

 

責任編輯:武曉燕 來源: bugstack蟲洞棧
相關推薦

2022-12-09 07:53:20

vo2dto方法AOP

2021-10-12 10:49:52

Vo2dto壓測數據

2024-11-29 07:34:36

PO持久化對象

2022-09-13 08:40:51

DTOVOPO

2021-03-08 08:54:12

驅動模型DTODO

2024-10-16 17:01:17

Java開發SpringBoot

2009-07-16 09:09:36

ibatis自動代碼

2009-09-11 09:15:32

C# get set

2012-04-19 17:16:32

Titanium實例代碼分析

2009-09-10 16:38:43

C# get set用

2014-01-21 09:42:32

Python代碼對象

2023-06-12 00:38:55

開源Java庫工具

2025-02-05 11:00:00

開發Java對象模型

2010-09-28 13:50:20

2010-09-25 16:06:58

SQL語句

2009-09-10 15:27:16

C# get set

2023-11-09 09:28:09

Java代碼

2009-08-27 15:22:27

C#中的GET與SET

2024-08-06 09:51:21

SpringHTTPJSON

2021-05-20 10:00:56

Go代碼Python
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产成人精品久久 | 国产一级一级毛片 | 久久精品一 | 九九久久精品 | 亚洲性人人天天夜夜摸 | 国产视频欧美 | 黄色一级大片在线免费看产 | 免费一级毛片 | 日韩久久久久久 | 亚洲欧美中文日韩在线v日本 | 99久久婷婷国产亚洲终合精品 | 成人不卡| 日韩av高清在线 | 亚洲成人精品一区二区 | 欧美亚洲视频 | 极情综合网 | 欧美一区二区三区视频在线观看 | 国产成人av一区二区三区 | 精品欧美乱码久久久久久1区2区 | 美国一级片在线观看 | 最新中文字幕在线播放 | 久久久精品一区 | 成人欧美一区二区三区在线观看 | 欧美在线一区二区三区 | 黄色三级免费网站 | 野狼在线社区2017入口 | 中文成人在线 | 国产视频一区二区三区四区五区 | 国产成人一区二区三区 | 91成人在线视频 | 午夜影院网站 | 在线观看亚洲精品视频 | 午夜影院在线观看视频 | 91精品国产乱码久久久久久久 | 一区二区片 | 国产精品欧美一区二区三区不卡 | 四虎在线观看 | 国产视频一区二区 | 欧美一区二区三区在线观看 | 国产a一区二区 | 久久久综合久久 |