Java “字段需要一个无法找到的类型的 bean。” 使用mongodb的错误spring restful API

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/42907553/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 00:30:32  来源:igfitidea点击:

'Field required a bean of type that could not be found.' error spring restful API using mongodb

javaspringmongodbrest

提问by Eka Rudianto

So I've been learning Spring in the couples of week, been following this tutorial

所以我在几周内一直在学习 Spring,一直在关注本教程

Building a RESTful Web Service

构建 RESTful Web 服务

All was well until I tried to integrate it to mongodb. So I follow this tutorial.

一切都很好,直到我尝试将它集成到 mongodb。所以我按照这个教程。

Accessing Data with MongoDB

使用 MongoDB 访问数据

But my practice is partially still using the first one. So my project directory structure is like this.

但我的实践部分仍在使用第一个。所以我的项目目录结构是这样的。

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

This is my model/User.javafile

这是我的模型/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;
    }
}

This is my rest/UsersController.javafile

这是我的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();
    }
}

This is my service/UserService.javafile

这是我的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<User, String> {
    public List<User> findAll();
}

I could compile them (I'm using gradle for compilation because I'm following the tutorial), but when I run the jar file it was throwing this error.

我可以编译它们(我正在使用 gradle 进行编译,因为我正在学习教程),但是当我运行 jar 文件时,它抛出了这个错误。


APPLICATION FAILED TO START


Description:

Field userService in main.java.rest.UsersController required a bean of type 'main.java.service.UserService' that could not be found.

Action:

Consider defining a bean of type 'main.java.service.UserService' in your configuration.


应用程序无法启动


描述:

main.java.rest.UsersController 中的字段 userService 需要一个无法找到的“main.java.service.UserService”类型的 bean。

行动:

考虑在您的配置中定义一个类型为“main.java.service.UserService”的 bean。

Not sure what is wrong I start googling around and found that I need to include Beans.xmlfile and register the userService in it. I did that but it's not working. I'm really new to this so I really have no clue on what's going on.

不知道出了什么问题,我开始在谷歌上搜索,发现我需要包含Beans.xml文件并在其中注册 userService。我这样做了,但它不起作用。我真的很陌生,所以我真的不知道发生了什么。

采纳答案by Eka Rudianto

Solved it. So by default, all packages that falls under @SpringBootApplicationdeclaration will be scanned.

解决了。所以默认情况下,所有属于@SpringBootApplication声明的包都将被扫描。

Assuming my main class ExampleApplicationthat has @SpringBootApplicationdeclaration is declared inside com.example.something, then all components that falls under com.example.somethingis scanned while com.example.applicantwill not be scanned.

假设我的主类ExampleApplication具有@SpringBootApplication声明声明里面com.example.something,那么落在下的所有组件com.example.something进行扫描,而com.example.applicant不会被扫描。

So, there are two ways to do it based on this question. Use

所以,基于这个问题,有两种方法可以做到。用

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

That way, the application will scan all the specified components, but I think what if the scale were getting bigger ?

这样,应用程序将扫描所有指定的组件,但我想如果规模越来越大怎么办?

So I use the second approach, by restructuring my packages and it worked ! Now my packages structure became like this.

所以我使用第二种方法,通过重组我的包,它奏效了!现在我的包结构变成了这样。

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

回答by dzzxjl

Add the @Servicein the service/UserService.java.

@Service在服务/UserService.java 中添加。

回答by Vitali Kuzmin

Spent a lot of time because of the auto-import. Intellij Idea somewhy imported @Servicefrom import org.jvnet.hk2.annotations.Service;instead of import org.springframework.stereotype.Service;!

由于自动导入而花费了大量时间。Intellij Idea 为什么@Service从而import org.jvnet.hk2.annotations.Service;不是从import org.springframework.stereotype.Service;!

回答by shabby

I also had the same 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

And my packages were constructed in the same way as mentioned in the accepted answer. I fixed my issue by adding EnableMongoRepositories annotation in the main class like this:

我的包的构建方式与接受的答案中提到的方式相同。我通过在主类中添加 EnableMongoRepositories 注释来解决我的问题,如下所示:

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

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

If you need to add multiple don't forget the curly braces:

如果您需要添加多个不要忘记花括号:

@EnableMongoRepositories(basePackageClasses
    = {
        MSASMSRepository.class, APartyMappingRepository.class
    })

回答by shubham bansal

Add the @Component in your controller class. May this work

在控制器类中添加@Component。愿这项工作

回答by Ahmad

I have same Issue, fixed by Adding @EnableMongoRepositories("in.topthree.util")

我有同样的问题,通过添加 @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);
    }

}

And my Repository is:

我的存储库是:

package in.topthree.util;

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

public interface StudentMongo extends MongoRepository<Student, Integer> {

    public Student findByUrl(String url);
}

Now Its Working

现在它的工作

回答by Akash Yellappa

I encountered the same issue and all I had to do was to place the Application in a package one level higher than the service, dao and domain packages.

我遇到了同样的问题,我所要做的就是将应用程序放在比 service、dao 和 domain 包高一级的包中。

回答by Hearen

Normally we can solve this problem in two aspects:

通常我们可以从两个方面来解决这个问题:

  1. proper annotation should be used for Spring Bootscanning the bean, like @Component;
  2. the scanningpath will include the classes just as all others mentioned above.
  1. Spring Boot扫描bean时应使用适当的注释,例如@Component
  2. 扫描路径包括,就像所有其他上面提到的类。

By the way, there is a very good explanation for the difference among @Component, @Repository, @Service, and @Controller.

顺便说一句,对于@Component、@Repository、@Service 和@Controller之间的区别,有一个很好的解释。

回答by Anand

Using this solved my issue.

使用这个解决了我的问题。

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

回答by benymor

This may happen when two beans have same names.

当两个 bean 具有相同的名称时,可能会发生这种情况。

Module1Beans.java

Module1Beans.java

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

Module2Beans.java

Module2Beans.java

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

A bean named retrofitServiceis first created, and it's type is GoogleAPI, then covered by a GithubAPIbecauce they're both created by a retrofitService()method. Now when you @Autowireda GoogleAPIyou'll get a message like Field googleAPI in com.example.GoogleService required a bean of type 'com.example.rest.GoogleAPI' that could not be found.

retrofitService首先创建一个名为 bean 的 bean ,它的类型是GoogleAPI,然后被GithubAPI一个retrofitService()方法覆盖,因为它们都是由一个方法创建的。现在当你@AutowiredaGoogleAPI你会收到一条消息Field googleAPI in com.example.GoogleService required a bean of type 'com.example.rest.GoogleAPI' that could not be found.