Я слежу за своим учителем, но меня немного смущает. Это интерфейс, расширяющий 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




В вашем примере вы можете опустить @Autowired для своего конструктора, потому что ваша служба имеет только один конструктор.
JPA Repositoriy, TaskRepository будет автоматически инициализирован при весенней загрузке.
Начиная с Spring Boot 1.5.7, аннотировать конструктор с помощью @Autowire не требуется.
да, если конструктор только один, его можно опустить.
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. Просто следую за своим учителем. :П
Как только вы помечаете свой класс @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 контроллера.
Это приложение для загрузки Spring? У вас есть какой-нибудь конфигурационный файл / класс?