如题,启动 Spring 项目报错:Field userRepository in com.example.demo.DemoApplication required a bean of type com.example.accessingdatamysql.UserRepository' that could not be found.

在测试连接 MySQL 数据库的 Spring demo 中,没有创建新的项目,而是在之前下载的 RESTful Web Service demo 上做的修改。

Spring demo 项目创建后的目录结构

然后启动时,就报了上面提到的错误。网站找了一下文章:stackoverflow.com 里提到,默认情况下,所有属于 @SpringBootApplication 声明的包都将被扫描。

在当前项目中,声明 @SpringBootApplication 注解的主类为 DemoApplication,所以 com.example.demo 包下的所有内容都会被自动扫描,但 com.example.accessingdatamysql 不属于一个包,就不会被扫描到,userRepository 就不会被自动装配,@Autowired private UserRepository userRepository; 就报错了,找不到这个类。

解决方法:

  • 将需要扫描的目录添加到 Spring Boot 注解初始化参数中
@SpringBootApplication(scanBasePackages={"com.example.accessingdatamysql", "com.example.demo"})

但当项目体量变大之后,需要加入到启动的包会越来越多。

  • 重构包结构,将 @SpringBootApplication 声明的主类放到其他子包的上一级

目录结构示例:

src/
├── main/
│   └── java/
|       ├── com.example/
|       |   └── Application.java
|       ├── com.example.model/
|       |   └── User.java
|       ├── com.example.controller/
|       |   ├── IndexController.java
|       |   └── UsersController.java
|       └── com.example.service/
|           └── UserService.java
└── resources/
    └── application.properties

所以,调整后的目录结构:

Spring demo 项目调整后的目录结构