Объясните, как работает @service в Spring

Я слежу за своим учителем, но меня немного смущает. Это интерфейс, расширяющий CrudRepository из данных Spring

import org.springframework.data.repository.CrudRepository;
public interface TaskRepository extends CrudRepository<Task,Integer>{

}

и это класс Service, использующий этот интерфейс:

@Service
@Transactional
public class TaskService {

private final TaskRepository taskRepository;

public TaskService(TaskRepository taskRepository) {
    this.taskRepository = taskRepository;
}


public List<Task> findAll(){

    List<Task> tasks = new ArrayList<>();
    for(Task task : taskRepository.findAll()) {
        tasks.add(task);
    }

    return tasks;
}
}

Я запутался, когда контроллер хочет использовать экземпляр TaskService. Он просто объявляет так:

@Autowired
private TaskService taskService;

Кто может мне объяснить, как это работает? Инициализация TaskService имеет в качестве аргумента TaskRepository. но я не нахожу где init TaskRepository

Это приложение для загрузки Spring? У вас есть какой-нибудь конфигурационный файл / класс?

gWombat 13.03.2018 14:41
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Версия Java на основе версии загрузки
Версия Java на основе версии загрузки
Если вы зайдете на официальный сайт Spring Boot , там представлен start.spring.io , который упрощает создание проектов Spring Boot, как показано ниже.
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
1
1
106
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

В вашем примере вы можете опустить @Autowired для своего конструктора, потому что ваша служба имеет только один конструктор.

JPA Repositoriy, TaskRepository будет автоматически инициализирован при весенней загрузке.

Начиная с Spring Boot 1.5.7, аннотировать конструктор с помощью @Autowire не требуется.

Yogesh Badke 13.03.2018 15:09

да, если конструктор только один, его можно опустить.

shan 13.03.2018 15:13

Spring boot автоматически инициализирует интерфейсы JPA Repositoriy, если они найдены.

By default, Spring Boot will enable JPA repository support and look in the package (and its subpackages) where @SpringBootApplication is located. If your configuration has JPA repository interface definitions located in a package not visible, you can point out alternate packages using @EnableJpaRepositories and its type-safe basePackageClasses=MyRepository.class parameter.

https://spring.io/guides/gs/accessing-data-jpa/

Кроме того, начиная с Spring Framework 4.3, если есть единственный конструктор, будет предпринята попытка автоматического подключения.

https://spring.io/blog/2016/03/04/core-container-refinements-in-spring-framework-4-3

Я понял. Спасибо. Плохо, я еще не изучил JPA. Просто следую за своим учителем. :П

Huy Phạm 13.03.2018 16:51
Ответ принят как подходящий

Как только вы помечаете свой класс @Component или любым его вариантом, например @Service / @Repository / @Controller, вы делегируете его управление объектами Spring.

При выполнении

@Autowired
private TaskService taskService;

вы говорите Spring, что при создании объекта контроллера сначала создайте объект TaskService и назначьте его переменной taskService, объявленной в контроллере.

Затем spring попытается создать объект TaskService, но при создании видит конструктор

public TaskService(TaskRepository taskRepository) {
    this.taskRepository = taskRepository;
}

Итак, теперь он попытается создать объект TaskRepository, потому что без этого объект TaskService не может быть создан.

Теперь TaskRepository - это интерфейс, расширяющий CrudRepository, и интерфейсы не могут быть созданы. Spring создает прокси, реализующий TaskRepository, создает объект и внедряет его в taskRepository конструктора TaskService.

Пока что spring построила объекты TaskRepository, TaskService. Он просто вставит объект TaskService в автоматически подключенную переменную taskService контроллера.

Другие вопросы по теме