Я считаю, что все использовали Lombok в проекте, потому что он может упростить наш код, но функций не так много. Так что же такое ломбок?Ломбок — это инструмент, который может помочь нам упростить и исключить некоторый обязательный, но раздутый Java-код в виде простых аннотаций.Проще говоря, например, мы создаем новый класс, а затем пишем в нем A несколько полей, а затем обычно нам нужно вручную создавать методы получения и установки, конструкторы и т. д. Роль ломбока состоит в том, чтобы избавить нас от необходимости вручную создавать эти коды, его можно использовать при компиляции исходного кода.Автоматическое создание этих методы для нас.
Так как же именно Ломбок это делает? Фактически, нижний слой должен использовать функцию аннотации времени компиляции.
Как использовать Ломбок
Lombok — это проект с открытым исходным кодом, код находится вlombok, если это проект Gradle, на него можно напрямую ссылаться в проекте следующим образом.
1compile ("org.projectlombok:lombok:1.16.6")
Функции
Так что же делает Ломбок? На самом деле это очень просто, один из самых простых примеров — автоматически генерировать некоторые методы, добавляя аннотации, чтобы сделать наш код более лаконичным и понятным. Например, следующий класс.
1@Data
2public class TestLombok {
3 private String name;
4 private Integer age;
5
6 public static void main(String[] args) {
7 TestLombok testLombok = new TestLombok();
8 testLombok.setAge(12);
9 testLombok.setName("zs");
10 }
11}
Мы используем ЛомбокData
Аннотация, без записиget、set
метод можно использовать и тогда, когдаget、set
метод. Посмотрим, как он скомпилированclass
файл, вы можете видеть, что он был автоматически сгенерирован для насget、set
метод.
1public class TestLombok {
2 private String name;
3 private Integer age;
4
5 public static void main(String[] args) {
6 TestLombok testLombok = new TestLombok();
7 testLombok.setAge(12);
8 testLombok.setName("zs");
9 }
10
11 public TestLombok() {
12 }
13
14 public String getName() {
15 return this.name;
16 }
17
18 public Integer getAge() {
19 return this.age;
20 }
21
22 public void setName(String name) {
23 this.name = name;
24 }
25
26 public void setAge(Integer age) {
27 this.age = age;
28 }
29
30}
Конечно, функций Lombok больше, чем это, и есть много других аннотаций, которые помогут нам легко разрабатывать.В Интернете есть много способов использовать Lombok, поэтому я не буду повторяться здесь. В обычных условиях мы настраиваем аннотации в проекте или используемSpring
в рамке@Controller、@Service
и т.д. Эти аннотации运行时注解
, аннотации времени выполнения в основном реализуются посредством отражения. иLombok
реализуется с использованием аннотаций времени компиляции. Так что же такое аннотации времени компиляции?
аннотации времени компиляции
Аннотации (также известные как метаданные) предоставляют нам формальный способ добавления информации в наш код, благодаря чему нам очень удобно использовать эти данные в более поздний момент времени. —————— Отрывок из книги «Мышление на Java»
Аннотации в Java делятся нааннотации времени выполненияианнотации времени компиляцииАннотации времени выполнения — это информация, которую мы часто используем для получения наших аннотаций посредством отражения во время работы программы, а затем для выполнения некоторых операций. И что такое аннотации времени компиляции? Он обрабатывается процессором аннотаций во время компиляции программы.
- Время компиляции. Время компиляции языка Java является неопределенной операцией, поскольку оно может
.java`文件转化成`.class
Процесс файла; он также может относиться к процессу преобразования байт-кода в машинный код; он также может напрямую относиться к*.java
Процесс компиляции в собственный машинный код - Время выполнения: процесс от загрузки файлов байт-кода JVM в память до выгрузки после окончательного использования относится к области времени выполнения.
Инструмент обработки аннотаций
Инструмент обработки аннотаций apt (Инструмент обработки аннотаций), который представляет собой инструмент, предоставляемый Sun для облегчения процесса обработки аннотаций, apt предназначен для управления исходными файлами Java, а не скомпилированными классами.
Это инструмент javac, что в переводе с китайского означает процессор аннотаций времени компиляции. APT можно использовать для сканирования и обработки аннотаций во время компиляции. Информацию об аннотациях и аннотируемых объектах можно получить через APT, после получения которой мы можем автоматически генерировать некоторые коды в соответствии с требованиями, устраняя необходимость ручного написания. Обратите внимание, что получение аннотаций и генерация кода находятся в коде.компилироватьПо завершении это значительно повышает производительность программы по сравнению с аннотациями, обрабатывающими отражение во время выполнения. Ядром APT является класс AbstractProcessor.
В обычных условиях с помощью инструмента APT можно создать только некоторые файлы (Не только файл класса, который мы себе представляем, но и файл xml и так далее.) и не может изменять исходную информацию о файле.
Но тут могут быть сомнения,Lombok
Разве это не просто добавление некоторой информации к нашему исходному файлу? Я объясню подробно позже, вот краткое введение, на самом делеLombok
изменено в Javaабстрактное синтаксическое деревоAST
Только после этого он модифицировал информацию своего исходного класса.
Далее мы покажем, как использоватьAPT
Инструмент создает файл класса, а затем мы говоримLombok
Как изменить свойства в существующем классе.
определить аннотации
Прежде всего, конечно, нам нужно определить наши собственные аннотации.
1@Retention(RetentionPolicy.SOURCE) // 注解只在源码中保留
2@Target(ElementType.TYPE) // 用于修饰类
3public @interface GeneratePrint {
4
5 String value();
6}
Retention
В аннотации есть значение атрибута, котороеRetentionPolicy
класс перечисления типа,RetentionPolicy
В классе enum есть три значения.
1public enum RetentionPolicy {
2
3 SOURCE,
4
5 CLASS,
6
7 RUNTIME
8}
-
SOURCE
Модифицированная аннотация: Модифицированная аннотация, указывающая, что информация аннотации будет отброшена компилятором и не останется в файле класса, а информация аннотации останется только в исходном файле. -
CLASS
Украшенные аннотации: информация, указывающая на аннотации, сохраняется в файле класса (файле байт-кода) при компиляции программы, но не считывается виртуальной машиной во время выполнения. -
RUNTIME
Украшенные аннотации: информация, указывающая на аннотации, сохраняется в файле класса (файле байт-кода) при компиляции программы и будет сохранена виртуальной машиной во время выполнения.Таким образом, его можно вызывать через отражение, поэтому аннотации используют этот параметр в обычном режиме выполнения.
Target
В аннотации также есть значение атрибута, котороеElementType
Перечень типов. Он используется для изменения места использования этой аннотации.
1public enum ElementType {
2 TYPE,
3
4 FIELD,
5
6 METHOD,
7
8 PARAMETER,
9
10 CONSTRUCTOR,
11
12 LOCAL_VARIABLE,
13
14 ANNOTATION_TYPE,
15
16 PACKAGE,
17
18 TYPE_PARAMETER,
19
20 TYPE_USE
21}
Определение процессоров аннотаций
Если мы хотим определить процессор аннотаций, нам нужно наследоватьAbstractProcessor
своего рода. После наследования основные типы кадров следующие:
1@SupportedSourceVersion(SourceVersion.RELEASE_8)
2@SupportedAnnotationTypes("aboutjava.annotion.MyGetter")
3public class MyGetterProcessor extends AbstractProcessor {
4 @Override
5 public synchronized void init(ProcessingEnvironment processingEnv) {
6 super.init(processingEnv);
7 }
8
9 @Override
10 public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
11 return true;
12 }
13}
Мы видим, что в подклассе есть две аннотации выше, аннотации описываются следующим образом
-
@SupportedSourceVersion
: указывает поддерживаемую версию Java. -
@SupportedAnnotationTypes
: указывает аннотацию, которую должен обрабатывать этот процессор.
Унаследовал два метода родительского класса, методы описываются следующим образом
- метод init: в основном для получения некоторой информации об окружающей среде во время компиляции
- метод процесса: во время компиляции метод, выполняемый компилятором. Здесь мы пишем конкретную логику
Мы демонстрируем, как использовать наследованиеAbstractProcessor
class для генерации классов во время компиляции, поэтому мы находимся вprocess
метод для написания кода для нашего сгенерированного класса. Следующее.
1@Override
2public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
3 StringBuilder builder = new StringBuilder()
4 .append("package aboutjava.annotion;\n\n")
5 .append("public class GeneratedClass {\n\n") // open class
6 .append("\tpublic String getMessage() {\n") // open method
7 .append("\t\treturn \"");
8 // for each javax.lang.model.element.Element annotated with the CustomAnnotation
9 for (Element element : roundEnv.getElementsAnnotatedWith(MyGetter.class)) {
10 String objectType = element.getSimpleName().toString();
11 // this is appending to the return statement
12 builder.append(objectType).append(" says hello!\\n");
13 }
14 builder.append("\";\n") // end return
15 .append("\t}\n") // close method
16 .append("}\n"); // close class
17 try { // write the file
18 JavaFileObject source = processingEnv.getFiler().createSourceFile("aboutjava.annotion.GeneratedClass");
19 Writer writer = source.openWriter();
20 writer.write(builder.toString());
21 writer.flush();
22 writer.close();
23 } catch (IOException e) {
24 // Note: calling e.printStackTrace() will print IO errors
25 // that occur from the file already existing after its first run, this is normal
26 }
27 return true;
28}
Определение классов с помощью аннотаций (тестовые классы)
Вышеупомянутые два класса являются основными классами инструментов, один определяет аннотации, другой определяет процессоры аннотаций, а затем мы определяем тестовый класс (TestAno.java). Мы добавляем наш пользовательский класс аннотаций в класс.
1@MyGetter
2public class TestAno {
3
4 public static void main(String[] args) {
5 System.out.printf("1");
6 }
7}
Таким образом, мы можем генерировать файлы во время компиляции. Далее мы продемонстрируем генерацию файлов во время компиляции. Не беспокойтесь о прямой компиляции javac сейчас.MyGetter
Классы — это классы аннотаций, да, ноMyGetterProcessor
является обработчиком класса аннотаций, то мы компилируемTestAno
Обработчик запускается при создании файла Java. Таким образом, два класса не могут быть скомпилированы вместе.
Позвольте мне сначала показать вам мою структуру каталогов
1aboutjava
2 -- annotion
3 -- MyGetter.java
4 -- MyGetterProcessor.java
5 -- TestAno.java
Итак, мы сначала компилируем класс аннотаций и класс процессора аннотаций.
1javac aboutjava/annotion/MyGett*
Далее компилируем наш тестовый класс.На этот раз нам нужно добавить его при компиляцииprocessor
Параметр для указания соответствующего класса обработки аннотаций.
1javac -processor aboutjava.annotion.MyGetterProcessor aboutjava/annotion/TestAno.java
Как видно на динамическом графике, файл Java генерируется автоматически.
кодовый адрес
Суммировать
В этой статье будет вторая статья, объясняющая принцип Lombok и способы изменения содержимого исходного класса. В качестве предварительного знания эта статья кратко представляет, что такое процессор аннотаций и как использовать процессор аннотаций для выполнения действий, которые мы можем выполнять только во время компиляции. Надеюсь, вы сможете протестировать его на своей машине.Если у вас есть какие-либо вопросы по этой статье, пожалуйста, укажите.
Если вам интересно, можете обратить внимание на мой новый паблик аккаунт и поискать [Сумка с сокровищами программиста]. Или просто отсканируйте код ниже.
Ссылаться на
- Всемогущий АПТ! Магия аннотаций времени компиляции
- Compile time processing using annotation processor
- Java Annotation Processing and Creating a Builder
- Анализ принципа Ломбока и реализация функции
- Обработчик аннотаций Java - изменить синтаксическое дерево во время компиляции
- Последняя часть головоломки АОП | Абстрактное синтаксическое дерево AST — самый легкий метод АОП
- Java Annotation Processing and Creating a Builder
- Анализ и использование AST абстрактного синтаксического дерева Java