|
|
@ -16,9 +16,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
package org.springframework.boot.sql.init.dependency;
|
|
|
|
package org.springframework.boot.sql.init.dependency;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import java.util.Arrays;
|
|
|
|
import java.util.Collection;
|
|
|
|
import java.util.Collection;
|
|
|
|
import java.util.Collections;
|
|
|
|
import java.util.Collections;
|
|
|
|
import java.util.HashSet;
|
|
|
|
import java.util.HashSet;
|
|
|
|
|
|
|
|
import java.util.LinkedHashSet;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.Set;
|
|
|
|
import java.util.Set;
|
|
|
|
|
|
|
|
|
|
|
@ -65,16 +67,23 @@ public class DatabaseInitializationDependencyConfigurer implements ImportBeanDef
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
|
|
|
|
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
|
|
|
|
if (registry.containsBeanDefinition(DependsOnDatabaseInitializationPostProcessor.class.getName())) {
|
|
|
|
String name = DependsOnDatabaseInitializationPostProcessor.class.getName();
|
|
|
|
return;
|
|
|
|
if (!registry.containsBeanDefinition(name)) {
|
|
|
|
|
|
|
|
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(
|
|
|
|
|
|
|
|
DependsOnDatabaseInitializationPostProcessor.class,
|
|
|
|
|
|
|
|
this::createDependsOnDatabaseInitializationPostProcessor);
|
|
|
|
|
|
|
|
registry.registerBeanDefinition(name, builder.getBeanDefinition());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
registry.registerBeanDefinition(DependsOnDatabaseInitializationPostProcessor.class.getName(),
|
|
|
|
|
|
|
|
BeanDefinitionBuilder
|
|
|
|
|
|
|
|
.genericBeanDefinition(DependsOnDatabaseInitializationPostProcessor.class,
|
|
|
|
|
|
|
|
() -> new DependsOnDatabaseInitializationPostProcessor(this.environment))
|
|
|
|
|
|
|
|
.getBeanDefinition());
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private DependsOnDatabaseInitializationPostProcessor createDependsOnDatabaseInitializationPostProcessor() {
|
|
|
|
|
|
|
|
return new DependsOnDatabaseInitializationPostProcessor(this.environment);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* {@link BeanFactoryPostProcessor} used to configure database initialization
|
|
|
|
|
|
|
|
* dependency relationships.
|
|
|
|
|
|
|
|
*/
|
|
|
|
static class DependsOnDatabaseInitializationPostProcessor implements BeanFactoryPostProcessor {
|
|
|
|
static class DependsOnDatabaseInitializationPostProcessor implements BeanFactoryPostProcessor {
|
|
|
|
|
|
|
|
|
|
|
|
private final Environment environment;
|
|
|
|
private final Environment environment;
|
|
|
@ -85,58 +94,55 @@ public class DatabaseInitializationDependencyConfigurer implements ImportBeanDef
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
|
|
|
|
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
|
|
|
|
Set<String> detectedDatabaseInitializers = detectDatabaseInitializers(beanFactory);
|
|
|
|
Set<String> initializerBeanNames = detectInitializerBeanNames(beanFactory);
|
|
|
|
if (detectedDatabaseInitializers.isEmpty()) {
|
|
|
|
if (initializerBeanNames.isEmpty()) {
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (String dependentDefinitionName : detectDependsOnDatabaseInitialization(beanFactory,
|
|
|
|
for (String dependsOnInitializationBeanNames : detectDependsOnInitializationBeanNames(beanFactory)) {
|
|
|
|
this.environment)) {
|
|
|
|
BeanDefinition definition = getBeanDefinition(dependsOnInitializationBeanNames, beanFactory);
|
|
|
|
BeanDefinition definition = getBeanDefinition(dependentDefinitionName, beanFactory);
|
|
|
|
definition.setDependsOn(merge(definition.getDependsOn(), initializerBeanNames));
|
|
|
|
String[] dependencies = definition.getDependsOn();
|
|
|
|
|
|
|
|
for (String dependencyName : detectedDatabaseInitializers) {
|
|
|
|
|
|
|
|
dependencies = StringUtils.addStringToArray(dependencies, dependencyName);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
definition.setDependsOn(dependencies);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private Set<String> detectDatabaseInitializers(ConfigurableListableBeanFactory beanFactory) {
|
|
|
|
private String[] merge(String[] source, Set<String> additional) {
|
|
|
|
List<DatabaseInitializerDetector> detectors = instantiateDetectors(beanFactory, this.environment,
|
|
|
|
Set<String> result = new LinkedHashSet<>((source != null) ? Arrays.asList(source) : Collections.emptySet());
|
|
|
|
DatabaseInitializerDetector.class);
|
|
|
|
result.addAll(additional);
|
|
|
|
Set<String> detected = new HashSet<>();
|
|
|
|
return StringUtils.toStringArray(result);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private Set<String> detectInitializerBeanNames(ConfigurableListableBeanFactory beanFactory) {
|
|
|
|
|
|
|
|
List<DatabaseInitializerDetector> detectors = getDetectors(beanFactory, DatabaseInitializerDetector.class);
|
|
|
|
|
|
|
|
Set<String> beanNames = new HashSet<>();
|
|
|
|
for (DatabaseInitializerDetector detector : detectors) {
|
|
|
|
for (DatabaseInitializerDetector detector : detectors) {
|
|
|
|
for (String initializerName : detector.detect(beanFactory)) {
|
|
|
|
for (String beanName : detector.detect(beanFactory)) {
|
|
|
|
detected.add(initializerName);
|
|
|
|
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
|
|
|
|
beanFactory.getBeanDefinition(initializerName)
|
|
|
|
beanDefinition.setAttribute(DatabaseInitializerDetector.class.getName(),
|
|
|
|
.setAttribute(DatabaseInitializerDetector.class.getName(), detector.getClass().getName());
|
|
|
|
detector.getClass().getName());
|
|
|
|
|
|
|
|
beanNames.add(beanName);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
detected = Collections.unmodifiableSet(detected);
|
|
|
|
beanNames = Collections.unmodifiableSet(beanNames);
|
|
|
|
for (DatabaseInitializerDetector detector : detectors) {
|
|
|
|
for (DatabaseInitializerDetector detector : detectors) {
|
|
|
|
detector.detectionComplete(beanFactory, detected);
|
|
|
|
detector.detectionComplete(beanFactory, beanNames);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return detected;
|
|
|
|
return beanNames;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private Collection<String> detectDependsOnDatabaseInitialization(ConfigurableListableBeanFactory beanFactory,
|
|
|
|
private Collection<String> detectDependsOnInitializationBeanNames(ConfigurableListableBeanFactory beanFactory) {
|
|
|
|
Environment environment) {
|
|
|
|
List<DependsOnDatabaseInitializationDetector> detectors = getDetectors(beanFactory,
|
|
|
|
List<DependsOnDatabaseInitializationDetector> detectors = instantiateDetectors(beanFactory, environment,
|
|
|
|
|
|
|
|
DependsOnDatabaseInitializationDetector.class);
|
|
|
|
DependsOnDatabaseInitializationDetector.class);
|
|
|
|
Set<String> dependentUponDatabaseInitialization = new HashSet<>();
|
|
|
|
Set<String> beanNames = new HashSet<>();
|
|
|
|
for (DependsOnDatabaseInitializationDetector detector : detectors) {
|
|
|
|
for (DependsOnDatabaseInitializationDetector detector : detectors) {
|
|
|
|
dependentUponDatabaseInitialization.addAll(detector.detect(beanFactory));
|
|
|
|
beanNames.addAll(detector.detect(beanFactory));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return dependentUponDatabaseInitialization;
|
|
|
|
return beanNames;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private <T> List<T> instantiateDetectors(ConfigurableListableBeanFactory beanFactory, Environment environment,
|
|
|
|
private <T> List<T> getDetectors(ConfigurableListableBeanFactory beanFactory, Class<T> type) {
|
|
|
|
Class<T> detectorType) {
|
|
|
|
List<String> names = SpringFactoriesLoader.loadFactoryNames(type, beanFactory.getBeanClassLoader());
|
|
|
|
List<String> detectorNames = SpringFactoriesLoader.loadFactoryNames(detectorType,
|
|
|
|
Instantiator<T> instantiator = new Instantiator<>(type,
|
|
|
|
beanFactory.getBeanClassLoader());
|
|
|
|
(availableParameters) -> availableParameters.add(Environment.class, this.environment));
|
|
|
|
Instantiator<T> instantiator = new Instantiator<>(detectorType,
|
|
|
|
return instantiator.instantiate(names);
|
|
|
|
(availableParameters) -> availableParameters.add(Environment.class, environment));
|
|
|
|
|
|
|
|
List<T> detectors = instantiator.instantiate(detectorNames);
|
|
|
|
|
|
|
|
return detectors;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static BeanDefinition getBeanDefinition(String beanName, ConfigurableListableBeanFactory beanFactory) {
|
|
|
|
private static BeanDefinition getBeanDefinition(String beanName, ConfigurableListableBeanFactory beanFactory) {
|
|
|
|