Некоторое время назад я написал пост на
Как я неправильно понял Ломбок
Сатьярт Аграхари ・ 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”