Некоторое время назад я написал пост на
Как я неправильно понял Ломбок
Сатьярт Аграхари ・ 13 ноября 20 ・ 2 минуты чтения
Так что на этот раз я не хотел повторять ту же ошибку, что возвращает нас к этому посту.
Давайте начнем с простого упражнения для людей, знакомых с ломбок и внедрение зависимостей . Как вы думаете, каким должен быть сгенерированный код из следующего блока
@RequiredArgsConstructor(onConstructor = @__(@Inject))
public class Test {
@NonNull @Named("testString") private final String testString;
}
Я думаю, что большинство людей догадались бы (кто видел сгенерированный ломбоком код), что это приведет к
public class Test {
@Generated
@Inject
Test(@NonNull @Named("testString") String testString) {
if (testString == null) {
throw new NullPointerException("testString is marked non-null but is null");
} else {
this.testString = testString;
}
}
}
Но если бы это было так, то нас бы здесь не было, не так ли?.. Итак, давайте посмотрим, что он на самом деле генерирует
public class Test {
@Generated
@Inject
Test(@NonNull String testString) {
if (testString == null) {
throw new NullPointerException("testString is marked non-null but is null");
} else {
this.testString = testString;
}
}
}
Но это странно, я ясно вижу, что я пометил свое поле с помощью @Named, и как бы оно вообще нашло правильную зависимость для внедрения, если у него не будет обнаружения имени во время внедрения зависимостей.
Ну, как оказалось, ломбок не соблюдает все аннотации, так как реализовать такое поведение становится слишком сложно. Вы можете ознакомиться с проблемами github для получения подробной информации 1 2
Итак, теперь, когда мы знаем, что это так, вопрос в том, как это решить.
- в более новых версиях lombok можно добавить
lombok.копируемый Annotations.google.inject.name . Названныйв файлеlombok.config, и ломбок попытается скопировать их при создании конструктора. - Используйте нашу старомодную инъекцию на основе конструктора и напишите
public class Test {
@Inject
Test(@NonNull @Named("testString") final String testString) {
this.testString = testString;
}
}
Я предпочитаю 2, по нескольким причинам
- Помещение conf в файл lombok.config, который определяет, что копируется, скрывает слишком много информации и, откровенно говоря, является просто несчастным случаем, ожидающим, когда кто-то увидит этот пример кода и попытается скопировать его, и это каким-то образом сработает, потому что столкновения не было.
- Он копирует только аннотации, для которых реализована возможность копирования, поэтому, если мы столкнемся с чем-то, что невозможно скопировать, мы в любом случае вернемся к реализации 2.
- Мне нравится 2-й вариант, так как он более выразительный, и мне нравится писать коды, которые более выразительны, так как в конечном итоге мы пишем их для людей, и лучше, если мы не будем скрывать слишком много вещей и будем делать все просто, чтобы человек, читающий код, мог больше сосредоточиться на бизнес-логике, а не тратить время на понимание того, почему или почему их внедрение не работает.
Оригинал: “https://dev.to/satylogin/playing-the-generator-game-2bk4”