BeanCurrentlyInCreationFailureAnalyzer Class — spring-boot Architecture
Architecture documentation for the BeanCurrentlyInCreationFailureAnalyzer class in BeanCurrentlyInCreationFailureAnalyzer.java from the spring-boot codebase.
Entity Profile
Relationship Graph
Source Code
core/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/BeanCurrentlyInCreationFailureAnalyzer.java lines 42–206
class BeanCurrentlyInCreationFailureAnalyzer extends AbstractFailureAnalyzer<BeanCurrentlyInCreationException> {
private final @Nullable AbstractAutowireCapableBeanFactory beanFactory;
BeanCurrentlyInCreationFailureAnalyzer(BeanFactory beanFactory) {
if (beanFactory instanceof AbstractAutowireCapableBeanFactory autowireCapableBeanFactory) {
this.beanFactory = autowireCapableBeanFactory;
}
else {
this.beanFactory = null;
}
}
@Override
protected @Nullable FailureAnalysis analyze(Throwable rootFailure, BeanCurrentlyInCreationException cause) {
DependencyCycle dependencyCycle = findCycle(rootFailure);
if (dependencyCycle == null) {
return null;
}
return new FailureAnalysis(buildMessage(dependencyCycle), action(), cause);
}
private String action() {
if (this.beanFactory != null && this.beanFactory.isAllowCircularReferences()) {
return "Despite circular references being allowed, the dependency cycle between beans could not be "
+ "broken. Update your application to remove the dependency cycle.";
}
return "Relying upon circular references is discouraged and they are prohibited by default. "
+ "Update your application to remove the dependency cycle between beans. "
+ "As a last resort, it may be possible to break the cycle automatically by setting "
+ "spring.main.allow-circular-references to true.";
}
private @Nullable DependencyCycle findCycle(Throwable rootFailure) {
List<BeanInCycle> beansInCycle = new ArrayList<>();
Throwable candidate = rootFailure;
int cycleStart = -1;
while (candidate != null) {
BeanInCycle beanInCycle = BeanInCycle.get(candidate);
if (beanInCycle != null) {
int index = beansInCycle.indexOf(beanInCycle);
if (index == -1) {
beansInCycle.add(beanInCycle);
}
cycleStart = (cycleStart != -1) ? cycleStart : index;
}
candidate = candidate.getCause();
}
if (cycleStart == -1) {
return null;
}
return new DependencyCycle(beansInCycle, cycleStart);
}
private String buildMessage(DependencyCycle dependencyCycle) {
StringBuilder message = new StringBuilder();
message.append(
String.format("The dependencies of some of the beans in the application context form a cycle:%n%n"));
List<BeanInCycle> beansInCycle = dependencyCycle.getBeansInCycle();
boolean singleBean = beansInCycle.size() == 1;
int cycleStart = dependencyCycle.getCycleStart();
for (int i = 0; i < beansInCycle.size(); i++) {
BeanInCycle beanInCycle = beansInCycle.get(i);
if (i == cycleStart) {
message.append(String.format(singleBean ? "┌──->──┐%n" : "┌─────┐%n"));
}
else if (i > 0) {
String leftSide = (i < cycleStart) ? " " : "↑";
message.append(String.format("%s ↓%n", leftSide));
}
String leftSide = (i < cycleStart) ? " " : "|";
message.append(String.format("%s %s%n", leftSide, beanInCycle));
}
message.append(String.format(singleBean ? "└──<-──┘%n" : "└─────┘%n"));
return message.toString();
}
private static final class DependencyCycle {
private final List<BeanInCycle> beansInCycle;
private final int cycleStart;
private DependencyCycle(List<BeanInCycle> beansInCycle, int cycleStart) {
this.beansInCycle = beansInCycle;
this.cycleStart = cycleStart;
}
List<BeanInCycle> getBeansInCycle() {
return this.beansInCycle;
}
int getCycleStart() {
return this.cycleStart;
}
}
private static final class BeanInCycle {
private final @Nullable String name;
private final String description;
private BeanInCycle(BeanCreationException ex) {
this.name = ex.getBeanName();
this.description = determineDescription(ex);
}
private String determineDescription(BeanCreationException ex) {
if (StringUtils.hasText(ex.getResourceDescription())) {
return String.format(" defined in %s", ex.getResourceDescription());
}
InjectionPoint failedInjectionPoint = findFailedInjectionPoint(ex);
if (failedInjectionPoint != null && failedInjectionPoint.getField() != null) {
return String.format(" (field %s)", failedInjectionPoint.getField());
}
return "";
}
private @Nullable InjectionPoint findFailedInjectionPoint(BeanCreationException ex) {
if (ex instanceof UnsatisfiedDependencyException unsatisfiedDependencyException) {
return unsatisfiedDependencyException.getInjectionPoint();
}
return null;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
return Objects.equals(this.name, ((BeanInCycle) obj).name);
}
@Override
public int hashCode() {
return Objects.hashCode(this.name);
}
@Override
public String toString() {
return this.name + this.description;
}
static @Nullable BeanInCycle get(Throwable ex) {
if (ex instanceof BeanCreationException beanCreationException) {
return get(beanCreationException);
}
return null;
}
private static @Nullable BeanInCycle get(BeanCreationException ex) {
if (StringUtils.hasText(ex.getBeanName())) {
return new BeanInCycle(ex);
}
return null;
}
}
}
Domain
Source
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free