Написал плагин IDEA с открытым исходным кодом, чтобы решить головную боль vo2dto.

задняя часть внешний интерфейс IntelliJ IDEA
Написал плагин IDEA с открытым исходным кодом, чтобы решить головную боль vo2dto.

Автор: Брат Сяофу
Блог:bugstack.cn

Осаждайте, делитесь, растите и позвольте себе и другим что-то получить! 😄

жареная голова,po2vo,vo2do,do2dto, куча свойств объекта, вынь и запихни. Если бы не антикоррозийность каждого слоя по архитектуре DDD,Я действительно хочу ударить его.

на томBeanUtils.copyPropertiesДа на самом деле преобразование объектов это не только этот метод, но и 12 однотипных методов, но в целом это ещеMapStructКонечный эффект генерации кода x.set (y.get) во время компиляции является наилучшим.Общие данные измерения давления выглядят следующим образом:

  • BeanUtils.copyPropertiesЭто самый распространенный инструментальный класс в коде каждого, но до тех пор, пока вы не используете его неправильно.ApacheУпакованный, но предоставленный Spring, он в основном не окажет большого влияния на производительность.
  • Но если производительность лучше, альтернатива ручномуget、setда, ещеMapStructЛучше использовать, потому что он генерируется во время компиляции.get、setкод, и мы пишемget、setТакой же.
  • Некоторые другие пакеты компонентов в основном основаны наAOP,ASM,CGlib, технические средства для достижения, поэтому будет соответствующая потеря производительности.

Что делать?Напишите по одному для каждой операции, преобразующей свойства объекта.MapStruct? Тоже не подходит.Некоторые из них очень простые операции в методе,и их можно сделать написав код.Проблема в том,что их лень писать,и легко написать ошибки,когда их слишком много.Не говоря уже о BeanUtils.copyProperties Иногда определяется, что есть проблема с производительностью, и добавление и уменьшение свойств не видно из кода

такЯ хочу написать подключаемый модуль IDEA для решения этой проблемы, цель одна, с помощью возможности разработки подключаемого модуля IDEA, определить 2 объекта, которые мне нужны для преобразования свойств, автоматически сгенерировать код преобразования 2 объектов и сплести их. в мою позицию позиционирования объекта.

Разработка плагина

Вот что я думаю: в коде проекта разработки IDEA между двумя объектами, которые необходимо преобразовать, скопируйте первый объект и свойства, а затем поместите курсор на преобразованный объект, затем я предоставляю ему кнопку или сочетание клавиш, все коды конвертации генерируются в одной точке, так что проблема почерка не решается.Эффект следующий:

1. Инженерное сооружение

vo2dto
├── .gradle
└── src
    ├── main
    │   └── java
    │   	└── cn.bugstack.guide.idea.plugin 
    │       	├── action
    │       	│	└── Vo2DtoGenerateAction.java     
    │       	├── application
    │       	│	└── IGenerateVo2Dto.java      
    │       	├── domain
    │       	│	├── model
    │       	│	│	├── GenerateContext.java     
    │       	│	│	├── GetObjConfigDO.java      
    │       	│	│	└── SetObjConfigDO.java       
    │       	│	└── service   
    │       	│	 	├── impl     
    │       	│	 	│	└── GenerateVo2DtoImpl.java    
    │       	│	 	└── AbstractGenerateVo2Dto.java      
    │       	└── infrastructure   
    │       	 	└── Utils.java    
    ├── resources
    │   └── META-INF
    │       └── plugin.xml 
    ├── build.gradle  
    └── gradle.properties

Получение исходного кода:GitHub.com/заместитель комиссара/… - 欢迎提交 issue、PR 共同维护

В этом проекте подключаемого модуля IDEA он в основном разделен на 4 области:

  • действие: Предоставляет форму строки меню, в плагине мы настраиваем эту строку меню наGenerateНиже, где вы обычно генерируете методы get, set и конструктора.
  • приложение: прикладной уровень определяет интерфейс, который определяет интерфейс метода для генерации кода и встраивания его в привязку.
  • domian: уровень предметной области специализируется на генерации и объединении кода.Этот уровень получает позицию привязки кода, копирует информацию из буфера обмена, контекст приложения, синтаксический анализ get и set в классе и, наконец, вплетает сгенерированный код в действие после достигнув точки привязки.
  • Инфраструктура: Предоставляет классы инструментов на базовом уровне для таких операций, как получение информации из буфера обмена и оценка положения точек привязки.

2. Переплетение интерфейса кода

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

public interface IGenerateVo2Dto {

    void doGenerate(Project project, DataContext dataContext);

}
  • Определение интерфейса на самом деле является очень важным шагом, поскольку на этом шаге определяются сгенерированные стандарты, и все действия по созданию должны инициироваться из этого интерфейса.То же самое верно и для изучения исходного кода: вам нужно найти основную точку входа, чтобы начать учиться лучше.

3. Определите метод шаблона

Поскольку операция генерации кода и вплетения позиции привязки фактически представляет собой набор операций процесса, поскольку в этом процессе необходимо получить контекстную информацию (то есть инженерные объекты), извлечь набор методов набора для класса в текущий момент положение якоря, после подачиCtrl+CИнформация из буфера обмена считывается для извлечения набора методов get.Четвертый шаг — объединить set и get и вплести код в якорную позицию. Общий процесс выглядит следующим образом:

  • Затем, после использования метода шаблона, очень легко разделить кусок кода, написанный в классе, в соответствии с обязанностями.
  • При этом из-за определения шаблона определяется весь набор стандартных процессов, а код исполняется под спецификацией процесса, и позже будет проще дополнить функцию логической итерации.

4. Код плетения анкеров

Прежде чем код будет вплетен в якорь, методы, которые мы определяем в классе шаблона, должны реализовать интерфейс для обработки.Ключевые моменты включают в себя:

  1. пройти черезCommonDataKeys.EDITOR.getData(dataContext),CommonDataKeys.PSI_ELEMENT.getData(dataContext)Инкапсулирует контекстную информацию объекта GenerateContext, то есть объекты некоторых классов, позиции привязки и редактирование документа.
  2. Получите информацию о классе Class, соответствующую позиции курсора, через PsiClass.psiClass.getMethods()Прочитайте метод объекта, отфильтруйте метод набора и инкапсулируйте его в коллекцию.
  3. пройти черезToolkit.getDefaultToolkit().getSystemClipboard()Получить информацию из буфера обмена, то есть вы генерируете объект в точке привязкиx.set(y.get)Когда , скопируйте объект Y y и начните извлекать метод get, который также инкапсулируется в коллекцию.
  4. Затем последний шаг — сборка и плетение кода.Эта часть нашего кода выглядит следующим образом;

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

@Override
protected void weavingSetGetCode(GenerateContext generateContext, SetObjConfigDO setObjConfigDO, GetObjConfigDO getObjConfigDO) {
    Application application = ApplicationManager.getApplication();
    // 获取空格位置长度
    int distance = Utils.getWordStartOffset(generateContext.getEditorText(), generateContext.getOffset()) - generateContext.getStartOffset();
    application.runWriteAction(() -> {
        StringBuilder blankSpace = new StringBuilder();
        for (int i = 0; i < distance; i++) {
            blankSpace.append(" ");
        }
        int lineNumberCurrent = generateContext.getDocument().getLineNumber(generateContext.getOffset()) + 1;
        List<String> setMtdList = setObjConfigDO.getParamList();
        for (String param : setMtdList) {
            int lineStartOffset = generateContext.getDocument().getLineStartOffset(lineNumberCurrent++);
            
            WriteCommandAction.runWriteCommandAction(generateContext.getProject(), () -> {
                generateContext.getDocument().insertString(lineStartOffset, blankSpace + setObjConfigDO.getClazzParamName() + "." + setObjConfigDO.getParamMtdMap().get(param) + "(" + (null == getObjConfigDO.getParamMtdMap().get(param) ? "" : getObjConfigDO.getClazzParam() + "." + getObjConfigDO.getParamMtdMap().get(param) + "()") + ");\n");
                generateContext.getEditor().getCaretModel().moveToOffset(lineStartOffset + 2);
                generateContext.getEditor().getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
            });
        }
    });
}
  • Действие процесса создания кода в основном заключается в обходе набора методов set и размещении соответствующихx.set(y.get)пройти черезdocument.insertStringк определенному месту и коду.
  • Наконец, вплетаются все методы сгенерированного кода, т. е. весьx.set(y.get)процесс.

5. Вход в меню конфигурации

plugin.xml

<actions>
    <!-- Add your actions here -->
    <action id="Vo2DtoGenerateAction" class="cn.bugstack.guide.idea.plugin.action.Vo2DtoGenerateAction"
            text="Vo2Dto - 小傅哥" description="Vo2Dto generate util" icon="/icons/logo.png">
        <add-to-group group-id="GenerateGroup" anchor="last"/>
        <keyboard-shortcut keymap="$default" first-keystroke="ctrl shift K"/>
    </action>
</actions>
  • На этот раз мы генерируемx.set(y.get)Добавление клавиши быстрого доступа к работе с кодом позволяет нам работать более удобно.

Установите и используйте проверку

Далее вы можете преобразовать объект So Easy следующим образом:

  1. Скопируйте объект, который необходимо преобразовать, так как после копирования плагин может получить информацию из буфера обмена, а также извлечь набор методов get.
  2. Наведите указатель мыши на объект, который необходимо преобразовать в заданное значение, затем щелкните правой кнопкой мыши и выберитеGenerate -> Vo2Dto - 小傅哥

1. Скопируйте объект

2. Генерация объектов

3. Окончательный эффект

  • Наконец, вы можете видеть, что все ваши объекты были преобразованы, а код сгенерирован автоматически, разве это не восхитительно?
  • Если вы используете горячие клавиши напрямуюCtrl + Shift + KОн также может быть сгенерирован автоматически.

Используйте его, лучше всего дать несколько предложений, отправить вопросы, отправить PR, все очень приветствуются!