Автор: Брат Сяофу
Блог: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, все очень приветствуются!