Last active
November 28, 2018 16:06
-
-
Save gdpotter/55e68308ac191308c294a2cc42e596b2 to your computer and use it in GitHub Desktop.
Spring Circular Dependency Analysis
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class DepGraph { | |
private final Map<String, Set<String>> nodes; | |
private DepGraph(Map<String, Set<String>> nodes) { | |
this.nodes = nodes; | |
} | |
public Set<String> calculateCycles() { | |
Set<String> visited = new HashSet<>(); | |
return nodes.keySet().stream() | |
.map(node -> calculateCycles(node, visited, Collections.emptyList())) | |
.flatMap(Set::stream) | |
.collect(Collectors.toSet()); | |
} | |
private Set<String> calculateCycles(String node, Set<String> visited, List<String> path) { | |
List<String> newPath = new LinkedList<>(path); | |
newPath.add(node); | |
if (path.contains(node)) { | |
List<String> cycle = newPath.subList(path.indexOf(node), path.size()); | |
return Collections.singleton(String.join("->", cycle)); | |
} | |
if (visited.contains(node)) { | |
return Collections.emptySet(); | |
} | |
visited.add(node); | |
Set<String> deps = nodes.getOrDefault(node, Collections.emptySet()); | |
return deps.stream() | |
.map(dep -> calculateCycles(dep, visited, newPath)) | |
.flatMap(Set::stream) | |
.collect(Collectors.toSet()); | |
} | |
public static DepGraph buildDependencyGraph(GenericApplicationContext applicationContext) { | |
ConfigurableListableBeanFactory factory = applicationContext.getBeanFactory(); | |
Map<String, Set<String>> beanDeps = Arrays.stream(factory.getBeanDefinitionNames()) | |
.filter(beanName -> !factory.getBeanDefinition(beanName).isAbstract()) | |
.collect(Collectors.toMap( | |
Function.identity(), | |
beanName -> new HashSet<>(Arrays.asList(factory.getDependenciesForBean(beanName))) | |
)); | |
return new DepGraph(beanDeps); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment