Merge branch '2.0.x'
This commit is contained in:
commit
646c20ed6a
|
@ -16,6 +16,7 @@
|
|||
|
||||
package org.springframework.boot.autoconfigure.diagnostics.analyzer;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
@ -30,6 +31,7 @@ import org.springframework.beans.factory.BeanFactory;
|
|||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.BeanFactoryUtils;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.UnsatisfiedDependencyException;
|
||||
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
|
@ -89,11 +91,23 @@ class NoSuchBeanDefinitionFailureAnalyzer
|
|||
message.append(String.format("%s required %s that could not be found.%n",
|
||||
(description != null) ? description : "A component",
|
||||
getBeanDescription(cause)));
|
||||
for (AutoConfigurationResult result : autoConfigurationResults) {
|
||||
message.append(String.format("\t- %s%n", result));
|
||||
List<Annotation> injectionAnnotations = findInjectionAnnotations(rootFailure);
|
||||
if (!injectionAnnotations.isEmpty()) {
|
||||
message.append(String
|
||||
.format("%nThe injection point has the following annotations:%n"));
|
||||
for (Annotation injectionAnnotation : injectionAnnotations) {
|
||||
message.append(String.format("\t- %s%n", injectionAnnotation));
|
||||
}
|
||||
}
|
||||
for (UserConfigurationResult result : userConfigurationResults) {
|
||||
message.append(String.format("\t- %s%n", result));
|
||||
if (!autoConfigurationResults.isEmpty() || !userConfigurationResults.isEmpty()) {
|
||||
message.append(String.format(
|
||||
"%nThe following candidates were found but could not be injected:%n"));
|
||||
for (AutoConfigurationResult result : autoConfigurationResults) {
|
||||
message.append(String.format("\t- %s%n", result));
|
||||
}
|
||||
for (UserConfigurationResult result : userConfigurationResults) {
|
||||
message.append(String.format("\t- %s%n", result));
|
||||
}
|
||||
}
|
||||
String action = String.format("Consider %s %s in your configuration.",
|
||||
(!autoConfigurationResults.isEmpty()
|
||||
|
@ -164,7 +178,7 @@ class NoSuchBeanDefinitionFailureAnalyzer
|
|||
if (!conditionAndOutcome.getOutcome().isMatch()) {
|
||||
for (MethodMetadata method : methods) {
|
||||
results.add(new AutoConfigurationResult(method,
|
||||
conditionAndOutcome.getOutcome(), source.isMethod()));
|
||||
conditionAndOutcome.getOutcome()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -179,11 +193,21 @@ class NoSuchBeanDefinitionFailureAnalyzer
|
|||
String message = String.format("auto-configuration '%s' was excluded",
|
||||
ClassUtils.getShortName(excludedClass));
|
||||
results.add(new AutoConfigurationResult(method,
|
||||
new ConditionOutcome(false, message), false));
|
||||
new ConditionOutcome(false, message)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<Annotation> findInjectionAnnotations(Throwable failure) {
|
||||
UnsatisfiedDependencyException unsatisfiedDependencyException = findCause(failure,
|
||||
UnsatisfiedDependencyException.class);
|
||||
if (unsatisfiedDependencyException == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return Arrays.asList(
|
||||
unsatisfiedDependencyException.getInjectionPoint().getAnnotations());
|
||||
}
|
||||
|
||||
private class Source {
|
||||
|
||||
private final String className;
|
||||
|
@ -204,10 +228,6 @@ class NoSuchBeanDefinitionFailureAnalyzer
|
|||
return this.methodName;
|
||||
}
|
||||
|
||||
public boolean isMethod() {
|
||||
return this.methodName != null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class BeanMethods implements Iterable<MethodMetadata> {
|
||||
|
@ -295,26 +315,17 @@ class NoSuchBeanDefinitionFailureAnalyzer
|
|||
|
||||
private final ConditionOutcome conditionOutcome;
|
||||
|
||||
private final boolean methodEvaluated;
|
||||
|
||||
AutoConfigurationResult(MethodMetadata methodMetadata,
|
||||
ConditionOutcome conditionOutcome, boolean methodEvaluated) {
|
||||
ConditionOutcome conditionOutcome) {
|
||||
this.methodMetadata = methodMetadata;
|
||||
this.conditionOutcome = conditionOutcome;
|
||||
this.methodEvaluated = methodEvaluated;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (this.methodEvaluated) {
|
||||
return String.format("Bean method '%s' in '%s' not loaded because %s",
|
||||
this.methodMetadata.getMethodName(),
|
||||
ClassUtils.getShortName(
|
||||
this.methodMetadata.getDeclaringClassName()),
|
||||
this.conditionOutcome.getMessage());
|
||||
}
|
||||
return String.format("Bean method '%s' not loaded because %s",
|
||||
return String.format("Bean method '%s' in '%s' not loaded because %s",
|
||||
this.methodMetadata.getMethodName(),
|
||||
ClassUtils.getShortName(this.methodMetadata.getDeclaringClassName()),
|
||||
this.conditionOutcome.getMessage());
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ import org.springframework.beans.DirectFieldAccessor;
|
|||
import org.springframework.beans.FatalBeanException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionEvaluationReport;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
|
@ -101,7 +102,7 @@ public class NoSuchBeanDefinitionFailureAnalyzerTests {
|
|||
assertDescriptionConstructorMissingType(analysis, StringHandler.class, 0,
|
||||
String.class);
|
||||
assertClassDisabled(analysis, "did not find required class 'com.example.FooBar'",
|
||||
"string");
|
||||
"string", ClassUtils.getShortName(TestTypeClassAutoConfiguration.class));
|
||||
assertActionMissingType(analysis, String.class);
|
||||
}
|
||||
|
||||
|
@ -116,7 +117,7 @@ public class NoSuchBeanDefinitionFailureAnalyzerTests {
|
|||
.getShortName(TestPropertyAutoConfiguration.class.getName());
|
||||
assertClassDisabled(analysis,
|
||||
String.format("auto-configuration '%s' was excluded", configClass),
|
||||
"string");
|
||||
"string", ClassUtils.getShortName(TestPropertyAutoConfiguration.class));
|
||||
assertActionMissingType(analysis, String.class);
|
||||
}
|
||||
|
||||
|
@ -130,7 +131,7 @@ public class NoSuchBeanDefinitionFailureAnalyzerTests {
|
|||
"did not find property 'spring.string.enabled'",
|
||||
TestPropertyAutoConfiguration.class, "string");
|
||||
assertClassDisabled(analysis, "did not find required class 'com.example.FooBar'",
|
||||
"string");
|
||||
"string", ClassUtils.getShortName(TestPropertyAutoConfiguration.class));
|
||||
assertActionMissingType(analysis, String.class);
|
||||
}
|
||||
|
||||
|
@ -169,6 +170,14 @@ public class NoSuchBeanDefinitionFailureAnalyzerTests {
|
|||
assertActionMissingType(analysis, String.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failureAnalysisForUnmatchedQualfier() {
|
||||
FailureAnalysis analysis = analyzeFailure(
|
||||
createFailure(QualifiedBeanConfiguration.class));
|
||||
assertThat(analysis.getDescription()).contains(
|
||||
"@org.springframework.beans.factory.annotation.Qualifier(value=alpha)");
|
||||
}
|
||||
|
||||
private void assertDescriptionConstructorMissingType(FailureAnalysis analysis,
|
||||
Class<?> component, int index, Class<?> type) {
|
||||
String expected = String.format(
|
||||
|
@ -201,9 +210,9 @@ public class NoSuchBeanDefinitionFailureAnalyzerTests {
|
|||
}
|
||||
|
||||
private void assertClassDisabled(FailureAnalysis analysis, String description,
|
||||
String methodName) {
|
||||
String expected = String.format("Bean method '%s' not loaded because",
|
||||
methodName);
|
||||
String methodName, String className) {
|
||||
String expected = String.format("Bean method '%s' in '%s' not loaded because",
|
||||
methodName, className);
|
||||
assertThat(analysis.getDescription()).contains(expected);
|
||||
assertThat(analysis.getDescription()).contains(description);
|
||||
}
|
||||
|
@ -340,6 +349,25 @@ public class NoSuchBeanDefinitionFailureAnalyzerTests {
|
|||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
public static class QualifiedBeanConfiguration {
|
||||
|
||||
@Bean
|
||||
public String consumer(@Qualifier("alpha") Thing thing) {
|
||||
return "consumer";
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Thing producer() {
|
||||
return new Thing();
|
||||
}
|
||||
|
||||
class Thing {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected static class StringHandler {
|
||||
|
||||
public StringHandler(String foo) {
|
||||
|
|
Loading…
Reference in New Issue