Почему для этого веб-приложения Spring Boot не требуется @Repository?

Я изучаю 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;
}
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
6
0
2 026
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

@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.

Речь идет о @org.springframework.stereotype.Repositoryаннотация, а не об интерфейсе org.springframework.data.repository.Repository

Lu55 08.06.2020 18:09

Вопрос @ Lu55 OP: «Почему нет необходимости помещать @Repository или @Component в класс AlienRepo», и я объяснил, почему Spring может делать это автоматически (автоматическая регистрация субинтерфейса Repository / CrudRepository через @EnableJpaRepositories). И, честно говоря, я даже не знаю, почему принят приведенный выше ответ, лол

Mạnh Quyết Nguyễn 09.06.2020 04:37

Ваш класс 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 не является обязательным?

elvis 20.08.2018 10:37

Рад помочь, Элвис! Я обновил свой ответ, надеюсь, он снова поможет.

Muhammed Ozdogan 20.08.2018 15:18

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