1.SpringBoot 断言机制:
@SuppressWarnings("unchecked")
private <C extends Exception> C findMostNestedCause(Throwable root, Class<C> type) {
Throwable candidate = root;
C result = null;
while (candidate != null) {
if (type.isAssignableFrom(candidate.getClass())) {
result = (C) candidate;
}
candidate = candidate.getCause();
}
return result;
}
private String getDescription(BeanInstantiationException ex) {
if (ex.getConstructingMethod() != null) {
return String.format("Method %s in %s", ex.getConstructingMethod().getName(),
ex.getConstructingMethod().getDeclaringClass().getName());
}
if (ex.getConstructor() != null) {
return String.format("Constructor in %s",
ClassUtils.getUserClass(ex.getConstructor().getDeclaringClass()).getName());
}
return ex.getBeanClass().getName();
}
private static final class BeanInCycle {
private final 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 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 this.name.equals(((BeanInCycle) obj).name);
}
@Override
public int hashCode() {
return this.name.hashCode();
}
@Override
public String toString() {
return this.name + this.description;
}
static BeanInCycle get(Throwable ex) {
if (ex instanceof BeanCreationException beanCreationException) {
return get(beanCreationException);
}
return null;
}
private static BeanInCycle get(BeanCreationException ex) {
if (StringUtils.hasText(ex.getBeanName())) {
return new BeanInCycle(ex);
}
return null;
}
}
}
public final class LoggingFailureAnalysisReporter implements FailureAnalysisReporter {
private static final Log logger = LogFactory.getLog(LoggingFailureAnalysisReporter.class);
@Override
public void report(FailureAnalysis failureAnalysis) {
if (logger.isDebugEnabled()) {
logger.debug("Application failed to start due to an exception", failureAnalysis.getCause());
}
if (logger.isErrorEnabled()) {
logger.error(buildMessage(failureAnalysis));
}
}
private String buildMessage(FailureAnalysis failureAnalysis) {
StringBuilder builder = new StringBuilder();
builder.append(String.format("%n%n"));
builder.append(String.format("***************************%n"));
builder.append(String.format("APPLICATION FAILED TO START%n"));
builder.append(String.format("***************************%n%n"));
builder.append(String.format("Description:%n%n"));
builder.append(String.format("%s%n", failureAnalysis.getDescription()));
if (StringUtils.hasText(failureAnalysis.getAction())) {
builder.append(String.format("%nAction:%n%n"));
builder.append(String.format("%s%n", failureAnalysis.getAction()));
}
return builder.toString();
}
}