为什么我得到 bean 'com.mypackage.service.blog.BlogService' 的 NoSuchBeanDefinitionException
Why do I get NoSuchBeanDefinitionException for bean 'com.mypackage.service.blog.BlogService'
在 spring 中,当我尝试从我的 BlogController
:
中解决 Unresolved Bean Exception
问题时
@Autowired BlogService blogService;
- 我正在使用
org.springframework.stereotype.Service
服务注释。
- 我的
ApiApplication
应用程序 class 被注释为 @ComponentScan("com.mypackage")
。
- 服务实现是带有
@Service
的注释,位于 com.mypackage.service.blog.BlogService"
- 服务不能是
Autowired
,但是服务使用的是@Repository
并且位于com.mypackage.repository.blog.BlogRepository
可以被控制器导入。
我的应用程序 class 如下所示:
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
class:
public interface BlogService extends CrudService<Blog, Long> {
}
我的com.mypackage.service.blog.impl.BlogServiceImpl
class:
@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)}
我是否应该采用一些特定的 class 路径到 DEBUG 而另一个到 INFO ?我在当前的 DEBUG 日志中没有看到服务创建和 class路径。
您可以使用下面的 class 查看在上下文中创建了哪些 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
此处不需要 @ComponentScan
,只需将其从应用程序的主要 class 中删除即可,即 ApiApplication
即可。
点#2
正如我们所见,BlogServiceImpl
没有实现 BlogService
,这意味着没有 BlogService
的具体实现,因此无法创建 Bean
。
您需要实现 BlogServiceImpl
接口 BlogService
来告诉 spring BlogServiceImpl
是 BlogService
的实现
public class BlogServiceImpl implements BlogService
和 我强烈建议您遵循包结构 As per spring docs 然后您将不需要包含 @ComponentScan
来创建 Bean
s.
com
+- example
+- myproject
+- Application.java
|
+- domain
| +- Customer.java
| +- CustomerRepository.java
|
+- service
| +- CustomerService.java
|
+- web
+- CustomerController.java
在 spring 中,当我尝试从我的 BlogController
:
Unresolved Bean Exception
问题时
@Autowired BlogService blogService;
- 我正在使用
org.springframework.stereotype.Service
服务注释。 - 我的
ApiApplication
应用程序 class 被注释为@ComponentScan("com.mypackage")
。 - 服务实现是带有
@Service
的注释,位于com.mypackage.service.blog.BlogService"
- 服务不能是
Autowired
,但是服务使用的是@Repository
并且位于com.mypackage.repository.blog.BlogRepository
可以被控制器导入。
我的应用程序 class 如下所示:
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
class:
public interface BlogService extends CrudService<Blog, Long> {
}
我的com.mypackage.service.blog.impl.BlogServiceImpl
class:
@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)}
我是否应该采用一些特定的 class 路径到 DEBUG 而另一个到 INFO ?我在当前的 DEBUG 日志中没有看到服务创建和 class路径。
您可以使用下面的 class 查看在上下文中创建了哪些 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
@ComponentScan
,只需将其从应用程序的主要 class 中删除即可,即 ApiApplication
即可。
点#2
正如我们所见,BlogServiceImpl
没有实现 BlogService
,这意味着没有 BlogService
的具体实现,因此无法创建 Bean
。
您需要实现 BlogServiceImpl
接口 BlogService
来告诉 spring BlogServiceImpl
是 BlogService
public class BlogServiceImpl implements BlogService
和 我强烈建议您遵循包结构 As per spring docs 然后您将不需要包含 @ComponentScan
来创建 Bean
s.
com
+- example
+- myproject
+- Application.java
|
+- domain
| +- Customer.java
| +- CustomerRepository.java
|
+- service
| +- CustomerService.java
|
+- web
+- CustomerController.java