|
|
@ -20,8 +20,10 @@ 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.LinkedHashMap;
|
|
|
|
import java.util.LinkedHashSet;
|
|
|
|
import java.util.LinkedHashSet;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
import java.util.Map;
|
|
|
|
import java.util.Set;
|
|
|
|
import java.util.Set;
|
|
|
|
|
|
|
|
|
|
|
|
import org.springframework.beans.factory.BeanFactory;
|
|
|
|
import org.springframework.beans.factory.BeanFactory;
|
|
|
@ -38,6 +40,7 @@ import org.springframework.core.Ordered;
|
|
|
|
import org.springframework.core.env.Environment;
|
|
|
|
import org.springframework.core.env.Environment;
|
|
|
|
import org.springframework.core.io.support.SpringFactoriesLoader;
|
|
|
|
import org.springframework.core.io.support.SpringFactoriesLoader;
|
|
|
|
import org.springframework.core.type.AnnotationMetadata;
|
|
|
|
import org.springframework.core.type.AnnotationMetadata;
|
|
|
|
|
|
|
|
import org.springframework.util.CollectionUtils;
|
|
|
|
import org.springframework.util.StringUtils;
|
|
|
|
import org.springframework.util.StringUtils;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -100,48 +103,49 @@ public class DatabaseInitializationDependencyConfigurer implements ImportBeanDef
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
|
|
|
|
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
|
|
|
|
Set<String> initializerBeanNames = detectInitializerBeanNames(beanFactory);
|
|
|
|
InitializerBeanNames initializerBeanNames = detectInitializerBeanNames(beanFactory);
|
|
|
|
if (initializerBeanNames.isEmpty()) {
|
|
|
|
if (initializerBeanNames.isEmpty()) {
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
String previousInitializerBeanName = null;
|
|
|
|
Set<String> previousInitializerBeanNamesBatch = null;
|
|
|
|
for (String initializerBeanName : initializerBeanNames) {
|
|
|
|
for (Set<String> initializerBeanNamesBatch : initializerBeanNames.batchedBeanNames()) {
|
|
|
|
BeanDefinition beanDefinition = getBeanDefinition(initializerBeanName, beanFactory);
|
|
|
|
for (String initializerBeanName : initializerBeanNamesBatch) {
|
|
|
|
beanDefinition.setDependsOn(merge(beanDefinition.getDependsOn(), previousInitializerBeanName));
|
|
|
|
BeanDefinition beanDefinition = getBeanDefinition(initializerBeanName, beanFactory);
|
|
|
|
previousInitializerBeanName = initializerBeanName;
|
|
|
|
beanDefinition
|
|
|
|
|
|
|
|
.setDependsOn(merge(beanDefinition.getDependsOn(), previousInitializerBeanNamesBatch));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
previousInitializerBeanNamesBatch = initializerBeanNamesBatch;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (String dependsOnInitializationBeanNames : detectDependsOnInitializationBeanNames(beanFactory)) {
|
|
|
|
for (String dependsOnInitializationBeanNames : detectDependsOnInitializationBeanNames(beanFactory)) {
|
|
|
|
BeanDefinition beanDefinition = getBeanDefinition(dependsOnInitializationBeanNames, beanFactory);
|
|
|
|
BeanDefinition beanDefinition = getBeanDefinition(dependsOnInitializationBeanNames, beanFactory);
|
|
|
|
beanDefinition.setDependsOn(merge(beanDefinition.getDependsOn(), initializerBeanNames));
|
|
|
|
beanDefinition.setDependsOn(merge(beanDefinition.getDependsOn(), initializerBeanNames.beanNames()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private String[] merge(String[] source, String additional) {
|
|
|
|
|
|
|
|
return merge(source, (additional != null) ? Collections.singleton(additional) : Collections.emptySet());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private String[] merge(String[] source, Set<String> additional) {
|
|
|
|
private String[] merge(String[] source, Set<String> additional) {
|
|
|
|
|
|
|
|
if (CollectionUtils.isEmpty(additional)) {
|
|
|
|
|
|
|
|
return source;
|
|
|
|
|
|
|
|
}
|
|
|
|
Set<String> result = new LinkedHashSet<>((source != null) ? Arrays.asList(source) : Collections.emptySet());
|
|
|
|
Set<String> result = new LinkedHashSet<>((source != null) ? Arrays.asList(source) : Collections.emptySet());
|
|
|
|
result.addAll(additional);
|
|
|
|
result.addAll(additional);
|
|
|
|
return StringUtils.toStringArray(result);
|
|
|
|
return StringUtils.toStringArray(result);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private Set<String> detectInitializerBeanNames(ConfigurableListableBeanFactory beanFactory) {
|
|
|
|
private InitializerBeanNames detectInitializerBeanNames(ConfigurableListableBeanFactory beanFactory) {
|
|
|
|
List<DatabaseInitializerDetector> detectors = getDetectors(beanFactory, DatabaseInitializerDetector.class);
|
|
|
|
List<DatabaseInitializerDetector> detectors = getDetectors(beanFactory, DatabaseInitializerDetector.class);
|
|
|
|
Set<String> beanNames = new LinkedHashSet<>();
|
|
|
|
InitializerBeanNames initializerBeanNames = new InitializerBeanNames();
|
|
|
|
for (DatabaseInitializerDetector detector : detectors) {
|
|
|
|
for (DatabaseInitializerDetector detector : detectors) {
|
|
|
|
for (String beanName : detector.detect(beanFactory)) {
|
|
|
|
for (String beanName : detector.detect(beanFactory)) {
|
|
|
|
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
|
|
|
|
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
|
|
|
|
beanDefinition.setAttribute(DatabaseInitializerDetector.class.getName(),
|
|
|
|
beanDefinition.setAttribute(DatabaseInitializerDetector.class.getName(),
|
|
|
|
detector.getClass().getName());
|
|
|
|
detector.getClass().getName());
|
|
|
|
beanNames.add(beanName);
|
|
|
|
initializerBeanNames.detected(detector, beanName);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
beanNames = Collections.unmodifiableSet(beanNames);
|
|
|
|
|
|
|
|
for (DatabaseInitializerDetector detector : detectors) {
|
|
|
|
for (DatabaseInitializerDetector detector : detectors) {
|
|
|
|
detector.detectionComplete(beanFactory, beanNames);
|
|
|
|
detector.detectionComplete(beanFactory, initializerBeanNames.beanNames());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return beanNames;
|
|
|
|
return initializerBeanNames;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private Collection<String> detectDependsOnInitializationBeanNames(ConfigurableListableBeanFactory beanFactory) {
|
|
|
|
private Collection<String> detectDependsOnInitializationBeanNames(ConfigurableListableBeanFactory beanFactory) {
|
|
|
@ -174,6 +178,31 @@ public class DatabaseInitializationDependencyConfigurer implements ImportBeanDef
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static class InitializerBeanNames {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private final Map<DatabaseInitializerDetector, Set<String>> byDetectorBeanNames = new LinkedHashMap<>();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private final Set<String> beanNames = new LinkedHashSet<>();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void detected(DatabaseInitializerDetector detector, String beanName) {
|
|
|
|
|
|
|
|
this.byDetectorBeanNames.computeIfAbsent(detector, (key) -> new LinkedHashSet<>()).add(beanName);
|
|
|
|
|
|
|
|
this.beanNames.add(beanName);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private boolean isEmpty() {
|
|
|
|
|
|
|
|
return this.beanNames.isEmpty();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private Iterable<Set<String>> batchedBeanNames() {
|
|
|
|
|
|
|
|
return this.byDetectorBeanNames.values();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private Set<String> beanNames() {
|
|
|
|
|
|
|
|
return Collections.unmodifiableSet(this.beanNames);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|