Spring Boot启动扫描无法识别Reactive Repository的问题排查
背景
我有一个Spring Boot沙箱应用,打算采用响应式开发方案,使用PostgreSQL作为数据库,已经引入R2DBC实现响应式Repository,但应用启动时提示找不到Repository的Bean。
相关代码
主应用类
@SpringBootApplication public class Springboot2Application { public static void main(String[] args) { SpringApplication.run(Springboot2Application.class, args); } }
Repository接口
@Repository public interface ToDoRepository extends ReactiveCrudRepository<ToDo,String> { }
Controller类
@RestController @RequestMapping("/api/v1") public class ToDoController { private final ToDoRepository repository; public ToDoController(ToDoRepository repository) { this.repository = repository; } @GetMapping(value = "/to-do", produces = { MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE, MediaType.TEXT_XML_VALUE}) public ResponseEntity<Flux<ToDo>> getToDos(@RequestHeader HttpHeaders headers){ return ResponseEntity.ok().body(repository.findAll()); } }
实体类
@Data @RequiredArgsConstructor @Entity @Table(name = "todo") public class ToDo { @Id @NotNull @GeneratedValue(generator = "system-uuid") @GenericGenerator(name = "system-uuid", strategy = "uuid") private String id; @NotNull @NotBlank private String description; @CreationTimestamp private Timestamp created; @UpdateTimestamp private Timestamp modified; private boolean completed; }
R2DBC配置类
@Configuration @EnableR2dbcRepositories(basePackages = "com.springboot2.repository") public class R2DBCConfig extends AbstractR2dbcConfiguration { @Bean public ConnectionFactory connectionFactory() { return ConnectionFactories.get( ConnectionFactoryOptions.builder() .option(DRIVER, "postgresql") .option(HOST, "localhost") .option(PORT, 5432) .option(USER, "admin") .option(PASSWORD, "admin") .option(DATABASE, "springdb") .build()); } }
启动错误信息
描述:
Parameter 0 of constructor in com.springboot2.controller.ToDoController required a bean of type 'com.springboot2.repository.ToDoRepository' that could not be found.Action:
Consider defining a bean of type 'com.springboot2.repository.ToDoRepository' in your configuration.
已尝试的解决方法
- 添加
@ComponentScan注解 - 将
ToDoRepository移至Springboot2Application所在的根包下
但问题依然存在。
pom.xml文件内容
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.3</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.springboot</groupId> <artifactId>springboot</artifactId> <version>0.0.1-SNAPSHOT</version> <name>springboot2</name> <description>Demo project for Spring Boot</description> <properties> <java.version>8</java.version> <spring-cloud.version>2021.0.3</spring-cloud.version> <!-- <spring-shell.version>2.1.0</spring-shell.version>--> </properties> <dependencies> <!-- DB,ORM, and plugins--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-r2dbc</artifactId> </dependency> <dependency> <groupId>io.r2dbc</groupId> <artifactId>r2dbc-postgresql</artifactId> <version>0.8.1.RELEASE</version> </dependency> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency> <!-- Reactive libs--> <dependency> <groupId>io.projectreactor</groupId> <artifactId>reactor-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> </configuration> </plugin> </plugins> </build> </project>
问题原因及解决方案
1. 包路径不匹配
@EnableR2dbcRepositories注解指定的包是com.springboot2.repository,但pom.xml的groupId是com.springboot,实际包结构大概率是com.springboot.repository。检查Repository所在包路径,确保和注解配置一致:
@EnableR2dbcRepositories(basePackages = "com.springboot.repository")
2. JPA与R2DBC依赖冲突
pom.xml同时引入了spring-boot-starter-data-jpa和spring-boot-starter-data-r2dbc,两者的Repository扫描逻辑会互相干扰。移除JPA依赖,因为响应式开发不需要JPA:
<!-- 删除该依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>
3. 实体类注解错误
R2DBC不支持JPA的@Entity注解,且不兼容@GeneratedValue的UUID生成方式。修改实体类:
@Data @NoArgsConstructor // 添加无参构造,R2DBC需要 @Table(name = "todo") public class ToDo { @Id @NotNull private String id; @NotNull @NotBlank private String description; private Timestamp created; private Timestamp modified; private boolean completed; // 手动生成UUID public ToDo(String description) { this.id = UUID.randomUUID().toString(); this.description = description; this.created = new Timestamp(System.currentTimeMillis()); this.modified = this.created; } }
4. 简化R2DBC配置
删除自定义的R2DBCConfig类,改用配置文件配置连接信息,在主应用类上添加@EnableR2dbcRepositories:
@SpringBootApplication @EnableR2dbcRepositories(basePackages = "com.springboot.repository") public class Springboot2Application { public static void main(String[] args) { SpringApplication.run(Springboot2Application.class, args); } }
application.properties配置:
spring.r2dbc.url=r2dbc:postgresql://localhost:5432/springdb spring.r2dbc.username=admin spring.r2dbc.password=admin
内容的提问来源于stack exchange,提问作者Sam Fisher

