考虑在配置中定义“包”类型的bean [Spring-Boot]


108

我收到以下错误:

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

我之前从未见过此错误,但是@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;
}

申请人Impl

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

现在,我应该可以只通过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";
    }

}

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

}

错误消失了,但是什么也没发生。然而,当我注释掉的一切交易与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.

我加了 @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);
    }

}

----------------------------更新3 -------------------- -

添加:

@SpringBootApplication
@ComponentScan("com")
public class WebServiceApplication extends SpringBootServletInitializer {

仍然在抱怨我的ApplicantImpl课堂,@Autowires我回购TApplicantRepository了它。


您的应用程序上下文文件在哪里?如果您没有,则应该考虑给Spring一些带有诸如@ComponentScan的批注的提示,以使所有bean都可用。
马里奥·桑蒂尼

@MarioSantini,请参阅更新1
Mike3355 '16

我认为每次更新后,错误都有变化吗?如果可能,请发布您的项目结构,并在每种情况下发布错误日志/堆栈跟踪。更好地了解“为什么”发生了这些错误,而不是“什么”使错误消失了。也将对遇到类似问题的其他人有所帮助。
Ameen.M,2016年

Answers:


201

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

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

5
凉。我的项目被许多模块划分。ComponentScan解决了我的问题!
kholofelo Maloma

ComponentScan批注解决了我的问题,但@EnableAutoConfiguration不能解决
jpl

实际上,EnableAutoConfiguration隐式定义了某些项目的基本“搜索包”,并且使用根包也允许使用ComponentScan批注,而无需指定basePackage属性。如果主类位于根包中,则可以使用@SpringBootApplication批注
jpl

1
此解决方案帮助我解决了版本2.0.4中的错误
manu muraleedharan

2
是的,这是由于该项目已分解为不同的模块。@EntityScan@EnableJpaRepositories使用正确的软件包名称为我工作。
Adi Sivasankaran

51

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


2
这应该是公认的答案,简单明了。谢谢。
晚上狂风

1
为我工作。谢谢。
Okafor T Kosiso

1
谢谢,我缺少
@Repository

1
是的,这应该是答案。以上答案只是假设扫描失败,这是错误的。
Sumit Badsara

48

您的申请人课程似乎没有被扫描。默认情况下,@SpringBootApplication将扫描所有以root开头的软件包(作为您放置的类)。

假设您的main类“ WebServiceApplication”位于“ com.service.something”中,则将com.service.something扫描“ ” 下的所有组件,并且com.service.applicant将不扫描“ ”。

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

根据评论更新

如果您有多个由maven / gradle管理的模块,则所有spring需求就是要扫描的软件包。您告诉spring扫描“ com.module1”,并且您有另一个模块的根软件包名称为“ com.module2”,这些组件将不会被扫描。您甚至可以告诉spring扫描“ com”,然后将扫描“ com.module1.”和“ com.module2.”中的所有组件


我的项目是结构是不同的模块。例如,服务将具有其自己的模块和build.gradle。这些build.gradle模块名称dependencies通过main方法添加到模块的中。因此,当您看到@ComponentScan("module-service")那是我认为会起作用的。但是里面module-service有一个包装。所以我的问题是什么样子?我只是命名软件包名称还是模块名称,或者两者都命名?
Mike3355 '16

包是否属于不同的模块无关紧要。应该在其中扫描组件的包装中指定弹簧。您可以在“ scanBasePackages”属性中为所有模块提供所有“根”软件包名称。以及必须提及的所有“软件包”,而不是模块。
Ameen.M,2016年

做到了您所说的,错误消失了,但只抱怨了另一个软件包。自然,我将其添加到列表中,但不会消失。我是这样实现的:@SpringBootApplication(scanBasePackages= {"com.delivery.service","com.delivery.request"})
Mike3355 '16

我刚刚做了@SpringBootApplication(scanBasePackages= "com"),它在抱怨JPA存储库。非常感谢你。如果执行上述操作,我不知道spring会扫描所有以“ com”开头的软件包。
Mike3355 '16

23

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

com.server
 - Applicacion.class (<--this class have @ComponentScan)
com.server.config
 - MongoConfig.class 
com.server.repository
 - UserRepository

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

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

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


2
实际上,您无需@ComponentScan在上述情况下进行指定。因为您的Application.class(带有@SpringBootApplication注释)被放置在com.server以及的根com.server.configcom.server.repository
Ameen.M

@ Ameen.M那是我的确切问题,为什么它仍然无法解决,为什么它需要使用mongo仓库进行显式扫描@EnableMongoRepositories
Karthikeyan


7

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


4

就我而言,这两个选项都有效。

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

  2. 只需添加@EnableAutoConfiguration; 它会自动识别所有的四季豆。


3

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

参数0需要找不到的MissingBeanName类型的Bean

在我的情况下,错误告诉我问题出在什么控制器上,删除@NonNull应用程序后启动正常


3

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

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

要修复它:

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

2

我在网上寻求答案,但似乎没有一个合适的解决方案:一开始,一切都如下进行:

@Slf4j
@Service
@AllArgsConstructor(onConstructor = @__(@Autowired))
public class GroupService {
    private Repository repository;
    private Service service;
}

然后,我试图添加地图以缓存某些内容,结果变成这样:

@Slf4j
@Service
@AllArgsConstructor(onConstructor = @__(@Autowired))
public class GroupService {
    private Repository repository;
    private Service service;
    Map<String, String> testMap;
}

繁荣!

Description:

Parameter 4 of constructor in *.GroupService required a bean of type 'java.lang.String' that could not be found.


Action:

Consider defining a bean of type 'java.lang.String' in your configuration.

我删除了@AllArgsConstructor(onConstructor = @__(@Autowired)),并添加@Autowired每个repositoryserviceMap<String, String>。它就像以前一样工作。

@Slf4j
@Service
public class SecurityGroupService {
    @Autowired
    private Repository repository;
    @Autowired
    private Service service;
    Map<String, String> testMap;
}

希望这会有所帮助。


2

在应用程序中添加以下注释后,它为我工作:

@ComponentScan({"com.seic.deliveryautomation.mapper"})

我收到以下错误:

“构造函数中的参数1需要找不到映射器类型的bean:



2

如果您不小心在两个不同的类中定义了相同的bean,也会收到此错误。那件事发生在我身上。错误消息具有误导性。当我删除多余的bean时,问题已解决。


1
@SpringBootApplication
@MapperScan("com.developer.project.mapper")

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

1

如果@Service类被标记为抽象,则可能会发生这种情况。


1

如果您的类依赖关系是由Spring管理的,那么如果我们忘记在POJO类中添加默认/空arg构造函数,则可能会发生此问题。


1

它可能会帮助别人。我有同样的问题,同样的错误信息,同样的东西。我尝试了其他答案的解决方案,直到我意识到所使用的Bean与实际上已自动接线的Bean具有相同的名称时才有用。它发生在重构期间,因此我不得不重命名该类,这产生了积极的结果。干杯


1

我遇到了同样的问题。Spring引导已识别出Mongo数据库存储库,但它没有为扩展mongo存储库的存储库接口创建Bean。

在我的情况下,问题是Maven pom中“ spring + mango”的版本说明不正确。我已经更改了工件的组ID,所有这些都像魔术一样工作。不需要注释,因为Spring Boot可以处理所有事情。

在解决问题期间,我到处都是Web搜索解决方案,并且意识到这个问题实际上与项目配置有关,任何面对此问题的人都应首先检查其项目设置并启用spring调试功能,以获取有关失败的更多详细信息,并密切注意正是在此过程中,创建失败了。


0

在我的情况下,出现此错误是因为我的导入错误,例如,使用spring,该导入会自动出现:

import org.jvnet.hk2.annotations.Service;

但我需要:

import org.springframework.stereotype.Service;

0

我遇到了需要将RestTemplate注入服务类的情况。但是,服务类无法拾取RestTemplate。我要做的是在与主应用程序相同的程序包下创建一个包装器类,并将包装器标记为Component并将该组件自动装配到服务类中。问题解决了。希望它也对你有用


0

我的错误是我包括了:

<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-jpa</artifactId>
    <version>2.2.5.RELEASE</version>
</dependency>

代替:

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

0

我认为,您在RequestController中缺少@Bean批注

在您的文件中添加Bean,这解决了我的问题,
当我从tutorialspoint学习Spring Boot时得到了这个解决方案

private Applicant applicant;

@Bean 
public Applicant applicant() { 
    return new Applicant(); 
}

0

添加Spring Boot Data JPA Starter依赖关系为我解决了这个问题。

马文

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
    <version>2.2.6.RELEASE</version>
</dependency>

摇篮

compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa', version: '2.2.6.RELEASE'

或者你可以直接去这里


在这种情况下,这实际上并不适用。它提示输入到数据库的连接详细信息(无法配置数据源:未指定'url'属性,并且无法配置任何嵌入式数据源。)。在我要手动测试而不与数据库交互的情况下,这将无法正常工作。
Thomas Okonkwo

0

如果你使用interface,你可以扩展CrudRepository<Applicant,Long>@Repository注解。


0

当您使用每个示例时,也会出现问题 @EnableMongoRepositories(YOUR_MONGO_REPOSITORIES_PACKAGE),后来您将包名称重命名或将其移动到另一个位置。

在多模块Maven项目和Spring Boot中经常遇到它


0

有一个机会,你正试图@Autowired接口实现接口之前。

解决方案示例:

    **HomeController.java**
    class HomeController{

      @Autowired
      UserService userService;
    .....
    }
----------------------------------------------------------------------
    **UserService.java** 
    public interface UserService {
        User findByUsername(String username);
    .....
    }
-----------------------------------------------------------------------
     **UserServiceImpl.java**
     @Service
     public class UserServiceImpl implements UserService{

         public User findByUsername(String username) {
           return userDao.findByUsername(username);
         }
        ....
      }

<i>This is not italic</i>, and [this is not a link](https://example.com)

0

从线程运行方法中删除诸如@Service之类的批注类型配置。

@Service, @Component

0

尝试如下配置项目结构:

将所有回购,服务,程序包放入主程序包的子程序包中:

package com.leisure.moviemax;  //Parent package
        
@SpringBootApplication
@PropertySource(value={"classpath:conf.properties"})
    
public class MoviemaxApplication implements CommandLineRunner {
        
package com.leisure.moviemax.repo; //child package

@Repository
public interface UsrRepository extends JpaRepository<UserEntity,String> {

0

提醒一下spring不扫描世界,它使用有针对性的扫描方式,这意味着将springbootapplication存储在软件包下的所有内容。因此可能会出现此错误“考虑在您的配置[Spring-Boot]中定义类型为'package'的bean”,因为您在其他springbootapplication软件包中具有服务接口。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.