parent
cf46f391d7
commit
d59991fcc9
|
@ -68,9 +68,6 @@ class BeanOverrideBeanFactoryPostProcessor implements BeanFactoryPostProcessor,
|
||||||
|
|
||||||
private static final BeanNameGenerator beanNameGenerator = DefaultBeanNameGenerator.INSTANCE;
|
private static final BeanNameGenerator beanNameGenerator = DefaultBeanNameGenerator.INSTANCE;
|
||||||
|
|
||||||
private static final String unableToOverrideByTypeDiagnosticsMessage = " If the bean is defined from a @Bean method,"
|
|
||||||
+ " please make sure the return type is the most specific type (recommended) or type can be assigned to %s";
|
|
||||||
|
|
||||||
private final Set<BeanOverrideHandler> beanOverrideHandlers;
|
private final Set<BeanOverrideHandler> beanOverrideHandlers;
|
||||||
|
|
||||||
private final BeanOverrideRegistry beanOverrideRegistry;
|
private final BeanOverrideRegistry beanOverrideRegistry;
|
||||||
|
@ -172,9 +169,11 @@ class BeanOverrideBeanFactoryPostProcessor implements BeanFactoryPostProcessor,
|
||||||
}
|
}
|
||||||
else if (requireExistingBean) {
|
else if (requireExistingBean) {
|
||||||
Field field = handler.getField();
|
Field field = handler.getField();
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException("""
|
||||||
"Unable to replace bean: there is no bean with name '%s' and type %s%s."
|
Unable to replace bean: there is no bean with name '%s' and type %s%s. \
|
||||||
.formatted(beanName, handler.getBeanType(), requiredByField(field, handler.getBeanType())));
|
If the bean is defined in a @Bean method, make sure the return type is the \
|
||||||
|
most specific type possible (for example, the concrete implementation type)."""
|
||||||
|
.formatted(beanName, handler.getBeanType(), requiredByField(field)));
|
||||||
}
|
}
|
||||||
// 4) We are creating a bean by-name with the provided beanName.
|
// 4) We are creating a bean by-name with the provided beanName.
|
||||||
}
|
}
|
||||||
|
@ -261,7 +260,11 @@ class BeanOverrideBeanFactoryPostProcessor implements BeanFactoryPostProcessor,
|
||||||
String message = "Unable to select a bean to wrap: ";
|
String message = "Unable to select a bean to wrap: ";
|
||||||
int candidateCount = candidateNames.size();
|
int candidateCount = candidateNames.size();
|
||||||
if (candidateCount == 0) {
|
if (candidateCount == 0) {
|
||||||
message += "there are no beans of type %s%s.".formatted(beanType, requiredByField(field, beanType));
|
message += """
|
||||||
|
there are no beans of type %s%s. \
|
||||||
|
If the bean is defined in a @Bean method, make sure the return type is the \
|
||||||
|
most specific type possible (for example, the concrete implementation type)."""
|
||||||
|
.formatted(beanType, requiredByField(field));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
message += "found %d beans of type %s%s: %s"
|
message += "found %d beans of type %s%s: %s"
|
||||||
|
@ -275,8 +278,10 @@ class BeanOverrideBeanFactoryPostProcessor implements BeanFactoryPostProcessor,
|
||||||
// We are wrapping an existing bean by-name.
|
// We are wrapping an existing bean by-name.
|
||||||
Set<String> candidates = getExistingBeanNamesByType(beanFactory, handler, false);
|
Set<String> candidates = getExistingBeanNamesByType(beanFactory, handler, false);
|
||||||
if (!candidates.contains(beanName)) {
|
if (!candidates.contains(beanName)) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException("""
|
||||||
"Unable to wrap bean: there is no bean with name '%s' and type %s%s."
|
Unable to wrap bean: there is no bean with name '%s' and type %s%s. \
|
||||||
|
If the bean is defined in a @Bean method, make sure the return type is the \
|
||||||
|
most specific type possible (for example, the concrete implementation type)."""
|
||||||
.formatted(beanName, beanType, requiredByField(field)));
|
.formatted(beanName, beanType, requiredByField(field)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -301,9 +306,11 @@ class BeanOverrideBeanFactoryPostProcessor implements BeanFactoryPostProcessor,
|
||||||
int candidateCount = candidateNames.size();
|
int candidateCount = candidateNames.size();
|
||||||
if (candidateCount == 0) {
|
if (candidateCount == 0) {
|
||||||
if (requireExistingBean) {
|
if (requireExistingBean) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException("""
|
||||||
"Unable to override bean: there are no beans of type %s%s."
|
Unable to override bean: there are no beans of type %s%s. \
|
||||||
.formatted(beanType, requiredByField(field, beanType)));
|
If the bean is defined in a @Bean method, make sure the return type is the \
|
||||||
|
most specific type possible (for example, the concrete implementation type)."""
|
||||||
|
.formatted(beanType, requiredByField(field)));
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -487,8 +494,4 @@ class BeanOverrideBeanFactoryPostProcessor implements BeanFactoryPostProcessor,
|
||||||
field.getDeclaringClass().getSimpleName(), field.getName());
|
field.getDeclaringClass().getSimpleName(), field.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String requiredByField(@Nullable Field field, ResolvableType requiredBeanType) {
|
|
||||||
return requiredByField(field) + '.' + unableToOverrideByTypeDiagnosticsMessage.formatted(requiredBeanType);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,9 +85,11 @@ class BeanOverrideBeanFactoryPostProcessorTests {
|
||||||
|
|
||||||
assertThatIllegalStateException()
|
assertThatIllegalStateException()
|
||||||
.isThrownBy(context::refresh)
|
.isThrownBy(context::refresh)
|
||||||
.withMessageStartingWith("""
|
.withMessage("""
|
||||||
Unable to replace bean: there is no bean with name 'descriptionBean' \
|
Unable to replace bean: there is no bean with name 'descriptionBean' \
|
||||||
and type java.lang.String (as required by field 'ByNameTestCase.description').""");
|
and type java.lang.String (as required by field 'ByNameTestCase.description'). \
|
||||||
|
If the bean is defined in a @Bean method, make sure the return type is the most \
|
||||||
|
specific type possible (for example, the concrete implementation type).""");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -97,9 +99,11 @@ class BeanOverrideBeanFactoryPostProcessorTests {
|
||||||
|
|
||||||
assertThatIllegalStateException()
|
assertThatIllegalStateException()
|
||||||
.isThrownBy(context::refresh)
|
.isThrownBy(context::refresh)
|
||||||
.withMessageStartingWith("""
|
.withMessage("""
|
||||||
Unable to replace bean: there is no bean with name 'descriptionBean' \
|
Unable to replace bean: there is no bean with name 'descriptionBean' \
|
||||||
and type java.lang.String (as required by field 'ByNameTestCase.description').""");
|
and type java.lang.String (as required by field 'ByNameTestCase.description'). \
|
||||||
|
If the bean is defined in a @Bean method, make sure the return type is the most \
|
||||||
|
specific type possible (for example, the concrete implementation type).""");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -144,9 +148,11 @@ class BeanOverrideBeanFactoryPostProcessorTests {
|
||||||
|
|
||||||
assertThatIllegalStateException()
|
assertThatIllegalStateException()
|
||||||
.isThrownBy(context::refresh)
|
.isThrownBy(context::refresh)
|
||||||
.withMessageStartingWith("""
|
.withMessage("""
|
||||||
Unable to override bean: there are no beans of type java.lang.Integer \
|
Unable to override bean: there are no beans of type java.lang.Integer \
|
||||||
(as required by field 'ByTypeTestCase.counter').""");
|
(as required by field 'ByTypeTestCase.counter'). \
|
||||||
|
If the bean is defined in a @Bean method, make sure the return type is the most \
|
||||||
|
specific type possible (for example, the concrete implementation type).""");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -40,9 +40,11 @@ public class TestBeanTests {
|
||||||
BeanOverrideContextCustomizerTestUtils.customizeApplicationContext(FailureByNameLookup.class, context);
|
BeanOverrideContextCustomizerTestUtils.customizeApplicationContext(FailureByNameLookup.class, context);
|
||||||
assertThatIllegalStateException()
|
assertThatIllegalStateException()
|
||||||
.isThrownBy(context::refresh)
|
.isThrownBy(context::refresh)
|
||||||
.withMessageStartingWith("""
|
.withMessage("""
|
||||||
Unable to replace bean: there is no bean with name 'beanToOverride' \
|
Unable to replace bean: there is no bean with name 'beanToOverride' \
|
||||||
and type java.lang.String (as required by field 'FailureByNameLookup.example').""");
|
and type java.lang.String (as required by field 'FailureByNameLookup.example'). \
|
||||||
|
If the bean is defined in a @Bean method, make sure the return type is the most \
|
||||||
|
specific type possible (for example, the concrete implementation type).""");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -52,9 +54,11 @@ public class TestBeanTests {
|
||||||
BeanOverrideContextCustomizerTestUtils.customizeApplicationContext(FailureByNameLookup.class, context);
|
BeanOverrideContextCustomizerTestUtils.customizeApplicationContext(FailureByNameLookup.class, context);
|
||||||
assertThatIllegalStateException()
|
assertThatIllegalStateException()
|
||||||
.isThrownBy(context::refresh)
|
.isThrownBy(context::refresh)
|
||||||
.withMessageStartingWith("""
|
.withMessage("""
|
||||||
Unable to replace bean: there is no bean with name 'beanToOverride' \
|
Unable to replace bean: there is no bean with name 'beanToOverride' \
|
||||||
and type java.lang.String (as required by field 'FailureByNameLookup.example').""");
|
and type java.lang.String (as required by field 'FailureByNameLookup.example'). \
|
||||||
|
If the bean is defined in a @Bean method, make sure the return type is the most \
|
||||||
|
specific type possible (for example, the concrete implementation type).""");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -63,9 +67,10 @@ public class TestBeanTests {
|
||||||
BeanOverrideContextCustomizerTestUtils.customizeApplicationContext(FailureByTypeLookup.class, context);
|
BeanOverrideContextCustomizerTestUtils.customizeApplicationContext(FailureByTypeLookup.class, context);
|
||||||
assertThatIllegalStateException()
|
assertThatIllegalStateException()
|
||||||
.isThrownBy(context::refresh)
|
.isThrownBy(context::refresh)
|
||||||
.withMessageStartingWith("""
|
.withMessage("""
|
||||||
Unable to override bean: there are no beans of \
|
Unable to override bean: there are no beans of type %s (as required by field '%s.example'). \
|
||||||
type %s (as required by field '%s.example').""",
|
If the bean is defined in a @Bean method, make sure the return type is the most \
|
||||||
|
specific type possible (for example, the concrete implementation type).""",
|
||||||
String.class.getName(), FailureByTypeLookup.class.getSimpleName());
|
String.class.getName(), FailureByTypeLookup.class.getSimpleName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2024 the original author or authors.
|
* Copyright 2002-2025 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -40,9 +40,11 @@ class MockitoBeanConfigurationErrorTests {
|
||||||
BeanOverrideContextCustomizerTestUtils.customizeApplicationContext(FailureByNameLookup.class, context);
|
BeanOverrideContextCustomizerTestUtils.customizeApplicationContext(FailureByNameLookup.class, context);
|
||||||
assertThatIllegalStateException()
|
assertThatIllegalStateException()
|
||||||
.isThrownBy(context::refresh)
|
.isThrownBy(context::refresh)
|
||||||
.withMessageStartingWith("""
|
.withMessage("""
|
||||||
Unable to replace bean: there is no bean with name 'beanToOverride' \
|
Unable to replace bean: there is no bean with name 'beanToOverride' \
|
||||||
and type java.lang.String (as required by field 'FailureByNameLookup.example').""");
|
and type java.lang.String (as required by field 'FailureByNameLookup.example'). \
|
||||||
|
If the bean is defined in a @Bean method, make sure the return type is the most \
|
||||||
|
specific type possible (for example, the concrete implementation type).""");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -52,9 +54,11 @@ class MockitoBeanConfigurationErrorTests {
|
||||||
BeanOverrideContextCustomizerTestUtils.customizeApplicationContext(FailureByNameLookup.class, context);
|
BeanOverrideContextCustomizerTestUtils.customizeApplicationContext(FailureByNameLookup.class, context);
|
||||||
assertThatIllegalStateException()
|
assertThatIllegalStateException()
|
||||||
.isThrownBy(context::refresh)
|
.isThrownBy(context::refresh)
|
||||||
.withMessageStartingWith("""
|
.withMessage("""
|
||||||
Unable to replace bean: there is no bean with name 'beanToOverride' \
|
Unable to replace bean: there is no bean with name 'beanToOverride' \
|
||||||
and type java.lang.String (as required by field 'FailureByNameLookup.example').""");
|
and type java.lang.String (as required by field 'FailureByNameLookup.example'). \
|
||||||
|
If the bean is defined in a @Bean method, make sure the return type is the most \
|
||||||
|
specific type possible (for example, the concrete implementation type).""");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -63,9 +67,11 @@ class MockitoBeanConfigurationErrorTests {
|
||||||
BeanOverrideContextCustomizerTestUtils.customizeApplicationContext(FailureByTypeLookup.class, context);
|
BeanOverrideContextCustomizerTestUtils.customizeApplicationContext(FailureByTypeLookup.class, context);
|
||||||
assertThatIllegalStateException()
|
assertThatIllegalStateException()
|
||||||
.isThrownBy(context::refresh)
|
.isThrownBy(context::refresh)
|
||||||
.withMessageStartingWith("""
|
.withMessage("""
|
||||||
Unable to override bean: there are no beans of \
|
Unable to override bean: there are no beans of \
|
||||||
type java.lang.String (as required by field 'FailureByTypeLookup.example').""");
|
type java.lang.String (as required by field 'FailureByTypeLookup.example'). \
|
||||||
|
If the bean is defined in a @Bean method, make sure the return type is the most \
|
||||||
|
specific type possible (for example, the concrete implementation type).""");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2024 the original author or authors.
|
* Copyright 2002-2025 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -41,7 +41,9 @@ class MockitoSpyBeanConfigurationErrorTests {
|
||||||
.isThrownBy(context::refresh)
|
.isThrownBy(context::refresh)
|
||||||
.withMessage("""
|
.withMessage("""
|
||||||
Unable to wrap bean: there is no bean with name 'beanToSpy' and \
|
Unable to wrap bean: there is no bean with name 'beanToSpy' and \
|
||||||
type java.lang.String (as required by field 'ByNameSingleLookup.example').""");
|
type java.lang.String (as required by field 'ByNameSingleLookup.example'). \
|
||||||
|
If the bean is defined in a @Bean method, make sure the return type is the most \
|
||||||
|
specific type possible (for example, the concrete implementation type).""");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -50,9 +52,11 @@ class MockitoSpyBeanConfigurationErrorTests {
|
||||||
BeanOverrideContextCustomizerTestUtils.customizeApplicationContext(ByTypeSingleLookup.class, context);
|
BeanOverrideContextCustomizerTestUtils.customizeApplicationContext(ByTypeSingleLookup.class, context);
|
||||||
assertThatIllegalStateException()
|
assertThatIllegalStateException()
|
||||||
.isThrownBy(context::refresh)
|
.isThrownBy(context::refresh)
|
||||||
.withMessageStartingWith("""
|
.withMessage("""
|
||||||
Unable to select a bean to wrap: there are no beans of type java.lang.String \
|
Unable to select a bean to wrap: there are no beans of type java.lang.String \
|
||||||
(as required by field 'ByTypeSingleLookup.example').""");
|
(as required by field 'ByTypeSingleLookup.example'). \
|
||||||
|
If the bean is defined in a @Bean method, make sure the return type is the most \
|
||||||
|
specific type possible (for example, the concrete implementation type).""");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
Loading…
Reference in New Issue