为什么我得到bean'com.mypackage.service.blog.BlogService'的NoSuchBeanDefinitionException

时间:2018-01-11 03:39:12

标签: java spring spring-mvc spring-boot autowired

在春天,当我尝试使用Unresolved Bean Exception时,我正尝试解析BlogController

@Autowired BlogService blogService;
  • 我正在使用org.springframework.stereotype.Service服务注释。
  • 我的ApiApplication应用程序类注释了@ComponentScan("com.mypackage")
  • 服务实现是@Service的注释,位于com.mypackage.service.blog.BlogService"
  • 该服务不能为Autowired,但服务使用的@Repository位于com.mypackage.repository.blog.BlogRepository,可由控制器导入。

我的应用程序类看起来像这样:

package com.mypackage;

import com.mypackage.core.Core;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.web.MultipartAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;

@SpringBootApplication
@ComponentScan({
        "com.mypackage",
        "com.mypackage.service.blog"
})
public class ApiApplication {

    private static final Logger logger = LoggerFactory.getLogger(ApiApplication.class);

    public static void main(String[] args) throws Exception {
        org.apache.ibatis.logging.LogFactory.useSlf4jLogging();
        SpringApplication.run(ApiApplication.class, args);
        logger.info("Application started!");
    }

}

这是我的com.mypackage.controller.blog.BlogController

@RestController
@RequestMapping("/blogs")
public class BlogController {

  @Autowired
  private BlogService blogService;

  @PostMapping
  @ResponseStatus(HttpStatus.CREATED)
  Long create(@RequestBody Blog blog) {
    blogService.insert(blog);
    return blog.getId();
  }

我的com.mypackage.service.blog.BlogService课程:

public interface BlogService extends CrudService<Blog, Long> {
}

我的com.mypackage.service.blog.impl.BlogServiceImpl课程:

@Service
@UserManagementTx
public class BlogServiceImpl extends AbstractCrudService<BlogRepository, Blog, Long> {

    @Autowired
    public BlogServiceImpl(BlogRepository repository) {
        super(repository);
    }

}

我已经调试了调试日志,我试图找到一些提示,为什么不导入服务。

org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.mypackage.service.blog.BlogService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

我应该将一些特定的类路径带到DEBUG而另一个带到INFO吗?我在当前的DEBUG日志中看不到服务创建和类路径。

2 个答案:

答案 0 :(得分:1)

您可以使用下面的类来查看在上下文中创建的bean。嘿,这会有所帮助。

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.Arrays;

@Component
class BeansLogger {
    private static final Logger LOGGER = LoggerFactory.getLogger(BeansLogger.class);

    private final ApplicationContext applicationContext;

    @Autowired
    public BeansLogger(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    @PostConstruct
    public void init() {
        final String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
        Arrays.sort(beanDefinitionNames);
        LOGGER.debug("Registered beans: {}", Arrays.asList(beanDefinitionNames));
    }
}

答案 1 :(得分:1)

#1

此处不需要

@ComponentScan,只需将其从主要应用类中移除,即ApiApplication即可。

#2

我们可以看到BlogServiceImpl没有实现BlogService,这意味着没有BlogService的具体实现,因此无法创建Bean

您需要实施BlogServiceImpl界面BlogService,告诉春天BlogServiceImplBlogService的实施

public class BlogServiceImpl implements BlogService

我强烈建议您按照包结构 As per spring docs,然后您不需要包含@ComponentScan来创建Bean

com
 +- example
     +- myproject
         +- Application.java
         |
         +- domain
         |   +- Customer.java
         |   +- CustomerRepository.java
         |
         +- service
         |   +- CustomerService.java
         |
         +- web
             +- CustomerController.java