需要一个找不到的“com.example.dao.InterfaceName”类型的 bean

Posted

技术标签:

【中文标题】需要一个找不到的“com.example.dao.InterfaceName”类型的 bean【英文标题】:Required a bean of type 'com.example.dao.InterfaceName' that could not be found 【发布时间】:2018-02-05 20:32:42 【问题描述】:

我正在使用带有 Java 1.8 的 Eclipse 和 maven 尝试构建一个基于 maven 项目的 spring 启动项目,因此我构建了自己的实体 underName Candidat 有这个完整的代码块

package com.example.demo.entities;

import java.io.Serializable;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity(name = "CandidatTable")
public class Candidat implements Serializable 

    @Id @GeneratedValue
    private Long id;

    private String name;
    private String prenom;
    private String reference;
    private String resumeCandidate;

    public Candidat() 
        super();
    

    public Candidat(String name, String prenom, String reference, String resumeCandidate) 
        super();
        this.name = name;
        this.prenom = prenom;
        this.reference = reference;
        this.resumeCandidate = resumeCandidate;
    

    public Long getId() 
        return id;
    

    public void setId(Long id) 
        this.id = id;
    

    public String getName() 
        return name;
    

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

    public String getPrenom() 
        return prenom;
    

    public void setPrenom(String prenom) 
        this.prenom = prenom;
    

    public String getReference() 
        return reference;
    

    public void setReference(String reference) 
        this.reference = reference;
    

    public String getResumeCandidate() 
        return resumeCandidate;
    

    public void setResumeCandidate(String resumeCandidate) 
        this.resumeCandidate = resumeCandidate;
    


在正常情况下,我们应该在其中构建一个接口,我们应该像我们所说的那样定义我们的服务方法:save()findAllRecords()findSpecificRecordByID()updateRecordLine()deleteRecord() ...等等,但在我的案例我在我的 maven 项目中使用了 Spring-data,在我的 web.xml 文件中我有这个依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>

所以不需要定义我们的方法,因为 Spring-data 在我们创建一个扩展通用接口JpaRepository 的接口的情况下使用它自己的方法,所以我的接口如下所示:

package com.example.dao;
import org.springframework.data.jpa.repository.JpaRepository;
import com.example.demo.entities.Candidat;

public interface ICandidate extends JpaRepository<Candidat, Long>
//no need to define our methods, because we gonna use methods difined 
// by SpringData whose comes from JPA specification.

最后,主类代码就是这个了:

package com.example.demo;

import java.util.List;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;

import com.example.dao.ICandidate;
import com.example.demo.entities.Candidat;

@SpringBootApplication
public class CatWebServiceApplication 


    public static void main(String[] args) 
        ApplicationContext context = 
                SpringApplication.run(CatWebServiceApplication.class, args);
        ICandidate condidateRep = context.getBean(ICandidate.class);

        condidateRep.save(
                new Candidat("UserName_1", "FirstName_1", "Ref_1", "/Home/file/docFile_1.docx")); //insert data using Ioc later after runing urself

        condidateRep.save(
                new Candidat("UserName_2", "FirstName_2", "Ref_2", "/Home/file/docFile_2.docx"));

        List<Candidat> cnds = condidateRep.findAll();
        cnds.forEach(p-> System.out.println(p.getResumeCandidate()));
    

我的应用程序应该转好,查看 web.xml 来管理应用程序依赖项,然后查看路径 src/main/resources,其中包含包含此代码的文件 application.properties

# DataSource settings:
spring.datasource.url = jdbc:mysql://localhost:3306/softherWebService
spring.datasource.username = root
spring.datasource.password = dbPassword
spring.datasource.driverClassName = com.mysql.jdbc.Driver
# Specify the DBMS
spring.jpa.database = MYSQL
# Show or not log for each sql query
spring.jpa.show-sql = true
# Hibernate ddl auto (create, create-drop, update)
spring.jpa.hibernate.ddl-auto = update
# Naming strategy
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect

我突然在我的 Eclipse 控制台上收到此错误消息:

线程“main”中的异常 org.springframework.beans.factory.NoSuchBeanDefinitionException: 否 'com.example.dao.ICandidate' 类型的限定 bean 可在 org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:353) 在 org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:340) 在 org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1090) 在 com.example.demo.CatWebServiceApplication.main(CatWebServiceApplication.java:19)

所以 getBean() 行中的问题,我也使用了 CommandLineRunner 但并没有解决我获取 bean 的问题。

【问题讨论】:

Spring boot 仅从定义它的包开始扫描包。您的应用程序类在 com.example.demo 包中,其他一切都不是,所以基本上没有检测到。最佳实践是将您的应用程序类放在对您可用的最顶层包中,在您的情况下将其移动到com.example。否则,您需要添加 @ComponentScan@EntityScan@EnableJpaRepositories 指向正确的包(可行但更多工作)。 @M.Deinum 这应该是一个答案(并且是一个被接受和赞成的答案) 【参考方案1】:

当使用@SpringBootApplication 时,它会自动暗示@ComponentScan@ComponentScan 的默认行为是,当没有明确定义 basePackages 时,是从定义它的类的包开始扫描。对于 Spring Boot,这也适用于所有其他自动配置,例如检测实体、检测 Spring Data 存储库等。

现在您的CatWebServiceApplication 定义在com.example.demo 中,而您的ICandidate 定义在com.example.dao 中,后者将不会被扫描,因为它不是com.example.demo 包的一部分。

有几种方法可以解决这个问题。

首先,您可以在@SpringBootApplication 上指定scanBasePackages 以检测组件,但这并不能解决此问题,因为您还需要@EnableJpaRepositories("com.example.dao")@EntityScan("com.example.dao"),并且在扩展技术时可能还需要更多。

最简单且推荐的方法是将您的CatWebServiceApplication 放入com.example 包中,这样就可以覆盖所有子包,您无需考虑需要添加的所有其他注释。

【讨论】:

【参考方案2】:

在您的接口定义上方添加@Repository 注释以消除错误。

【讨论】:

以上是关于需要一个找不到的“com.example.dao.InterfaceName”类型的 bean的主要内容,如果未能解决你的问题,请参考以下文章

spring boot简单的小demo(适合于初学者)

spring boot关于多个模块(module)的配置问题

Windows 无法安装程序包 因为找不到此程序包所依赖的另一个程序包。此程序包需要具有 any publisher

需要一个 json 文件导致错误:找不到模块

Spring boot Field 需要一个找不到类型的 bean

签名的 JWT 被拒绝:需要另一个算法,或者找不到匹配的密钥