【问题标题】:Spring @ComponentScan doesn't work on @RepositorySpring @ComponentScan 不适用于 @Repository
【发布时间】:2019-04-09 20:53:45
【问题描述】:

我有一个与配置类不同的包中的存储库,因此我使用@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 就足够了


更新

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

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

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

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

在我的情况下,@Repository 未被检测到

【问题讨论】:

  • 如果您从 Spring 存储库扩展以使用基本的 CRUD 操作,则需要通过 @EnableJPARepositories 启用它们,以便 springboot 在运行时检测和初始化它们的实现。
  • @TürkmenMustafaDemirci aaah 你的意思是,如果我创建自己的存储库,它会起作用吗?
  • 我想它应该在没有 @enableJPARepositories 的情况下工作。试一试,请告诉我们我也想知道的结果。
  • @MohammadKarmi 我建议您创建一个像 com.app.repository 这样的包并将您的存储库类移到那里,然后在运行器上添加 @EnableJpaRepositories("com.app.reporsitory")。
  • @MohammadRezaAlagheband 再次我知道解决方案,它会起作用,但我要求解释

标签: java spring-boot webapp2 component-scan


【解决方案1】:

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

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

@Repository
public class UserTest {


    public List<Object> findById(long l) {

             .......
    }
}

【讨论】:

    【解决方案2】:

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

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

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

    更新:为什么需要@EnableJpaRepositories?

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

    @配置 @EnableAutoConfiguration @ComponentScan

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

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

    希望你明白了。

    金句:

    如果你想最大限度地利用spring boot的自动配置特性,最好将你所有的class包放在spring boot主应用包下(直接放在主包或间接作为子包) .

    【讨论】:

    • 我知道这是解决方案,但这是预期的吗?在他们说@ComponentScan 在@Repository 上工作的文档中
    • 感谢Alien的回答,是的没错我知道spring boot提供了以上3个注解。但这里的主要问题是,如果 enableJpaReposiotry 就足够了,为什么我需要 @Repository 上的 componentScan 如果它根本不起作用?
    • 如果您按照我的回答中的金句,就不需要任何东西,只要@SpringBootApplication就足够了
    • 你是完全正确的。但我对此很好奇:)。查看我更新的问题
    • I did and here they say what they say : 指示是否应该启用对使用@Component @Repository、@Service 或@Controller 注释的类的自动检测。
    【解决方案3】:

    您应该使用如下代码,因为@ComponentScan 始终与基本包一起使用,因此您的实现应该如下所示。

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

    【讨论】:

    • 这没有回答问题。存储库位于 com.app 之外。我在问为什么需要 enablejparepositories
    • 你能试试这个方法吗
    • 如果您正在执行任何 crud 操作,那么您必须使用 jpa 依赖项,为此您必须启用 @EnableJPARepositories
    • @EnableJPARepositories 扫描您在配置类中的包。我知道与@Alien 提到的相同的解决方案,我已经说过有问题的解决方案。我在问原因不是解决方案
    • @MohammadKarmi 请参考第三条评论,这是一个 springboot 功能,您必须为任何 JpaRepository 操作启用 JPARepositories。
    猜你喜欢
    • 2016-05-19
    • 1970-01-01
    • 1970-01-01
    • 2016-06-02
    • 2018-06-14
    • 1970-01-01
    • 2015-04-12
    • 1970-01-01
    • 2016-11-23
    相关资源
    最近更新 更多