"Поле требовало, чтобы тип компонента не был найден". ошибка весна restful API с использованием mongodb

Поэтому я изучаю Весну в парах недели, следуя этому руководству

Создание веб-службы RESTful

Все было хорошо, пока я не попытался интегрировать его в mongodb. Поэтому я следую этому руководству.

Доступ к данным с помощью MongoDB

Но моя практика частично все еще использует первый. Таким образом, структура моего проекта похожа на это.

src/
├── main/
│   └── java/
|       ├── model/
|       |   └── User.java
|       ├── rest/
|       |   ├── Application.java
|       |   ├── IndexController.java
|       |   └── UsersController.java
|       └── service/
|           └── UserService.java
└── resources/
    └── application.properties

Это мой файл model/User.java

package main.java.model;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

@Document(collection="user")
public class User {

    private int age;
    private String country; 
    @Id
    private String id;
    private String name;


    public User() {
        super();
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }
}

Это мой файл rest/UsersController.java

package main.java.rest;

import java.util.List;
import main.java.service.UserService;
import main.java.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping(value = "/users")
public class UsersController {

    @Autowired
    UserService userService;

    @RequestMapping(method = RequestMethod.GET)
    public List<User> getAllUsers() {
        return userService.findAll();
    }
}

Это мой сервис/UserService.java файл

package main.java.service;

import java.util.List;
import main.java.model.User;
import org.springframework.data.mongodb.repository.MongoRepository;

public interface UserService extends MongoRepository<User, String> {
    public List<User> findAll();
}

Я мог бы скомпилировать их (я использую gradle для компиляции, потому что я следую за учебником), но когда я запускаю файл jar, он выбрасывал эту ошибку.


ЗАЯВЛЕНИЕ НЕ ДОПУСКАЕТСЯ


Описание:

Поле userService в main.java.rest.UsersController требовало, чтобы компонент "main.java.service.UserService" не был найден.

Действие:

Рассмотрим конфигурацию компонента "main.java.service.UserService" в вашей конфигурации.

Не уверен, что не так. Я начинаю искать и обнаруживаю, что мне нужно включить файл Beans.xml и зарегистрировать в нем пользовательский сервис. Я сделал это, но он не работает. Я действительно новичок в этом, поэтому я действительно не знаю, что происходит.

Ответы

Ответ 1

Решил. Таким образом, по умолчанию будут проверены все пакеты, которые попадают под объявление @SpringBootApplication.

Предполагая, что мой основной класс ExampleApplication что @SpringBootApplication декларация объявленную внутри com.example.something, то все компоненты, которые попадают под com.example.something сканируется в то время как com.example.applicant не будет проверяться.

Итак, есть два способа сделать это на основе этого вопроса. использование

@SpringBootApplication(scanBasePackages={
"com.example.something", "com.example.application"})

Таким образом, приложение сканирует все указанные компоненты, но я думаю, что, если масштаб стал больше?

Поэтому я использую второй подход, реструктурируя свои пакеты, и это сработало! Теперь моя структура пакетов стала такой.

src/
├── main/
│   └── java/
|       ├── com.example/
|       |   └── Application.java
|       ├── com.example.model/
|       |   └── User.java
|       ├── com.example.controller/
|       |   ├── IndexController.java
|       |   └── UsersController.java
|       └── com.example.service/
|           └── UserService.java
└── resources/
    └── application.properties

Ответ 2

Добавьте @Service в службу /UserService.java.

Ответ 3

У меня также была такая же ошибка:

***************************
APPLICATION FAILED TO START
***************************

Description:

Field repository in com.kalsym.next.gen.campaign.controller.CampaignController required a bean of type 'com.kalsym.next.gen.campaign.data.CustomerRepository' that could not be found.


Action:

Consider defining a bean of type 'com.kalsym.next.gen.campaign.data.CustomerRepository' in your configuration.de here

И мои пакеты были построены так же, как указано в принятом ответе. Я исправил свою проблему, добавив аннотацию EnableMongoRepositories в основной класс следующим образом:

@SpringBootApplication
@EnableMongoRepositories(basePackageClasses = CustomerRepository.class)
public class CampaignAPI {

    public static void main(String[] args) {
        SpringApplication.run(CampaignAPI.class, args);
    }
}

Ответ 4

Я столкнулся с той же проблемой, и все, что мне нужно было сделать, это разместить приложение в пакете на один уровень выше, чем пакеты услуг, dao и domain.

Ответ 5

Эта тема старая, но я публикую свой ответ, который может быть полезен для других.

Я была такая же проблема. Оказалось, что есть другой класс с таким же именем в другом модуле. Я переименовал этот класс, и это решило проблему.

Ответ 6

Прошло много времени из-за авто-импорта. Intellij Idea somehy импортировала @Service из import org.jvnet.hk2.annotations.Service; вместо import org.springframework.stereotype.Service; !

Ответ 7

Добавьте @Component в свой класс контроллера. Пусть эта работа

Ответ 8

Обычно мы можем решить эту проблему в двух аспектах:

  1. собственно аннотацию следует использовать для загрузки Spring сканирования боб, как @Component;
  2. путь сканирования будет включать классы, как и все другие, упомянутые выше.

Кстати, есть очень хорошее объяснение различий между @Component, @Repository, @Service и @Controller.

Ответ 9

У меня та же проблема, исправленная добавлением @EnableMongoRepositories ("in.topthree.util")

package in.topthree.core;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;

import in.topthree.util.Student;

@SpringBootApplication
@EnableMongoRepositories("in.topthree.util")
public class Run implements CommandLineRunner {

    public static void main(String[] args) {
        SpringApplication.run(Run.class, args);
        System.out.println("Run");
    }

    @Autowired
    private Process pr;

    @Override
    public void run(String... args) throws Exception {
        pr.saveDB(new Student("Testing", "FB"));
        System.exit(0);
    }

}

И мой репозиторий:

package in.topthree.util;

import org.springframework.data.mongodb.repository.MongoRepository;

public interface StudentMongo extends MongoRepository<Student, Integer> {

    public Student findByUrl(String url);
}

Сейчас работает

Ответ 10

В моем случае я просто поместил класс MyprojectApplication в пакет (com.example.start) с тем же уровнем модели, контроллера, пакетов услуг.

Ответ 11

В моем случае я случайно определил abstract класс обслуживания при выполнении копирования и вставки.

@Serivce
@Valdiated
public abstract class MyService { // remove the abstract modifier!!!
}

Ответ 12

Мои классы реализации Mapper в моей целевой папке были удалены, поэтому в моих интерфейсах Mapper больше не было классов реализации. Таким образом, я получил ту же ошибку. Field *** required a bean of type ***Mapper that could not be found.

Я просто должен был восстановить мои mappers-реализации с помощью maven и обновить проект...

Ответ 13

Я пришел к этому сообщению в поисках помощи при использовании Spring Webflux с Mongo Repository.

Моя ошибка была похожа на владельца

Field usersRepository in foobar.UsersService required
a bean of type 'foobar.UsersRepository' that could not be found.

Поскольку раньше я работал с Spring MVC, я был удивлен этой ошибкой.

Поскольку поиск помощи не был так очевиден, я ставлю ответ на этот вопрос, поскольку он как-то связан, и этот вопрос высок в результатах поиска.

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

Вторым важным моментом является то, что если вы используете Webflux, вам нужно использовать какой-то другой пакет, а при использовании Spring MVC, например, для MongoDB, вам нужно добавить

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
</dependency>

с -reactive в конце.

Ответ 14

Использование всех аннотаций @решило мою проблему. (Да, я новичок в Spring) Если вы используете сервисный класс, добавьте @Service, и то же самое для @Controller и @Repository.

Затем эта аннотация на App.java устранила проблему (я использую JPA + Hibernate)

@SpringBootApplication
@EnableAutoConfiguration(exclude = { ErrorMvcAutoConfiguration.class })
@ComponentScan(basePackages = {"es.unileon.inso2"})
@EntityScan("es.unileon.inso2.model")
@EnableJpaRepositories("es.unileon.inso2.repository")

Пакетное дерево:

src/
├── main/
│   └── java/
|       ├── es.unileon.inso2/
|       |   └── App.java
|       ├── es.unileon.inso2.model/
|       |   └── User.java
|       ├── es.unileon.inso2.controller/
|       |   ├── IndexController.java
|       |   └── UserController.java
|       ├── es.unileon.inso2.service/
|       |    └── UserService.java
|       └── es.unileon.inso2.repository/
|            └── UserRepository.java
└── resources/
    └── application.properties

Ответ 15

С помощью этого решена моя проблема.

@SpringBootApplication(scanBasePackages={"com.example.something", "com.example.application"})

Ответ 16

Это может произойти, когда два компонента имеют одинаковые имена.

Module1Beans.java:

@Configuration
public class Module1Beans {
    @Bean
    public GoogleAPI retrofitService(){
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://www.google.com/")
                .addConverterFactory(JacksonConverterFactory.create())
                .build();
        return retrofit.create(GoogleAPI.class);
    }
}

Module2Beans.java:

@Configuration
public class Module2Beans {
    @Bean
    public GithubAPI retrofitService(){
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://www.github.com/")
                .addConverterFactory(JacksonConverterFactory.create())
                .build();
        return retrofit.create(GithubAPI.class);
    }
}

Боба имени retrofitService сначала создается, и тип GoogleAPI, затем покрывается GithubAPI becauce они оба созданы в retrofitService() метод. Теперь, когда вы @Autowired GoogleAPI вы получите сообщение, подобное Field googleAPI in com.example.GoogleService required a bean of type 'com.example.rest.GoogleAPI' that could not be found.