Home / Class/ NoUniqueBeanDefinitionFailureAnalyzer Class — spring-boot Architecture

NoUniqueBeanDefinitionFailureAnalyzer Class — spring-boot Architecture

Architecture documentation for the NoUniqueBeanDefinitionFailureAnalyzer class in NoUniqueBeanDefinitionFailureAnalyzer.java from the spring-boot codebase.

Entity Profile

Relationship Graph

Source Code

core/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/NoUniqueBeanDefinitionFailureAnalyzer.java lines 37–101

class NoUniqueBeanDefinitionFailureAnalyzer extends AbstractInjectionFailureAnalyzer<NoUniqueBeanDefinitionException> {

	private final ConfigurableBeanFactory beanFactory;

	NoUniqueBeanDefinitionFailureAnalyzer(BeanFactory beanFactory) {
		Assert.isInstanceOf(ConfigurableBeanFactory.class, beanFactory);
		this.beanFactory = (ConfigurableBeanFactory) beanFactory;
	}

	@Override
	protected @Nullable FailureAnalysis analyze(Throwable rootFailure, NoUniqueBeanDefinitionException cause,
			@Nullable String description) {
		String[] beanNames = extractBeanNames(cause);
		if (beanNames == null) {
			return null;
		}
		StringBuilder message = new StringBuilder();
		message.append(String.format("%s required a single bean, but %d were found:%n",
				(description != null) ? description : "A component", beanNames.length));
		for (String beanName : beanNames) {
			buildMessage(message, beanName);
		}
		MissingParameterNamesFailureAnalyzer.appendPossibility(message);
		StringBuilder action = new StringBuilder(
				"Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, "
						+ "or using @Qualifier to identify the bean that should be consumed");
		action.append("%n%n%s".formatted(MissingParameterNamesFailureAnalyzer.ACTION));
		return new FailureAnalysis(message.toString(), action.toString(), cause);
	}

	private void buildMessage(StringBuilder message, String beanName) {
		try {
			BeanDefinition definition = this.beanFactory.getMergedBeanDefinition(beanName);
			message.append(getDefinitionDescription(beanName, definition));
		}
		catch (NoSuchBeanDefinitionException ex) {
			message.append(String.format("\t- %s: a programmatically registered singleton%n", beanName));
		}
	}

	private String getDefinitionDescription(String beanName, BeanDefinition definition) {
		if (StringUtils.hasText(definition.getFactoryMethodName())) {
			return String.format("\t- %s: defined by method '%s' in %s%n", beanName, definition.getFactoryMethodName(),
					getResourceDescription(definition));
		}
		return String.format("\t- %s: defined in %s%n", beanName, getResourceDescription(definition));
	}

	private String getResourceDescription(BeanDefinition definition) {
		String resourceDescription = definition.getResourceDescription();
		return (resourceDescription != null) ? resourceDescription : "unknown location";
	}

	private String @Nullable [] extractBeanNames(NoUniqueBeanDefinitionException cause) {
		String message = cause.getMessage();
		if (message == null) {
			message = "";
		}
		if (message.contains("but found")) {
			return StringUtils.commaDelimitedListToStringArray(message.substring(message.lastIndexOf(':') + 1).trim());
		}
		return null;
	}

}

Domain

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free