Spring-Data-JDBC出现Repository无法注入IOC容器的情况

起因

最近在做平台的ORM框架技术选型,本来想着用Mybatis-Plus,但是看github好像对SpringBoot3的支持还有些问题,恰好看到了Spring-Data-JDBC这个库,支持DSL、方法名、方式构建查询请求,而且还内置了分页、基础crud的方法,在解决Mybatis-Plus 80%的功能的情况下又做到了很轻量,而且同为Spring出品,与项目的结合更容易。
于是我便兴冲冲的引入了Spring-Boot-JDBC的库
因为时SpringBoot项目,所以不用指定版本号了,由Spring BOM统一管理

<dependency>
    <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-data-jdbc</artifactId>
 </dependency>

按照官方文档,使用了SpringBoot,什么也不用配置,只要ioc中存在一个Datasource对象即可
文档原文

This configuration can be further simplified by using Spring Boot. With Spring Boot a DataSource is sufficient once the starter spring-boot-starter-data-jdbc is included in the dependencies. Everything else is done by Spring Boot.

好家伙,这也太方便了,我直接新建一个接口继承Repository,然后准备相关类然后按照文档的方式直接自动注入Repository对象,打算大展拳脚时

User.clas

public interface UserRepository extends CrudRepository<User, Long> {
}

User.class

public class User {
    @Id
    private Long userId;
    
    public Long getUserId() {
        return userId;
    }
    
    public void setUserId(Long userId) {
        this.userId = userId;
    }
}

Test.service

@Service
public class Test {
    private UserRepository userRepository;
    
    //当然这里使用@Autowired也可以
    public Test(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
}

项目启动却给了我狠狠一击

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 0 of constructor in com.example.demo.test.Test required a bean of type 'com.example.demo.test.UserRepository' that could not be found.

无法注入什么鬼
文档不就是这么写的么
然后翻遍互联网和github的issue
看到了这位朋友的文章
https://www.cnblogs.com/XingXiaoMeng/p/14350772.html
发现在类上加了个Spring-Data-JDBC的@Table注解就可以注入了
Why!
后来在文档里发现这一段

8.3.2. Using Repositories with Multiple Spring Data Modules
Using a unique Spring Data module in your application makes things simple, because all repository interfaces in the defined scope are bound to the Spring Data module. Sometimes, applications require using more than one Spring Data module. In such cases, a repository definition must distinguish between persistence technologies. When it detects multiple repository factories on the class path, Spring Data enters strict repository configuration mode. Strict configuration uses details on the repository or the domain class to decide about Spring Data module binding for a repository definition:

If the repository definition extends the module-specific repository, it is a valid candidate for the particular Spring Data module.

If the domain class is annotated with the module-specific type annotation, it is a valid candidate for the particular Spring Data module. Spring Data modules accept either third-party annotations (such as JPA’s @Entity) or provide their own annotations (such as @Document for Spring Data MongoDB and Spring Data Elasticsearch).

翻译了下

8.3.2. 使用具有多个 Spring Data 模块的存储库
在应用程序中使用独特的 Spring Data 模块使事情变得简单,因为定义范围内的所有存储库接口都绑定到 Spring Data 模块。有时,应用程序需要使用多个 Spring Data 模块。在这种情况下,存储库定义必须区分持久性技术。当它在类路径上检测到多个存储库工厂时,Spring Data 会进入严格的存储库配置模式。严格配置使用存储库或域类的详细信息来决定存储库定义的 Spring Data 模块绑定:

如果存储库定义扩展了特定于模块的存储库,那么它是特定 Spring Data 模块的有效候选者。

如果域类使用特定于模块的类型注释进行注释,那么它是特定 Spring Data 模块的有效候选者。Spring Data 模块接受第三方注释(例如 JPA @Entity)或提供自己的注释(例如@DocumentSpring Data MongoDB 和 Spring Data Elasticsearch)。

原来如此
因为我项目中也引入了Spring-Data-JDBC,Spring-Data-Elasticsearch,而我继承的CrudRepository是属于org.springframework.data.repository;包下的通用Repository,Spring无法判断到底该将这个Repository实例化成针对于哪种储存技术的Repository,所以就报错了。

但是这个报错信息能不能友好点?
不看文档是根本不知道的

解决方案

最后的解决方案也是比较简单的
官网给了3种方法

1.继承特定储存模块的Repository

interface MyRepository extends JpaRepository<User, Long> { }
2.使用特定储存模块的注释(也就是文中提到的解决方法)

//这里的@Table是
//org.springframework.data.relational.core.mapping.Table包下的
@Table
class User {}
3.使用@EnableJdbcRepositories指定具体包

这个貌似没什么用,不清楚原因

@EnableJdbcRepositories(basePackages = "a.b.c")
@SpringBootApplication
public class MyApplication
{
    public static void main(String[] args)
    {
        SpringApplication.run(MyApplication.class, args);
    }
}

具体的源码逻辑没有深入看,感兴趣的小伙伴可以自己研究!

  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值