В чем разница между использованием аннотации с автоматическим подключением и использованием закрытого финала для репозитория на уровне сервиса? - PullRequest
0 голосов
/ 05 августа 2020

Я видел учебники, в которых sh используется другой синтаксис для выполнения одного и того же. После того, как запрос POST для создания объекта студента поступает через контроллер, уровень обслуживания внедряет репозиторий с помощью этих двух методов.

метод 1:

@Service
@AllArgsConstructor
@Transactional
public class StudentService {
    private final StudentRepository studentRepo;
    // complete service code using studentRepo
}

Также как метод 2:

@Service
public class StudentService {
    @Autowire
    private StudentRepository studentRepo;
    // complete service code using studentRepo
}

Я читал, что это как-то связано с конструктором и внедрением полей, но я серьезно не понимаю, как этот синтаксис устраняет разницу. Какие-нибудь объяснения или ресурсы для лучшего понимания? Заранее спасибо!

Ответы [ 2 ]

2 голосов
/ 05 августа 2020

Вы складываете множество фреймворков, что вносит путаницу. Путаница, вероятно, связана с тем, что вы используете Lombok. @AllArgsConstructor автоматически добавляет конструктор со всеми аргументами, необходимыми для создания экземпляра службы.

@AllArgsConstructor создает конструктор с 1 параметром для каждого поля в вашем класс. Поля, отмеченные @NonNull, приводят к нулевым проверкам этих параметров. - Источник: Документация Lombok

Использование @AllArgsConstructor эффективно генерирует следующий класс

@Service
@Transactional
public class StudentService {

    private final StudentRepository studentRepo;

    public StudentService(StudentRepository studentRepo) {
        this.studentRepo=studentRepo;
    }
    // complete service code using studentRepo
}

Теперь, поскольку этот класс имеет только один конструктор, Spring будет использовать его для внедрения зависимостей. . Это называется инъекцией зависимостей на основе конструктора.

@Service
@Transactional
public class StudentService {
    @Autowire
    private StudentRepository studentRepo;
    // complete service code using studentRepo
}

В то время как это называется инъекцией зависимостей на основе поля.

ИМХО, вам следует предпочесть инъекцию зависимостей на основе конструктора по простой причине, что это очень легко использовать и прямо в лицо. Вы можете легко протестировать его, пока с инъекцией поля писать модульный тест сложно (э-э), так как вам нужно отражение, чтобы ввести поле.

См. Также Внедрение зависимостей в Java для получения дополнительной информации подробное объяснение различных стилей внедрения зависимостей.

0 голосов
/ 05 августа 2020

Внедрение зависимостей может быть достигнуто разными способами. Вот два способа, о которых вы говорите и, вероятно, не совсем понимаете:

  1. Внедрение поля :
@Service
public class StudentService {
  @Autowired
  private StudentRepository studentRepo;
   // complete service code using studentRepo
}
Конструктор DI :
@Service
//@AllArgsConstructor <-- commenting this for now. Probably your source of confusion
@Transactional
public class StudentService {
    private final StudentRepository studentRepo;

     // For Spring Boot 1.4 and above, using @Autowired on constructor is optional
     // Dependency being injected through constructor
    public StudentService(StudentRepository studentRepo) {
             this.studentRepo = studentRepo;
    }
     // complete service code using studentRepo
}

Теперь, если вы поместите @AllArgsConstructor (аннотацию из проекта lombok ), то constructor будет сгенерирован со всеми полями членов для вас в файле .class, и будет иметь место требуемый DI.

...