Support comma-separated basePackage values in EntityScan

See gh-27355
This commit is contained in:
Saraswathy Hariharakrishnan 2021-07-15 15:21:13 -07:00 committed by Madhura Bhave
parent 66cedfa544
commit 00b9a8811d
2 changed files with 20 additions and 1 deletions

View File

@ -30,6 +30,7 @@ import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition; import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.annotation.AnnotationAttributes; import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
@ -141,7 +142,10 @@ public class EntityScanPackages {
.fromMap(metadata.getAnnotationAttributes(EntityScan.class.getName())); .fromMap(metadata.getAnnotationAttributes(EntityScan.class.getName()));
Set<String> packagesToScan = new LinkedHashSet<>(); Set<String> packagesToScan = new LinkedHashSet<>();
for (String basePackage : attributes.getStringArray("basePackages")) { for (String basePackage : attributes.getStringArray("basePackages")) {
addResolvedPackage(basePackage, packagesToScan); String[] tokenized = StringUtils.tokenizeToStringArray(
this.environment.resolvePlaceholders(basePackage),
ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
Collections.addAll(packagesToScan, tokenized);
} }
for (Class<?> basePackageClass : attributes.getClassArray("basePackageClasses")) { for (Class<?> basePackageClass : attributes.getClassArray("basePackageClasses")) {
addResolvedPackage(ClassUtils.getPackageName(basePackageClass), packagesToScan); addResolvedPackage(ClassUtils.getPackageName(basePackageClass), packagesToScan);

View File

@ -25,6 +25,7 @@ import javax.persistence.Entity;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
import org.springframework.boot.autoconfigure.data.jpa.city.City;
import org.springframework.boot.autoconfigure.domain.scan.a.EmbeddableA; import org.springframework.boot.autoconfigure.domain.scan.a.EmbeddableA;
import org.springframework.boot.autoconfigure.domain.scan.a.EntityA; import org.springframework.boot.autoconfigure.domain.scan.a.EntityA;
import org.springframework.boot.autoconfigure.domain.scan.b.EmbeddableB; import org.springframework.boot.autoconfigure.domain.scan.b.EmbeddableB;
@ -119,6 +120,20 @@ class EntityScannerTests {
assertThat(annotationTypeFilter.getValue().getAnnotationType()).isEqualTo(Entity.class); assertThat(annotationTypeFilter.getValue().getAnnotationType()).isEqualTo(Entity.class);
} }
@Test
void scanShouldScanCommaSeparatedPackagesInPlaceholderPackage() throws Exception {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
TestPropertyValues.of(
"com.example.entity-package=org.springframework.boot.autoconfigure.domain.scan,org.springframework.boot.autoconfigure.data.jpa.city")
.applyTo(context);
context.register(ScanPlaceholderConfig.class);
context.refresh();
EntityScanner scanner = new EntityScanner(context);
Set<Class<?>> scanned = scanner.scan(Entity.class);
assertThat(scanned).containsOnly(EntityA.class, EntityB.class, EntityC.class, City.class);
context.close();
}
private static class TestEntityScanner extends EntityScanner { private static class TestEntityScanner extends EntityScanner {
private final ClassPathScanningCandidateComponentProvider candidateComponentProvider; private final ClassPathScanningCandidateComponentProvider candidateComponentProvider;