Polish reference documentation
This commit is contained in:
parent
60b5bbe334
commit
f481a4b60b
|
|
@ -167,19 +167,19 @@ therefore recommendable for your parameter names to match the target bean names.
|
||||||
As an alternative for injection by name, consider the JSR-250 `@Resource` annotation
|
As an alternative for injection by name, consider the JSR-250 `@Resource` annotation
|
||||||
which is semantically defined to identify a specific target component by its unique name,
|
which is semantically defined to identify a specific target component by its unique name,
|
||||||
with the declared type being irrelevant for the matching process. `@Autowired` has rather
|
with the declared type being irrelevant for the matching process. `@Autowired` has rather
|
||||||
different semantics: After selecting candidate beans by type, the specified `String`
|
different semantics: after selecting candidate beans by type, the specified `String`
|
||||||
qualifier value is considered within those type-selected candidates only (for example,
|
qualifier value is considered within those type-selected candidates only (for example,
|
||||||
matching an `account` qualifier against beans marked with the same qualifier label).
|
matching an `account` qualifier against beans marked with the same qualifier label).
|
||||||
|
|
||||||
For beans that are themselves defined as a collection, `Map`, or array type, `@Resource`
|
For beans that are themselves defined as a collection, `Map`, or array type, `@Resource`
|
||||||
is a fine solution, referring to the specific collection or array bean by unique name.
|
is a fine solution, referring to the specific collection or array bean by unique name.
|
||||||
That said, as of 4.3, you can match collection, `Map`, and array types through Spring's
|
That said, you can match collection, `Map`, and array types through Spring's
|
||||||
`@Autowired` type matching algorithm as well, as long as the element type information
|
`@Autowired` type matching algorithm as well, as long as the element type information
|
||||||
is preserved in `@Bean` return type signatures or collection inheritance hierarchies.
|
is preserved in `@Bean` return type signatures or collection inheritance hierarchies.
|
||||||
In this case, you can use qualifier values to select among same-typed collections,
|
In this case, you can use qualifier values to select among same-typed collections,
|
||||||
as outlined in the previous paragraph.
|
as outlined in the previous paragraph.
|
||||||
|
|
||||||
As of 4.3, `@Autowired` also considers self references for injection (that is, references
|
`@Autowired` also considers self references for injection (that is, references
|
||||||
back to the bean that is currently injected). Note that self injection is a fallback.
|
back to the bean that is currently injected). Note that self injection is a fallback.
|
||||||
Regular dependencies on other components always have precedence. In that sense, self
|
Regular dependencies on other components always have precedence. In that sense, self
|
||||||
references do not participate in regular candidate selection and are therefore in
|
references do not participate in regular candidate selection and are therefore in
|
||||||
|
|
|
||||||
|
|
@ -78,19 +78,20 @@ lead to concurrent access exceptions, inconsistent state in the bean container,
|
||||||
[[beans-definition-overriding]]
|
[[beans-definition-overriding]]
|
||||||
== Overriding Beans
|
== Overriding Beans
|
||||||
|
|
||||||
Bean overriding is happening when a bean is registered using an identifier that is
|
Bean overriding occurs when a bean is registered using an identifier that is already
|
||||||
already allocated. While bean overriding is possible, it makes the configuration harder
|
allocated. While bean overriding is possible, it makes the configuration harder to read.
|
||||||
to read and this feature will be deprecated in a future release.
|
|
||||||
|
WARNING: Bean overriding will be deprecated in a future release.
|
||||||
|
|
||||||
To disable bean overriding altogether, you can set the `allowBeanDefinitionOverriding`
|
To disable bean overriding altogether, you can set the `allowBeanDefinitionOverriding`
|
||||||
flag to `false` on the `ApplicationContext` before it is refreshed. In such setup, an
|
flag to `false` on the `ApplicationContext` before it is refreshed. In such a setup, an
|
||||||
exception is thrown if bean overriding is used.
|
exception is thrown if bean overriding is used.
|
||||||
|
|
||||||
By default, the container logs every bean overriding at `INFO` level so that you can
|
By default, the container logs every attempt to override a bean at `INFO` level so that
|
||||||
adapt your configuration accordingly. While not recommended, you can silence those logs
|
you can adapt your configuration accordingly. While not recommended, you can silence
|
||||||
by setting the `allowBeanDefinitionOverriding` flag to `true`.
|
those logs by setting the `allowBeanDefinitionOverriding` flag to `true`.
|
||||||
|
|
||||||
.Java-configuration
|
.Java Configuration
|
||||||
****
|
****
|
||||||
If you use Java Configuration, a corresponding `@Bean` method always silently overrides
|
If you use Java Configuration, a corresponding `@Bean` method always silently overrides
|
||||||
a scanned bean class with the same component name as long as the return type of the
|
a scanned bean class with the same component name as long as the return type of the
|
||||||
|
|
@ -98,8 +99,8 @@ a scanned bean class with the same component name as long as the return type of
|
||||||
the `@Bean` factory method in favor of any pre-declared constructor on the bean class.
|
the `@Bean` factory method in favor of any pre-declared constructor on the bean class.
|
||||||
****
|
****
|
||||||
|
|
||||||
NOTE: We acknowledge that overriding beans in a test scenario is convenient,
|
NOTE: We acknowledge that overriding beans in test scenarios is convenient, and there is
|
||||||
and there is explicit support for this as of Spring Framework 6.2. Please refer to
|
explicit support for this as of Spring Framework 6.2. Please refer to
|
||||||
xref:testing/testcontext-framework/bean-overriding.adoc[this section] for more details.
|
xref:testing/testcontext-framework/bean-overriding.adoc[this section] for more details.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,24 @@
|
||||||
[[spring-testing-annotation-beanoverriding-mockitobean]]
|
[[spring-testing-annotation-beanoverriding-mockitobean]]
|
||||||
= `@MockitoBean` and `@MockitoSpyBean`
|
= `@MockitoBean` and `@MockitoSpyBean`
|
||||||
|
|
||||||
`@MockitoBean` and `@MockitoSpyBean` are used on test class fields to override beans in
|
`@MockitoBean` and `@MockitoSpyBean` are used on fields in test classes to override beans
|
||||||
the test's `ApplicationContext` with a Mockito mock or spy, respectively. In the latter
|
in the test's `ApplicationContext` with a Mockito mock or spy, respectively. In the
|
||||||
case, the original bean definition is not replaced, but instead an early instance of the
|
latter case, the original bean definition is not replaced, but instead an early instance
|
||||||
bean is captured and wrapped by the spy.
|
of the bean is captured and wrapped by the spy.
|
||||||
|
|
||||||
By default, the annotated field's type is used to search for candidate definitions to
|
By default, the annotated field's type is used to search for candidate bean definitions
|
||||||
override. If multiple candidates match, the usual `@Qualifier` can be provided to
|
to override. If multiple candidates match, `@Qualifier` can be provided to narrow the
|
||||||
narrow the candidate to override. Alternatively, a candidate whose bean definition name
|
candidate to override. Alternatively, a candidate whose bean definition name matches the
|
||||||
matches the name of the field will match.
|
name of the field will match.
|
||||||
|
|
||||||
To use a by-name override rather than a by-type override, specify the `name` attribute
|
To use a by-name override rather than a by-type override, specify the `name` attribute
|
||||||
of the annotation.
|
of the annotation.
|
||||||
|
|
||||||
[WARNING]
|
[WARNING]
|
||||||
====
|
====
|
||||||
The qualifiers, including the name of the field are used to determine if a separate
|
Qualifiers, including the name of the field, are used to determine if a separate
|
||||||
`ApplicationContext` needs to be created. If you are using this feature to mock or
|
`ApplicationContext` needs to be created. If you are using this feature to mock or spy
|
||||||
spy the same bean in several tests, make sure to name the field consistently to avoid
|
the same bean in several tests, make sure to name the field consistently to avoid
|
||||||
creating unnecessary contexts.
|
creating unnecessary contexts.
|
||||||
====
|
====
|
||||||
|
|
||||||
|
|
@ -26,14 +26,12 @@ Each annotation also defines Mockito-specific attributes to fine-tune the mockin
|
||||||
|
|
||||||
The `@MockitoBean` annotation uses the `REPLACE_OR_CREATE_DEFINITION`
|
The `@MockitoBean` annotation uses the `REPLACE_OR_CREATE_DEFINITION`
|
||||||
xref:testing/testcontext-framework/bean-overriding.adoc#testcontext-bean-overriding-custom[strategy for test bean overriding].
|
xref:testing/testcontext-framework/bean-overriding.adoc#testcontext-bean-overriding-custom[strategy for test bean overriding].
|
||||||
|
If no existing bean definition matches, a new bean definition is created on the fly.
|
||||||
If no definition matches, then a definition is created on-the-fly.
|
|
||||||
|
|
||||||
The `@MockitoSpyBean` annotation uses the `WRAP_BEAN`
|
The `@MockitoSpyBean` annotation uses the `WRAP_BEAN`
|
||||||
xref:testing/testcontext-framework/bean-overriding.adoc#testcontext-bean-overriding-custom[strategy],
|
xref:testing/testcontext-framework/bean-overriding.adoc#testcontext-bean-overriding-custom[strategy],
|
||||||
and the original instance is wrapped in a Mockito spy.
|
and the original instance is wrapped in a Mockito spy. This strategy requires that
|
||||||
|
exactly one candidate bean definition exists.
|
||||||
It requires that exactly one candidate definition exists.
|
|
||||||
|
|
||||||
The following example shows how to use the default behavior of the `@MockitoBean` annotation:
|
The following example shows how to use the default behavior of the `@MockitoBean` annotation:
|
||||||
|
|
||||||
|
|
@ -44,8 +42,8 @@ Java::
|
||||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||||
----
|
----
|
||||||
class OverrideBeanTests {
|
class OverrideBeanTests {
|
||||||
@MockitoBean // <1>
|
@MockitoBean // <1>
|
||||||
private CustomService customService;
|
CustomService customService;
|
||||||
|
|
||||||
// test case body...
|
// test case body...
|
||||||
}
|
}
|
||||||
|
|
@ -53,11 +51,11 @@ Java::
|
||||||
<1> Replace the bean with type `CustomService` with a Mockito `mock`.
|
<1> Replace the bean with type `CustomService` with a Mockito `mock`.
|
||||||
======
|
======
|
||||||
|
|
||||||
In the example above, we are creating a mock for `CustomService`. If more that
|
In the example above, we are creating a mock for `CustomService`. If more than one bean
|
||||||
one bean with such type exist, the bean named `customService` is considered. Otherwise,
|
of that type exists, the bean named `customService` is considered. Otherwise, the test
|
||||||
the test will fail and you will need to provide a qualifier of some sort to identify which
|
will fail, and you will need to provide a qualifier of some sort to identify which of the
|
||||||
of the `CustomService` beans you want to override. If no such bean exists, a bean
|
`CustomService` beans you want to override. If no such bean exists, a bean definition
|
||||||
definition will be created with an auto-generated bean name.
|
will be created with an auto-generated bean name.
|
||||||
|
|
||||||
The following example uses a by-name lookup, rather than a by-type lookup:
|
The following example uses a by-name lookup, rather than a by-type lookup:
|
||||||
|
|
||||||
|
|
@ -68,14 +66,14 @@ Java::
|
||||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||||
----
|
----
|
||||||
class OverrideBeanTests {
|
class OverrideBeanTests {
|
||||||
@MockitoBean(name = "service") // <1>
|
@MockitoBean(name = "service") // <1>
|
||||||
private CustomService customService;
|
CustomService customService;
|
||||||
|
|
||||||
// test case body...
|
// test case body...
|
||||||
|
|
||||||
}
|
}
|
||||||
----
|
----
|
||||||
<1> Replace the bean named `service` with a Mockito `mock`.
|
<1> Replace the bean named `service` with a Mockito `mock`.
|
||||||
======
|
======
|
||||||
|
|
||||||
If no bean definition named `service` exists, one is created.
|
If no bean definition named `service` exists, one is created.
|
||||||
|
|
@ -89,8 +87,8 @@ Java::
|
||||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||||
----
|
----
|
||||||
class OverrideBeanTests {
|
class OverrideBeanTests {
|
||||||
@MockitoSpyBean // <1>
|
@MockitoSpyBean // <1>
|
||||||
private CustomService customService;
|
CustomService customService;
|
||||||
|
|
||||||
// test case body...
|
// test case body...
|
||||||
}
|
}
|
||||||
|
|
@ -98,10 +96,10 @@ Java::
|
||||||
<1> Wrap the bean with type `CustomService` with a Mockito `spy`.
|
<1> Wrap the bean with type `CustomService` with a Mockito `spy`.
|
||||||
======
|
======
|
||||||
|
|
||||||
In the example above, we are wrapping the bean with type `CustomService`. If more that
|
In the example above, we are wrapping the bean with type `CustomService`. If more than
|
||||||
one bean with such type exist, the bean named `customService` is considered. Otherwise,
|
one bean of that type exists, the bean named `customService` is considered. Otherwise,
|
||||||
the test will fail and you will need to provide a qualifier of some sort to identify which
|
the test will fail, and you will need to provide a qualifier of some sort to identify
|
||||||
of the `CustomService` beans you want to spy.
|
which of the `CustomService` beans you want to spy.
|
||||||
|
|
||||||
The following example uses a by-name lookup, rather than a by-type lookup:
|
The following example uses a by-name lookup, rather than a by-type lookup:
|
||||||
|
|
||||||
|
|
@ -112,12 +110,12 @@ Java::
|
||||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||||
----
|
----
|
||||||
class OverrideBeanTests {
|
class OverrideBeanTests {
|
||||||
@MockitoSpyBean(name = "service") // <1>
|
@MockitoSpyBean(name = "service") // <1>
|
||||||
private CustomService customService;
|
CustomService customService;
|
||||||
|
|
||||||
// test case body...
|
// test case body...
|
||||||
|
|
||||||
}
|
}
|
||||||
----
|
----
|
||||||
<1> Wrap the bean named `service` with a Mockito `spy`.
|
<1> Wrap the bean named `service` with a Mockito `spy`.
|
||||||
======
|
======
|
||||||
|
|
|
||||||
|
|
@ -1,30 +1,29 @@
|
||||||
[[spring-testing-annotation-beanoverriding-testbean]]
|
[[spring-testing-annotation-beanoverriding-testbean]]
|
||||||
= `@TestBean`
|
= `@TestBean`
|
||||||
|
|
||||||
`@TestBean` is used on a test class field to override a specific bean in the test's
|
`@TestBean` is used on a field in a test class to override a specific bean in the test's
|
||||||
`ApplicationContext` with an instance provided by a conventionally named static factory
|
`ApplicationContext` with an instance provided by a factory method.
|
||||||
method.
|
|
||||||
|
|
||||||
The associated factory method name is derived from the annotated field's name, or bean
|
The associated factory method name is derived from the annotated field's name, or the
|
||||||
name if specified. A `static` method with no argument that returns a type compatible
|
bean name if specified. The factory method must be `static`, accept no arguments, and
|
||||||
with the type of the bean to override is expected. To make things more explicit, or if
|
have a return type compatible with the type of the bean to override. To make things more
|
||||||
you'd rather use a different name, the annotation allows for a specific method name to
|
explicit, or if you'd rather use a different name, the annotation allows for a specific
|
||||||
be provided.
|
method name to be provided.
|
||||||
|
|
||||||
By default, the annotated field's type is used to search for candidate definitions to
|
By default, the annotated field's type is used to search for candidate bean definitions
|
||||||
override. If multiple candidates match, the usual `@Qualifier` can be provided to
|
to override. If multiple candidates match, `@Qualifier` can be provided to narrow the
|
||||||
narrow the candidate to override. Alternatively, a candidate whose bean definition name
|
candidate to override. Alternatively, a candidate whose bean definition name matches the
|
||||||
matches the name of the field will match.
|
name of the field will match.
|
||||||
|
|
||||||
To use a by-name override rather than a by-type override, specify the `name` attribute
|
To use a by-name override rather than a by-type override, specify the `name` attribute
|
||||||
of the annotation.
|
of the annotation.
|
||||||
|
|
||||||
[WARNING]
|
[WARNING]
|
||||||
====
|
====
|
||||||
The qualifiers, including the name of the field are used to determine if a separate
|
Qualifiers, including the name of the field, are used to determine if a separate
|
||||||
`ApplicationContext` needs to be created. If you are using this feature to override
|
`ApplicationContext` needs to be created. If you are using this feature to override the
|
||||||
the same bean in several tests, make sure to name the field consistently to avoid
|
same bean in several tests, make sure to name the field consistently to avoid creating
|
||||||
creating unnecessary contexts.
|
unnecessary contexts.
|
||||||
====
|
====
|
||||||
|
|
||||||
The following example shows how to use the default behavior of the `@TestBean` annotation:
|
The following example shows how to use the default behavior of the `@TestBean` annotation:
|
||||||
|
|
@ -36,25 +35,24 @@ Java::
|
||||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||||
----
|
----
|
||||||
class OverrideBeanTests {
|
class OverrideBeanTests {
|
||||||
@TestBean // <1>
|
@TestBean // <1>
|
||||||
private CustomService customService;
|
CustomService customService;
|
||||||
|
|
||||||
// test case body...
|
// test case body...
|
||||||
|
|
||||||
private static CustomService customService() { // <2>
|
static CustomService customService() { // <2>
|
||||||
return new MyFakeCustomService();
|
return new MyFakeCustomService();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
----
|
----
|
||||||
<1> Mark a field for overriding of the bean with type `CustomService`.
|
<1> Mark a field for overriding the bean with type `CustomService`.
|
||||||
<2> The result of this static method will be used as the instance and injected into the field.
|
<2> The result of this static method will be used as the instance and injected into the field.
|
||||||
======
|
======
|
||||||
|
|
||||||
In the example above, we are overriding the bean with type `CustomService`. If more that
|
In the example above, we are overriding the bean with type `CustomService`. If more than
|
||||||
one bean with such type exist, the bean named `customService` is considered. Otherwise,
|
one bean of that type exists, the bean named `customService` is considered. Otherwise,
|
||||||
the test will fail and you will need to provide a qualifier of some sort to identify which
|
the test will fail, and you will need to provide a qualifier of some sort to identify
|
||||||
of the `CustomService` beans you want to override.
|
which of the `CustomService` beans you want to override.
|
||||||
|
|
||||||
|
|
||||||
The following example uses a by-name lookup, rather than a by-type lookup:
|
The following example uses a by-name lookup, rather than a by-type lookup:
|
||||||
|
|
||||||
|
|
@ -65,17 +63,18 @@ Java::
|
||||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||||
----
|
----
|
||||||
class OverrideBeanTests {
|
class OverrideBeanTests {
|
||||||
@TestBean(name = "service", methodName = "createCustomService") // <1>
|
@TestBean(name = "service", methodName = "createCustomService") // <1>
|
||||||
private CustomService customService;
|
CustomService customService;
|
||||||
|
|
||||||
// test case body...
|
// test case body...
|
||||||
|
|
||||||
private static CustomService createCustomService() { // <2>
|
static CustomService createCustomService() { // <2>
|
||||||
return new MyFakeCustomService();
|
return new MyFakeCustomService();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
----
|
----
|
||||||
<1> Mark a field for overriding of the bean with name `service`.
|
<1> Mark a field for overriding the bean with name `service`, and specify that the
|
||||||
|
factory method is named `createCustomService`.
|
||||||
<2> The result of this static method will be used as the instance and injected into the field.
|
<2> The result of this static method will be used as the instance and injected into the field.
|
||||||
======
|
======
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -74,14 +74,15 @@ public abstract class OverrideMetadata {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse the given {@code testClass} and provide the use of bean override.
|
* Parse the given {@code testClass} and build the corresponding list of
|
||||||
|
* bean {@code OverrideMetadata}.
|
||||||
* @param testClass the class to parse
|
* @param testClass the class to parse
|
||||||
* @return a list of bean overrides metadata
|
* @return a list of {@code OverrideMetadata}
|
||||||
*/
|
*/
|
||||||
public static List<OverrideMetadata> forTestClass(Class<?> testClass) {
|
public static List<OverrideMetadata> forTestClass(Class<?> testClass) {
|
||||||
List<OverrideMetadata> all = new LinkedList<>();
|
List<OverrideMetadata> metadataList = new LinkedList<>();
|
||||||
ReflectionUtils.doWithFields(testClass, field -> parseField(field, testClass, all));
|
ReflectionUtils.doWithFields(testClass, field -> parseField(field, testClass, metadataList));
|
||||||
return all;
|
return metadataList;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void parseField(Field field, Class<?> testClass, List<OverrideMetadata> metadataList) {
|
private static void parseField(Field field, Class<?> testClass, List<OverrideMetadata> metadataList) {
|
||||||
|
|
@ -182,9 +183,9 @@ public abstract class OverrideMetadata {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int hash = Objects.hash(getClass().hashCode(), this.beanType.getType(), this.beanName, this.strategy);
|
int hash = Objects.hash(getClass(), this.beanType.getType(), this.beanName, this.strategy);
|
||||||
return (this.beanName != null ? hash : hash +
|
return (this.beanName != null ? hash : hash +
|
||||||
Objects.hash(this.field.getName(), Arrays.hashCode(this.field.getAnnotations())));
|
31 * Objects.hash(this.field.getName(), Arrays.hashCode(this.field.getAnnotations())));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue