Momh
Momh

Reputation: 774

Spring boot custom starter and Spring Data JPA - How to correctly provide repositories on my own custom autoconfigure/starter module

I am trying to write an autoconfigure / starter module for one of my project. This module handles the persistence through Spring Data JPA. It aims at providing several spring data repositories.

Right now, my autoconfiguration looks like this:

@Configuration(proxyBeanMethods = false)
@AutoConfigureAfter(JpaRepositoriesAutoConfiguration::class)
@EnableJpaRepositories(basePackageClasses = [ItemRepository::class])
@EntityScan(basePackageClasses = [ItemRepository::class])
class DomainPersistenceDataJpaAutoConfiguration() {

}

As stated in spring boot reference documentation, auto configuration should not enable component scanning, although @EnableJpaRepositories uses component scanning.

What would be a good alternative approach? Is there any example of existing spring boot start which provides repositories implementation I could consult?

Upvotes: 3

Views: 2088

Answers (1)

RastislavC
RastislavC

Reputation: 61

What you're looking for is probably AutoConfigurationPackages#register method, I think the common approach would be to implement ImportBeanDefinitionRegistrar and import this implementation in your autoconfiguration using @Import. A very elegant solution can be seen in Axon framework's RegisterDefaultEntities annotation and DefaultEntityRegistrar which it imports. This way your packages will be included in jpa and entity scans.

Edit: Adding actual example since as the review pointed out, the links might change over time.

In your case the ImportBeanDefinitionRegistrar could look something like this:

import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.boot.autoconfigure.AutoConfigurationPackages;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata; 

public class StarterEntityRegistrar implements ImportBeanDefinitionRegistrar {

   @Override
   public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
      AutoConfigurationPackages.register(registry, ItemRepository.class.getPackageName());
   }
}

and your autoconfiguration would be just:

@Configuration(proxyBeanMethods = false)
@AutoConfigureAfter(JpaRepositoriesAutoConfiguration.class)
@Import(StarterEntityRegistrar.class)
class DomainPersistenceDataJpaAutoConfiguration() {

}

Upvotes: 4

Related Questions