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

问题描述 投票:59回答:12

我收到以下错误:

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

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

现在我应该可以只使用Autowire申请人并且能够访问,但是在这种情况下,当我在我的@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";
    }

}

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

}

而错误消失但没有任何反应。然而,当我在添加Applicant之前在RestController中注释掉@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);
    }

}

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

添加:

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

仍在抱怨我的ApplicantImpl@Autowires我的回购TApplicantRepository进入它。

java spring-boot
12个回答
139
投票

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

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

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

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

1
投票

如果@Service类标记为abstract,则会发生这种情况。


1
投票

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

1
投票

在应用程序中添加以下注释后,它对我有用:

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

我收到以下错误:

“构造函数的参数1需要一个无法找到的mapper类型的bean:


0
投票

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

import org.jvnet.hk2.annotations.Service;

但我需要:

import org.springframework.stereotype.Service;

38
投票

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

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

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

根据评论更新

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


23
投票

有机会...... 您可能会在各自的实现类中缺少@Service@Repository注释。


17
投票

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

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

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


4
投票

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


3
投票

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

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

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


3
投票

就我而言,我犯了一个可怕的错误。我把@Service放到了服务界面。

为了解决它,我把@Service放在服务文件的实现上,它对我有用。


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))并为每个@Autowiredrepository添加service,除了Map<String, String>。它就像以前一样工作。

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

希望这可能会有所帮助。


2
投票

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

  1. //@ComponentScan ({"myapp", "myapp.resources","myapp.services"})中也包括将Application.class列入清单的包裹,或者
  2. 只需添加@EnableAutoConfiguration;它会自动识别所有的春豆。
© www.soinside.com 2019 - 2024. All rights reserved.