‘Field requirió un bean de tipo que no se pudo encontrar’. Error Spring restful API con mongodb

Así que he estado aprendiendo Primavera en las parejas de la semana, siguiendo este tutorial

Construyendo un servicio web RESTful

Todo estuvo bien hasta que traté de integrarlo a mongodb. Entonces sigo este tutorial

Accediendo a los datos con MongoDB

Pero mi práctica todavía está usando parcialmente la primera. Entonces mi estructura de directorio de proyecto es así.

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

Este es mi archivo de modelo / 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; } } 

Este es mi archivo de descanso / 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 getAllUsers() { return userService.findAll(); } } 

Este es mi archivo service / 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 { public List findAll(); } 

Pude comstackrlos (estoy usando gradle para comstackción porque sigo el tutorial), pero cuando ejecuté el archivo jar estaba arrojando este error.


LA APLICACIÓN NO PUEDE INICIAR


Descripción:

Field userService en main.java.rest.UsersController requirió un bean de tipo ‘main.java.service.UserService’ que no se pudo encontrar.

Acción:

Considere la posibilidad de definir un bean de tipo ‘main.java.service.UserService’ en su configuración.

No estoy seguro de qué está mal. Empiezo a buscar en Google y descubrí que necesito incluir el archivo Beans.xml y registrar el userService en él. Lo hice pero no está funcionando. Soy realmente nuevo en esto, así que realmente no tengo ni idea de lo que está pasando.

Resuelto. Por lo tanto, de forma predeterminada, se @SpringBootApplication todos los paquetes @SpringBootApplication statement @SpringBootApplication .

Suponiendo que mi clase principal ExampleApplication que tiene la statement @SpringBootApplication se declara dentro de com.example.something , todos los componentes que se com.example.something en com.example.something se escanean mientras que com.example.applicant no se analizará.

Entonces, hay dos formas de hacerlo en base a esta pregunta . Utilizar

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

De esa forma, la aplicación escaneará todos los componentes especificados, pero creo que ¿qué pasaría si la báscula fuera cada vez más grande?

¡Así que uso el segundo enfoque, reestructurando mis paquetes y funcionó! Ahora mi estructura de paquetes se volvió así.

 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 

Agregue @Service en el servicio / UserService.java.

También tuve el mismo error:

 *************************** 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 

Y mis paquetes fueron construidos de la misma manera que se menciona en la respuesta aceptada. Solucioné mi problema agregando la anotación EnableMongoRepositories en la clase principal como esta:

 @SpringBootApplication @EnableMongoRepositories(basePackageClasses = CustomerRepository.class) public class CampaignAPI { public static void main(String[] args) { SpringApplication.run(CampaignAPI.class, args); } } 

Encontré el mismo problema y todo lo que tuve que hacer fue colocar la aplicación en un paquete un nivel más alto que el servicio, el dao y los paquetes de dominio.

Pasé mucho tiempo debido a la importación automática. Intellij Idea por qué importó @Service desde la import org.jvnet.hk2.annotations.Service; en lugar de import org.springframework.stereotype.Service; !

Agregue el @Component en su clase de controlador. Que esto funcione

Normalmente podemos resolver este problema en dos aspectos:

  1. la anotación adecuada debe usarse para Spring Boot escaneando el bean , como @Component ;
  2. la ruta de exploración incluirá las clases como todas las demás mencionadas anteriormente.

Por cierto, hay una muy buena explicación para la diferencia entre @Component, @Repository, @Service y @Controller .

Tengo el mismo problema, solucionado al agregar @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); } } 

Y mi repository

  package in.topthree.util; import org.springframework.data.mongodb.repository.MongoRepository; public interface StudentMongo extends MongoRepository { public Student findByUrl(String url); } 

Ahora funciona

En mi caso acabo de poner la clase MyprojectApplication en un paquete (com.example.start) con el mismo nivel de modelo, controlador, paquetes de servicio.

Esto puede suceder cuando dos granos tienen los mismos nombres.

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); } } 

Primero se crea un bean llamado retrofitService , y su tipo es GoogleAPI , luego cubierto por GithubAPI porque ambos son creados por un método retrofitService() . Ahora cuando @Autowired a GoogleAPI recibirá un mensaje como Field googleAPI in com.example.GoogleService required a bean of type 'com.example.rest.GoogleAPI' that could not be found.

Usando esto resolvió mi problema.

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