Рубрики
Без рубрики

Играем в игру генератор

Некоторое время назад я написал пост о том, как я неправильно понял Ломбок… С тегами java, ломбок, программирование, внедрение зависимостей.

Некоторое время назад я написал пост на

Как я неправильно понял Ломбок

Сатьярт Аграхари ・ 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

Итак, теперь, когда мы знаем, что это так, вопрос в том, как это решить.

  1. в более новых версиях lombok можно добавить lombok.копируемый Annotations.google.inject.name . Названный в файле lombok.config , и ломбок попытается скопировать их при создании конструктора.
  2. Используйте нашу старомодную инъекцию на основе конструктора и напишите
public class Test {
    @Inject
    Test(@NonNull @Named("testString") final String testString) {
        this.testString = testString;
    }
}

Я предпочитаю 2, по нескольким причинам

  1. Помещение conf в файл lombok.config, который определяет, что копируется, скрывает слишком много информации и, откровенно говоря, является просто несчастным случаем, ожидающим, когда кто-то увидит этот пример кода и попытается скопировать его, и это каким-то образом сработает, потому что столкновения не было.
  2. Он копирует только аннотации, для которых реализована возможность копирования, поэтому, если мы столкнемся с чем-то, что невозможно скопировать, мы в любом случае вернемся к реализации 2.
  3. Мне нравится 2-й вариант, так как он более выразительный, и мне нравится писать коды, которые более выразительны, так как в конечном итоге мы пишем их для людей, и лучше, если мы не будем скрывать слишком много вещей и будем делать все просто, чтобы человек, читающий код, мог больше сосредоточиться на бизнес-логике, а не тратить время на понимание того, почему или почему их внедрение не работает.

Оригинал: “https://dev.to/satylogin/playing-the-generator-game-2bk4”