Spring @ComponentScan 不适用于@Repository

Spring @ComponentScan doesn't work on @Repository

我有一个与配置 class 不同的包中的存储库,所以我用 @Repostiory:

将其注释如下
package test;

@Repository
public interface UserTest extends JpaRepository<User, Long> {
}

我已经对其进行了组件扫描,但没有成功:

package com.app;
@SpringBootApplication
@ComponentScan({"test","com.app"})
public class Application extends SpringBootServletInitializer {
}

异常:没有可用的 'test.UserTest' 类型的符合条件的 bean:预计至少有 1 个符合自动装配候选条件的 bean。

为什么除非我添加 enableJpaRepositories 否则组件扫描无法在存储库上运行?我认为 componetScan 就足够了


更新:

由于一些答案提供了解决方案,我问的是解释而不是解决方案。以下内容甚至无需在 "test" 上进行组件扫描即可工作:

SpringBootApplication
@EnableJpaRepositories({"test","com.app"})
public class Application extends SpringBootServletInitializer{
}

现在的问题是为什么我什至需要在 @Repository 上使用 componentscan ,而它不起作用?为什么在文档中 @Repository 在没有效果时被 componentscan 扫描,而 @EnableJpaRepostiories 是 enoguh?

来自 Spring 组件扫描文档: 指示是否应启用自动检测使用 @Component @Repository、@Service 或 @Controller 注释的 classes。

没有检测到我的@Repository

您应该像下面这样使用您的代码,因为@ComponentScan 始终使用基础包,因此您的实现应该如下所示。

 package com.app;
    @SpringBootApplication
    @ComponentScan(basePackages={"test","com.app"})
    @EnableJPARepositories 
    public class Application extends SpringBootServletInitializer {
    }

为了让 spring 知道什么 DataSource 与什么 Repository 相关,您应该在 @EnableJpaRepositories 注释中定义它。

尝试启用如下所示的 jpa 存储库。

@SpringBootApplication
@ComponentScan({"test","com.app"})
@EnableJpaRepositories("test")
public class Application extends SpringBootServletInitializer {
}

更新:为什么需要@EnableJpaRepositories?

@SpringBootApplication自动提供以下注解的特性

@配置 @EnableAutoConfiguration @ComponentScan

但是如果您尝试定义自己的注释,那么 spring 引导将不会处理内部自动配置,因此这就是我们必须启用存储库的原因。

我有一些项目,如果您不编写自己的东西,那么只有 @SpringBootApplication 就足够了。

希望你明白了。

金字招牌:

如果您想最大程度地利用 spring 引导的自动配置功能,则应将所有 class 包放在 spring 启动主应用程序包(直接在主包中或间接作为子包)。

我找到了关于我做错了什么的解释。带有 componentscan 的 @Repository 注释不会导致 spring 实现 spring jpa 存储库。对于实现 crud 存储库的接口,应该使用 enablejparepository。

现在 @Repository 与 componentscan 的使用是当你有一个存储库 class 并且你有自己的 DAO 不适用于 spring curd repo 否则不会创建实现:

@Repository
public class UserTest {


    public List<Object> findById(long l) {

             .......
    }
}