考虑在配置中定义一个'package'类型的bean [Spring-Boot]

Dre*_*208 78 java spring-boot

我收到以下错误:

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

Description:

Parameter 0 of method setApplicant in webService.controller.RequestController required a bean of type 'com.service.applicant.Applicant' that could not be found.


Action:

Consider defining a bean of type 'com.service.applicant.Applicant' in your configuration.
Run Code Online (Sandbox Code Playgroud)

我之前从未见过这个错误,但@Autowire无法正常工作,这很奇怪.这是项目结构:

申请人界面

public interface Applicant {

    TApplicant findBySSN(String ssn) throws ServletException;

    void deleteByssn(String ssn) throws ServletException;

    void createApplicant(TApplicant tApplicant) throws ServletException;

    void updateApplicant(TApplicant tApplicant) throws ServletException;

    List<TApplicant> getAllApplicants() throws ServletException;
}
Run Code Online (Sandbox Code Playgroud)

ApplicantImpl

@Service
@Transactional
public class ApplicantImpl implements Applicant {

private static Log log = LogFactory.getLog(ApplicantImpl.class);

    private TApplicantRepository applicantRepo;

@Override
    public List<TApplicant> getAllApplicants() throws ServletException {

        List<TApplicant> applicantList = applicantRepo.findAll();

        return applicantList;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我应该可以只使用Autowire Applicant并且能够访问,但是在这种情况下,当我在我的电话中调用它时它无法正常工作 @RestController:

@RestController
public class RequestController extends LoggingAware {

    private Applicant applicant;

    @Autowired
    public void setApplicant(Applicant applicant){
        this.applicant = applicant;
    }

    @RequestMapping(value="/", method = RequestMethod.GET)
    public String helloWorld() {

        try {
            List<TApplicant> applicantList = applicant.getAllApplicants();

            for (TApplicant tApplicant : applicantList){
                System.out.println("Name: "+tApplicant.getIndivName()+" SSN "+tApplicant.getIndSsn());
            }

            return "home";
        }
        catch (ServletException e) {
            e.printStackTrace();
        }

        return "error";
    }

}
Run Code Online (Sandbox Code Playgroud)

------------------------ UPDATE 1 -----------------------

我补充道

@SpringBootApplication
@ComponentScan("module-service")
public class WebServiceApplication extends SpringBootServletInitializer {

    @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(WebServiceApplication.class);
    }

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

}
Run Code Online (Sandbox Code Playgroud)

而错误消失但没有任何反应.但是当我ApplicantRestController添加之前注释掉所有处理的东西时,我@ComponentScan()能够返回一个字符串UI,这意味着我RestController正在工作,现在它被跳过了.我Whitelabel Error Page现在很难看

---------------------更新2 --------------------------- ---

我添加了它抱怨的bean的基本包.错误读取:

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

Description:

Parameter 0 of method setApplicantRepo in com.service.applicant.ApplicantImpl required a bean of type 'com.delivery.service.request.repository.TApplicantRepository' that could not be found.


Action:

Consider defining a bean of type 'com.delivery.request.request.repository.TApplicantRepository' in your configuration.
Run Code Online (Sandbox Code Playgroud)

我补充道 @ComponentScan

@SpringBootApplication
@ComponentScan({"com.delivery.service","com.delivery.request"})
public class WebServiceApplication extends SpringBootServletInitializer {

    @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(WebServiceApplication.class);
    }

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

}
Run Code Online (Sandbox Code Playgroud)

---------------------------- Update 3 -------------------- -

添加:

@SpringBootApplication
@ComponentScan("com")
public class WebServiceApplication extends SpringBootServletInitializer {
Run Code Online (Sandbox Code Playgroud)

还在抱怨我的ApplicantImpl课程,@Autowires我的回复TApplicantRepository.

Dre*_*208 156

这可能是因为该项目已被分解为不同的模块.

@SpringBootApplication
@ComponentScan({"com.delivery.request"})
@EntityScan("com.delivery.domain")
@EnableJpaRepositories("com.delivery.repository")
public class WebServiceApplication extends SpringBootServletInitializer {
Run Code Online (Sandbox Code Playgroud)

  • 是的,这是因为该项目已分解为不同的模块。`@EntityScan` 和 `@EnableJpaRepositories` 具有正确的包名称对我有用。 (4认同)
  • 凉.我的项目被许多模块分开.ComponentScan解决了我的问题! (3认同)
  • 此解决方案帮助我解决了 2.0.4 版中的此错误 (2认同)

Ame*_*n.M 42

您的申请人类似乎没有扫描.默认情况下,@SpringBootApplication将扫描以root开头的所有包作为您放置的类.

假设您的main类"WebServiceApplication"在" com.service.something"中,则com.service.something扫描所有属于" "的组件,并且com.service.applicant不扫描" ".

您可以重新构建包,使"WebServiceApplication"属于根包,所有其他组件都成为该根包的一部分.或者您可以包含@SpringBootApplication(scanBasePackages={"com.service.something","com.service.application"})等,以便在弹簧容器中扫描和初始化"所有"组件.

根据评论更新

如果您有多个由maven/gradle管理的模块,则所有弹簧需求都是要扫描的包.你告诉spring扫描"com.module1",你有另一个模块,其根包名为"com.module2",这些组件不会被扫描.您甚至可以告诉spring扫描"com",然后扫描" com.module1."和" com.module2."中的所有组件


Cod*_*rld 31

有机会的话......
你可能会丢失@Service,@Repository标注上你们各自的实现类.

  • 这应该是公认的答案,简单明了。谢谢。 (2认同)
  • 是的,这应该是答案。上面的答案只是假设扫描失败,这是错误的。 (2认同)
  • 完美,谢谢!我正在阅读一些教程来创建 REST api,它们使用服务来实现各种功能,但没有一个教程用 `@Service` 注释接口。如果其他人也遇到同样的问题,这里有一个解决方案! (2认同)

小智 18

基本上,当您将类应用程序放在"另一个包"中时会发生这种情况.例如:

com.server
 - Applicacion.class (<--this class have @ComponentScan)
com.server.config
 - MongoConfig.class 
com.server.repository
 - UserRepository
Run Code Online (Sandbox Code Playgroud)

我在Application.class中解决了这个问题

@SpringBootApplication
@ComponentScan ({"com.server", "com.server.config"})
@EnableMongoRepositories ("com.server.repository") // this fix the problem
Run Code Online (Sandbox Code Playgroud)

另一个不太优雅的方法是:将所有配置类放在同一个包中.

  • 事实上,您不需要在上述场景中指定 `@ComponentScan`。因为您的“Application.class”(带有“@SpringBootApplication”注释)被放置在“com.server”中,它无论如何都是“com.server.config”和“com.server.repository”的根。 (4认同)

小智 10

如果 bean 与 @Autowired 位于同一个包中,则永远不会导致此类问题。但是,默认情况下无法从不同的包访问 bean。要解决此问题,请执行以下步骤:

  1. 在您的主类中导入以下内容:
    import org.springframework.context.annotation.ComponentScan;
  2. 在主类上添加注释:
@ComponentScan(basePackages = {"your.company.domain.package"})
public class SpringExampleApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringExampleApplication.class, args);
    }
}
Run Code Online (Sandbox Code Playgroud)


eri*_*egz 10

重要的:

对于任何通过谷歌搜索通用 bean 错误消息来到这里,但实际上试图通过客户端接口上的注释将假客户端添加到其 Spring Boot 应用程序的人@FeignClient来说,上述解决方案都不适合您。

要解决此问题,您需要将@EnableFeignClients注释添加到您的 Application 类中,如下所示:

@SpringBootApplication
// ... (other pre-existing annotations) ...
@EnableFeignClients // <------- THE IMPORTANT ONE
public class Application {
Run Code Online (Sandbox Code Playgroud)

旁注:添加@ComponentScan(...)under@SpringBootApplication 是多余的,您的 IDE 应该将其标记为这样(至少 IntelliJ IDEA 是这样做的)。

  • 谢谢,这正是我遇到的 @FeignClient 未得到识别的问题。但添加 EnableFeignClients 解决了问题。谢谢! (3认同)

Daw*_*yca 6

如果您使用 Lombok 并且添加了@RequiredArgsConstructor@NonNullfor 字段,但某些字段不会注入到构造函数中,也可能会发生这种情况。这只是出现相同错误的可能性之一。

参数 0 需要类型为 MissingBeanName 的 bean,但无法找到

就我而言,错误告诉我问题出在哪个控制器上,删除@NonNull应用程序后开始正常


小智 6

就我而言,我犯了一个严重的错误。我安装@Service了服务接口。

为了解决这个问题,我放上@Service了服务文件的实现,它对我有用。

  • 我也是。谢谢 (2认同)

ale*_*dia 6

我在使用 Spring Boot 2 的 Maven 多模块项目中遇到了熟悉的问题。该问题与子 Maven 模块中包的命名有关。

@SpringBootApplication 封装了很多组件,如@ComponentScan、@EnableAutoConfiguration、jpa-repositories、json-serialization 等。他将@ComponentScan 放在 com.*******.space 包中。这部分包 com.********.space 必须是所有模块通用的。

为了修复它:

  1. 您应该重命名所有模块包。换句话说,您必须在所有 Maven 模块中的所有包中拥有相同的父部分。例如 - com.*******.space
  2. 您还必须将入口点移动到此包 - com.********.space


小智 5

我认为您可以通过使用@Repository注释存储库来简化它,然后它将由Spring Framework自动启用。


Sri*_*r.v 5

在我的情况下,这两个选项有效。

  1. //@ComponentScan ({"myapp", "myapp.resources","myapp.services"}) 包括保持该包Application.class在列表中,或者

  2. 只需添加@EnableAutoConfiguration; 它会自动识别所有的 spring bean。