Я изучаю Spring Boot и JPA, Spring Data Rest, базу данных H2, и я нашел руководство. Я пытаюсь понять это, это простой пример, но я чего-то не понимаю. Почему не обязательно помещать @Repository или @Component в класс AlienRepo?
Объект репо вводится в класс AlienController, и из предыдущих руководств я знаю, что вам нужно использовать @Component или @Repository. Я думал, что обязательно использовать эту аннотацию.
Контроллер:
package com.dgs.springbootjpa.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.dgs.springbootjpa.dao.AlienRepo;
import com.dgs.springbootjpa.model.Alien;
@Controller
public class AlienController {
@Autowired
AlienRepo repo;
@RequestMapping("/")
public String home() {
return "home.jsp";
}
@RequestMapping("/addAlien")
public String addAlien(Alien alien) {
repo.save(alien);
return "home.jsp";
}
}
POJO:
package com.dgs.springbootjpa.model;
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class Alien {
@Id
private int aid;
private String aname;
public int getAid() {
return aid;
}
public void setAid(int aid) {
this.aid = aid;
}
public String getAname() {
return aname;
}
public void setAname(String aname) {
this.aname = aname;
}
@Override
public String toString() {
return "Alien [aid = " + aid + ", aname = " + aname + "]";
}
}
Интерфейс dao:
package com.dgs.springbootjpa.dao;
import org.springframework.data.repository.CrudRepository;
import com.dgs.springbootjpa.model.Alien;
public interface AlienRepo extends CrudRepository<Alien, Integer> {
}
Вы можете видеть, что в интерфейсе AlienRepo нет @Repository или @Component и код работает успешно.
Спасибо!
Обновлять---------------------------------------------
Я хочу получить данные из базы данных и добавляю приведенный ниже код. Я хочу спросить вас, почему @RequestParam не является обязательным? Если я удалю @RequestParam, приложение будет работать успешно.
@RequestMapping("/getAlien")
public ModelAndView addAlien(@RequestParam int aid) {
ModelAndView mv = new ModelAndView("showAlien");
Alien alien = repo.findById(aid).orElse(new Alien());
mv.addObject(alien);
return mv;
}




@Component и @Repository можно использовать в классах, чтобы использовать их в качестве Spring Beans. Однако AlienRepo - это не класс, это интерфейс, расширяющий интерфейс Spring Data. Spring Data не использует аннотации, он обнаруживает интерфейсы, сканируя путь к классам и просматривая иерархию интерфейсов, чтобы увидеть, расширен ли интерфейс Spring Data. В этом случае он создает реализацию для каждого интерфейса во время выполнения, которая затем добавляется в контекст приложения как Spring Bean. Вот почему вам не нужны аннотации в интерфейсе Spring Data.
Ваш @SpringBootApplication обеспечивает эффект аннотации @EnableAutoConfiguration:
@EnableAutoConfiguration
public @interface SpringBootApplication
Эта аннотация будет угадывать и автоматически настраивать bean-компоненты.
Auto-configuration for Spring Data's JPA Repositories. Activates when there is a bean of type DataSource configured in the context, the Spring Data JPA JpaRepository type is on the classpath, and there is no other, existing JpaRepository configured.
Once in effect, the auto-configuration is the equivalent of enabling JPA repositories using the EnableJpaRepositories annotation.
This configuration class will activate after the Hibernate auto-configuration.
public class JpaRepositoriesAutoConfiguration {
}
Когда вы добавляете зависимость data-jpa, срабатывает JpaRepositoriesAutoConfiguration и приводит к эффекту аннотации @EnableJpaRepositories в вашем приложении.
Затем ваш репозиторий настроен автоматически:
Spring Data repositories usually extend from the Repository or CrudRepository interfaces. If you use auto-configuration, repositories are searched from the package containing your main configuration class (the one annotated with @EnableAutoConfiguration or @SpringBootApplication) down.
Вопрос @ Lu55 OP: «Почему нет необходимости помещать @Repository или @Component в класс AlienRepo», и я объяснил, почему Spring может делать это автоматически (автоматическая регистрация субинтерфейса Repository / CrudRepository через @EnableJpaRepositories). И, честно говоря, я даже не знаю, почему принят приведенный выше ответ, лол
Ваш класс AlienRepo расширяет CrudRepository, поэтому Spring сможет просматривать пакеты, указанные в конфигурации, и находить репозитории.
В качестве примечания, вы можете отказаться от @Autowired, если существует ровно один конструктор AlienController(AlienRepo), Spring тоже может это выяснить.
Вы заметили, что CrudRepository имеет аннотацию @NoRepositoryBean, и эта аннотация делает CrudRepository промежуточным интерфейсом. Промежуточный интерфейс в основном добавляет общие функциональные возможности для производных репозиториев.
Если какой-либо класс, аннотированный с помощью @NoRepositoryBean Spring Data, не создает экземпляров во время выполнения. Потому что это промежуточный класс, и он создан для добавления функциональности производному классу.
Если вы расширяете интерфейс с @NoRepositoryBean, а в производном интерфейсе нет @NoRepositoryBean, Spring знает, что вы пытаетесь использовать эту функциональность в своем реальном интерфейсе репозитория, поэтому добавление аннотации @ Репозиторий будет многословным.
Обновлено: почему @RequestParam не является обязательным?
Из официальная документация вы можете увидеть таблицу «Аргумент метода контроллера», последняя строка таблицы говорит:
Любой другой аргумент:
If a method argument is not matched to any of the above, by default it is resolved as an @RequestParam if it is a simple type, as determined by BeanUtils#isSimpleProperty, or as an @ModelAttribute otherwise.
Поэтому, если вы опускаете аннотацию для «Аргумента метода контроллера» и не пишете что-то вроде @MatrixVariable, @PathVariable или @RequestParam.
По умолчанию это @RequestParam.
Я очень благодарен вам за помощь! Не могли бы вы помочь мне с обновлением? Почему @RequestParam не является обязательным?
Рад помочь, Элвис! Я обновил свой ответ, надеюсь, он снова поможет.
Речь идет о
@org.springframework.stereotype.Repositoryаннотация, а не об интерфейсеorg.springframework.data.repository.Repository