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:
@Component
; 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"})