Автор: Брат Сяофу
Блог: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. Код плетения анкеров
Прежде чем код будет вплетен в якорь, методы, которые мы определяем в классе шаблона, должны реализовать интерфейс для обработки.Ключевые моменты включают в себя:
- пройти через
CommonDataKeys.EDITOR.getData(dataContext)
,CommonDataKeys.PSI_ELEMENT.getData(dataContext)
Инкапсулирует контекстную информацию объекта GenerateContext, то есть объекты некоторых классов, позиции привязки и редактирование документа. - Получите информацию о классе Class, соответствующую позиции курсора, через PsiClass.
psiClass.getMethods()
Прочитайте метод объекта, отфильтруйте метод набора и инкапсулируйте его в коллекцию. - пройти через
Toolkit.getDefaultToolkit().getSystemClipboard()
Получить информацию из буфера обмена, то есть вы генерируете объект в точке привязкиx.set(y.get)
Когда , скопируйте объект Y y и начните извлекать метод get, который также инкапсулируется в коллекцию. - Затем последний шаг — сборка и плетение кода.Эта часть нашего кода выглядит следующим образом;
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)
Добавление клавиши быстрого доступа к работе с кодом позволяет нам работать более удобно.
Установите и используйте проверку
- Поскольку для публикации плагинов необходимоplugins.jetbrains.com/И ждем обзора, чтобы его можно было скачать в релизном пакете:GitHub.com/заместитель комиссара/…После загрузки вы можете установить его вручную.
Далее вы можете преобразовать объект So Easy следующим образом:
- Скопируйте объект, который необходимо преобразовать, так как после копирования плагин может получить информацию из буфера обмена, а также извлечь набор методов get.
- Наведите указатель мыши на объект, который необходимо преобразовать в заданное значение, затем щелкните правой кнопкой мыши и выберите
Generate
->Vo2Dto - 小傅哥
1. Скопируйте объект
2. Генерация объектов
3. Окончательный эффект
- Наконец, вы можете видеть, что все ваши объекты были преобразованы, а код сгенерирован автоматически, разве это не восхитительно?
- Если вы используете горячие клавиши напрямую
Ctrl + Shift + K
Он также может быть сгенерирован автоматически.
Используйте его, лучше всего дать несколько предложений, отправить вопросы, отправить PR, все очень приветствуются!