当前位置: 首页 > 知识库问答 >
问题:

有没有办法注册一个存储库基类与一个Spring启动自动配置?

艾谦
2023-03-14

我们有一个基本的JPA存储库类,其中有一些我们在项目中使用的附加实用程序方法。在Spring Data JPA留档之后,我们创建了这个类,并在配置类中使用@EnableJpaRepository注释,如以下示例所示:

@Configuration
@EnableJpaRepositories(basePackageClasses = MyApplication.class,
    repositoryBaseClass = MyJpaRepositoryImpl.class)
public class SpringDataJpaMyRepositoryConfiguration {
}

由于配置类不在应用程序根包中,因此我们还设置了base PackageClass属性,以便找到我们的存储库。一切都按预期进行,因此到目前为止没有问题。

现在,我们想创建一个spring启动启动程序,在不进行进一步配置的情况下将存储库基类添加到我们的项目中,但我们不知道如何做到这一点。如果我们使用EnableJpaRepositories注释设置repositoryBaseClass属性来创建一个自动配置类,那么在@SpringBootApplication注释的类下查找存储库的自动存储库查找策略将不再有效。

而且我们不能使用base PackageClass属性,因为我们不知道使用自动配置的项目的主类或包。

有什么办法吗?也许在我们的自动配置中重新定义一些bean?

理想的方法是允许设置存储库基类,而不必再次定义所有的Spring Data JPA自动配置。

共有2个答案

薛欣荣
2023-03-14

编辑:我几乎重写了我的答案——我误解了最初的问题

这不是最好的解决方案,但我能看到这一点的唯一方法是在@EnableJpaRepositories中使用SpEL。

然后,可以在自动配置中使用@ConditionalOnProperty仅在设置了基本包属性的情况下进行自动配置

@Configuration
@ConditionalOnProperty("repositories-base-packages")
public class BaseRepositoryAutoConfiguration {

    @Configuration
    @EnableJpaRepositories(
            repositoryBaseClass = MyJpaRepositoryImpl.class,
            basePackages = "${repositories-base-packages}"
    )
    public static class JpaRepositoriesConfig { }

}

然后确保你有一个应用程序。属性应用程序。yml在应用程序中定义存储库基本包

不确定如何声明多个基本包,我的SpEL知识是原始的,所以不确定它是否可能。

黄淇
2023-03-14

这个问题当时把我逼疯了,所以我想我可以在这方面帮你。

基本上,这个想法是:

  • 为Jpa配置创建一个配置类
  • 添加引用与basePackageClass相同的配置类的@EntityScan和@EnableJpaRepositories
  • 在自动配置中导入此配置
  • 创建一个注释,然后在需要Jpa配置的地方重用它

在您的示例中,您使用Spring应用程序类作为扫描的基础。

我已经提出了一个示例项目POC的主要想法在https://github.com/rdlopes/custom-jpa-demo

在本例中,有一个JPA实体/存储库项目公开了一个JPA配置:

   @Configuration
   @EntityScan(basePackageClasses = JpaConfiguration.class)
   @EnableJpaRepositories(basePackageClasses = JpaConfiguration.class,
                          repositoryBaseClass = BaseRepositoryImpl.class)
   public class JpaConfiguration {

   }

小心你的存储库的通用实现,你需要显示一个特殊的签名:

@NoRepositoryBean
public class BaseRepositoryImpl<T, ID extends Serializable>
        extends SimpleJpaRepository<T, ID>
        implements BaseRepository<T, ID> {

    public BaseRepositoryImpl(JpaEntityInformation<T, ID> entityInformation, EntityManager entityManager) {
        super(entityInformation, entityManager);
    }

    @Override
    public String someCustomMethod(ID id) {
        return "Class for entity of id " + id + " is: " + getDomainClass().getSimpleName();
    }
}

然后,您可以创建如下自动配置:

@Configuration
@ConditionalOnClass(CustomJpaRepositories.class)
@Import(JpaConfiguration.class)
public class JpaCustomAutoConfiguration {

}

提供一个注释来保持整洁,并在需要JPA的地方使用它:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface CustomJpaRepositories {
}

使用您的JPA类将非常简单,就像使用以下注释一样,您可以在其中调用您的JPA存储库:

@SpringBootApplication
@CustomJpaRepositories
public class CustomJpaSampleApplication {

    public static void main(String[] args) {
        SpringApplication.run(CustomJpaSampleApplication.class, args);
    }

    @Bean
    public CommandLineRunner dataInitializer(UserRepository userRepository) {
        return args -> {
            User user1 = new User();
            user1.setName("user 1");
            userRepository.save(user1);

            User user2 = new User();
            user2.setName("user 2");
            userRepository.save(user2);

            userRepository.findAll()
                          .forEach(user -> System.out.println(
                                  userRepository.someCustomMethod(user.getId())));
        };
    }
}

希望这有助于你度过挠头的时刻:-)

 类似资料:
  • 问题内容: 根据MDN 文档: 该 方法冻结对象:即,防止向其添加新属性;防止现有属性被删除;并防止更改现有属性或其可枚举性,可配置性或可写性。本质上,对象实际上是不可变的。该方法返回被冻结的对象。 我期望在某个日期调用冻结会阻止对该日期进行更改,但是它似乎没有用。这是我正在做的(运行Node.js v5.3.0): 我本以为调用会失败或什么都不做。任何想法如何冻结日期? 问题答案: 有没有办法O

  • @java接口注释。 如果我添加@Target(value=ElementType.METHOD),可以为Java方法导入此注释。 有没有办法让这个注释自动检查Java方法参数类型? 比如,我有一个方法: 一旦我添加了客户注释,它会自动检查sayHello参数类型是否匹配,如果不匹配,将导致编译错误。 它可以实现吗?如果,如何实现?排除在Runtime中使用java Reflect进行检查的想法,

  • 嘿,我是c的新手,我正在尝试创建一个可以存储多种类型的地图: Wich显然给我带来了一些错误。 我在网上查了一下,发现了一些有趣的东西,但没有答案。也许我漏掉了一点c语言词汇。 我也会尝试一些关于任何类型的一流三明治商店,我不知道它是否有效。 谢谢你的帮助!

  • 我正在开发一个数据访问库,并希望能够以最少的配置将其作为依赖项包含在其他项目中(理想情况下只是自动连接存储库)。特别是,这个库使用自动配置类(在中启用)进行设置,并且需要禁用其他自动配置类才能工作(和)。 是否可以在从属项目之外执行此操作? 为了使配置尽可能简单,我希望避免将排除项放在依赖项目的注释或其属性中。 更新: 在我的@Configuration上,我尝试添加注释: 这导致了 Illega

  • 我已经用@Autowired注释为相应的存储库定义了服务类 存储库接口定义为从JpaReepository扩展 应用程序自动编译服务类 运行时,我得到以下错误

  • spring-boot使用“starters”来定义项目可能包含的一组库依赖项。这个maven模块,泽西的启动器,例如: https://github.com/spring-projects/spring-boot/tree/master/spring-boot-starters/spring-boot-starter-jersey spring-boot使用autoconfigures来实例化和