Как получить функциональность @Autowired JpaRepository по его классу

В моем весеннем загрузочном приложении у меня есть репозиторий класса, который можно найти по имени класса.

Class<?> repo = Class.forName("com.example.demo.repository." + modelName + "Repository");

где modelName является строкой.

repo.toString() возвращает

interface com.example.demo.repository.LaptopRepository

Я хочу иметь возможность использовать методы LaptopRepository.findAll(). Я точно не знаю, какое название модели у меня будет. Поэтому я не мог использовать аннотацию @Autowired вне метода.

Вместо этого я хочу использовать LaptopRepository внутри метода, который принимает атрибут modelName.

@GetMapping("/administration")
public String getModelInstances(@RequestParam("modelName")String modelName, Model model) throws ClassNotFoundException {
    Class<?> repo = Class.forName("com.example.demo.repository." + modelName + "Repository");

    // @Autowired
    // repo repoRepository;

    model.addAttribute("objects", repoRepositories.findAll());
    return "administration";
}

почему вы используете отражение, чтобы получить этот bean?

Almas Abdrazak 07.04.2019 12:58

Я не уверен, что findAll сработает при смешивании отражения и JpaRepository

Andronicus 07.04.2019 12:59

Используйте метод getBean() контекста Spring. Но будьте осторожны: это огромная дыра в безопасности: вы, по сути, позволяете любому вызывать findAll() в любом из ваших репозиториев, что потенциально дает доступ к конфиденциальной информации или просто приводит к сбою вашего сервера из-за большого количества сущностей, которые будут загружены в память. По крайней мере, вам нужно проверить, входит ли представленная модель в четко определенный список допустимых значений.

JB Nizet 07.04.2019 13:03
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
3
93
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Просто используйте контекст приложения Sping, чтобы получить желаемый компонент репозитория по его типу.

1) Контекст Autowire в вашем контроллере

@Autowired
private ApplicationContext appContext;

2) Используйте его в своем методе

appContext.getBean(Class.forName("com.example.demo.repository." + modelName + "Repository"));

Но как я могу получить доступ к методу findAll(). Я хочу автоматически подключить репозиторий внутри метода, потому что я заранее не знаю, какой JpaRepository я буду использовать (имя используемого репозитория я получаю из браузера в формате String).

Bekzhan Satarov 07.04.2019 13:22

Просто приведите bean-компонент к интерфейсу JPARepository

Dmitry Margolis 07.04.2019 13:23

В основном лучше использовать некоторое перечисление для доступного имени модели, потому что в вашем подходе пользователь может получить любую незащищенную таблицу.

Dmitry Margolis 07.04.2019 13:25

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