mirror of
https://github.com/spring-projects/spring-framework
synced 2026-06-08 17:33:33 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5a30a43b75 |
@@ -38,7 +38,6 @@ public class KotlinConventions {
|
||||
kotlinOptions.setApiVersion("1.7");
|
||||
kotlinOptions.setLanguageVersion("1.7");
|
||||
kotlinOptions.setJvmTarget("17");
|
||||
kotlinOptions.setJavaParameters(true);
|
||||
kotlinOptions.setAllWarningsAsErrors(true);
|
||||
List<String> freeCompilerArgs = new ArrayList<>(compile.getKotlinOptions().getFreeCompilerArgs());
|
||||
freeCompilerArgs.addAll(List.of("-Xsuppress-version-warnings", "-Xjsr305=strict", "-opt-in=kotlin.RequiresOptIn"));
|
||||
|
||||
@@ -10,18 +10,6 @@ configurations {
|
||||
asciidoctorExtensions
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api(project(":spring-context"))
|
||||
api(project(":spring-web"))
|
||||
|
||||
implementation(project(":spring-core-test"))
|
||||
implementation("org.assertj:assertj-core")
|
||||
}
|
||||
|
||||
checkstyle {
|
||||
sourceSets = []
|
||||
}
|
||||
|
||||
jar {
|
||||
enabled = false
|
||||
}
|
||||
@@ -92,6 +80,8 @@ rootProject.tasks.dokkaHtmlMultiModule.configure {
|
||||
}
|
||||
|
||||
asciidoctorj {
|
||||
def docRoot = 'https://docs.spring.io'
|
||||
def docsSpringFramework = "${docRoot}/spring-framework/docs/${project.version}"
|
||||
version = '2.4.3'
|
||||
fatalWarnings ".*"
|
||||
options doctype: 'book', eruby: 'erubis'
|
||||
@@ -102,7 +92,11 @@ asciidoctorj {
|
||||
revnumber: project.version,
|
||||
sectanchors: '',
|
||||
sectnums: '',
|
||||
'spring-version': project.version
|
||||
'spring-version': project.version,
|
||||
'spring-framework-main-code': 'https://github.com/spring-projects/spring-framework/tree/main',
|
||||
'doc-root': docRoot,
|
||||
'docs-spring-framework': docsSpringFramework,
|
||||
'api-spring-framework': "${docsSpringFramework}/javadoc-api/org/springframework"
|
||||
])
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
[[appendix]]
|
||||
= Appendix
|
||||
include::attributes.adoc[]
|
||||
include::page-layout.adoc[]
|
||||
:toc: left
|
||||
:toclevels: 4
|
||||
:tabsize: 4
|
||||
:docinfo1:
|
||||
|
||||
This part of the reference documentation covers topics that apply to multiple modules
|
||||
within the core Spring Framework.
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
:chomp: default headers packages
|
||||
:docs-site: https://docs.spring.io
|
||||
// Spring Framework
|
||||
:docs-spring-framework: {docs-site}/spring-framework/docs/{spring-version}
|
||||
:api-spring-framework: {docs-spring-framework}/javadoc-api/org/springframework
|
||||
:docs-java: {docdir}/../../main/java/org/springframework/docs
|
||||
:docs-kotlin: {docdir}/../../main/kotlin/org/springframework/docs
|
||||
:docs-resources: {docdir}/../../main/resources
|
||||
:spring-framework-main-code: https://github.com/spring-projects/spring-framework/tree/main
|
||||
// Spring portfolio Links
|
||||
:docs-spring-boot: {docs-site}/spring-boot/docs/current/reference
|
||||
:docs-spring-gemfire: {docs-site}/spring-gemfire/docs/current/reference
|
||||
:docs-spring-security: {docs-site}/spring-security/reference
|
||||
// Third-party Links
|
||||
:docs-graalvm: https://www.graalvm.org/22.3/reference-manual
|
||||
:gh-rsocket: https://github.com/rsocket
|
||||
:gh-rsocket-extensions: {gh-rsocket}/rsocket/blob/master/Extensions
|
||||
:gh-rsocket-java: {gh-rsocket}/rsocket-java
|
||||
@@ -1,7 +1,9 @@
|
||||
[[spring-core]]
|
||||
= Core Technologies
|
||||
include::attributes.adoc[]
|
||||
include::page-layout.adoc[]
|
||||
:toc: left
|
||||
:toclevels: 4
|
||||
:tabsize: 4
|
||||
:docinfo1:
|
||||
|
||||
This part of the reference documentation covers all the technologies that are
|
||||
absolutely integral to the Spring Framework.
|
||||
|
||||
@@ -1755,5 +1755,5 @@ support for new custom advice types be added without changing the core framework
|
||||
The only constraint on a custom `Advice` type is that it must implement the
|
||||
`org.aopalliance.aop.Advice` marker interface.
|
||||
|
||||
See the {api-spring-framework}/aop/framework/adapter/package-summary.html[`org.springframework.aop.framework.adapter`]
|
||||
See the {api-spring-framework}/aop/framework/adapter/package-frame.html[`org.springframework.aop.framework.adapter`]
|
||||
javadoc for further information.
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
[[core.aot]]
|
||||
[[aot]]
|
||||
= Ahead of Time Optimizations
|
||||
|
||||
This chapter covers Spring's Ahead of Time (AOT) optimizations.
|
||||
|
||||
For AOT support specific to integration tests, see <<testing.adoc#testcontext-aot, Ahead of Time Support for Tests>>.
|
||||
|
||||
[[core.aot.introduction]]
|
||||
[[aot-introduction]]
|
||||
== Introduction to Ahead of Time Optimizations
|
||||
|
||||
Spring's support for AOT optimizations is meant to inspect an `ApplicationContext` at build time and apply decisions and discovery logic that usually happens at runtime.
|
||||
@@ -26,9 +26,9 @@ A Spring AOT processed application typically generates:
|
||||
* {api-spring-framework}/aot/hint/RuntimeHints.html[`RuntimeHints`] for the use of reflection, resource loading, serialization, and JDK proxies.
|
||||
|
||||
NOTE: At the moment, AOT is focused on allowing Spring applications to be deployed as native images using GraalVM.
|
||||
We intend to support more JVM-based use cases in future generations.
|
||||
We intend to offer more JVM-based use cases in future generations.
|
||||
|
||||
[[core.aot.basics]]
|
||||
[[aot-basics]]
|
||||
== AOT engine overview
|
||||
|
||||
The entry point of the AOT engine for processing an `ApplicationContext` arrangement is `ApplicationContextAotGenerator`. It takes care of the following steps, based on a `GenericApplicationContext` that represents the application to optimize and a {api-spring-framework}/aot/generate/GenerationContext.html[`GenerationContext`]:
|
||||
@@ -37,14 +37,14 @@ The entry point of the AOT engine for processing an `ApplicationContext` arrange
|
||||
* Invoke the available `BeanFactoryInitializationAotProcessor` implementations and apply their contributions against the `GenerationContext`.
|
||||
For instance, a core implementation iterates over all candidate bean definitions and generates the necessary code to restore the state of the `BeanFactory`.
|
||||
|
||||
Once this process completes, the `GenerationContext` will have been updated with the generated code, resources, and classes that are necessary for the application to run.
|
||||
Once this process completes, the `GenerationContext` has been updated with the generated code, resources, and classes that are necessary for the application to run.
|
||||
The `RuntimeHints` instance can also be used to generate the relevant GraalVM native image configuration files.
|
||||
|
||||
`ApplicationContextAotGenerator#processAheadOfTime` returns the class name of the `ApplicationContextInitializer` entry point that allows the context to be started with AOT optimizations.
|
||||
|
||||
Those steps are covered in greater detail in the sections below.
|
||||
Those steps are covered in more details in the sections below.
|
||||
|
||||
[[core.aot.refresh]]
|
||||
[[aot-refresh]]
|
||||
== Refresh for AOT Processing
|
||||
|
||||
Refresh for AOT processing is supported on all `GenericApplicationContext` implementations.
|
||||
@@ -52,13 +52,27 @@ An application context is created with any number of entry points, usually in th
|
||||
|
||||
Let's look at a basic example:
|
||||
|
||||
include::code:AotProcessingSample[tag=myapplication]
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
@Configuration(proxyBeanMethods=false)
|
||||
@ComponentScan
|
||||
@Import({DataSourceConfiguration.class, ContainerConfiguration.class})
|
||||
public class MyApplication {
|
||||
}
|
||||
----
|
||||
|
||||
Starting this application with the regular runtime involves a number of steps including classpath scanning, configuration class parsing, bean instantiation, and lifecycle callback handling.
|
||||
Refresh for AOT processing only applies a subset of what happens with a <<beans-introduction,regular `refresh`>>.
|
||||
AOT processing can be triggered as follows:
|
||||
|
||||
include::code:AotProcessingSample[tag=aotcontext]
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
GenericApplicationContext applicationContext = new AnnotatedConfigApplicationContext();
|
||||
context.register(MyApplication.class);
|
||||
context.refreshForAotProcessing();
|
||||
----
|
||||
|
||||
In this mode, <<beans-factory-extension-factory-postprocessors,`BeanFactoryPostProcessor` implementations>> are invoked as usual.
|
||||
This includes configuration class parsing, import selectors, classpath scanning, etc.
|
||||
@@ -70,11 +84,11 @@ These are:
|
||||
|
||||
* `MergedBeanDefinitionPostProcessor` implementations post-process bean definitions to extract additional settings, such as `init` and `destroy` methods.
|
||||
* `SmartInstantiationAwareBeanPostProcessor` implementations determine a more precise bean type if necessary.
|
||||
This makes sure to create any proxy that will be required at runtime.
|
||||
This makes sure to create any proxy that is required at runtime.
|
||||
|
||||
One this part completes, the `BeanFactory` contains the bean definitions that are necessary for the application to run. It does not trigger bean instantiation but allows the AOT engine to inspect the beans that will be created at runtime.
|
||||
One this part completes, the `BeanFactory` contains the bean definitions that are necessary for the application to run. It does not trigger bean instantiation but allows the AOT engine to inspect the beans that would be created at runtime.
|
||||
|
||||
[[core.aot.bean-factory-initialization-contributions]]
|
||||
[[aot-bean-factory-initialization-contributions]]
|
||||
== Bean Factory Initialization AOT Contributions
|
||||
|
||||
Components that want to participate in this step can implement the {api-spring-framework}/beans/factory/aot/BeanFactoryInitializationAotProcessor.html[`BeanFactoryInitializationAotProcessor`] interface.
|
||||
@@ -97,7 +111,7 @@ If such a bean is registered using an `@Bean` factory method, ensure the method
|
||||
====
|
||||
|
||||
|
||||
[[core.aot.bean-registration-contributions]]
|
||||
[[aot-bean-registration-contributions]]
|
||||
=== Bean Registration AOT Contributions
|
||||
|
||||
A core `BeanFactoryInitializationAotProcessor` implementation is responsible for collecting the necessary contributions for each candidate `BeanDefinition`.
|
||||
@@ -184,7 +198,7 @@ When a `datasource` instance is required, a `BeanInstanceSupplier` is called.
|
||||
This supplier invokes the `dataSource()` method on the `dataSourceConfiguration` bean.
|
||||
|
||||
|
||||
[[core.aot.hints]]
|
||||
[[aot-hints]]
|
||||
== Runtime Hints
|
||||
|
||||
Running an application as a native image requires additional information compared to a regular JVM runtime.
|
||||
@@ -208,14 +222,31 @@ For cases that the core container cannot infer, you can register such hints prog
|
||||
A number of convenient annotations are also provided for common use cases.
|
||||
|
||||
|
||||
[[core.aot.hints.import-runtime-hints]]
|
||||
[[aot-hints-import-runtime-hints]]
|
||||
=== `@ImportRuntimeHints`
|
||||
|
||||
`RuntimeHintsRegistrar` implementations allow you to get a callback to the `RuntimeHints` instance managed by the AOT engine.
|
||||
Implementations of this interface can be registered using `@ImportRuntimeHints` on any Spring bean or `@Bean` factory method.
|
||||
`RuntimeHintsRegistrar` implementations are detected and invoked at build time.
|
||||
|
||||
include::code:SpellCheckService[]
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
@Component
|
||||
@ImportRuntimeHints(MyComponentRuntimeHints.class)
|
||||
public class MyComponent {
|
||||
|
||||
// ...
|
||||
|
||||
private static class MyComponentRuntimeHints implements RuntimeHintsRegistrar {
|
||||
|
||||
@Override
|
||||
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
If at all possible, `@ImportRuntimeHints` should be used as close as possible to the component that requires the hints.
|
||||
This way, if the component is not contributed to the `BeanFactory`, the hints won't be contributed either.
|
||||
@@ -223,7 +254,7 @@ This way, if the component is not contributed to the `BeanFactory`, the hints wo
|
||||
It is also possible to register an implementation statically by adding an entry in `META-INF/spring/aot.factories` with a key equal to the fully qualified name of the `RuntimeHintsRegistrar` interface.
|
||||
|
||||
|
||||
[[core.aot.hints.reflective]]
|
||||
[[aot-hints-reflective]]
|
||||
=== `@Reflective`
|
||||
|
||||
{api-spring-framework}/aot/hint/annotation/Reflective.html[`@Reflective`] provides an idiomatic way to flag the need for reflection on an annotated element.
|
||||
@@ -237,7 +268,7 @@ Library authors can reuse this annotation for their own purposes.
|
||||
If components other than Spring beans need to be processed, a `BeanFactoryInitializationAotProcessor` can detect the relevant types and use `ReflectiveRuntimeHintsRegistrar` to process them.
|
||||
|
||||
|
||||
[[core.aot.hints.register-reflection-for-binding]]
|
||||
[[aot-hints-register-reflection-for-binding]]
|
||||
=== `@RegisterReflectionForBinding`
|
||||
|
||||
{api-spring-framework}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`] is a specialization of `@Reflective` that registers the need for serializing arbitrary types.
|
||||
@@ -259,49 +290,3 @@ The following example registers `Account` for serialization.
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
[[core.aot.hints.testing]]
|
||||
=== Testing Runtime Hints
|
||||
|
||||
Spring Core also ships `RuntimeHintsPredicates`, a utility for checking that existing hints match a particular use case.
|
||||
This can be used in your own tests to validate that a `RuntimeHintsRegistrar` contains the expected results.
|
||||
We can write a test for our `SpellCheckService` and ensure that we will be able to load a dictionary at runtime:
|
||||
|
||||
include::code:SpellCheckServiceTests[tag=hintspredicates]
|
||||
|
||||
With `RuntimeHintsPredicates`, we can check for reflection, resource, serialization, or proxy generation hints.
|
||||
This approach works well for unit tests but implies that the runtime behavior of a component is well known.
|
||||
|
||||
You can learn more about the global runtime behavior of an application by running its test suite (or the app itself) with the {docs-graalvm}/native-image/metadata/AutomaticMetadataCollection/[GraalVM tracing agent].
|
||||
This agent will record all relevant calls requiring GraalVM hints at runtime and write them out as JSON configuration files.
|
||||
|
||||
For more targeted discovery and testing, Spring Framework ships a dedicated module with core AOT testing utilities, `"org.springframework:spring-core-test"`.
|
||||
This module contains the RuntimeHints Agent, a Java agent that records all method invocations that are related to runtime hints and helps you to assert that a given `RuntimeHints` instance covers all recorded invocations.
|
||||
Let's consider a piece of infrastructure for which we'd like to test the hints we're contributing during the AOT processing phase.
|
||||
|
||||
include::code:SampleReflection[]
|
||||
|
||||
We can then write a unit test (no native compilation required) that checks our contributed hints:
|
||||
|
||||
include::code:SampleReflectionRuntimeHintsTests[]
|
||||
|
||||
If you forgot to contribute a hint, the test will fail and provide some details about the invocation:
|
||||
|
||||
[source,txt,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
org.springframework.docs.core.aot.hints.testing.SampleReflection performReflection
|
||||
INFO: Spring version:6.0.0-SNAPSHOT
|
||||
|
||||
Missing <"ReflectionHints"> for invocation <java.lang.Class#forName>
|
||||
with arguments ["org.springframework.core.SpringVersion",
|
||||
false,
|
||||
jdk.internal.loader.ClassLoaders$AppClassLoader@251a69d7].
|
||||
Stacktrace:
|
||||
<"org.springframework.util.ClassUtils#forName, Line 284
|
||||
io.spring.runtimehintstesting.SampleReflection#performReflection, Line 19
|
||||
io.spring.runtimehintstesting.SampleReflectionRuntimeHintsTests#lambda$shouldRegisterReflectionHints$0, Line 25
|
||||
----
|
||||
|
||||
There are various ways to configure this Java agent in your build, so please refer to the documentation of your build tool and test execution plugin.
|
||||
The agent itself can be configured to instrument specific packages (by default, only `org.springframework` is instrumented).
|
||||
You'll find more details in the {spring-framework-main-code}/buildSrc/README.md[Spring Framework `buildSrc` README] file.
|
||||
|
||||
@@ -107,14 +107,16 @@ configuration metadata is actually written. These days, many developers choose
|
||||
|
||||
For information about using other forms of metadata with the Spring container, see:
|
||||
|
||||
* <<beans-annotation-config,Annotation-based configuration>>: define beans using
|
||||
annotation-based configuration metadata.
|
||||
* <<beans-java, Java-based configuration>>: define beans external to your application
|
||||
classes by using Java rather than XML files. To use these features, see the
|
||||
{api-spring-framework}/context/annotation/Configuration.html[`@Configuration`],
|
||||
{api-spring-framework}/context/annotation/Bean.html[`@Bean`],
|
||||
{api-spring-framework}/context/annotation/Import.html[`@Import`],
|
||||
and {api-spring-framework}/context/annotation/DependsOn.html[`@DependsOn`] annotations.
|
||||
* <<beans-annotation-config,Annotation-based configuration>>: Spring 2.5 introduced
|
||||
support for annotation-based configuration metadata.
|
||||
* <<beans-java, Java-based configuration>>: Starting with Spring 3.0, many features
|
||||
provided by the Spring JavaConfig project became part of the core Spring Framework.
|
||||
Thus, you can define beans external to your application classes by using Java rather
|
||||
than XML files. To use these new features, see the
|
||||
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/Configuration.html[`@Configuration`],
|
||||
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/Bean.html[`@Bean`],
|
||||
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/Import.html[`@Import`],
|
||||
and https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/DependsOn.html[`@DependsOn`] annotations.
|
||||
|
||||
Spring configuration consists of at least one and typically more than one bean
|
||||
definition that the container must manage. XML-based configuration metadata configures these
|
||||
@@ -122,12 +124,14 @@ beans as `<bean/>` elements inside a top-level `<beans/>` element. Java
|
||||
configuration typically uses `@Bean`-annotated methods within a `@Configuration` class.
|
||||
|
||||
These bean definitions correspond to the actual objects that make up your application.
|
||||
Typically, you define service layer objects, persistence layer objects such as
|
||||
repositories or data access objects (DAOs), presentation objects such as Web controllers,
|
||||
infrastructure objects such as a JPA `EntityManagerFactory`, JMS queues, and so forth.
|
||||
Typically, one does not configure fine-grained domain objects in the container, because
|
||||
it is usually the responsibility of repositories and business logic to create and load
|
||||
domain objects.
|
||||
Typically, you define service layer objects, data access objects (DAOs), presentation
|
||||
objects such as Struts `Action` instances, infrastructure objects such as Hibernate
|
||||
`SessionFactories`, JMS `Queues`, and so forth. Typically, one does not configure
|
||||
fine-grained domain objects in the container, because it is usually the responsibility
|
||||
of DAOs and business logic to create and load domain objects. However, you can use
|
||||
Spring's integration with AspectJ to configure objects that have been created outside
|
||||
the control of an IoC container. See <<aop-atconfigurable,Using AspectJ to
|
||||
dependency-inject domain objects with Spring>>.
|
||||
|
||||
The following example shows the basic structure of XML-based configuration metadata:
|
||||
|
||||
@@ -153,11 +157,12 @@ The following example shows the basic structure of XML-based configuration metad
|
||||
----
|
||||
|
||||
<1> The `id` attribute is a string that identifies the individual bean definition.
|
||||
<2> The `class` attribute defines the type of the bean and uses the fully qualified
|
||||
class name.
|
||||
|
||||
The value of the `id` attribute can be used to refer to collaborating objects. The XML
|
||||
for referring to collaborating objects is not shown in this example. See
|
||||
<2> The `class` attribute defines the type of the bean and uses the fully qualified
|
||||
classname.
|
||||
|
||||
The value of the `id` attribute refers to collaborating objects. The XML for
|
||||
referring to collaborating objects is not shown in this example. See
|
||||
<<beans-dependencies,Dependencies>> for more information.
|
||||
|
||||
|
||||
@@ -2834,7 +2839,7 @@ processed by the Spring `DispatcherServlet`, no special setup is necessary.
|
||||
`DispatcherServlet` already exposes all relevant state.
|
||||
|
||||
If you use a Servlet web container, with requests processed outside of Spring's
|
||||
`DispatcherServlet` (for example, when using JSF), you need to register the
|
||||
`DispatcherServlet` (for example, when using JSF or Struts), you need to register the
|
||||
`org.springframework.web.context.request.RequestContextListener` `ServletRequestListener`.
|
||||
This can be done programmatically by using the `WebApplicationInitializer` interface.
|
||||
Alternatively, add the following declaration to your web application's `web.xml` file:
|
||||
@@ -5200,7 +5205,6 @@ with specific arguments, narrowing the set of type matches so that a specific be
|
||||
chosen for each argument. In the simplest case, this can be a plain descriptive value, as
|
||||
shown in the following example:
|
||||
|
||||
--
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
@@ -5225,20 +5229,18 @@ shown in the following example:
|
||||
// ...
|
||||
}
|
||||
----
|
||||
--
|
||||
|
||||
You can also specify the `@Qualifier` annotation on individual constructor arguments or
|
||||
method parameters, as shown in the following example:
|
||||
|
||||
--
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
public class MovieRecommender {
|
||||
|
||||
private final MovieCatalog movieCatalog;
|
||||
private MovieCatalog movieCatalog;
|
||||
|
||||
private final CustomerPreferenceDao customerPreferenceDao;
|
||||
private CustomerPreferenceDao customerPreferenceDao;
|
||||
|
||||
@Autowired
|
||||
public void prepare(@Qualifier("main") MovieCatalog movieCatalog,
|
||||
@@ -5269,11 +5271,9 @@ method parameters, as shown in the following example:
|
||||
// ...
|
||||
}
|
||||
----
|
||||
--
|
||||
|
||||
The following example shows corresponding bean definitions.
|
||||
|
||||
--
|
||||
[source,xml,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
@@ -5307,7 +5307,6 @@ The following example shows corresponding bean definitions.
|
||||
is qualified with the same value.
|
||||
<2> The bean with the `action` qualifier value is wired with the constructor argument that
|
||||
is qualified with the same value.
|
||||
--
|
||||
|
||||
For a fallback match, the bean name is considered a default qualifier value. Thus, you
|
||||
can define the bean with an `id` of `main` instead of the nested qualifier element, leading
|
||||
@@ -5385,7 +5384,6 @@ constructor or a multi-argument method.
|
||||
You can create your own custom qualifier annotations. To do so, define an annotation and
|
||||
provide the `@Qualifier` annotation within your definition, as the following example shows:
|
||||
|
||||
--
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
@@ -5405,12 +5403,10 @@ provide the `@Qualifier` annotation within your definition, as the following exa
|
||||
@Qualifier
|
||||
annotation class Genre(val value: String)
|
||||
----
|
||||
--
|
||||
|
||||
Then you can provide the custom qualifier on autowired fields and parameters, as the
|
||||
following example shows:
|
||||
|
||||
--
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
@@ -5449,7 +5445,6 @@ following example shows:
|
||||
// ...
|
||||
}
|
||||
----
|
||||
--
|
||||
|
||||
Next, you can provide the information for the candidate bean definitions. You can add
|
||||
`<qualifier/>` tags as sub-elements of the `<bean/>` tag and then specify the `type` and
|
||||
@@ -5458,7 +5453,6 @@ fully-qualified class name of the annotation. Alternately, as a convenience if n
|
||||
conflicting names exists, you can use the short class name. The following example
|
||||
demonstrates both approaches:
|
||||
|
||||
--
|
||||
[source,xml,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
@@ -5486,7 +5480,6 @@ demonstrates both approaches:
|
||||
|
||||
</beans>
|
||||
----
|
||||
--
|
||||
|
||||
In <<beans-classpath-scanning>>, you can see an annotation-based alternative to
|
||||
providing the qualifier metadata in XML. Specifically, see <<beans-scanning-qualifiers>>.
|
||||
@@ -5497,7 +5490,6 @@ several different types of dependencies. For example, you may provide an offline
|
||||
catalog that can be searched when no Internet connection is available. First, define
|
||||
the simple annotation, as the following example shows:
|
||||
|
||||
--
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
@@ -5505,6 +5497,7 @@ the simple annotation, as the following example shows:
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Qualifier
|
||||
public @interface Offline {
|
||||
|
||||
}
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
@@ -5515,12 +5508,10 @@ the simple annotation, as the following example shows:
|
||||
@Qualifier
|
||||
annotation class Offline
|
||||
----
|
||||
--
|
||||
|
||||
Then add the annotation to the field or property to be autowired, as shown in the
|
||||
following example:
|
||||
|
||||
--
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
@@ -5548,11 +5539,9 @@ class MovieRecommender {
|
||||
}
|
||||
----
|
||||
<1> This line adds the `@Offline` annotation.
|
||||
--
|
||||
|
||||
Now the bean definition only needs a qualifier `type`, as shown in the following example:
|
||||
|
||||
--
|
||||
[source,xml,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
<bean class="example.SimpleMovieCatalog">
|
||||
@@ -5561,7 +5550,6 @@ Now the bean definition only needs a qualifier `type`, as shown in the following
|
||||
</bean>
|
||||
----
|
||||
<1> This element specifies the qualifier.
|
||||
--
|
||||
|
||||
|
||||
You can also define custom qualifier annotations that accept named attributes in
|
||||
@@ -5570,7 +5558,6 @@ then specified on a field or parameter to be autowired, a bean definition must m
|
||||
all such attribute values to be considered an autowire candidate. As an example,
|
||||
consider the following annotation definition:
|
||||
|
||||
--
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
@@ -5592,11 +5579,9 @@ consider the following annotation definition:
|
||||
@Qualifier
|
||||
annotation class MovieQualifier(val genre: String, val format: Format)
|
||||
----
|
||||
--
|
||||
|
||||
In this case `Format` is an enum, defined as follows:
|
||||
|
||||
--
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
@@ -5611,12 +5596,10 @@ In this case `Format` is an enum, defined as follows:
|
||||
VHS, DVD, BLURAY
|
||||
}
|
||||
----
|
||||
--
|
||||
|
||||
The fields to be autowired are annotated with the custom qualifier and include values
|
||||
for both attributes: `genre` and `format`, as the following example shows:
|
||||
|
||||
--
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
@@ -5665,7 +5648,6 @@ for both attributes: `genre` and `format`, as the following example shows:
|
||||
// ...
|
||||
}
|
||||
----
|
||||
--
|
||||
|
||||
Finally, the bean definitions should contain matching qualifier values. This example
|
||||
also demonstrates that you can use bean meta attributes instead of the
|
||||
@@ -5674,7 +5656,6 @@ precedence, but the autowiring mechanism falls back on the values provided withi
|
||||
`<meta/>` tags if no such qualifier is present, as in the last two bean definitions in
|
||||
the following example:
|
||||
|
||||
--
|
||||
[source,xml,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
@@ -5718,7 +5699,6 @@ the following example:
|
||||
|
||||
</beans>
|
||||
----
|
||||
--
|
||||
|
||||
|
||||
|
||||
@@ -5850,7 +5830,6 @@ endpoints. Spring supports this pattern for Spring-managed objects as well.
|
||||
the bean name to be injected. In other words, it follows by-name semantics,
|
||||
as demonstrated in the following example:
|
||||
|
||||
--
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
@@ -5876,7 +5855,6 @@ class SimpleMovieLister {
|
||||
}
|
||||
----
|
||||
<1> This line injects a `@Resource`.
|
||||
--
|
||||
|
||||
|
||||
If no name is explicitly specified, the default name is derived from the field name or
|
||||
@@ -5884,7 +5862,6 @@ setter method. In case of a field, it takes the field name. In case of a setter
|
||||
it takes the bean property name. The following example is going to have the bean
|
||||
named `movieFinder` injected into its setter method:
|
||||
|
||||
--
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
@@ -5908,7 +5885,6 @@ named `movieFinder` injected into its setter method:
|
||||
|
||||
}
|
||||
----
|
||||
--
|
||||
|
||||
NOTE: The name provided with the annotation is resolved as a bean name by the
|
||||
`ApplicationContext` of which the `CommonAnnotationBeanPostProcessor` is aware.
|
||||
@@ -5927,7 +5903,6 @@ Thus, in the following example, the `customerPreferenceDao` field first looks fo
|
||||
named "customerPreferenceDao" and then falls back to a primary type match for the type
|
||||
`CustomerPreferenceDao`:
|
||||
|
||||
--
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
@@ -5965,7 +5940,6 @@ named "customerPreferenceDao" and then falls back to a primary type match for th
|
||||
----
|
||||
<1> The `context` field is injected based on the known resolvable dependency type:
|
||||
`ApplicationContext`.
|
||||
--
|
||||
|
||||
[[beans-value-annotations]]
|
||||
=== Using `@Value`
|
||||
@@ -7541,7 +7515,7 @@ container. It includes the following topics:
|
||||
[[beans-java-basic-concepts]]
|
||||
=== Basic Concepts: `@Bean` and `@Configuration`
|
||||
|
||||
The central artifacts in Spring's Java configuration support are
|
||||
The central artifacts in Spring's new Java-configuration support are
|
||||
`@Configuration`-annotated classes and `@Bean`-annotated methods.
|
||||
|
||||
The `@Bean` annotation is used to indicate that a method instantiates, configures, and
|
||||
@@ -8125,7 +8099,7 @@ class AppConfig {
|
||||
By default, beans defined with Java configuration that have a public `close` or `shutdown`
|
||||
method are automatically enlisted with a destruction callback. If you have a public
|
||||
`close` or `shutdown` method and you do not wish for it to be called when the container
|
||||
shuts down, you can add `@Bean(destroyMethod = "")` to your bean definition to disable the
|
||||
shuts down, you can add `@Bean(destroyMethod="")` to your bean definition to disable the
|
||||
default `(inferred)` mode.
|
||||
|
||||
You may want to do that by default for a resource that you acquire with JNDI, as its
|
||||
@@ -8138,7 +8112,7 @@ The following example shows how to prevent an automatic destruction callback for
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
@Bean(destroyMethod = "")
|
||||
@Bean(destroyMethod="")
|
||||
public DataSource dataSource() throws NamingException {
|
||||
return (DataSource) jndiTemplate.lookup("MyDS");
|
||||
}
|
||||
@@ -9482,7 +9456,7 @@ now looks like the following listing:
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
@Bean(destroyMethod = "")
|
||||
@Bean(destroyMethod="")
|
||||
public DataSource dataSource() throws Exception {
|
||||
Context ctx = new InitialContext();
|
||||
return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource");
|
||||
@@ -9521,7 +9495,6 @@ annotation lets you indicate that a component is eligible for registration
|
||||
when one or more specified profiles are active. Using our preceding example, we
|
||||
can rewrite the `dataSource` configuration as follows:
|
||||
|
||||
--
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
@@ -9556,9 +9529,7 @@ can rewrite the `dataSource` configuration as follows:
|
||||
}
|
||||
}
|
||||
----
|
||||
--
|
||||
|
||||
--
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
@@ -9566,15 +9537,13 @@ can rewrite the `dataSource` configuration as follows:
|
||||
@Profile("production")
|
||||
public class JndiDataConfig {
|
||||
|
||||
@Bean(destroyMethod = "") // <1>
|
||||
@Bean(destroyMethod="")
|
||||
public DataSource dataSource() throws Exception {
|
||||
Context ctx = new InitialContext();
|
||||
return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource");
|
||||
}
|
||||
}
|
||||
----
|
||||
<1> `@Bean(destroyMethod = "")` disables default destroy method inference.
|
||||
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
@@ -9582,15 +9551,13 @@ can rewrite the `dataSource` configuration as follows:
|
||||
@Profile("production")
|
||||
class JndiDataConfig {
|
||||
|
||||
@Bean(destroyMethod = "") // <1>
|
||||
@Bean(destroyMethod = "")
|
||||
fun dataSource(): DataSource {
|
||||
val ctx = InitialContext()
|
||||
return ctx.lookup("java:comp/env/jdbc/datasource") as DataSource
|
||||
}
|
||||
}
|
||||
----
|
||||
<1> `@Bean(destroyMethod = "")` disables default destroy method inference.
|
||||
--
|
||||
|
||||
NOTE: As mentioned earlier, with `@Bean` methods, you typically choose to use programmatic
|
||||
JNDI lookups, by using either Spring's `JndiTemplate`/`JndiLocatorDelegate` helpers or the
|
||||
@@ -9602,9 +9569,9 @@ profile expression. A profile expression allows for more complicated profile log
|
||||
expressed (for example, `production & us-east`). The following operators are supported in
|
||||
profile expressions:
|
||||
|
||||
* `!`: A logical `NOT` of the profile
|
||||
* `&`: A logical `AND` of the profiles
|
||||
* `|`: A logical `OR` of the profiles
|
||||
* `!`: A logical "`not`" of the profile
|
||||
* `&`: A logical "`and`" of the profiles
|
||||
* `|`: A logical "`or`" of the profiles
|
||||
|
||||
NOTE: You cannot mix the `&` and `|` operators without using parentheses. For example,
|
||||
`production & us-east | eu-central` is not a valid expression. It must be expressed as
|
||||
@@ -9615,7 +9582,6 @@ of creating a custom composed annotation. The following example defines a custom
|
||||
`@Production` annotation that you can use as a drop-in replacement for
|
||||
`@Profile("production")`:
|
||||
|
||||
--
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
@@ -9633,7 +9599,6 @@ of creating a custom composed annotation. The following example defines a custom
|
||||
@Profile("production")
|
||||
annotation class Production
|
||||
----
|
||||
--
|
||||
|
||||
TIP: If a `@Configuration` class is marked with `@Profile`, all of the `@Bean` methods and
|
||||
`@Import` annotations associated with that class are bypassed unless one or more of
|
||||
@@ -9648,7 +9613,6 @@ active. For example, given `@Profile({"p1", "!p2"})`, registration will occur if
|
||||
of a configuration class (for example, for alternative variants of a particular bean), as
|
||||
the following example shows:
|
||||
|
||||
--
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
@@ -9700,7 +9664,6 @@ the following example shows:
|
||||
----
|
||||
<1> The `standaloneDataSource` method is available only in the `development` profile.
|
||||
<2> The `jndiDataSource` method is available only in the `production` profile.
|
||||
--
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
@@ -9871,7 +9834,7 @@ activates multiple profiles:
|
||||
Declaratively, `spring.profiles.active` may accept a comma-separated list of profile names,
|
||||
as the following example shows:
|
||||
|
||||
[literal,indent=0,subs="verbatim,quotes"]
|
||||
[literal,subs="verbatim,quotes"]
|
||||
----
|
||||
-Dspring.profiles.active="profile1,profile2"
|
||||
----
|
||||
@@ -10267,13 +10230,13 @@ handled in the JDK-standard way of resolving messages through `ResourceBundle` o
|
||||
purposes of the example, assume the contents of two of the above resource bundle files
|
||||
are as follows:
|
||||
|
||||
[source,properties,indent=0,subs="verbatim,quotes"]
|
||||
[literal,subs="verbatim,quotes"]
|
||||
----
|
||||
# in format.properties
|
||||
message=Alligators rock!
|
||||
----
|
||||
|
||||
[source,properties,indent=0,subs="verbatim,quotes"]
|
||||
[literal,subs="verbatim,quotes"]
|
||||
----
|
||||
# in exceptions.properties
|
||||
argument.required=The {0} argument is required.
|
||||
|
||||
@@ -1634,7 +1634,7 @@ If you prefer XML-based configuration, you can use a
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans
|
||||
https://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
https://www.springframework.org/schema/beans/spring-beans.xsd>
|
||||
|
||||
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
|
||||
<property name="registerDefaultFormatters" value="false" />
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
[[spring-data-tier]]
|
||||
= Data Access
|
||||
include::attributes.adoc[]
|
||||
include::page-layout.adoc[]
|
||||
:toc: left
|
||||
:toclevels: 4
|
||||
:tabsize: 4
|
||||
:docinfo1:
|
||||
|
||||
This part of the reference documentation is concerned with data access and the
|
||||
interaction between the data access layer and the business or service layer.
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
:noheader:
|
||||
= Spring Framework Documentation
|
||||
include::attributes.adoc[]
|
||||
|
||||
[horizontal]
|
||||
<<overview.adoc#overview, Overview>> :: history, design philosophy, feedback,
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
[[spring-integration]]
|
||||
= Integration
|
||||
include::attributes.adoc[]
|
||||
include::page-layout.adoc[]
|
||||
:doc-spring-amqp: {doc-root}/spring-amqp/docs/current/reference
|
||||
:doc-spring-gemfire: {doc-root}/spring-gemfire/docs/current/reference
|
||||
:toc: left
|
||||
:toclevels: 4
|
||||
:tabsize: 4
|
||||
:docinfo1:
|
||||
|
||||
This part of the reference documentation covers Spring Framework's integration with
|
||||
a number of technologies.
|
||||
@@ -5647,7 +5651,7 @@ GemFire is a memory-oriented, disk-backed, elastically scalable, continuously av
|
||||
active (with built-in pattern-based subscription notifications), globally replicated
|
||||
database and provides fully-featured edge caching. For further information on how to
|
||||
use GemFire as a `CacheManager` (and more), see the
|
||||
{docs-spring-gemfire}/html/[Spring Data GemFire reference documentation].
|
||||
{doc-spring-gemfire}/html/[Spring Data GemFire reference documentation].
|
||||
|
||||
|
||||
[[cache-store-configuration-jsr107]]
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
[[languages]]
|
||||
= Language Support
|
||||
include::attributes.adoc[]
|
||||
include::page-layout.adoc[]
|
||||
:toc: left
|
||||
:toclevels: 4
|
||||
:tabsize: 4
|
||||
:docinfo1:
|
||||
|
||||
include::languages/kotlin.adoc[leveloffset=+1]
|
||||
|
||||
|
||||
@@ -20,9 +20,6 @@ Feel free to join the #spring channel of https://slack.kotlinlang.org/[Kotlin Sl
|
||||
or ask a question with `spring` and `kotlin` as tags on
|
||||
https://stackoverflow.com/questions/tagged/spring+kotlin[Stackoverflow] if you need support.
|
||||
|
||||
|
||||
|
||||
|
||||
[[kotlin-requirements]]
|
||||
== Requirements
|
||||
|
||||
@@ -40,9 +37,6 @@ for serializing or deserializing JSON data for Kotlin classes with Jackson, so m
|
||||
`com.fasterxml.jackson.module:jackson-module-kotlin` dependency to your project if you have such need.
|
||||
It is automatically registered when found in the classpath.
|
||||
|
||||
|
||||
|
||||
|
||||
[[kotlin-extensions]]
|
||||
== Extensions
|
||||
|
||||
@@ -86,9 +80,6 @@ With Kotlin and the Spring Framework extensions, you can instead write the follo
|
||||
As in Java, `users` in Kotlin is strongly typed, but Kotlin's clever type inference allows
|
||||
for shorter syntax.
|
||||
|
||||
|
||||
|
||||
|
||||
[[kotlin-null-safety]]
|
||||
== Null-safety
|
||||
|
||||
@@ -124,9 +115,6 @@ NOTE: Generic type arguments, varargs, and array elements nullability are not su
|
||||
but should be in an upcoming release. See https://github.com/Kotlin/KEEP/issues/79[this discussion]
|
||||
for up-to-date information.
|
||||
|
||||
|
||||
|
||||
|
||||
[[kotlin-classes-interfaces]]
|
||||
== Classes and Interfaces
|
||||
|
||||
@@ -136,16 +124,12 @@ with default values.
|
||||
|
||||
Kotlin parameter names are recognized through a dedicated `KotlinReflectionParameterNameDiscoverer`,
|
||||
which allows finding interface method parameter names without requiring the Java 8 `-parameters`
|
||||
compiler flag to be enabled during compilation. (For completeness, we nevertheless recommend
|
||||
running the Kotlin compiler with its `-java-parameters` flag for standard Java parameter exposure.)
|
||||
compiler flag to be enabled during compilation.
|
||||
|
||||
You can declare configuration classes as
|
||||
https://kotlinlang.org/docs/reference/nested-classes.html[top level or nested but not inner],
|
||||
since the later requires a reference to the outer class.
|
||||
|
||||
|
||||
|
||||
|
||||
[[kotlin-annotations]]
|
||||
== Annotations
|
||||
|
||||
@@ -172,9 +156,6 @@ https://kotlinlang.org/docs/reference/annotations.html#annotation-use-site-targe
|
||||
such as `@field:NotNull` or `@get:Size(min=5, max=15)`, as described in
|
||||
https://stackoverflow.com/a/35853200/1092077[this Stack Overflow response].
|
||||
|
||||
|
||||
|
||||
|
||||
[[kotlin-bean-definition-dsl]]
|
||||
== Bean Definition DSL
|
||||
|
||||
@@ -282,20 +263,16 @@ as the following example shows:
|
||||
}
|
||||
----
|
||||
|
||||
|
||||
NOTE: Spring Boot is based on JavaConfig and
|
||||
https://github.com/spring-projects/spring-boot/issues/8115[does not yet provide specific support for functional bean definition],
|
||||
but you can experimentally use functional bean definitions through Spring Boot's `ApplicationContextInitializer` support.
|
||||
See https://stackoverflow.com/questions/45935931/how-to-use-functional-bean-definition-kotlin-dsl-with-spring-boot-and-spring-w/46033685#46033685[this Stack Overflow answer]
|
||||
for more details and up-to-date information. See also the experimental Kofu DSL developed in https://github.com/spring-projects/spring-fu[Spring Fu incubator].
|
||||
|
||||
|
||||
|
||||
|
||||
[[kotlin-web]]
|
||||
== Web
|
||||
|
||||
|
||||
|
||||
=== Router DSL
|
||||
|
||||
Spring Framework comes with a Kotlin router DSL available in 3 flavors:
|
||||
@@ -337,8 +314,6 @@ when you need to register routes depending on dynamic data (for example, from a
|
||||
|
||||
See https://github.com/mixitconf/mixit/[MiXiT project] for a concrete example.
|
||||
|
||||
|
||||
|
||||
=== MockMvc DSL
|
||||
|
||||
A Kotlin DSL is provided via `MockMvc` Kotlin extensions in order to provide a more
|
||||
@@ -364,8 +339,6 @@ mockMvc.get("/person/{name}", "Lee") {
|
||||
}
|
||||
----
|
||||
|
||||
|
||||
|
||||
=== Kotlin Script Templates
|
||||
|
||||
Spring Framework provides a
|
||||
@@ -384,7 +357,9 @@ dependencies {
|
||||
}
|
||||
----
|
||||
|
||||
Configuration is usually done with `ScriptTemplateConfigurer` and `ScriptTemplateViewResolver` beans.
|
||||
Configuration is usually done with `ScriptTemplateConfigurer` and `ScriptTemplateViewResolver`
|
||||
beans.
|
||||
|
||||
|
||||
`KotlinScriptConfiguration.kt`
|
||||
[source,kotlin,indent=0]
|
||||
@@ -411,8 +386,6 @@ class KotlinScriptConfiguration {
|
||||
See the https://github.com/sdeleuze/kotlin-script-templating[kotlin-script-templating] example
|
||||
project for more details.
|
||||
|
||||
|
||||
|
||||
=== Kotlin multiplatform serialization
|
||||
|
||||
As of Spring Framework 5.3, https://github.com/Kotlin/kotlinx.serialization[Kotlin multiplatform serialization] is
|
||||
@@ -424,9 +397,6 @@ Kotlin serialization is designed to serialize only Kotlin classes annotated with
|
||||
With Spring Messaging (RSocket), make sure that neither Jackson, GSON or JSONB are in the classpath if you want automatic configuration,
|
||||
if Jackson is needed configure `KotlinSerializationJsonMessageConverter` manually.
|
||||
|
||||
|
||||
|
||||
|
||||
== Coroutines
|
||||
|
||||
Kotlin https://kotlinlang.org/docs/reference/coroutines-overview.html[Coroutines] are Kotlin
|
||||
@@ -445,8 +415,6 @@ Spring Framework provides support for Coroutines on the following scope:
|
||||
* Suspending function and `Flow` support in RSocket `@MessageMapping` annotated methods
|
||||
* Extensions for {docs-spring-framework}/kdoc-api/spring-messaging/org.springframework.messaging.rsocket/index.html[`RSocketRequester`]
|
||||
|
||||
|
||||
|
||||
=== Dependencies
|
||||
|
||||
Coroutines support is enabled when `kotlinx-coroutines-core` and `kotlinx-coroutines-reactor`
|
||||
@@ -464,8 +432,6 @@ dependencies {
|
||||
|
||||
Version `1.4.0` and above are supported.
|
||||
|
||||
|
||||
|
||||
=== How Reactive translates to Coroutines?
|
||||
|
||||
For return values, the translation from Reactive to Coroutines APIs is the following:
|
||||
@@ -492,8 +458,6 @@ https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coro
|
||||
Read this blog post about https://spring.io/blog/2019/04/12/going-reactive-with-spring-coroutines-and-kotlin-flow[Going Reactive with Spring, Coroutines and Kotlin Flow]
|
||||
for more details, including how to run code concurrently with Coroutines.
|
||||
|
||||
|
||||
|
||||
=== Controllers
|
||||
|
||||
Here is an example of a Coroutines `@RestController`.
|
||||
@@ -590,8 +554,6 @@ class CoroutinesViewController(banner: Banner) {
|
||||
}
|
||||
----
|
||||
|
||||
|
||||
|
||||
=== WebFlux.fn
|
||||
|
||||
Here is an example of Coroutines router defined via the {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }] DSL and related handlers.
|
||||
@@ -625,8 +587,6 @@ class UserHandler(builder: WebClient.Builder) {
|
||||
}
|
||||
----
|
||||
|
||||
|
||||
|
||||
=== Transactions
|
||||
|
||||
Transactions on Coroutines are supported via the programmatic variant of the Reactive
|
||||
@@ -676,8 +636,6 @@ For Kotlin `Flow`, a `Flow<T>.transactional` extension is provided.
|
||||
----
|
||||
|
||||
|
||||
|
||||
|
||||
[[kotlin-spring-projects-in-kotlin]]
|
||||
== Spring Projects in Kotlin
|
||||
|
||||
@@ -725,8 +683,6 @@ NOTE: The Kotlin code samples in Spring Framework documentation do not explicitl
|
||||
`open` on the classes and their member functions. The samples are written for projects
|
||||
using the `kotlin-allopen` plugin, since this is the most commonly used setup.
|
||||
|
||||
|
||||
|
||||
=== Using Immutable Class Instances for Persistence
|
||||
|
||||
In Kotlin, it is convenient and considered to be a best practice to declare read-only properties
|
||||
@@ -770,8 +726,6 @@ NOTE: As of the Kay release train, Spring Data supports Kotlin immutable class i
|
||||
does not require the `kotlin-noarg` plugin if the module uses Spring Data object mappings
|
||||
(such as MongoDB, Redis, Cassandra, and others).
|
||||
|
||||
|
||||
|
||||
=== Injecting Dependencies
|
||||
|
||||
Our recommendation is to try to favor constructor injection with `val` read-only (and
|
||||
@@ -807,8 +761,6 @@ as the following example shows:
|
||||
}
|
||||
----
|
||||
|
||||
|
||||
|
||||
=== Injecting Configuration Properties
|
||||
|
||||
In Java, you can inject configuration properties by using annotations (such as pass:q[`@Value("${property}")`)].
|
||||
@@ -849,7 +801,6 @@ that uses the `${...}` syntax, with configuration beans, as the following exampl
|
||||
----
|
||||
|
||||
|
||||
|
||||
=== Checked Exceptions
|
||||
|
||||
Java and https://kotlinlang.org/docs/reference/exceptions.html[Kotlin exception handling]
|
||||
@@ -862,8 +813,6 @@ To get the original exception thrown like in Java, methods should be annotated w
|
||||
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/-throws/index.html[`@Throws`]
|
||||
to specify explicitly the checked exceptions thrown (for example `@Throws(IOException::class)`).
|
||||
|
||||
|
||||
|
||||
=== Annotation Array Attributes
|
||||
|
||||
Kotlin annotations are mostly similar to Java annotations, but array attributes (which are
|
||||
@@ -908,8 +857,6 @@ use a shortcut annotation, such as `@GetMapping`, `@PostMapping`, and others.
|
||||
NOTE: If the `@RequestMapping` `method` attribute is not specified, all HTTP methods will
|
||||
be matched, not only the `GET` method.
|
||||
|
||||
|
||||
|
||||
=== Testing
|
||||
|
||||
This section addresses testing with the combination of Kotlin and Spring Framework.
|
||||
@@ -919,7 +866,6 @@ https://mockk.io/[Mockk] for mocking.
|
||||
NOTE: If you are using Spring Boot, see
|
||||
https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-kotlin-testing[this related documentation].
|
||||
|
||||
|
||||
==== Constructor injection
|
||||
|
||||
As described in the <<testing#testcontext-junit-jupiter-di, dedicated section>>,
|
||||
@@ -941,7 +887,6 @@ class OrderServiceIntegrationTests(val orderService: OrderService,
|
||||
----
|
||||
====
|
||||
|
||||
|
||||
==== `PER_CLASS` Lifecycle
|
||||
|
||||
Kotlin lets you specify meaningful test function names between backticks (```).
|
||||
@@ -985,7 +930,6 @@ class IntegrationTests {
|
||||
}
|
||||
----
|
||||
|
||||
|
||||
==== Specification-like Tests
|
||||
|
||||
You can create specification-like tests with JUnit 5 and Kotlin.
|
||||
@@ -1015,7 +959,6 @@ class SpecificationLikeTests {
|
||||
}
|
||||
----
|
||||
|
||||
|
||||
[[kotlin-webtestclient-issue]]
|
||||
==== `WebTestClient` Type Inference Issue in Kotlin
|
||||
|
||||
@@ -1025,24 +968,17 @@ since it provides a workaround for the Kotlin issue with the Java API.
|
||||
|
||||
See also the related https://jira.spring.io/browse/SPR-16057[SPR-16057] issue.
|
||||
|
||||
|
||||
|
||||
|
||||
[[kotlin-getting-started]]
|
||||
== Getting Started
|
||||
|
||||
The easiest way to learn how to build a Spring application with Kotlin is to follow
|
||||
https://spring.io/guides/tutorials/spring-boot-kotlin/[the dedicated tutorial].
|
||||
|
||||
|
||||
|
||||
=== `start.spring.io`
|
||||
|
||||
The easiest way to start a new Spring Framework project in Kotlin is to create a new Spring
|
||||
Boot 2 project on https://start.spring.io/#!language=kotlin&type=gradle-project[start.spring.io].
|
||||
|
||||
|
||||
|
||||
=== Choosing the Web Flavor
|
||||
|
||||
Spring Framework now comes with two different web stacks: <<web#mvc, Spring MVC>> and
|
||||
@@ -1055,9 +991,6 @@ Kotlin DSL.
|
||||
For other use cases, especially if you are using blocking technologies such as JPA, Spring
|
||||
MVC and its annotation-based programming model is the recommended choice.
|
||||
|
||||
|
||||
|
||||
|
||||
[[kotlin-resources]]
|
||||
== Resources
|
||||
|
||||
@@ -1071,8 +1004,6 @@ Kotlin and the Spring Framework:
|
||||
* https://blog.jetbrains.com/kotlin/[Kotlin blog]
|
||||
* https://kotlin.link/[Awesome Kotlin]
|
||||
|
||||
|
||||
|
||||
=== Examples
|
||||
|
||||
The following Github projects offer examples that you can learn from and possibly even extend:
|
||||
@@ -1085,8 +1016,6 @@ The following Github projects offer examples that you can learn from and possibl
|
||||
* https://github.com/sdeleuze/spring-kotlin-deepdive[spring-kotlin-deepdive]: A step-by-step migration guide for Boot 1.0 and Java to Boot 2.0 and Kotlin
|
||||
* https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-kotlin-samples/spring-cloud-gcp-kotlin-app-sample[spring-cloud-gcp-kotlin-app-sample]: Spring Boot with Google Cloud Platform Integrations
|
||||
|
||||
|
||||
|
||||
=== Issues
|
||||
|
||||
The following list categorizes the pending issues related to Spring and Kotlin support:
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
[[overview]]
|
||||
= Spring Framework Overview
|
||||
include::attributes.adoc[]
|
||||
:toc: left
|
||||
:toclevels: 1
|
||||
:docinfo1:
|
||||
@@ -8,8 +7,10 @@ include::attributes.adoc[]
|
||||
Spring makes it easy to create Java enterprise applications. It provides everything you
|
||||
need to embrace the Java language in an enterprise environment, with support for Groovy
|
||||
and Kotlin as alternative languages on the JVM, and with the flexibility to create many
|
||||
kinds of architectures depending on an application's needs. As of Spring Framework 6.0,
|
||||
Spring requires Java 17+.
|
||||
kinds of architectures depending on an application's needs. As of Spring Framework 5.1,
|
||||
Spring requires JDK 8+ (Java SE 8+) and provides out-of-the-box support for JDK 11 LTS.
|
||||
Java SE 8 update 60 is suggested as the minimum patch release for Java 8, but it is
|
||||
generally recommended to use a recent patch release.
|
||||
|
||||
Spring supports a wide range of application scenarios. In a large enterprise, applications
|
||||
often exist for a long time and have to run on a JDK and application server whose upgrade
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
:toc: left
|
||||
:toclevels: 4
|
||||
:tabsize: 4
|
||||
:docinfo1:
|
||||
@@ -1,7 +1,8 @@
|
||||
[[rsocket]]
|
||||
= RSocket
|
||||
include::attributes.adoc[]
|
||||
include::page-layout.adoc[]
|
||||
:gh-rsocket: https://github.com/rsocket
|
||||
:gh-rsocket-java: {gh-rsocket}/rsocket-java
|
||||
:gh-rsocket-extensions: {gh-rsocket}/rsocket/blob/master/Extensions
|
||||
|
||||
This section describes Spring Framework's support for the RSocket protocol.
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
:noheader:
|
||||
= Spring Framework Documentation
|
||||
include::attributes.adoc[]
|
||||
|
||||
include::overview.adoc[leveloffset=+1]
|
||||
include::core.adoc[leveloffset=+1]
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,155 +0,0 @@
|
||||
[[integration-testing]]
|
||||
= Integration Testing
|
||||
|
||||
It is important to be able to perform some integration testing without requiring
|
||||
deployment to your application server or connecting to other enterprise infrastructure.
|
||||
Doing so lets you test things such as:
|
||||
|
||||
* The correct wiring of your Spring IoC container contexts.
|
||||
* Data access using JDBC or an ORM tool. This can include such things as the correctness
|
||||
of SQL statements, Hibernate queries, JPA entity mappings, and so forth.
|
||||
|
||||
The Spring Framework provides first-class support for integration testing in the
|
||||
`spring-test` module. The name of the actual JAR file might include the release version
|
||||
and might also be in the long `org.springframework.test` form, depending on where you get
|
||||
it from (see the <<core.adoc#beans-dependencies, section on Dependency Management>>
|
||||
for an explanation). This library includes the `org.springframework.test` package, which
|
||||
contains valuable classes for integration testing with a Spring container. This testing
|
||||
does not rely on an application server or other deployment environment. Such tests are
|
||||
slower to run than unit tests but much faster than the equivalent Selenium tests or
|
||||
remote tests that rely on deployment to an application server.
|
||||
|
||||
Unit and integration testing support is provided in the form of the annotation-driven
|
||||
<<testcontext-framework, Spring TestContext Framework>>. The TestContext framework is
|
||||
agnostic of the actual testing framework in use, which allows instrumentation of tests
|
||||
in various environments, including JUnit, TestNG, and others.
|
||||
|
||||
The following section provides an overview of the high-level goals of Spring's
|
||||
integration support, and the rest of this chapter then focuses on dedicated topics:
|
||||
|
||||
* <<integration-testing-support-jdbc>>
|
||||
* <<testcontext-framework>>
|
||||
* <<webtestclient>>
|
||||
* <<spring-mvc-test-framework>>
|
||||
* <<spring-mvc-test-client>>
|
||||
* <<integration-testing-annotations>>
|
||||
|
||||
|
||||
|
||||
[[integration-testing-goals]]
|
||||
== Goals of Integration Testing
|
||||
|
||||
Spring's integration testing support has the following primary goals:
|
||||
|
||||
* To manage <<testing-ctx-management, Spring IoC container caching>> between tests.
|
||||
* To provide <<testing-fixture-di, Dependency Injection of test fixture instances>>.
|
||||
* To provide <<testing-tx, transaction management>> appropriate to integration testing.
|
||||
* To supply <<testing-support-classes, Spring-specific base classes>> that assist
|
||||
developers in writing integration tests.
|
||||
|
||||
The next few sections describe each goal and provide links to implementation and
|
||||
configuration details.
|
||||
|
||||
|
||||
[[testing-ctx-management]]
|
||||
=== Context Management and Caching
|
||||
|
||||
The Spring TestContext Framework provides consistent loading of Spring
|
||||
`ApplicationContext` instances and `WebApplicationContext` instances as well as caching
|
||||
of those contexts. Support for the caching of loaded contexts is important, because
|
||||
startup time can become an issue -- not because of the overhead of Spring itself, but
|
||||
because the objects instantiated by the Spring container take time to instantiate. For
|
||||
example, a project with 50 to 100 Hibernate mapping files might take 10 to 20 seconds to
|
||||
load the mapping files, and incurring that cost before running every test in every test
|
||||
fixture leads to slower overall test runs that reduce developer productivity.
|
||||
|
||||
Test classes typically declare either an array of resource locations for XML or Groovy
|
||||
configuration metadata -- often in the classpath -- or an array of component classes that
|
||||
is used to configure the application. These locations or classes are the same as or
|
||||
similar to those specified in `web.xml` or other configuration files for production
|
||||
deployments.
|
||||
|
||||
By default, once loaded, the configured `ApplicationContext` is reused for each test.
|
||||
Thus, the setup cost is incurred only once per test suite, and subsequent test execution
|
||||
is much faster. In this context, the term "`test suite`" means all tests run in the same
|
||||
JVM -- for example, all tests run from an Ant, Maven, or Gradle build for a given project
|
||||
or module. In the unlikely case that a test corrupts the application context and requires
|
||||
reloading (for example, by modifying a bean definition or the state of an application
|
||||
object) the TestContext framework can be configured to reload the configuration and
|
||||
rebuild the application context before executing the next test.
|
||||
|
||||
See <<testcontext-ctx-management>> and <<testcontext-ctx-management-caching>> with the
|
||||
TestContext framework.
|
||||
|
||||
|
||||
[[testing-fixture-di]]
|
||||
=== Dependency Injection of Test Fixtures
|
||||
|
||||
When the TestContext framework loads your application context, it can optionally
|
||||
configure instances of your test classes by using Dependency Injection. This provides a
|
||||
convenient mechanism for setting up test fixtures by using preconfigured beans from your
|
||||
application context. A strong benefit here is that you can reuse application contexts
|
||||
across various testing scenarios (for example, for configuring Spring-managed object
|
||||
graphs, transactional proxies, `DataSource` instances, and others), thus avoiding the
|
||||
need to duplicate complex test fixture setup for individual test cases.
|
||||
|
||||
As an example, consider a scenario where we have a class (`HibernateTitleRepository`)
|
||||
that implements data access logic for a `Title` domain entity. We want to write
|
||||
integration tests that test the following areas:
|
||||
|
||||
* The Spring configuration: Basically, is everything related to the configuration of the
|
||||
`HibernateTitleRepository` bean correct and present?
|
||||
* The Hibernate mapping file configuration: Is everything mapped correctly and are the
|
||||
correct lazy-loading settings in place?
|
||||
* The logic of the `HibernateTitleRepository`: Does the configured instance of this class
|
||||
perform as anticipated?
|
||||
|
||||
See dependency injection of test fixtures with the
|
||||
<<testcontext-fixture-di, TestContext framework>>.
|
||||
|
||||
|
||||
[[testing-tx]]
|
||||
=== Transaction Management
|
||||
|
||||
One common issue in tests that access a real database is their effect on the state of the
|
||||
persistence store. Even when you use a development database, changes to the state may
|
||||
affect future tests. Also, many operations -- such as inserting or modifying persistent
|
||||
data -- cannot be performed (or verified) outside of a transaction.
|
||||
|
||||
The TestContext framework addresses this issue. By default, the framework creates and
|
||||
rolls back a transaction for each test. You can write code that can assume the existence
|
||||
of a transaction. If you call transactionally proxied objects in your tests, they behave
|
||||
correctly, according to their configured transactional semantics. In addition, if a test
|
||||
method deletes the contents of selected tables while running within the transaction
|
||||
managed for the test, the transaction rolls back by default, and the database returns to
|
||||
its state prior to execution of the test. Transactional support is provided to a test by
|
||||
using a `PlatformTransactionManager` bean defined in the test's application context.
|
||||
|
||||
If you want a transaction to commit (unusual, but occasionally useful when you want a
|
||||
particular test to populate or modify the database), you can tell the TestContext
|
||||
framework to cause the transaction to commit instead of roll back by using the
|
||||
<<integration-testing-annotations, `@Commit`>> annotation.
|
||||
|
||||
See transaction management with the <<testcontext-tx, TestContext framework>>.
|
||||
|
||||
|
||||
[[testing-support-classes]]
|
||||
=== Support Classes for Integration Testing
|
||||
|
||||
The Spring TestContext Framework provides several `abstract` support classes that
|
||||
simplify the writing of integration tests. These base test classes provide well-defined
|
||||
hooks into the testing framework as well as convenient instance variables and methods,
|
||||
which let you access:
|
||||
|
||||
* The `ApplicationContext`, for performing explicit bean lookups or testing the state of
|
||||
the context as a whole.
|
||||
* A `JdbcTemplate`, for executing SQL statements to query the database. You can use such
|
||||
queries to confirm database state both before and after execution of database-related
|
||||
application code, and Spring ensures that such queries run in the scope of the same
|
||||
transaction as the application code. When used in conjunction with an ORM tool, be sure
|
||||
to avoid <<testcontext-tx-false-positives, false positives>>.
|
||||
|
||||
In addition, you may want to create your own custom, application-wide superclass with
|
||||
instance variables and methods specific to your project.
|
||||
|
||||
See support classes for the <<testcontext-support-classes, TestContext framework>>.
|
||||
@@ -1,136 +0,0 @@
|
||||
[[spring-mvc-test-client]]
|
||||
= Testing Client Applications
|
||||
|
||||
You can use client-side tests to test code that internally uses the `RestTemplate`. The
|
||||
idea is to declare expected requests and to provide "`stub`" responses so that you can
|
||||
focus on testing the code in isolation (that is, without running a server). The following
|
||||
example shows how to do so:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
|
||||
MockRestServiceServer mockServer = MockRestServiceServer.bindTo(restTemplate).build();
|
||||
mockServer.expect(requestTo("/greeting")).andRespond(withSuccess());
|
||||
|
||||
// Test code that uses the above RestTemplate ...
|
||||
|
||||
mockServer.verify();
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
val restTemplate = RestTemplate()
|
||||
|
||||
val mockServer = MockRestServiceServer.bindTo(restTemplate).build()
|
||||
mockServer.expect(requestTo("/greeting")).andRespond(withSuccess())
|
||||
|
||||
// Test code that uses the above RestTemplate ...
|
||||
|
||||
mockServer.verify()
|
||||
----
|
||||
|
||||
In the preceding example, `MockRestServiceServer` (the central class for client-side REST
|
||||
tests) configures the `RestTemplate` with a custom `ClientHttpRequestFactory` that
|
||||
asserts actual requests against expectations and returns "`stub`" responses. In this
|
||||
case, we expect a request to `/greeting` and want to return a 200 response with
|
||||
`text/plain` content. We can define additional expected requests and stub responses as
|
||||
needed. When we define expected requests and stub responses, the `RestTemplate` can be
|
||||
used in client-side code as usual. At the end of testing, `mockServer.verify()` can be
|
||||
used to verify that all expectations have been satisfied.
|
||||
|
||||
By default, requests are expected in the order in which expectations were declared. You
|
||||
can set the `ignoreExpectOrder` option when building the server, in which case all
|
||||
expectations are checked (in order) to find a match for a given request. That means
|
||||
requests are allowed to come in any order. The following example uses `ignoreExpectOrder`:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
server = MockRestServiceServer.bindTo(restTemplate).ignoreExpectOrder(true).build();
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
server = MockRestServiceServer.bindTo(restTemplate).ignoreExpectOrder(true).build()
|
||||
----
|
||||
|
||||
Even with unordered requests by default, each request is allowed to run once only.
|
||||
The `expect` method provides an overloaded variant that accepts an `ExpectedCount`
|
||||
argument that specifies a count range (for example, `once`, `manyTimes`, `max`, `min`,
|
||||
`between`, and so on). The following example uses `times`:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
|
||||
MockRestServiceServer mockServer = MockRestServiceServer.bindTo(restTemplate).build();
|
||||
mockServer.expect(times(2), requestTo("/something")).andRespond(withSuccess());
|
||||
mockServer.expect(times(3), requestTo("/somewhere")).andRespond(withSuccess());
|
||||
|
||||
// ...
|
||||
|
||||
mockServer.verify();
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
val restTemplate = RestTemplate()
|
||||
|
||||
val mockServer = MockRestServiceServer.bindTo(restTemplate).build()
|
||||
mockServer.expect(times(2), requestTo("/something")).andRespond(withSuccess())
|
||||
mockServer.expect(times(3), requestTo("/somewhere")).andRespond(withSuccess())
|
||||
|
||||
// ...
|
||||
|
||||
mockServer.verify()
|
||||
----
|
||||
|
||||
Note that, when `ignoreExpectOrder` is not set (the default), and, therefore, requests
|
||||
are expected in order of declaration, then that order applies only to the first of any
|
||||
expected request. For example if "/something" is expected two times followed by
|
||||
"/somewhere" three times, then there should be a request to "/something" before there is
|
||||
a request to "/somewhere", but, aside from that subsequent "/something" and "/somewhere",
|
||||
requests can come at any time.
|
||||
|
||||
As an alternative to all of the above, the client-side test support also provides a
|
||||
`ClientHttpRequestFactory` implementation that you can configure into a `RestTemplate` to
|
||||
bind it to a `MockMvc` instance. That allows processing requests using actual server-side
|
||||
logic but without running a server. The following example shows how to do so:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
|
||||
this.restTemplate = new RestTemplate(new MockMvcClientHttpRequestFactory(mockMvc));
|
||||
|
||||
// Test code that uses the above RestTemplate ...
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
val mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build()
|
||||
restTemplate = RestTemplate(MockMvcClientHttpRequestFactory(mockMvc))
|
||||
|
||||
// Test code that uses the above RestTemplate ...
|
||||
----
|
||||
|
||||
[[spring-mvc-test-client-static-imports]]
|
||||
== Static Imports
|
||||
|
||||
As with server-side tests, the fluent API for client-side tests requires a few static
|
||||
imports. Those are easy to find by searching for `MockRest*`. Eclipse users should add
|
||||
`MockRestRequestMatchers.{asterisk}` and `MockRestResponseCreators.{asterisk}` as
|
||||
"`favorite static members`" in the Eclipse preferences under Java -> Editor -> Content
|
||||
Assist -> Favorites. That allows using content assist after typing the first character of
|
||||
the static method name. Other IDEs (such IntelliJ) may not require any additional
|
||||
configuration. Check for the support for code completion on static members.
|
||||
|
||||
[[spring-mvc-test-client-resources]]
|
||||
== Further Examples of Client-side REST Tests
|
||||
|
||||
Spring MVC Test's own tests include
|
||||
{spring-framework-main-code}/spring-test/src/test/java/org/springframework/test/web/client/samples[example
|
||||
tests] of client-side REST tests.
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,6 +0,0 @@
|
||||
[[testing.appendix]]
|
||||
= Appendix
|
||||
|
||||
include::testing-annotations.adoc[leveloffset=+1]
|
||||
|
||||
include::testing-resources.adoc[leveloffset=+1]
|
||||
@@ -1,8 +0,0 @@
|
||||
[[testing-introduction]]
|
||||
= Introduction to Spring Testing
|
||||
|
||||
Testing is an integral part of enterprise software development. This chapter focuses on
|
||||
the value added by the IoC principle to <<unit-testing, unit testing>> and on the benefits
|
||||
of the Spring Framework's support for <<integration-testing, integration testing>>. (A
|
||||
thorough treatment of testing in the enterprise is beyond the scope of this reference
|
||||
manual.)
|
||||
@@ -1,32 +0,0 @@
|
||||
[[testing-resources]]
|
||||
= Further Resources
|
||||
See the following resources for more information about testing:
|
||||
|
||||
* https://www.junit.org/[JUnit]: "A programmer-friendly testing framework for Java and the JVM".
|
||||
Used by the Spring Framework in its test suite and supported in the
|
||||
<<testcontext-framework, Spring TestContext Framework>>.
|
||||
* https://testng.org/[TestNG]: A testing framework inspired by JUnit with added support
|
||||
for test groups, data-driven testing, distributed testing, and other features. Supported
|
||||
in the <<testcontext-framework, Spring TestContext Framework>>
|
||||
* https://assertj.github.io/doc/[AssertJ]: "Fluent assertions for Java",
|
||||
including support for Java 8 lambdas, streams, and numerous other features.
|
||||
* https://en.wikipedia.org/wiki/Mock_Object[Mock Objects]: Article in Wikipedia.
|
||||
* http://www.mockobjects.com/[MockObjects.com]: Web site dedicated to mock objects, a
|
||||
technique for improving the design of code within test-driven development.
|
||||
* https://mockito.github.io[Mockito]: Java mock library based on the
|
||||
http://xunitpatterns.com/Test%20Spy.html[Test Spy] pattern. Used by the Spring Framework
|
||||
in its test suite.
|
||||
* https://easymock.org/[EasyMock]: Java library "that provides Mock Objects for
|
||||
interfaces (and objects through the class extension) by generating them on the fly using
|
||||
Java's proxy mechanism."
|
||||
* https://jmock.org/[JMock]: Library that supports test-driven development of Java code
|
||||
with mock objects.
|
||||
* https://www.dbunit.org/[DbUnit]: JUnit extension (also usable with Ant and Maven) that
|
||||
is targeted at database-driven projects and, among other things, puts your database into
|
||||
a known state between test runs.
|
||||
* https://www.testcontainers.org/[Testcontainers]: Java library that supports JUnit
|
||||
tests, providing lightweight, throwaway instances of common databases, Selenium web
|
||||
browsers, or anything else that can run in a Docker container.
|
||||
* https://sourceforge.net/projects/grinder/[The Grinder]: Java load testing framework.
|
||||
* https://github.com/Ninja-Squad/springmockk[SpringMockK]: Support for Spring Boot
|
||||
integration tests written in Kotlin using https://mockk.io/[MockK] instead of Mockito.
|
||||
@@ -1,35 +0,0 @@
|
||||
[[integration-testing-support-jdbc]]
|
||||
= JDBC Testing Support
|
||||
|
||||
[[integration-testing-support-jdbc-test-utils]]
|
||||
== JdbcTestUtils
|
||||
|
||||
The `org.springframework.test.jdbc` package contains `JdbcTestUtils`, which is a
|
||||
collection of JDBC-related utility functions intended to simplify standard database
|
||||
testing scenarios. Specifically, `JdbcTestUtils` provides the following static utility
|
||||
methods.
|
||||
|
||||
* `countRowsInTable(..)`: Counts the number of rows in the given table.
|
||||
* `countRowsInTableWhere(..)`: Counts the number of rows in the given table by using the
|
||||
provided `WHERE` clause.
|
||||
* `deleteFromTables(..)`: Deletes all rows from the specified tables.
|
||||
* `deleteFromTableWhere(..)`: Deletes rows from the given table by using the provided
|
||||
`WHERE` clause.
|
||||
* `dropTables(..)`: Drops the specified tables.
|
||||
|
||||
[TIP]
|
||||
====
|
||||
<<testcontext-support-classes-junit4, `AbstractTransactionalJUnit4SpringContextTests`>>
|
||||
and <<testcontext-support-classes-testng, `AbstractTransactionalTestNGSpringContextTests`>>
|
||||
provide convenience methods that delegate to the aforementioned methods in
|
||||
`JdbcTestUtils`.
|
||||
====
|
||||
|
||||
[[integration-testing-support-jdbc-embedded-database]]
|
||||
== Embedded Databases
|
||||
|
||||
The `spring-jdbc` module provides support for configuring and launching an embedded
|
||||
database, which you can use in integration tests that interact with a database.
|
||||
For details, see <<data-access.adoc#jdbc-embedded-database-support, Embedded Database
|
||||
Support>> and <<data-access.adoc#jdbc-embedded-database-dao-testing, Testing Data Access
|
||||
Logic with an Embedded Database>>.
|
||||
@@ -1,168 +0,0 @@
|
||||
[[unit-testing]]
|
||||
= Unit Testing
|
||||
|
||||
Dependency injection should make your code less dependent on the container than it would
|
||||
be with traditional J2EE / Java EE development. The POJOs that make up your application
|
||||
should be testable in JUnit or TestNG tests, with objects instantiated by using the `new`
|
||||
operator, without Spring or any other container. You can use <<mock-objects, mock objects>>
|
||||
(in conjunction with other valuable testing techniques) to test your code in isolation.
|
||||
If you follow the architecture recommendations for Spring, the resulting clean layering
|
||||
and componentization of your codebase facilitate easier unit testing. For example,
|
||||
you can test service layer objects by stubbing or mocking DAO or repository interfaces,
|
||||
without needing to access persistent data while running unit tests.
|
||||
|
||||
True unit tests typically run extremely quickly, as there is no runtime infrastructure to
|
||||
set up. Emphasizing true unit tests as part of your development methodology can boost
|
||||
your productivity. You may not need this section of the testing chapter to help you write
|
||||
effective unit tests for your IoC-based applications. For certain unit testing scenarios,
|
||||
however, the Spring Framework provides mock objects and testing support classes, which
|
||||
are described in this chapter.
|
||||
|
||||
|
||||
|
||||
[[mock-objects]]
|
||||
== Mock Objects
|
||||
|
||||
Spring includes a number of packages dedicated to mocking:
|
||||
|
||||
* <<mock-objects-env>>
|
||||
* <<mock-objects-jndi>>
|
||||
* <<mock-objects-servlet>>
|
||||
* <<mock-objects-web-reactive>>
|
||||
|
||||
|
||||
[[mock-objects-env]]
|
||||
=== Environment
|
||||
|
||||
The `org.springframework.mock.env` package contains mock implementations of the
|
||||
`Environment` and `PropertySource` abstractions (see
|
||||
<<core.adoc#beans-definition-profiles, Bean Definition Profiles>>
|
||||
and <<core.adoc#beans-property-source-abstraction, `PropertySource` Abstraction>>).
|
||||
`MockEnvironment` and `MockPropertySource` are useful for developing
|
||||
out-of-container tests for code that depends on environment-specific properties.
|
||||
|
||||
|
||||
[[mock-objects-jndi]]
|
||||
=== JNDI
|
||||
|
||||
The `org.springframework.mock.jndi` package contains a partial implementation of the JNDI
|
||||
SPI, which you can use to set up a simple JNDI environment for test suites or stand-alone
|
||||
applications. If, for example, JDBC `DataSource` instances get bound to the same JNDI
|
||||
names in test code as they do in a Jakarta EE container, you can reuse both application code
|
||||
and configuration in testing scenarios without modification.
|
||||
|
||||
WARNING: The mock JNDI support in the `org.springframework.mock.jndi` package is
|
||||
officially deprecated as of Spring Framework 5.2 in favor of complete solutions from third
|
||||
parties such as https://github.com/h-thurow/Simple-JNDI[Simple-JNDI].
|
||||
|
||||
|
||||
[[mock-objects-servlet]]
|
||||
=== Servlet API
|
||||
|
||||
The `org.springframework.mock.web` package contains a comprehensive set of Servlet API
|
||||
mock objects that are useful for testing web contexts, controllers, and filters. These
|
||||
mock objects are targeted at usage with Spring's Web MVC framework and are generally more
|
||||
convenient to use than dynamic mock objects (such as https://easymock.org/[EasyMock])
|
||||
or alternative Servlet API mock objects (such as http://www.mockobjects.com[MockObjects]).
|
||||
|
||||
TIP: Since Spring Framework 6.0, the mock objects in `org.springframework.mock.web` are
|
||||
based on the Servlet 6.0 API.
|
||||
|
||||
The Spring MVC Test framework builds on the mock Servlet API objects to provide an
|
||||
integration testing framework for Spring MVC. See <<spring-mvc-test-framework>>.
|
||||
|
||||
|
||||
[[mock-objects-web-reactive]]
|
||||
=== Spring Web Reactive
|
||||
|
||||
The `org.springframework.mock.http.server.reactive` package contains mock implementations
|
||||
of `ServerHttpRequest` and `ServerHttpResponse` for use in WebFlux applications. The
|
||||
`org.springframework.mock.web.server` package contains a mock `ServerWebExchange` that
|
||||
depends on those mock request and response objects.
|
||||
|
||||
Both `MockServerHttpRequest` and `MockServerHttpResponse` extend from the same abstract
|
||||
base classes as server-specific implementations and share behavior with them. For
|
||||
example, a mock request is immutable once created, but you can use the `mutate()` method
|
||||
from `ServerHttpRequest` to create a modified instance.
|
||||
|
||||
In order for the mock response to properly implement the write contract and return a
|
||||
write completion handle (that is, `Mono<Void>`), it by default uses a `Flux` with
|
||||
`cache().then()`, which buffers the data and makes it available for assertions in tests.
|
||||
Applications can set a custom write function (for example, to test an infinite stream).
|
||||
|
||||
The <<webtestclient>> builds on the mock request and response to provide support for
|
||||
testing WebFlux applications without an HTTP server. The client can also be used for
|
||||
end-to-end tests with a running server.
|
||||
|
||||
|
||||
|
||||
[[unit-testing-support-classes]]
|
||||
== Unit Testing Support Classes
|
||||
|
||||
Spring includes a number of classes that can help with unit testing. They fall into two
|
||||
categories:
|
||||
|
||||
* <<unit-testing-utilities>>
|
||||
* <<unit-testing-spring-mvc>>
|
||||
|
||||
|
||||
[[unit-testing-utilities]]
|
||||
=== General Testing Utilities
|
||||
|
||||
The `org.springframework.test.util` package contains several general purpose utilities
|
||||
for use in unit and integration testing.
|
||||
|
||||
{api-spring-framework}/test/util/AopTestUtils.html[`AopTestUtils`] is a collection of
|
||||
AOP-related utility methods. You can use these methods to obtain a reference to the
|
||||
underlying target object hidden behind one or more Spring proxies. For example, if you
|
||||
have configured a bean as a dynamic mock by using a library such as EasyMock or Mockito,
|
||||
and the mock is wrapped in a Spring proxy, you may need direct access to the underlying
|
||||
mock to configure expectations on it and perform verifications. For Spring's core AOP
|
||||
utilities, see {api-spring-framework}/aop/support/AopUtils.html[`AopUtils`] and
|
||||
{api-spring-framework}/aop/framework/AopProxyUtils.html[`AopProxyUtils`].
|
||||
|
||||
{api-spring-framework}/test/util/ReflectionTestUtils.html[`ReflectionTestUtils`] is a
|
||||
collection of reflection-based utility methods. You can use these methods in testing
|
||||
scenarios where you need to change the value of a constant, set a non-`public` field,
|
||||
invoke a non-`public` setter method, or invoke a non-`public` configuration or lifecycle
|
||||
callback method when testing application code for use cases such as the following:
|
||||
|
||||
* ORM frameworks (such as JPA and Hibernate) that condone `private` or `protected` field
|
||||
access as opposed to `public` setter methods for properties in a domain entity.
|
||||
* Spring's support for annotations (such as `@Autowired`, `@Inject`, and `@Resource`),
|
||||
that provide dependency injection for `private` or `protected` fields, setter methods,
|
||||
and configuration methods.
|
||||
* Use of annotations such as `@PostConstruct` and `@PreDestroy` for lifecycle callback
|
||||
methods.
|
||||
|
||||
{api-spring-framework}/test/util/TestSocketUtils.html[`TestSocketUtils`] is a simple
|
||||
utility for finding available TCP ports on `localhost` for use in integration testing
|
||||
scenarios.
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
`TestSocketUtils` can be used in integration tests which start an external server on an
|
||||
available random port. However, these utilities make no guarantee about the subsequent
|
||||
availability of a given port and are therefore unreliable. Instead of using
|
||||
`TestSocketUtils` to find an available local port for a server, it is recommended that
|
||||
you rely on a server's ability to start on a random ephemeral port that it selects or is
|
||||
assigned by the operating system. To interact with that server, you should query the
|
||||
server for the port it is currently using.
|
||||
====
|
||||
|
||||
|
||||
[[unit-testing-spring-mvc]]
|
||||
=== Spring MVC Testing Utilities
|
||||
|
||||
The `org.springframework.test.web` package contains
|
||||
{api-spring-framework}/test/web/ModelAndViewAssert.html[`ModelAndViewAssert`], which you
|
||||
can use in combination with JUnit, TestNG, or any other testing framework for unit tests
|
||||
that deal with Spring MVC `ModelAndView` objects.
|
||||
|
||||
.Unit testing Spring MVC Controllers
|
||||
TIP: To unit test your Spring MVC `Controller` classes as POJOs, use `ModelAndViewAssert`
|
||||
combined with `MockHttpServletRequest`, `MockHttpSession`, and so on from Spring's
|
||||
<<mock-objects-servlet, Servlet API mocks>>. For thorough integration testing of your
|
||||
Spring MVC and REST `Controller` classes in conjunction with your `WebApplicationContext`
|
||||
configuration for Spring MVC, use the
|
||||
<<spring-mvc-test-framework, Spring MVC Test Framework>> instead.
|
||||
@@ -1,12 +1,14 @@
|
||||
[[spring-web-reactive]]
|
||||
= Web on Reactive Stack
|
||||
include::attributes.adoc[]
|
||||
include::page-layout.adoc[]
|
||||
:toc: left
|
||||
:toclevels: 4
|
||||
:tabsize: 4
|
||||
:docinfo1:
|
||||
|
||||
This part of the documentation covers support for reactive-stack web applications built
|
||||
on a https://www.reactive-streams.org/[Reactive Streams] API to run on non-blocking
|
||||
servers, such as Netty, Undertow, and Servlet containers. Individual chapters cover
|
||||
the <<webflux, Spring WebFlux>> framework,
|
||||
the <<webflux.adoc#webflux, Spring WebFlux>> framework,
|
||||
the reactive <<webflux-client, `WebClient`>>, support for <<webflux-test, testing>>,
|
||||
and <<webflux-reactive-libraries, reactive libraries>>. For Servlet-stack web applications,
|
||||
see <<web.adoc#spring-web, Web on Servlet Stack>>.
|
||||
@@ -33,7 +35,7 @@ include::web/webflux-websocket.adoc[leveloffset=+1]
|
||||
|
||||
[[webflux-test]]
|
||||
== Testing
|
||||
[.small]#<<web.adoc#webmvc.test, Same in Spring MVC>>#
|
||||
[.small]#<<web.adoc#testing, Same in Spring MVC>>#
|
||||
|
||||
The `spring-test` module provides mock implementations of `ServerHttpRequest`,
|
||||
`ServerHttpResponse`, and `ServerWebExchange`.
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
[[spring-web]]
|
||||
= Web on Servlet Stack
|
||||
include::attributes.adoc[]
|
||||
include::page-layout.adoc[]
|
||||
:toc: left
|
||||
:toclevels: 4
|
||||
:tabsize: 4
|
||||
:docinfo1:
|
||||
|
||||
This part of the documentation covers support for Servlet-stack web applications built on the
|
||||
Servlet API and deployed to Servlet containers. Individual chapters include <<mvc, Spring MVC>>,
|
||||
|
||||
@@ -9,7 +9,7 @@ particular architecture, technology, or methodology (although it certainly recom
|
||||
some over others). This freedom to pick and choose the architecture, technology, or
|
||||
methodology that is most relevant to a developer and their development team is
|
||||
arguably most evident in the web area, where Spring provides its own web frameworks
|
||||
(<<mvc, Spring MVC>> and <<web-reactive.adoc#webflux, Spring WebFlux>>) while, at the same time,
|
||||
(<<mvc, Spring MVC>> and <<webflux.adoc#webflux, Spring WebFlux>>) while, at the same time,
|
||||
supporting integration with a number of popular third-party web frameworks.
|
||||
|
||||
|
||||
@@ -23,21 +23,21 @@ first take a look at common Spring configuration that is not specific to any one
|
||||
framework. (This section is equally applicable to Spring's own web framework variants.)
|
||||
|
||||
One of the concepts (for want of a better word) espoused by Spring's lightweight
|
||||
application model is that of a layered architecture. Remember that in a "classic"
|
||||
application model is that of a layered architecture. Remember that in a "`classic`"
|
||||
layered architecture, the web layer is but one of many layers. It serves as one of the
|
||||
entry points into a server-side application, and it delegates to service objects
|
||||
(facades) that are defined in a service layer to satisfy business-specific (and
|
||||
presentation-technology agnostic) use cases. In Spring, these service objects, any other
|
||||
business-specific objects, data-access objects, and others exist in a distinct "business
|
||||
context", which contains no web or presentation layer objects (presentation objects,
|
||||
such as Spring MVC controllers, are typically configured in a distinct "presentation
|
||||
context"). This section details how you can configure a Spring container (a
|
||||
business-specific objects, data-access objects, and others exist in a distinct "`business
|
||||
context`", which contains no web or presentation layer objects (presentation objects,
|
||||
such as Spring MVC controllers, are typically configured in a distinct "`presentation
|
||||
context`"). This section details how you can configure a Spring container (a
|
||||
`WebApplicationContext`) that contains all of the 'business beans' in your application.
|
||||
|
||||
Moving on to specifics, all you need to do is declare a
|
||||
{api-spring-framework}/web/context/ContextLoaderListener.html[`ContextLoaderListener`]
|
||||
in the standard Jakarta EE servlet `web.xml` file of your web application and add a
|
||||
`contextConfigLocation` `<context-param/>` section (in the same file) that defines which
|
||||
`contextConfigLocation`<context-param/> section (in the same file) that defines which
|
||||
set of Spring XML configuration files to load.
|
||||
|
||||
Consider the following `<listener/>` configuration:
|
||||
@@ -67,7 +67,7 @@ object based on the bean definitions and stores it in the `ServletContext` of th
|
||||
application.
|
||||
|
||||
All Java web frameworks are built on top of the Servlet API, so you can use the
|
||||
following code snippet to get access to this "business context" `ApplicationContext`
|
||||
following code snippet to get access to this "`business context`" `ApplicationContext`
|
||||
created by the `ContextLoaderListener`.
|
||||
|
||||
The following example shows how to get the `WebApplicationContext`:
|
||||
@@ -119,7 +119,7 @@ The key element in Spring's JSF integration is the JSF `ELResolver` mechanism.
|
||||
|
||||
`SpringBeanFacesELResolver` is a JSF compliant `ELResolver` implementation,
|
||||
integrating with the standard Unified EL as used by JSF and JSP. It delegates to
|
||||
Spring's "business context" `WebApplicationContext` first and then to the
|
||||
Spring's "`business context`" `WebApplicationContext` first and then to the
|
||||
default resolver of the underlying JSF implementation.
|
||||
|
||||
Configuration-wise, you can define `SpringBeanFacesELResolver` in your JSF
|
||||
@@ -157,26 +157,27 @@ The following example shows how to use `FacesContextUtils`:
|
||||
|
||||
|
||||
[[struts]]
|
||||
== Apache Struts
|
||||
== Apache Struts 2.x
|
||||
|
||||
Invented by Craig McClanahan, https://struts.apache.org[Struts] is an open-source project
|
||||
hosted by the Apache Software Foundation. Struts 1.x greatly simplified the
|
||||
hosted by the Apache Software Foundation. At the time, it greatly simplified the
|
||||
JSP/Servlet programming paradigm and won over many developers who were using proprietary
|
||||
frameworks. It simplified the programming model; it was open source; and it had a large
|
||||
community, which let the project grow and become popular among Java web developers.
|
||||
frameworks. It simplified the programming model, it was open source (and thus free as in
|
||||
beer), and it had a large community, which let the project grow and become popular among
|
||||
Java web developers.
|
||||
|
||||
As a successor to the original Struts 1.x, check out Struts 2.x or more recent versions
|
||||
as well as the Struts-provided
|
||||
https://struts.apache.org/plugins/spring/[Spring Plugin] for built-in Spring integration.
|
||||
As a successor to the original Struts 1.x, check out Struts 2.x and the Struts-provided
|
||||
https://struts.apache.org/release/2.3.x/docs/spring-plugin.html[Spring Plugin] for the
|
||||
built-in Spring integration.
|
||||
|
||||
|
||||
|
||||
|
||||
[[tapestry]]
|
||||
== Apache Tapestry
|
||||
== Apache Tapestry 5.x
|
||||
|
||||
https://tapestry.apache.org/[Tapestry] is a "Component oriented framework for creating
|
||||
dynamic, robust, highly scalable web applications in Java."
|
||||
https://tapestry.apache.org/[Tapestry] is a ""Component oriented framework for creating
|
||||
dynamic, robust, highly scalable web applications in Java.""
|
||||
|
||||
While Spring has its own <<mvc, powerful web layer>>, there are a number of unique
|
||||
advantages to building an enterprise Java application by using a combination of Tapestry
|
||||
@@ -194,6 +195,6 @@ https://tapestry.apache.org/integrating-with-spring-framework.html[integration m
|
||||
The following links go to further resources about the various web frameworks described in
|
||||
this chapter.
|
||||
|
||||
* The https://www.oracle.com/java/technologies/javaserverfaces.html[JSF] homepage
|
||||
* The https://www.oracle.com/technetwork/java/javaee/javaserverfaces-139869.html[JSF] homepage
|
||||
* The https://struts.apache.org/[Struts] homepage
|
||||
* The https://tapestry.apache.org/[Tapestry] homepage
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
[[webflux-cors]]
|
||||
= CORS
|
||||
:doc-spring-security: {doc-root}/spring-security/reference
|
||||
[.small]#<<web.adoc#mvc-cors, Web MVC>>#
|
||||
|
||||
Spring WebFlux lets you handle CORS (Cross-Origin Resource Sharing). This section
|
||||
@@ -309,7 +310,7 @@ You can apply CORS support through the built-in
|
||||
good fit with <<webflux-fn, functional endpoints>>.
|
||||
|
||||
NOTE: If you try to use the `CorsFilter` with Spring Security, keep in mind that Spring
|
||||
Security has {docs-spring-security}/servlet/integrations/cors.html[built-in support] for
|
||||
Security has {doc-spring-security}/servlet/integrations/cors.html[built-in support] for
|
||||
CORS.
|
||||
|
||||
To configure the filter, you can declare a `CorsWebFilter` bean and pass a
|
||||
|
||||
@@ -98,7 +98,7 @@ as the following example shows:
|
||||
}
|
||||
}
|
||||
----
|
||||
<1> Create router using Coroutines router DSL; a Reactive alternative is also available via `router { }`.
|
||||
<1> Create router using Coroutines router DSL, a Reactive alternative is also available via `router { }`.
|
||||
|
||||
One way to run a `RouterFunction` is to turn it into an `HttpHandler` and install it
|
||||
through one of the built-in <<web-reactive.adoc#webflux-httphandler, server adapters>>:
|
||||
@@ -300,6 +300,7 @@ ServerResponse.created(location).build()
|
||||
Depending on the codec used, it is possible to pass hint parameters to customize how the
|
||||
body is serialized or deserialized. For example, to specify a https://www.baeldung.com/jackson-json-view-annotation[Jackson JSON view]:
|
||||
|
||||
====
|
||||
[source,java,role="primary"]
|
||||
.Java
|
||||
----
|
||||
@@ -310,6 +311,7 @@ ServerResponse.ok().hint(Jackson2CodecSupport.JSON_VIEW_HINT, MyJacksonView.clas
|
||||
----
|
||||
ServerResponse.ok().hint(Jackson2CodecSupport.JSON_VIEW_HINT, MyJacksonView::class.java).body(...)
|
||||
----
|
||||
====
|
||||
|
||||
|
||||
[[webflux-fn-handler-classes]]
|
||||
@@ -523,8 +525,8 @@ header:
|
||||
----
|
||||
val route = coRouter {
|
||||
GET("/hello-world", accept(TEXT_PLAIN)) {
|
||||
ServerResponse.ok().bodyValueAndAwait("Hello World")
|
||||
}
|
||||
ServerResponse.ok().bodyValueAndAwait("Hello World")
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
@@ -640,7 +642,7 @@ RouterFunction<ServerResponse> route = route()
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
val route = coRouter { // <1>
|
||||
val route = coRouter {
|
||||
"/person".nest {
|
||||
GET("/{id}", accept(APPLICATION_JSON), handler::getPerson)
|
||||
GET(accept(APPLICATION_JSON), handler::listPeople)
|
||||
@@ -648,7 +650,6 @@ RouterFunction<ServerResponse> route = route()
|
||||
}
|
||||
}
|
||||
----
|
||||
<1> Create router using Coroutines router DSL; a Reactive alternative is also available via `router { }`.
|
||||
|
||||
Though path-based nesting is the most common, you can nest on any kind of predicate by using
|
||||
the `nest` method on the builder.
|
||||
|
||||
@@ -253,7 +253,7 @@ To configure a connection timeout:
|
||||
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000);
|
||||
|
||||
val webClient = WebClient.builder()
|
||||
.clientConnector(ReactorClientHttpConnector(httpClient))
|
||||
.clientConnector(new ReactorClientHttpConnector(httpClient))
|
||||
.build();
|
||||
----
|
||||
|
||||
@@ -281,8 +281,8 @@ To configure a read or write timeout:
|
||||
|
||||
val httpClient = HttpClient.create()
|
||||
.doOnConnected { conn -> conn
|
||||
.addHandlerLast(ReadTimeoutHandler(10))
|
||||
.addHandlerLast(WriteTimeoutHandler(10))
|
||||
.addHandlerLast(new ReadTimeoutHandler(10))
|
||||
.addHandlerLast(new WriteTimeoutHandler(10))
|
||||
}
|
||||
|
||||
// Create WebClient...
|
||||
@@ -392,7 +392,7 @@ The following example shows how to customize Jetty `HttpClient` settings:
|
||||
httpClient.cookieStore = ...
|
||||
|
||||
val webClient = WebClient.builder()
|
||||
.clientConnector(JettyClientHttpConnector(httpClient))
|
||||
.clientConnector(new JettyClientHttpConnector(httpClient))
|
||||
.build();
|
||||
----
|
||||
|
||||
@@ -788,8 +788,8 @@ multipart request. The following example shows how to create a `MultiValueMap<St
|
||||
----
|
||||
val builder = MultipartBodyBuilder().apply {
|
||||
part("fieldPart", "fieldValue")
|
||||
part("filePart1", FileSystemResource("...logo.png"))
|
||||
part("jsonPart", Person("Jason"))
|
||||
part("filePart1", new FileSystemResource("...logo.png"))
|
||||
part("jsonPart", new Person("Jason"))
|
||||
part("myPart", part) // Part from a server request
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
[[webflux]]
|
||||
:chapter: webflux
|
||||
= Spring WebFlux
|
||||
:doc-spring-security: {doc-root}/spring-security/reference
|
||||
|
||||
The original web framework included in the Spring Framework, Spring Web MVC, was
|
||||
purpose-built for the Servlet API and Servlet containers. The reactive-stack web framework,
|
||||
@@ -1532,8 +1533,8 @@ register support for any other data type.
|
||||
See <<webflux-ann-typeconversion>> and <<webflux-ann-initbinder>>.
|
||||
|
||||
URI variables can be named explicitly (for example, `@PathVariable("customId")`), but you can
|
||||
leave that detail out if the names are the same and you compile your code with the `-parameters`
|
||||
compiler flag.
|
||||
leave that detail out if the names are the same and you compile your code with debugging
|
||||
information or with the `-parameters` compiler flag on Java 8.
|
||||
|
||||
The syntax `{*varName}` declares a URI variable that matches zero or more remaining path
|
||||
segments. For example `/resources/{*path}` matches all files under `/resources/`, and the
|
||||
@@ -2004,7 +2005,7 @@ generally supported for all return values.
|
||||
value) is considered to have fully handled the response if it also has a `ServerHttpResponse`,
|
||||
a `ServerWebExchange` argument, or an `@ResponseStatus` annotation. The same is also true
|
||||
if the controller has made a positive ETag or `lastModified` timestamp check.
|
||||
See <<webflux-caching-etag-lastmodified>> for details.
|
||||
// TODO: See <<webflux-caching-etag-lastmodified>> for details.
|
||||
|
||||
If none of the above is true, a `void` return type can also indicate "`no response body`" for
|
||||
REST controllers or default view name selection for HTML controllers.
|
||||
@@ -3742,10 +3743,10 @@ The https://spring.io/projects/spring-security[Spring Security] project provides
|
||||
for protecting web applications from malicious exploits. See the Spring Security
|
||||
reference documentation, including:
|
||||
|
||||
* {docs-spring-security}/reactive/configuration/webflux.html[WebFlux Security]
|
||||
* {docs-spring-security}/reactive/test/index.html[WebFlux Testing Support]
|
||||
* {docs-spring-security}/features/exploits/csrf.html#csrf-protection[CSRF protection]
|
||||
* {docs-spring-security}/features/exploits/headers.html[Security Response Headers]
|
||||
* {doc-spring-security}/reactive/configuration/webflux.html[WebFlux Security]
|
||||
* {doc-spring-security}/reactive/test/index.html[WebFlux Testing Support]
|
||||
* {doc-spring-security}/features/exploits/csrf.html#csrf-protection[CSRF protection]
|
||||
* {doc-spring-security}/features/exploits/headers.html[Security Response Headers]
|
||||
|
||||
|
||||
|
||||
@@ -4408,7 +4409,7 @@ In the next example, given a request that starts with `/resources`, the relative
|
||||
used to find and serve static resources relative to `/static` on the classpath. Resources
|
||||
are served with a one-year future expiration to ensure maximum use of the browser cache
|
||||
and a reduction in HTTP requests made by the browser. The `Last-Modified` header is also
|
||||
evaluated and, if present, a `304` status code is returned. The following listing shows
|
||||
evaluated and, if present, a `304` status code is returned. The following list shows
|
||||
the example:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
@@ -4442,7 +4443,7 @@ the example:
|
||||
}
|
||||
----
|
||||
|
||||
See also <<webflux-caching-static-resources, HTTP caching support for static resources>>.
|
||||
// TODO: See also <<webflux-caching-static-resources, HTTP caching support for static resources>>.
|
||||
|
||||
The resource handler also supports a chain of
|
||||
{api-spring-framework}/web/reactive/resource/ResourceResolver.html[`ResourceResolver`] implementations and
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
[[mvc-cors]]
|
||||
= CORS
|
||||
:doc-spring-security: {doc-root}/spring-security/reference
|
||||
[.small]#<<web-reactive.adoc#webflux-cors, WebFlux>>#
|
||||
|
||||
Spring MVC lets you handle CORS (Cross-Origin Resource Sharing). This section
|
||||
@@ -335,7 +336,7 @@ You can apply CORS support through the built-in
|
||||
{api-spring-framework}/web/filter/CorsFilter.html[`CorsFilter`].
|
||||
|
||||
NOTE: If you try to use the `CorsFilter` with Spring Security, keep in mind that Spring
|
||||
Security has {docs-spring-security}/servlet/integrations/cors.html[built-in support] for
|
||||
Security has {doc-spring-security}/servlet/integrations/cors.html[built-in support] for
|
||||
CORS.
|
||||
|
||||
To configure the filter, pass a `CorsConfigurationSource` to its constructor, as the
|
||||
|
||||
@@ -623,14 +623,13 @@ RouterFunction<ServerResponse> route = route()
|
||||
import org.springframework.web.servlet.function.router
|
||||
|
||||
val route = router {
|
||||
"/person".nest { // <1>
|
||||
"/person".nest {
|
||||
GET("/{id}", accept(APPLICATION_JSON), handler::getPerson)
|
||||
GET(accept(APPLICATION_JSON), handler::listPeople)
|
||||
POST(handler::createPerson)
|
||||
}
|
||||
}
|
||||
----
|
||||
<1> Using `nest` DSL.
|
||||
|
||||
Though path-based nesting is the most common, you can nest on any kind of predicate by using
|
||||
the `nest` method on the builder.
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
[[mvc]]
|
||||
:chapter: mvc
|
||||
= Spring Web MVC
|
||||
:doc-spring-security: {doc-root}/spring-security/reference
|
||||
|
||||
Spring Web MVC is the original web framework built on the Servlet API and has been included
|
||||
in the Spring Framework from the very beginning. The formal name, "Spring Web MVC,"
|
||||
in the Spring Framework from the very beginning. The formal name, "`Spring Web MVC,`"
|
||||
comes from the name of its source module
|
||||
({spring-framework-main-code}/spring-webmvc[`spring-webmvc`]),
|
||||
but it is more commonly known as "Spring MVC".
|
||||
but it is more commonly known as "`Spring MVC`".
|
||||
|
||||
Parallel to Spring Web MVC, Spring Framework 5.0 introduced a reactive-stack web framework
|
||||
whose name, "Spring WebFlux," is also based on its source module
|
||||
whose name, "`Spring WebFlux,`" is also based on its source module
|
||||
({spring-framework-main-code}/spring-webflux[`spring-webflux`]).
|
||||
This chapter covers Spring Web MVC. The <<web-reactive.adoc#spring-web-reactive, next chapter>>
|
||||
This section covers Spring Web MVC. The <<web-reactive.adoc#spring-web-reactive, next section>>
|
||||
covers Spring WebFlux.
|
||||
|
||||
For baseline information and compatibility with Servlet container and Jakarta EE version
|
||||
@@ -1141,10 +1142,9 @@ request with a simple request parameter.
|
||||
[.small]#<<web-reactive.adoc#webflux-multipart, WebFlux>>#
|
||||
|
||||
`MultipartResolver` from the `org.springframework.web.multipart` package is a strategy
|
||||
for parsing multipart requests including file uploads. There is a container-based
|
||||
`StandardServletMultipartResolver` implementation for Servlet multipart request parsing.
|
||||
Note that the outdated `CommonsMultipartResolver` based on Apache Commons FileUpload is
|
||||
not available anymore, as of Spring Framework 6.0 with its new Servlet 5.0+ baseline.
|
||||
for parsing multipart requests including file uploads. There is one implementation
|
||||
based on https://commons.apache.org/proper/commons-fileupload[Commons FileUpload] and
|
||||
another based on Servlet multipart request parsing.
|
||||
|
||||
To enable multipart handling, you need to declare a `MultipartResolver` bean in your
|
||||
`DispatcherServlet` Spring configuration with a name of `multipartResolver`.
|
||||
@@ -1154,6 +1154,26 @@ content wraps the current `HttpServletRequest` as a `MultipartHttpServletRequest
|
||||
provide access to resolved files in addition to exposing parts as request parameters.
|
||||
|
||||
|
||||
[[mvc-multipart-resolver-commons]]
|
||||
==== Apache Commons `FileUpload`
|
||||
|
||||
To use Apache Commons `FileUpload`, you can configure a bean of type
|
||||
`CommonsMultipartResolver` with a name of `multipartResolver`. You also need to have
|
||||
the `commons-fileupload` jar as a dependency on your classpath.
|
||||
|
||||
This resolver variant delegates to a local library within the application, providing
|
||||
maximum portability across Servlet containers. As an alternative, consider standard
|
||||
Servlet multipart resolution through the container's own parser as discussed below.
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
Commons FileUpload traditionally applies to POST requests only but accepts any
|
||||
`multipart/` content type. See the
|
||||
{api-spring-framework}/web/multipart/commons/CommonsMultipartResolver.html[`CommonsMultipartResolver`]
|
||||
javadoc for details and configuration options.
|
||||
====
|
||||
|
||||
|
||||
[[mvc-multipart-resolver-standard]]
|
||||
==== Servlet Multipart Parsing
|
||||
|
||||
@@ -1680,8 +1700,8 @@ register support for any other data type.
|
||||
See <<mvc-ann-typeconversion>> and <<mvc-ann-initbinder>>.
|
||||
|
||||
You can explicitly name URI variables (for example, `@PathVariable("customId")`), but you can
|
||||
leave that detail out if the names are the same and your code is compiled with the `-parameters`
|
||||
compiler flag.
|
||||
leave that detail out if the names are the same and your code is compiled with debugging
|
||||
information or with the `-parameters` compiler flag on Java 8.
|
||||
|
||||
The syntax `{varName:regex}` declares a URI variable with a regular expression that has
|
||||
syntax of `{varName:regex}`. For example, given URL `"/spring-web-3.0.5.jar"`, the following method
|
||||
@@ -1918,7 +1938,6 @@ You can also use the same with request header conditions, as the following examp
|
||||
// ...
|
||||
}
|
||||
----
|
||||
<1> Testing whether `myHeader` equals `myValue`.
|
||||
|
||||
TIP: You can match `Content-Type` and `Accept` with the headers condition, but it is better to use
|
||||
<<mvc-ann-requestmapping-consumes, consumes>> and <<mvc-ann-requestmapping-produces, produces>>
|
||||
@@ -2642,21 +2661,19 @@ query parameters and form fields. The following example shows how to do so:
|
||||
.Java
|
||||
----
|
||||
@PostMapping("/owners/{ownerId}/pets/{petId}/edit")
|
||||
public String processSubmit(@ModelAttribute Pet pet) { // <1>
|
||||
public String processSubmit(@ModelAttribute Pet pet) {
|
||||
// method logic...
|
||||
}
|
||||
----
|
||||
<1> Bind an instance of `Pet`.
|
||||
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
@PostMapping("/owners/{ownerId}/pets/{petId}/edit")
|
||||
fun processSubmit(@ModelAttribute pet: Pet): String { // <1>
|
||||
fun processSubmit(@ModelAttribute pet: Pet): String {
|
||||
// method logic...
|
||||
}
|
||||
----
|
||||
<1> Bind an instance of `Pet`.
|
||||
|
||||
The `Pet` instance above is sourced in one of the following ways:
|
||||
|
||||
@@ -2684,21 +2701,18 @@ could load the `Account` from a data store:
|
||||
.Java
|
||||
----
|
||||
@PutMapping("/accounts/{account}")
|
||||
public String save(@ModelAttribute("account") Account account) { // <1>
|
||||
public String save(@ModelAttribute("account") Account account) {
|
||||
// ...
|
||||
}
|
||||
----
|
||||
<1> Bind an instance of `Account` using an explicit attribute name.
|
||||
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
@PutMapping("/accounts/{account}")
|
||||
fun save(@ModelAttribute("account") account: Account): String { // <1>
|
||||
fun save(@ModelAttribute("account") account: Account): String {
|
||||
// ...
|
||||
}
|
||||
----
|
||||
<1> Bind an instance of `Account` using an explicit attribute name.
|
||||
|
||||
After the model attribute instance is obtained, data binding is applied. The
|
||||
`WebDataBinder` class matches Servlet request parameter names (query parameters and form
|
||||
@@ -2812,7 +2826,6 @@ You can automatically apply validation after data binding by adding the
|
||||
// ...
|
||||
}
|
||||
----
|
||||
<1> Validate the `Pet` instance.
|
||||
|
||||
Note that using `@ModelAttribute` is optional (for example, to set its attributes).
|
||||
By default, any argument that is not a simple value type (as determined by
|
||||
@@ -2932,7 +2945,6 @@ as the following example shows:
|
||||
// ...
|
||||
}
|
||||
----
|
||||
<1> Using a `@SessionAttribute` annotation.
|
||||
|
||||
For use cases that require adding or removing session attributes, consider injecting
|
||||
`org.springframework.web.context.request.WebRequest` or
|
||||
@@ -3547,6 +3559,8 @@ to the model, as the following example shows:
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
import org.springframework.ui.set
|
||||
|
||||
@Controller
|
||||
class UserController : AbstractController() {
|
||||
|
||||
@@ -4435,7 +4449,13 @@ as the following example shows:
|
||||
----
|
||||
@PostMapping
|
||||
public Callable<String> processUpload(final MultipartFile file) {
|
||||
return () -> "someView";
|
||||
|
||||
return new Callable<String>() {
|
||||
public String call() throws Exception {
|
||||
// ...
|
||||
return "someView";
|
||||
}
|
||||
};
|
||||
}
|
||||
----
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
@@ -4772,7 +4792,7 @@ are written to the Reactor `Context` as key-value pairs, using the key assigned
|
||||
For other asynchronous handling scenarios, you can use the Context Propagation library
|
||||
directly. For example:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
----
|
||||
// Capture ThreadLocal values from the main thread ...
|
||||
@@ -5053,10 +5073,10 @@ The https://spring.io/projects/spring-security[Spring Security] project provides
|
||||
for protecting web applications from malicious exploits. See the Spring Security
|
||||
reference documentation, including:
|
||||
|
||||
* {docs-spring-security}/servlet/integrations/mvc.html[Spring MVC Security]
|
||||
* {docs-spring-security}/servlet/test/mockmvc/setup.html[Spring MVC Test Support]
|
||||
* {docs-spring-security}/features/exploits/csrf.html#csrf-protection[CSRF protection]
|
||||
* {docs-spring-security}/features/exploits/headers.html[Security Response Headers]
|
||||
* {doc-spring-security}/servlet/integrations/mvc.html[Spring MVC Security]
|
||||
* {doc-spring-security}/servlet/test/mockmvc/setup.html[Spring MVC Test Support]
|
||||
* {doc-spring-security}/features/exploits/csrf.html#csrf-protection[CSRF protection]
|
||||
* {doc-spring-security}/features/exploits/headers.html[Security Response Headers]
|
||||
|
||||
https://hdiv.org/[HDIV] is another web security framework that integrates with Spring MVC.
|
||||
|
||||
@@ -5894,6 +5914,7 @@ The MVC namespace provides dedicated elements. The following example works with
|
||||
|
||||
[source,xml,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
|
||||
<mvc:view-resolvers>
|
||||
<mvc:content-negotiation>
|
||||
<mvc:default-views>
|
||||
@@ -5906,6 +5927,7 @@ The MVC namespace provides dedicated elements. The following example works with
|
||||
<mvc:freemarker-configurer>
|
||||
<mvc:template-loader-path location="/freemarker"/>
|
||||
</mvc:freemarker-configurer>
|
||||
|
||||
----
|
||||
|
||||
In Java configuration, you can add the respective `Configurer` bean,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
[[websocket]]
|
||||
= WebSockets
|
||||
:doc-spring-security: {doc-root}/spring-security/reference
|
||||
[.small]#<<web-reactive.adoc#webflux-websocket, WebFlux>>#
|
||||
|
||||
This part of the reference documentation covers support for Servlet stack, WebSocket
|
||||
@@ -626,7 +627,7 @@ response. By default, the Spring Security Java configuration sets it to `DENY`.
|
||||
In 3.2, the Spring Security XML namespace does not set that header by default
|
||||
but can be configured to do so. In the future, it may set it by default.
|
||||
|
||||
See {docs-spring-security}/features/exploits/headers.html#headers-default[Default Security Headers]
|
||||
See {doc-spring-security}/features/exploits/headers.html#headers-default[Default Security Headers]
|
||||
of the Spring Security documentation for details on how to configure the
|
||||
setting of the `X-Frame-Options` header. You can also see
|
||||
https://github.com/spring-projects/spring-security/issues/2718[gh-2718]
|
||||
@@ -1810,7 +1811,7 @@ its own implementation of `WebSocketMessageBrokerConfigurer` that is marked with
|
||||
=== Authorization
|
||||
|
||||
Spring Security provides
|
||||
{docs-spring-security}/servlet/integrations/websocket.html#websocket-authorization[WebSocket sub-protocol authorization]
|
||||
{doc-spring-security}/servlet/integrations/websocket.html#websocket-authorization[WebSocket sub-protocol authorization]
|
||||
that uses a `ChannelInterceptor` to authorize messages based on the user header in them.
|
||||
Also, Spring Session provides
|
||||
https://docs.spring.io/spring-session/reference/web-socket.html[WebSocket integration]
|
||||
|
||||
-44
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.docs.core.aot.hints.importruntimehints;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import org.springframework.aot.hint.RuntimeHints;
|
||||
import org.springframework.aot.hint.RuntimeHintsRegistrar;
|
||||
import org.springframework.context.annotation.ImportRuntimeHints;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@ImportRuntimeHints(SpellCheckService.SpellCheckServiceRuntimeHints.class)
|
||||
public class SpellCheckService {
|
||||
|
||||
public void loadDictionary(Locale locale) {
|
||||
ClassPathResource resource = new ClassPathResource("dicts/" + locale.getLanguage() + ".txt");
|
||||
//...
|
||||
}
|
||||
|
||||
static class SpellCheckServiceRuntimeHints implements RuntimeHintsRegistrar {
|
||||
|
||||
@Override
|
||||
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
|
||||
hints.resources().registerPattern("dicts/*");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-42
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.docs.core.aot.hints.testing;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
public class SampleReflection {
|
||||
|
||||
private final Log logger = LogFactory.getLog(SampleReflection.class);
|
||||
|
||||
public void performReflection() {
|
||||
try {
|
||||
Class<?> springVersion = ClassUtils.forName("org.springframework.core.SpringVersion", null);
|
||||
Method getVersion = ClassUtils.getMethod(springVersion, "getVersion");
|
||||
String version = (String) getVersion.invoke(null);
|
||||
logger.info("Spring version:" + version);
|
||||
}
|
||||
catch (Exception exc) {
|
||||
logger.error("reflection failed", exc);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-55
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.docs.core.aot.hints.testing;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.aot.hint.ExecutableMode;
|
||||
import org.springframework.aot.hint.RuntimeHints;
|
||||
import org.springframework.aot.test.agent.EnabledIfRuntimeHintsAgent;
|
||||
import org.springframework.aot.test.agent.RuntimeHintsInvocations;
|
||||
import org.springframework.aot.test.agent.RuntimeHintsRecorder;
|
||||
import org.springframework.core.SpringVersion;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
// @EnabledIfRuntimeHintsAgent signals that the annotated test class or test
|
||||
// method is only enabled if the RuntimeHintsAgent is loaded on the current JVM.
|
||||
// It also tags tests with the "RuntimeHints" JUnit tag.
|
||||
@EnabledIfRuntimeHintsAgent
|
||||
class SampleReflectionRuntimeHintsTests {
|
||||
|
||||
@Test
|
||||
void shouldRegisterReflectionHints() {
|
||||
RuntimeHints runtimeHints = new RuntimeHints();
|
||||
// Call a RuntimeHintsRegistrar that contributes hints like:
|
||||
runtimeHints.reflection().registerType(SpringVersion.class, typeHint -> {
|
||||
typeHint.withMethod("getVersion", List.of(), ExecutableMode.INVOKE);
|
||||
});
|
||||
|
||||
// Invoke the relevant piece of code we want to test within a recording lambda
|
||||
RuntimeHintsInvocations invocations = RuntimeHintsRecorder.record(() -> {
|
||||
SampleReflection sample = new SampleReflection();
|
||||
sample.performReflection();
|
||||
});
|
||||
// assert that the recorded invocations are covered by the contributed hints
|
||||
assertThat(invocations).match(runtimeHints);
|
||||
}
|
||||
|
||||
}
|
||||
-48
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.docs.core.aot.hints.testing;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.aot.hint.RuntimeHints;
|
||||
import org.springframework.aot.hint.RuntimeHintsRegistrar;
|
||||
import org.springframework.aot.hint.predicate.RuntimeHintsPredicates;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class SpellCheckServiceTests {
|
||||
|
||||
// tag::hintspredicates[]
|
||||
@Test
|
||||
void shouldRegisterResourceHints() {
|
||||
RuntimeHints hints = new RuntimeHints();
|
||||
new SpellCheckServiceRuntimeHints().registerHints(hints, getClass().getClassLoader());
|
||||
assertThat(RuntimeHintsPredicates.resource().forResource("dicts/en.txt"))
|
||||
.accepts(hints);
|
||||
}
|
||||
// end::hintspredicates[]
|
||||
|
||||
// Copied here because it is package private in SpellCheckService
|
||||
static class SpellCheckServiceRuntimeHints implements RuntimeHintsRegistrar {
|
||||
|
||||
@Override
|
||||
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
|
||||
hints.resources().registerPattern("dicts/*");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-50
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.docs.core.aot.refresh;
|
||||
|
||||
import org.springframework.aot.hint.RuntimeHints;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
public class AotProcessingSample {
|
||||
|
||||
public void createAotContext() {
|
||||
// tag::aotcontext[]
|
||||
RuntimeHints hints = new RuntimeHints();
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
context.register(MyApplication.class);
|
||||
context.refreshForAotProcessing(hints);
|
||||
// end::aotcontext[]
|
||||
}
|
||||
|
||||
// tag::myapplication[]
|
||||
@Configuration(proxyBeanMethods=false)
|
||||
@ComponentScan
|
||||
@Import({DataSourceConfiguration.class, ContainerConfiguration.class})
|
||||
public class MyApplication {
|
||||
}
|
||||
// end::myapplication[]
|
||||
|
||||
class DataSourceConfiguration {
|
||||
}
|
||||
|
||||
class ContainerConfiguration {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,7 +7,7 @@ javaPlatform {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api(platform("com.fasterxml.jackson:jackson-bom:2.14.1"))
|
||||
api(platform("com.fasterxml.jackson:jackson-bom:2.14.0"))
|
||||
api(platform("io.micrometer:micrometer-bom:1.10.0"))
|
||||
api(platform("io.netty:netty-bom:4.1.85.Final"))
|
||||
api(platform("io.netty:netty5-bom:5.0.0.Alpha5"))
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
version=6.0.2
|
||||
version=6.0.0
|
||||
|
||||
org.gradle.caching=true
|
||||
org.gradle.jvmargs=-Xmx2048m
|
||||
org.gradle.parallel=true
|
||||
|
||||
kotlinVersion=1.7.21
|
||||
kotlinVersion=1.7.20
|
||||
|
||||
kotlin.stdlib.default.dependency=false
|
||||
|
||||
+8
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -132,17 +132,17 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
|
||||
private static final int STEP_REFERENCE_PCUT_BINDING = 7;
|
||||
private static final int STEP_FINISHED = 8;
|
||||
|
||||
private static final Set<String> singleValuedAnnotationPcds = Set.of(
|
||||
"@this",
|
||||
"@target",
|
||||
"@within",
|
||||
"@withincode",
|
||||
"@annotation");
|
||||
|
||||
private static final Set<String> singleValuedAnnotationPcds = new HashSet<>();
|
||||
private static final Set<String> nonReferencePointcutTokens = new HashSet<>();
|
||||
|
||||
|
||||
static {
|
||||
singleValuedAnnotationPcds.add("@this");
|
||||
singleValuedAnnotationPcds.add("@target");
|
||||
singleValuedAnnotationPcds.add("@within");
|
||||
singleValuedAnnotationPcds.add("@withincode");
|
||||
singleValuedAnnotationPcds.add("@annotation");
|
||||
|
||||
Set<PointcutPrimitive> pointcutPrimitives = PointcutParser.getAllSupportedPointcutPrimitives();
|
||||
for (PointcutPrimitive primitive : pointcutPrimitives) {
|
||||
nonReferencePointcutTokens.add(primitive.getName());
|
||||
|
||||
+16
-11
@@ -21,6 +21,7 @@ import java.io.ObjectInputStream;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@@ -84,17 +85,21 @@ import org.springframework.util.StringUtils;
|
||||
public class AspectJExpressionPointcut extends AbstractExpressionPointcut
|
||||
implements ClassFilter, IntroductionAwareMethodMatcher, BeanFactoryAware {
|
||||
|
||||
private static final Set<PointcutPrimitive> SUPPORTED_PRIMITIVES = Set.of(
|
||||
PointcutPrimitive.EXECUTION,
|
||||
PointcutPrimitive.ARGS,
|
||||
PointcutPrimitive.REFERENCE,
|
||||
PointcutPrimitive.THIS,
|
||||
PointcutPrimitive.TARGET,
|
||||
PointcutPrimitive.WITHIN,
|
||||
PointcutPrimitive.AT_ANNOTATION,
|
||||
PointcutPrimitive.AT_WITHIN,
|
||||
PointcutPrimitive.AT_ARGS,
|
||||
PointcutPrimitive.AT_TARGET);
|
||||
private static final Set<PointcutPrimitive> SUPPORTED_PRIMITIVES = new HashSet<>();
|
||||
|
||||
static {
|
||||
SUPPORTED_PRIMITIVES.add(PointcutPrimitive.EXECUTION);
|
||||
SUPPORTED_PRIMITIVES.add(PointcutPrimitive.ARGS);
|
||||
SUPPORTED_PRIMITIVES.add(PointcutPrimitive.REFERENCE);
|
||||
SUPPORTED_PRIMITIVES.add(PointcutPrimitive.THIS);
|
||||
SUPPORTED_PRIMITIVES.add(PointcutPrimitive.TARGET);
|
||||
SUPPORTED_PRIMITIVES.add(PointcutPrimitive.WITHIN);
|
||||
SUPPORTED_PRIMITIVES.add(PointcutPrimitive.AT_ANNOTATION);
|
||||
SUPPORTED_PRIMITIVES.add(PointcutPrimitive.AT_WITHIN);
|
||||
SUPPORTED_PRIMITIVES.add(PointcutPrimitive.AT_ARGS);
|
||||
SUPPORTED_PRIMITIVES.add(PointcutPrimitive.AT_TARGET);
|
||||
}
|
||||
|
||||
|
||||
private static final Log logger = LogFactory.getLog(AspectJExpressionPointcut.class);
|
||||
|
||||
|
||||
+3
-3
@@ -195,7 +195,7 @@ abstract class AbstractAspectJAdvisorFactoryTests {
|
||||
|
||||
Advised advised = (Advised) itb;
|
||||
// Will be ExposeInvocationInterceptor, synthetic instantiation advisor, 2 method advisors
|
||||
assertThat(advised.getAdvisors()).hasSize(4);
|
||||
assertThat(advised.getAdvisors().length).isEqualTo(4);
|
||||
ReflectiveAspectJAdvisorFactory.SyntheticInstantiationAdvisor sia =
|
||||
(ReflectiveAspectJAdvisorFactory.SyntheticInstantiationAdvisor) advised.getAdvisors()[1];
|
||||
assertThat(sia.getPointcut().getMethodMatcher().matches(TestBean.class.getMethod("getSpouse"), null)).isTrue();
|
||||
@@ -231,7 +231,7 @@ abstract class AbstractAspectJAdvisorFactoryTests {
|
||||
|
||||
Advised advised = (Advised) itb;
|
||||
// Will be ExposeInvocationInterceptor, synthetic instantiation advisor, 2 method advisors
|
||||
assertThat(advised.getAdvisors()).hasSize(4);
|
||||
assertThat(advised.getAdvisors().length).isEqualTo(4);
|
||||
ReflectiveAspectJAdvisorFactory.SyntheticInstantiationAdvisor sia =
|
||||
(ReflectiveAspectJAdvisorFactory.SyntheticInstantiationAdvisor) advised.getAdvisors()[1];
|
||||
assertThat(sia.getPointcut().getMethodMatcher().matches(TestBean.class.getMethod("getSpouse"), null)).isTrue();
|
||||
@@ -366,7 +366,7 @@ abstract class AbstractAspectJAdvisorFactoryTests {
|
||||
new SingletonMetadataAwareAspectInstanceFactory(new MakeLockable(), "someBean")),
|
||||
CannotBeUnlocked.class).isEmpty()).isTrue();
|
||||
assertThat(AopUtils.findAdvisorsThatCanApply(getFixture().getAdvisors(
|
||||
new SingletonMetadataAwareAspectInstanceFactory(new MakeLockable(),"someBean")), NotLockable.class)).hasSize(2);
|
||||
new SingletonMetadataAwareAspectInstanceFactory(new MakeLockable(),"someBean")), NotLockable.class).size()).isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.aop.support;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.testfixture.beans.TestBean;
|
||||
import org.springframework.core.testfixture.io.SerializationTestUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Rod Johnson
|
||||
* @author Dmitriy Kopylenko
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public abstract class AbstractRegexpMethodPointcutTests {
|
||||
|
||||
private AbstractRegexpMethodPointcut rpc;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
rpc = getRegexpMethodPointcut();
|
||||
}
|
||||
|
||||
protected abstract AbstractRegexpMethodPointcut getRegexpMethodPointcut();
|
||||
|
||||
@Test
|
||||
public void testNoPatternSupplied() throws Exception {
|
||||
noPatternSuppliedTests(rpc);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerializationWithNoPatternSupplied() throws Exception {
|
||||
rpc = SerializationTestUtils.serializeAndDeserialize(rpc);
|
||||
noPatternSuppliedTests(rpc);
|
||||
}
|
||||
|
||||
protected void noPatternSuppliedTests(AbstractRegexpMethodPointcut rpc) throws Exception {
|
||||
assertThat(rpc.matches(Object.class.getMethod("hashCode"), String.class)).isFalse();
|
||||
assertThat(rpc.matches(Object.class.getMethod("wait"), Object.class)).isFalse();
|
||||
assertThat(rpc.getPatterns().length).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExactMatch() throws Exception {
|
||||
rpc.setPattern("java.lang.Object.hashCode");
|
||||
exactMatchTests(rpc);
|
||||
rpc = SerializationTestUtils.serializeAndDeserialize(rpc);
|
||||
exactMatchTests(rpc);
|
||||
}
|
||||
|
||||
protected void exactMatchTests(AbstractRegexpMethodPointcut rpc) throws Exception {
|
||||
// assumes rpc.setPattern("java.lang.Object.hashCode");
|
||||
assertThat(rpc.matches(Object.class.getMethod("hashCode"), String.class)).isTrue();
|
||||
assertThat(rpc.matches(Object.class.getMethod("hashCode"), Object.class)).isTrue();
|
||||
assertThat(rpc.matches(Object.class.getMethod("wait"), Object.class)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpecificMatch() throws Exception {
|
||||
rpc.setPattern("java.lang.String.hashCode");
|
||||
assertThat(rpc.matches(Object.class.getMethod("hashCode"), String.class)).isTrue();
|
||||
assertThat(rpc.matches(Object.class.getMethod("hashCode"), Object.class)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWildcard() throws Exception {
|
||||
rpc.setPattern(".*Object.hashCode");
|
||||
assertThat(rpc.matches(Object.class.getMethod("hashCode"), Object.class)).isTrue();
|
||||
assertThat(rpc.matches(Object.class.getMethod("wait"), Object.class)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWildcardForOneClass() throws Exception {
|
||||
rpc.setPattern("java.lang.Object.*");
|
||||
assertThat(rpc.matches(Object.class.getMethod("hashCode"), String.class)).isTrue();
|
||||
assertThat(rpc.matches(Object.class.getMethod("wait"), String.class)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchesObjectClass() throws Exception {
|
||||
rpc.setPattern("java.lang.Object.*");
|
||||
assertThat(rpc.matches(Exception.class.getMethod("hashCode"), IOException.class)).isTrue();
|
||||
// Doesn't match a method from Throwable
|
||||
assertThat(rpc.matches(Exception.class.getMethod("getMessage"), Exception.class)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithExclusion() throws Exception {
|
||||
this.rpc.setPattern(".*get.*");
|
||||
this.rpc.setExcludedPattern(".*Age.*");
|
||||
assertThat(this.rpc.matches(TestBean.class.getMethod("getName"), TestBean.class)).isTrue();
|
||||
assertThat(this.rpc.matches(TestBean.class.getMethod("getAge"), TestBean.class)).isFalse();
|
||||
}
|
||||
|
||||
}
|
||||
+5
-84
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,93 +16,14 @@
|
||||
|
||||
package org.springframework.aop.support;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.testfixture.beans.TestBean;
|
||||
import org.springframework.core.testfixture.io.SerializationTestUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Rod Johnson
|
||||
* @author Dmitriy Kopylenko
|
||||
* @author Chris Beams
|
||||
* @author Dmitriy Kopylenko
|
||||
*/
|
||||
class JdkRegexpMethodPointcutTests {
|
||||
public class JdkRegexpMethodPointcutTests extends AbstractRegexpMethodPointcutTests {
|
||||
|
||||
private AbstractRegexpMethodPointcut rpc = new JdkRegexpMethodPointcut();
|
||||
|
||||
|
||||
@Test
|
||||
void noPatternSupplied() throws Exception {
|
||||
noPatternSuppliedTests(rpc);
|
||||
}
|
||||
|
||||
@Test
|
||||
void serializationWithNoPatternSupplied() throws Exception {
|
||||
rpc = SerializationTestUtils.serializeAndDeserialize(rpc);
|
||||
noPatternSuppliedTests(rpc);
|
||||
}
|
||||
|
||||
private void noPatternSuppliedTests(AbstractRegexpMethodPointcut rpc) throws Exception {
|
||||
assertThat(rpc.matches(Object.class.getMethod("hashCode"), String.class)).isFalse();
|
||||
assertThat(rpc.matches(Object.class.getMethod("wait"), Object.class)).isFalse();
|
||||
assertThat(rpc.getPatterns()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void exactMatch() throws Exception {
|
||||
rpc.setPattern("java.lang.Object.hashCode");
|
||||
exactMatchTests(rpc);
|
||||
rpc = SerializationTestUtils.serializeAndDeserialize(rpc);
|
||||
exactMatchTests(rpc);
|
||||
}
|
||||
|
||||
private void exactMatchTests(AbstractRegexpMethodPointcut rpc) throws Exception {
|
||||
// assumes rpc.setPattern("java.lang.Object.hashCode");
|
||||
assertThat(rpc.matches(Object.class.getMethod("hashCode"), String.class)).isTrue();
|
||||
assertThat(rpc.matches(Object.class.getMethod("hashCode"), Object.class)).isTrue();
|
||||
assertThat(rpc.matches(Object.class.getMethod("wait"), Object.class)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void specificMatch() throws Exception {
|
||||
rpc.setPattern("java.lang.String.hashCode");
|
||||
assertThat(rpc.matches(Object.class.getMethod("hashCode"), String.class)).isTrue();
|
||||
assertThat(rpc.matches(Object.class.getMethod("hashCode"), Object.class)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void wildcard() throws Exception {
|
||||
rpc.setPattern(".*Object.hashCode");
|
||||
assertThat(rpc.matches(Object.class.getMethod("hashCode"), Object.class)).isTrue();
|
||||
assertThat(rpc.matches(Object.class.getMethod("wait"), Object.class)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void wildcardForOneClass() throws Exception {
|
||||
rpc.setPattern("java.lang.Object.*");
|
||||
assertThat(rpc.matches(Object.class.getMethod("hashCode"), String.class)).isTrue();
|
||||
assertThat(rpc.matches(Object.class.getMethod("wait"), String.class)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void matchesObjectClass() throws Exception {
|
||||
rpc.setPattern("java.lang.Object.*");
|
||||
assertThat(rpc.matches(Exception.class.getMethod("hashCode"), IOException.class)).isTrue();
|
||||
// Doesn't match a method from Throwable
|
||||
assertThat(rpc.matches(Exception.class.getMethod("getMessage"), Exception.class)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void withExclusion() throws Exception {
|
||||
this.rpc.setPattern(".*get.*");
|
||||
this.rpc.setExcludedPattern(".*Age.*");
|
||||
assertThat(this.rpc.matches(TestBean.class.getMethod("getName"), TestBean.class)).isTrue();
|
||||
assertThat(this.rpc.matches(TestBean.class.getMethod("getAge"), TestBean.class)).isFalse();
|
||||
@Override
|
||||
protected AbstractRegexpMethodPointcut getRegexpMethodPointcut() {
|
||||
return new JdkRegexpMethodPointcut();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,16 +11,10 @@ sourceSets.test.java.srcDirs = files()
|
||||
compileAspectj {
|
||||
sourceCompatibility "17"
|
||||
targetCompatibility "17"
|
||||
ajcOptions {
|
||||
compilerArgs += "-parameters"
|
||||
}
|
||||
}
|
||||
compileTestAspectj {
|
||||
sourceCompatibility "17"
|
||||
targetCompatibility "17"
|
||||
ajcOptions {
|
||||
compilerArgs += "-parameters"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
@@ -61,7 +61,7 @@ import org.springframework.util.StringUtils;
|
||||
* <p>Mainly for internal use within the framework, but to some degree also
|
||||
* useful for application classes. Consider
|
||||
* <a href="https://commons.apache.org/proper/commons-beanutils/">Apache Commons BeanUtils</a>,
|
||||
* <a href="https://github.com/ExpediaGroup/bull">BULL - Bean Utils Light Library</a>,
|
||||
* <a href="https://hotelsdotcom.github.io/bull/">BULL - Bean Utils Light Library</a>,
|
||||
* or similar third-party frameworks for more comprehensive bean utilities.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
|
||||
+22
-20
@@ -599,8 +599,8 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
exposedObject = initializeBean(beanName, exposedObject, mbd);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
if (ex instanceof BeanCreationException bce && beanName.equals(bce.getBeanName())) {
|
||||
throw bce;
|
||||
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
|
||||
throw (BeanCreationException) ex;
|
||||
}
|
||||
else {
|
||||
throw new BeanCreationException(mbd.getResourceDescription(), beanName, ex.getMessage(), ex);
|
||||
@@ -862,9 +862,9 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
// declaration without instantiating the containing bean at all.
|
||||
BeanDefinition factoryBeanDefinition = getBeanDefinition(factoryBeanName);
|
||||
Class<?> factoryBeanClass;
|
||||
if (factoryBeanDefinition instanceof AbstractBeanDefinition abstractBeanDefinition &&
|
||||
abstractBeanDefinition.hasBeanClass()) {
|
||||
factoryBeanClass = abstractBeanDefinition.getBeanClass();
|
||||
if (factoryBeanDefinition instanceof AbstractBeanDefinition &&
|
||||
((AbstractBeanDefinition) factoryBeanDefinition).hasBeanClass()) {
|
||||
factoryBeanClass = ((AbstractBeanDefinition) factoryBeanDefinition).getBeanClass();
|
||||
}
|
||||
else {
|
||||
RootBeanDefinition fbmbd = getMergedBeanDefinition(factoryBeanName, factoryBeanDefinition);
|
||||
@@ -975,8 +975,8 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
return (FactoryBean<?>) bw.getWrappedInstance();
|
||||
}
|
||||
Object beanInstance = getSingleton(beanName, false);
|
||||
if (beanInstance instanceof FactoryBean<?> factoryBean) {
|
||||
return factoryBean;
|
||||
if (beanInstance instanceof FactoryBean) {
|
||||
return (FactoryBean<?>) beanInstance;
|
||||
}
|
||||
if (isSingletonCurrentlyInCreation(beanName) ||
|
||||
(mbd.getFactoryBeanName() != null && isSingletonCurrentlyInCreation(mbd.getFactoryBeanName()))) {
|
||||
@@ -1389,7 +1389,11 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
}
|
||||
pvs = newPvs;
|
||||
}
|
||||
if (hasInstantiationAwareBeanPostProcessors()) {
|
||||
|
||||
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
|
||||
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
|
||||
|
||||
if (hasInstAwareBpps) {
|
||||
if (pvs == null) {
|
||||
pvs = mbd.getPropertyValues();
|
||||
}
|
||||
@@ -1401,8 +1405,6 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
pvs = pvsToUse;
|
||||
}
|
||||
}
|
||||
|
||||
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
|
||||
if (needsDepCheck) {
|
||||
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
|
||||
checkDependencies(beanName, mbd, filteredPds, pvs);
|
||||
@@ -1675,8 +1677,8 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
}
|
||||
deepCopy.add(pv);
|
||||
}
|
||||
else if (convertible && originalValue instanceof TypedStringValue typedStringValue &&
|
||||
!typedStringValue.isDynamic() &&
|
||||
else if (convertible && originalValue instanceof TypedStringValue &&
|
||||
!((TypedStringValue) originalValue).isDynamic() &&
|
||||
!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
|
||||
pv.setConvertedValue(convertedValue);
|
||||
deepCopy.add(pv);
|
||||
@@ -1707,8 +1709,8 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
private Object convertForProperty(
|
||||
@Nullable Object value, String propertyName, BeanWrapper bw, TypeConverter converter) {
|
||||
|
||||
if (converter instanceof BeanWrapperImpl beanWrapper) {
|
||||
return beanWrapper.convertForProperty(value, propertyName);
|
||||
if (converter instanceof BeanWrapperImpl) {
|
||||
return ((BeanWrapperImpl) converter).convertForProperty(value, propertyName);
|
||||
}
|
||||
else {
|
||||
PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
|
||||
@@ -1759,17 +1761,17 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
|
||||
private void invokeAwareMethods(String beanName, Object bean) {
|
||||
if (bean instanceof Aware) {
|
||||
if (bean instanceof BeanNameAware beanNameAware) {
|
||||
beanNameAware.setBeanName(beanName);
|
||||
if (bean instanceof BeanNameAware) {
|
||||
((BeanNameAware) bean).setBeanName(beanName);
|
||||
}
|
||||
if (bean instanceof BeanClassLoaderAware beanClassLoaderAware) {
|
||||
if (bean instanceof BeanClassLoaderAware) {
|
||||
ClassLoader bcl = getBeanClassLoader();
|
||||
if (bcl != null) {
|
||||
beanClassLoaderAware.setBeanClassLoader(bcl);
|
||||
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
|
||||
}
|
||||
}
|
||||
if (bean instanceof BeanFactoryAware beanFactoryAware) {
|
||||
beanFactoryAware.setBeanFactory(AbstractAutowireCapableBeanFactory.this);
|
||||
if (bean instanceof BeanFactoryAware) {
|
||||
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+5
-5
@@ -1342,11 +1342,11 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
Class<?> type = descriptor.getDependencyType();
|
||||
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
|
||||
if (value != null) {
|
||||
if (value instanceof String strValue) {
|
||||
String resolvedValue = resolveEmbeddedValue(strValue);
|
||||
if (value instanceof String) {
|
||||
String strVal = resolveEmbeddedValue((String) value);
|
||||
BeanDefinition bd = (beanName != null && containsBean(beanName) ?
|
||||
getMergedBeanDefinition(beanName) : null);
|
||||
value = evaluateBeanDefinitionString(resolvedValue, bd);
|
||||
value = evaluateBeanDefinitionString(strVal, bd);
|
||||
}
|
||||
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
|
||||
try {
|
||||
@@ -2125,11 +2125,11 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
return resolveStream(true);
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@SuppressWarnings("unchecked")
|
||||
private Stream<Object> resolveStream(boolean ordered) {
|
||||
DependencyDescriptor descriptorToUse = new StreamDependencyDescriptor(this.descriptor, ordered);
|
||||
Object result = doResolveDependency(descriptorToUse, this.beanName, null, null);
|
||||
return (result instanceof Stream stream ? stream : Stream.of(result));
|
||||
return (result instanceof Stream ? (Stream<Object>) result : Stream.of(result));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+19
-20
@@ -1010,11 +1010,11 @@ abstract class AbstractPropertyAccessorTests {
|
||||
accessor.setPropertyValue("list", list);
|
||||
assertThat(target.getCollection()).hasSize(1);
|
||||
assertThat(target.getCollection().containsAll(coll)).isTrue();
|
||||
assertThat(target.getSet()).hasSize(1);
|
||||
assertThat(target.getSet().size()).isEqualTo(1);
|
||||
assertThat(target.getSet().containsAll(set)).isTrue();
|
||||
assertThat(target.getSortedSet()).hasSize(1);
|
||||
assertThat(target.getSortedSet().size()).isEqualTo(1);
|
||||
assertThat(target.getSortedSet().containsAll(sortedSet)).isTrue();
|
||||
assertThat(target.getList()).hasSize(1);
|
||||
assertThat(target.getList().size()).isEqualTo(1);
|
||||
assertThat(target.getList().containsAll(list)).isTrue();
|
||||
}
|
||||
|
||||
@@ -1037,11 +1037,11 @@ abstract class AbstractPropertyAccessorTests {
|
||||
accessor.setPropertyValue("list", list.toArray());
|
||||
assertThat(target.getCollection()).hasSize(1);
|
||||
assertThat(target.getCollection().containsAll(coll)).isTrue();
|
||||
assertThat(target.getSet()).hasSize(1);
|
||||
assertThat(target.getSet().size()).isEqualTo(1);
|
||||
assertThat(target.getSet().containsAll(set)).isTrue();
|
||||
assertThat(target.getSortedSet()).hasSize(1);
|
||||
assertThat(target.getSortedSet().size()).isEqualTo(1);
|
||||
assertThat(target.getSortedSet().containsAll(sortedSet)).isTrue();
|
||||
assertThat(target.getList()).hasSize(1);
|
||||
assertThat(target.getList().size()).isEqualTo(1);
|
||||
assertThat(target.getList().containsAll(list)).isTrue();
|
||||
}
|
||||
|
||||
@@ -1064,11 +1064,11 @@ abstract class AbstractPropertyAccessorTests {
|
||||
accessor.setPropertyValue("list", new int[]{3});
|
||||
assertThat(target.getCollection()).hasSize(1);
|
||||
assertThat(target.getCollection().containsAll(coll)).isTrue();
|
||||
assertThat(target.getSet()).hasSize(1);
|
||||
assertThat(target.getSet().size()).isEqualTo(1);
|
||||
assertThat(target.getSet().containsAll(set)).isTrue();
|
||||
assertThat(target.getSortedSet()).hasSize(1);
|
||||
assertThat(target.getSortedSet().size()).isEqualTo(1);
|
||||
assertThat(target.getSortedSet().containsAll(sortedSet)).isTrue();
|
||||
assertThat(target.getList()).hasSize(1);
|
||||
assertThat(target.getList().size()).isEqualTo(1);
|
||||
assertThat(target.getList().containsAll(list)).isTrue();
|
||||
}
|
||||
|
||||
@@ -1091,11 +1091,11 @@ abstract class AbstractPropertyAccessorTests {
|
||||
accessor.setPropertyValue("list", 3);
|
||||
assertThat(target.getCollection()).hasSize(1);
|
||||
assertThat(target.getCollection().containsAll(coll)).isTrue();
|
||||
assertThat(target.getSet()).hasSize(1);
|
||||
assertThat(target.getSet().size()).isEqualTo(1);
|
||||
assertThat(target.getSet().containsAll(set)).isTrue();
|
||||
assertThat(target.getSortedSet()).hasSize(1);
|
||||
assertThat(target.getSortedSet().size()).isEqualTo(1);
|
||||
assertThat(target.getSortedSet().containsAll(sortedSet)).isTrue();
|
||||
assertThat(target.getList()).hasSize(1);
|
||||
assertThat(target.getList().size()).isEqualTo(1);
|
||||
assertThat(target.getList().containsAll(list)).isTrue();
|
||||
}
|
||||
|
||||
@@ -1113,16 +1113,15 @@ abstract class AbstractPropertyAccessorTests {
|
||||
Set<String> list = new HashSet<>();
|
||||
list.add("list1");
|
||||
accessor.setPropertyValue("list", "list1");
|
||||
assertThat(target.getSet()).hasSize(1);
|
||||
assertThat(target.getSet().size()).isEqualTo(1);
|
||||
assertThat(target.getSet().containsAll(set)).isTrue();
|
||||
assertThat(target.getSortedSet()).hasSize(1);
|
||||
assertThat(target.getSortedSet().size()).isEqualTo(1);
|
||||
assertThat(target.getSortedSet().containsAll(sortedSet)).isTrue();
|
||||
assertThat(target.getList()).hasSize(1);
|
||||
assertThat(target.getList().size()).isEqualTo(1);
|
||||
assertThat(target.getList().containsAll(list)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void setCollectionPropertyWithStringValueAndCustomEditor() {
|
||||
IndexedTestBean target = new IndexedTestBean();
|
||||
AbstractPropertyAccessor accessor = createAccessor(target);
|
||||
@@ -1132,11 +1131,11 @@ abstract class AbstractPropertyAccessorTests {
|
||||
accessor.setPropertyValue("set", "set1 ");
|
||||
accessor.setPropertyValue("sortedSet", "sortedSet1");
|
||||
accessor.setPropertyValue("list", "list1 ");
|
||||
assertThat(target.getSet()).hasSize(1);
|
||||
assertThat(target.getSet().size()).isEqualTo(1);
|
||||
assertThat(target.getSet().contains("set1")).isTrue();
|
||||
assertThat(target.getSortedSet()).hasSize(1);
|
||||
assertThat(target.getSortedSet().size()).isEqualTo(1);
|
||||
assertThat(target.getSortedSet().contains("sortedSet1")).isTrue();
|
||||
assertThat(target.getList()).hasSize(1);
|
||||
assertThat(target.getList().size()).isEqualTo(1);
|
||||
assertThat(target.getList().contains("list1")).isTrue();
|
||||
|
||||
accessor.setPropertyValue("list", Collections.singletonList("list1 "));
|
||||
@@ -1170,7 +1169,7 @@ abstract class AbstractPropertyAccessorTests {
|
||||
accessor.setPropertyValue("sortedMap", sortedMap);
|
||||
assertThat(target.getMap()).hasSize(1);
|
||||
assertThat(target.getMap().get("key")).isEqualTo("value");
|
||||
assertThat(target.getSortedMap()).hasSize(1);
|
||||
assertThat(target.getSortedMap().size()).isEqualTo(1);
|
||||
assertThat(target.getSortedMap().get("sortedKey")).isEqualTo("sortedValue");
|
||||
}
|
||||
|
||||
|
||||
+6
-6
@@ -63,7 +63,7 @@ public class BeanWrapperAutoGrowingTests {
|
||||
@Test
|
||||
public void getPropertyValueAutoGrowArray() {
|
||||
assertNotNull(wrapper.getPropertyValue("array[0]"));
|
||||
assertThat(bean.getArray()).hasSize(1);
|
||||
assertThat(bean.getArray().length).isEqualTo(1);
|
||||
assertThat(bean.getArray()[0]).isInstanceOf(Bean.class);
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ public class BeanWrapperAutoGrowingTests {
|
||||
@Test
|
||||
public void getPropertyValueAutoGrowArrayBySeveralElements() {
|
||||
assertNotNull(wrapper.getPropertyValue("array[4]"));
|
||||
assertThat(bean.getArray()).hasSize(5);
|
||||
assertThat(bean.getArray().length).isEqualTo(5);
|
||||
assertThat(bean.getArray()[0]).isInstanceOf(Bean.class);
|
||||
assertThat(bean.getArray()[1]).isInstanceOf(Bean.class);
|
||||
assertThat(bean.getArray()[2]).isInstanceOf(Bean.class);
|
||||
@@ -91,7 +91,7 @@ public class BeanWrapperAutoGrowingTests {
|
||||
@Test
|
||||
public void getPropertyValueAutoGrow2dArray() {
|
||||
assertNotNull(wrapper.getPropertyValue("multiArray[0][0]"));
|
||||
assertThat(bean.getMultiArray()[0]).hasSize(1);
|
||||
assertThat(bean.getMultiArray()[0].length).isEqualTo(1);
|
||||
assertThat(bean.getMultiArray()[0][0]).isInstanceOf(Bean.class);
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ public class BeanWrapperAutoGrowingTests {
|
||||
@Test
|
||||
public void getPropertyValueAutoGrowList() {
|
||||
assertNotNull(wrapper.getPropertyValue("list[0]"));
|
||||
assertThat(bean.getList()).hasSize(1);
|
||||
assertThat(bean.getList().size()).isEqualTo(1);
|
||||
assertThat(bean.getList().get(0)).isInstanceOf(Bean.class);
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ public class BeanWrapperAutoGrowingTests {
|
||||
@Test
|
||||
public void getPropertyValueAutoGrowListBySeveralElements() {
|
||||
assertNotNull(wrapper.getPropertyValue("list[4]"));
|
||||
assertThat(bean.getList()).hasSize(5);
|
||||
assertThat(bean.getList().size()).isEqualTo(5);
|
||||
assertThat(bean.getList().get(0)).isInstanceOf(Bean.class);
|
||||
assertThat(bean.getList().get(1)).isInstanceOf(Bean.class);
|
||||
assertThat(bean.getList().get(2)).isInstanceOf(Bean.class);
|
||||
@@ -161,7 +161,7 @@ public class BeanWrapperAutoGrowingTests {
|
||||
@Test
|
||||
public void getPropertyValueAutoGrowMultiDimensionalList() {
|
||||
assertNotNull(wrapper.getPropertyValue("multiList[0][0]"));
|
||||
assertThat(bean.getMultiList().get(0)).hasSize(1);
|
||||
assertThat(bean.getMultiList().get(0).size()).isEqualTo(1);
|
||||
assertThat(bean.getMultiList().get(0).get(0)).isInstanceOf(Bean.class);
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ public class BeanWrapperEnumTests {
|
||||
GenericBean<?> gb = new GenericBean<>();
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
bw.setPropertyValue("customEnumArray", "VALUE_1");
|
||||
assertThat(gb.getCustomEnumArray()).hasSize(1);
|
||||
assertThat(gb.getCustomEnumArray().length).isEqualTo(1);
|
||||
assertThat(gb.getCustomEnumArray()[0]).isEqualTo(CustomEnum.VALUE_1);
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ public class BeanWrapperEnumTests {
|
||||
GenericBean<?> gb = new GenericBean<>();
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
bw.setPropertyValue("customEnumArray", new String[] {"VALUE_1", "VALUE_2"});
|
||||
assertThat(gb.getCustomEnumArray()).hasSize(2);
|
||||
assertThat(gb.getCustomEnumArray().length).isEqualTo(2);
|
||||
assertThat(gb.getCustomEnumArray()[0]).isEqualTo(CustomEnum.VALUE_1);
|
||||
assertThat(gb.getCustomEnumArray()[1]).isEqualTo(CustomEnum.VALUE_2);
|
||||
}
|
||||
@@ -81,7 +81,7 @@ public class BeanWrapperEnumTests {
|
||||
GenericBean<?> gb = new GenericBean<>();
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
bw.setPropertyValue("customEnumArray", "VALUE_1,VALUE_2");
|
||||
assertThat(gb.getCustomEnumArray()).hasSize(2);
|
||||
assertThat(gb.getCustomEnumArray().length).isEqualTo(2);
|
||||
assertThat(gb.getCustomEnumArray()[0]).isEqualTo(CustomEnum.VALUE_1);
|
||||
assertThat(gb.getCustomEnumArray()[1]).isEqualTo(CustomEnum.VALUE_2);
|
||||
}
|
||||
@@ -91,7 +91,7 @@ public class BeanWrapperEnumTests {
|
||||
GenericBean<?> gb = new GenericBean<>();
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
bw.setPropertyValue("customEnumSet", "VALUE_1");
|
||||
assertThat(gb.getCustomEnumSet()).hasSize(1);
|
||||
assertThat(gb.getCustomEnumSet().size()).isEqualTo(1);
|
||||
assertThat(gb.getCustomEnumSet().contains(CustomEnum.VALUE_1)).isTrue();
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ public class BeanWrapperEnumTests {
|
||||
GenericBean<?> gb = new GenericBean<>();
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
bw.setPropertyValue("customEnumSet", new String[] {"VALUE_1", "VALUE_2"});
|
||||
assertThat(gb.getCustomEnumSet()).hasSize(2);
|
||||
assertThat(gb.getCustomEnumSet().size()).isEqualTo(2);
|
||||
assertThat(gb.getCustomEnumSet().contains(CustomEnum.VALUE_1)).isTrue();
|
||||
assertThat(gb.getCustomEnumSet().contains(CustomEnum.VALUE_2)).isTrue();
|
||||
}
|
||||
@@ -110,7 +110,7 @@ public class BeanWrapperEnumTests {
|
||||
GenericBean<?> gb = new GenericBean<>();
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
bw.setPropertyValue("customEnumSet", "VALUE_1,VALUE_2");
|
||||
assertThat(gb.getCustomEnumSet()).hasSize(2);
|
||||
assertThat(gb.getCustomEnumSet().size()).isEqualTo(2);
|
||||
assertThat(gb.getCustomEnumSet().contains(CustomEnum.VALUE_1)).isTrue();
|
||||
assertThat(gb.getCustomEnumSet().contains(CustomEnum.VALUE_2)).isTrue();
|
||||
}
|
||||
@@ -120,7 +120,7 @@ public class BeanWrapperEnumTests {
|
||||
GenericBean<?> gb = new GenericBean<>();
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
bw.setPropertyValue("customEnumSetMismatch", new String[] {"VALUE_1", "VALUE_2"});
|
||||
assertThat(gb.getCustomEnumSet()).hasSize(2);
|
||||
assertThat(gb.getCustomEnumSet().size()).isEqualTo(2);
|
||||
assertThat(gb.getCustomEnumSet().contains(CustomEnum.VALUE_1)).isTrue();
|
||||
assertThat(gb.getCustomEnumSet().contains(CustomEnum.VALUE_2)).isTrue();
|
||||
}
|
||||
@@ -132,7 +132,7 @@ public class BeanWrapperEnumTests {
|
||||
bw.setConversionService(new DefaultConversionService());
|
||||
assertThat(gb.getStandardEnumSet()).isNull();
|
||||
bw.setPropertyValue("standardEnumSet", new String[] {"VALUE_1", "VALUE_2"});
|
||||
assertThat(gb.getStandardEnumSet()).hasSize(2);
|
||||
assertThat(gb.getStandardEnumSet().size()).isEqualTo(2);
|
||||
assertThat(gb.getStandardEnumSet().contains(CustomEnum.VALUE_1)).isTrue();
|
||||
assertThat(gb.getStandardEnumSet().contains(CustomEnum.VALUE_2)).isTrue();
|
||||
}
|
||||
@@ -144,7 +144,7 @@ public class BeanWrapperEnumTests {
|
||||
bw.setAutoGrowNestedPaths(true);
|
||||
assertThat(gb.getStandardEnumSet()).isNull();
|
||||
bw.getPropertyValue("standardEnumSet.class");
|
||||
assertThat(gb.getStandardEnumSet()).isEmpty();
|
||||
assertThat(gb.getStandardEnumSet().size()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -157,7 +157,7 @@ public class BeanWrapperEnumTests {
|
||||
map.put("VALUE_1", 1);
|
||||
map.put("VALUE_2", 2);
|
||||
bw.setPropertyValue("standardEnumMap", map);
|
||||
assertThat(gb.getStandardEnumMap()).hasSize(2);
|
||||
assertThat(gb.getStandardEnumMap().size()).isEqualTo(2);
|
||||
assertThat(gb.getStandardEnumMap().get(CustomEnum.VALUE_1)).isEqualTo(1);
|
||||
assertThat(gb.getStandardEnumMap().get(CustomEnum.VALUE_2)).isEqualTo(2);
|
||||
}
|
||||
@@ -169,7 +169,7 @@ public class BeanWrapperEnumTests {
|
||||
bw.setAutoGrowNestedPaths(true);
|
||||
assertThat(gb.getStandardEnumMap()).isNull();
|
||||
bw.setPropertyValue("standardEnumMap[VALUE_1]", 1);
|
||||
assertThat(gb.getStandardEnumMap()).hasSize(1);
|
||||
assertThat(gb.getStandardEnumMap().size()).isEqualTo(1);
|
||||
assertThat(gb.getStandardEnumMap().get(CustomEnum.VALUE_1)).isEqualTo(1);
|
||||
}
|
||||
|
||||
|
||||
@@ -200,11 +200,11 @@ class ExtendedBeanInfoTests {
|
||||
}
|
||||
{ // always passes
|
||||
BeanInfo info = Introspector.getBeanInfo(Bean.class);
|
||||
assertThat(info.getPropertyDescriptors()).hasSize(2);
|
||||
assertThat(info.getPropertyDescriptors().length).isEqualTo(2);
|
||||
}
|
||||
{ // failed prior to fix for SPR-9453
|
||||
BeanInfo info = new ExtendedBeanInfo(Introspector.getBeanInfo(Bean.class));
|
||||
assertThat(info.getPropertyDescriptors()).hasSize(2);
|
||||
assertThat(info.getPropertyDescriptors().length).isEqualTo(2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -585,7 +585,7 @@ class ExtendedBeanInfoTests {
|
||||
assertThat(hasReadMethodForProperty(ebi, "foo")).isTrue();
|
||||
assertThat(hasWriteMethodForProperty(ebi, "foo")).isTrue();
|
||||
|
||||
assertThat(ebi.getPropertyDescriptors()).hasSize(bi.getPropertyDescriptors().length);
|
||||
assertThat(ebi.getPropertyDescriptors().length).isEqualTo(bi.getPropertyDescriptors().length);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -711,7 +711,7 @@ class ExtendedBeanInfoTests {
|
||||
BeanInfo bi = Introspector.getBeanInfo(TestBean.class);
|
||||
BeanInfo ebi = new ExtendedBeanInfo(bi);
|
||||
|
||||
assertThat(ebi.getPropertyDescriptors()).hasSize(bi.getPropertyDescriptors().length);
|
||||
assertThat(ebi.getPropertyDescriptors().length).isEqualTo(bi.getPropertyDescriptors().length);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -731,7 +731,7 @@ class ExtendedBeanInfoTests {
|
||||
}
|
||||
}
|
||||
assertThat(found).isTrue();
|
||||
assertThat(ebi.getPropertyDescriptors()).hasSize(bi.getPropertyDescriptors().length+1);
|
||||
assertThat(ebi.getPropertyDescriptors().length).isEqualTo(bi.getPropertyDescriptors().length+1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+20
-20
@@ -103,14 +103,14 @@ public class BeanFactoryUtilsTests {
|
||||
public void testHierarchicalNamesWithNoMatch() {
|
||||
List<String> names = Arrays.asList(
|
||||
BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.listableBeanFactory, NoOp.class));
|
||||
assertThat(names).isEmpty();
|
||||
assertThat(names.size()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHierarchicalNamesWithMatchOnlyInRoot() {
|
||||
List<String> names = Arrays.asList(
|
||||
BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.listableBeanFactory, IndexedTestBean.class));
|
||||
assertThat(names).hasSize(1);
|
||||
assertThat(names.size()).isEqualTo(1);
|
||||
assertThat(names.contains("indexedBean")).isTrue();
|
||||
// Distinguish from default ListableBeanFactory behavior
|
||||
assertThat(listableBeanFactory.getBeanNamesForType(IndexedTestBean.class).length == 0).isTrue();
|
||||
@@ -121,7 +121,7 @@ public class BeanFactoryUtilsTests {
|
||||
List<String> names = Arrays.asList(
|
||||
BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.listableBeanFactory, ITestBean.class));
|
||||
// includes 2 TestBeans from FactoryBeans (DummyFactory definitions)
|
||||
assertThat(names).hasSize(4);
|
||||
assertThat(names.size()).isEqualTo(4);
|
||||
assertThat(names.contains("test")).isTrue();
|
||||
assertThat(names.contains("test3")).isTrue();
|
||||
assertThat(names.contains("testFactory1")).isTrue();
|
||||
@@ -150,7 +150,7 @@ public class BeanFactoryUtilsTests {
|
||||
lbf.addBean("t4", t4);
|
||||
|
||||
Map<String, ?> beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(lbf, ITestBean.class, true, true);
|
||||
assertThat(beans).hasSize(4);
|
||||
assertThat(beans.size()).isEqualTo(4);
|
||||
assertThat(beans.get("t1")).isEqualTo(t1);
|
||||
assertThat(beans.get("t2")).isEqualTo(t2);
|
||||
assertThat(beans.get("t3")).isEqualTo(t3.getObject());
|
||||
@@ -158,12 +158,12 @@ public class BeanFactoryUtilsTests {
|
||||
assertThat(condition).isTrue();
|
||||
|
||||
beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(lbf, DummyFactory.class, true, true);
|
||||
assertThat(beans).hasSize(2);
|
||||
assertThat(beans.size()).isEqualTo(2);
|
||||
assertThat(beans.get("&t3")).isEqualTo(t3);
|
||||
assertThat(beans.get("&t4")).isEqualTo(t4);
|
||||
|
||||
beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(lbf, FactoryBean.class, true, true);
|
||||
assertThat(beans).hasSize(2);
|
||||
assertThat(beans.size()).isEqualTo(2);
|
||||
assertThat(beans.get("&t3")).isEqualTo(t3);
|
||||
assertThat(beans.get("&t4")).isEqualTo(t4);
|
||||
}
|
||||
@@ -185,7 +185,7 @@ public class BeanFactoryUtilsTests {
|
||||
|
||||
Map<String, ?> beans =
|
||||
BeanFactoryUtils.beansOfTypeIncludingAncestors(this.listableBeanFactory, ITestBean.class, true, false);
|
||||
assertThat(beans).hasSize(6);
|
||||
assertThat(beans.size()).isEqualTo(6);
|
||||
assertThat(beans.get("test3")).isEqualTo(test3);
|
||||
assertThat(beans.get("test")).isEqualTo(test);
|
||||
assertThat(beans.get("t1")).isEqualTo(t1);
|
||||
@@ -199,7 +199,7 @@ public class BeanFactoryUtilsTests {
|
||||
|
||||
beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(this.listableBeanFactory, ITestBean.class, false, true);
|
||||
Object testFactory1 = this.listableBeanFactory.getBean("testFactory1");
|
||||
assertThat(beans).hasSize(5);
|
||||
assertThat(beans.size()).isEqualTo(5);
|
||||
assertThat(beans.get("test")).isEqualTo(test);
|
||||
assertThat(beans.get("testFactory1")).isEqualTo(testFactory1);
|
||||
assertThat(beans.get("t1")).isEqualTo(t1);
|
||||
@@ -207,7 +207,7 @@ public class BeanFactoryUtilsTests {
|
||||
assertThat(beans.get("t3")).isEqualTo(t3.getObject());
|
||||
|
||||
beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(this.listableBeanFactory, ITestBean.class, true, true);
|
||||
assertThat(beans).hasSize(8);
|
||||
assertThat(beans.size()).isEqualTo(8);
|
||||
assertThat(beans.get("test3")).isEqualTo(test3);
|
||||
assertThat(beans.get("test")).isEqualTo(test);
|
||||
assertThat(beans.get("testFactory1")).isEqualTo(testFactory1);
|
||||
@@ -220,14 +220,14 @@ public class BeanFactoryUtilsTests {
|
||||
assertThat(condition).isTrue();
|
||||
|
||||
beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(this.listableBeanFactory, DummyFactory.class, true, true);
|
||||
assertThat(beans).hasSize(4);
|
||||
assertThat(beans.size()).isEqualTo(4);
|
||||
assertThat(beans.get("&testFactory1")).isEqualTo(this.listableBeanFactory.getBean("&testFactory1"));
|
||||
assertThat(beans.get("&testFactory2")).isEqualTo(this.listableBeanFactory.getBean("&testFactory2"));
|
||||
assertThat(beans.get("&t3")).isEqualTo(t3);
|
||||
assertThat(beans.get("&t4")).isEqualTo(t4);
|
||||
|
||||
beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(this.listableBeanFactory, FactoryBean.class, true, true);
|
||||
assertThat(beans).hasSize(4);
|
||||
assertThat(beans.size()).isEqualTo(4);
|
||||
assertThat(beans.get("&testFactory1")).isEqualTo(this.listableBeanFactory.getBean("&testFactory1"));
|
||||
assertThat(beans.get("&testFactory2")).isEqualTo(this.listableBeanFactory.getBean("&testFactory2"));
|
||||
assertThat(beans.get("&t3")).isEqualTo(t3);
|
||||
@@ -241,22 +241,22 @@ public class BeanFactoryUtilsTests {
|
||||
|
||||
Map<String, ?> beans =
|
||||
BeanFactoryUtils.beansOfTypeIncludingAncestors(this.listableBeanFactory, ITestBean.class, true, false);
|
||||
assertThat(beans).hasSize(2);
|
||||
assertThat(beans.size()).isEqualTo(2);
|
||||
assertThat(beans.get("test3")).isEqualTo(test3);
|
||||
assertThat(beans.get("test")).isEqualTo(test);
|
||||
|
||||
beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(this.listableBeanFactory, ITestBean.class, false, false);
|
||||
assertThat(beans).hasSize(1);
|
||||
assertThat(beans.size()).isEqualTo(1);
|
||||
assertThat(beans.get("test")).isEqualTo(test);
|
||||
|
||||
beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(this.listableBeanFactory, ITestBean.class, false, true);
|
||||
Object testFactory1 = this.listableBeanFactory.getBean("testFactory1");
|
||||
assertThat(beans).hasSize(2);
|
||||
assertThat(beans.size()).isEqualTo(2);
|
||||
assertThat(beans.get("test")).isEqualTo(test);
|
||||
assertThat(beans.get("testFactory1")).isEqualTo(testFactory1);
|
||||
|
||||
beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(this.listableBeanFactory, ITestBean.class, true, true);
|
||||
assertThat(beans).hasSize(4);
|
||||
assertThat(beans.size()).isEqualTo(4);
|
||||
assertThat(beans.get("test3")).isEqualTo(test3);
|
||||
assertThat(beans.get("test")).isEqualTo(test);
|
||||
assertThat(beans.get("testFactory1")).isEqualTo(testFactory1);
|
||||
@@ -264,12 +264,12 @@ public class BeanFactoryUtilsTests {
|
||||
assertThat(condition).isTrue();
|
||||
|
||||
beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(this.listableBeanFactory, DummyFactory.class, true, true);
|
||||
assertThat(beans).hasSize(2);
|
||||
assertThat(beans.size()).isEqualTo(2);
|
||||
assertThat(beans.get("&testFactory1")).isEqualTo(this.listableBeanFactory.getBean("&testFactory1"));
|
||||
assertThat(beans.get("&testFactory2")).isEqualTo(this.listableBeanFactory.getBean("&testFactory2"));
|
||||
|
||||
beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(this.listableBeanFactory, FactoryBean.class, true, true);
|
||||
assertThat(beans).hasSize(2);
|
||||
assertThat(beans.size()).isEqualTo(2);
|
||||
assertThat(beans.get("&testFactory1")).isEqualTo(this.listableBeanFactory.getBean("&testFactory1"));
|
||||
assertThat(beans.get("&testFactory2")).isEqualTo(this.listableBeanFactory.getBean("&testFactory2"));
|
||||
}
|
||||
@@ -278,14 +278,14 @@ public class BeanFactoryUtilsTests {
|
||||
public void testHierarchicalNamesForAnnotationWithNoMatch() {
|
||||
List<String> names = Arrays.asList(
|
||||
BeanFactoryUtils.beanNamesForAnnotationIncludingAncestors(this.listableBeanFactory, Override.class));
|
||||
assertThat(names).isEmpty();
|
||||
assertThat(names.size()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHierarchicalNamesForAnnotationWithMatchOnlyInRoot() {
|
||||
List<String> names = Arrays.asList(
|
||||
BeanFactoryUtils.beanNamesForAnnotationIncludingAncestors(this.listableBeanFactory, TestAnnotation.class));
|
||||
assertThat(names).hasSize(1);
|
||||
assertThat(names.size()).isEqualTo(1);
|
||||
assertThat(names.contains("annotatedBean")).isTrue();
|
||||
// Distinguish from default ListableBeanFactory behavior
|
||||
assertThat(listableBeanFactory.getBeanNamesForAnnotation(TestAnnotation.class).length == 0).isTrue();
|
||||
@@ -297,7 +297,7 @@ public class BeanFactoryUtilsTests {
|
||||
this.listableBeanFactory.registerSingleton("anotherAnnotatedBean", annotatedBean);
|
||||
List<String> names = Arrays.asList(
|
||||
BeanFactoryUtils.beanNamesForAnnotationIncludingAncestors(this.listableBeanFactory, TestAnnotation.class));
|
||||
assertThat(names).hasSize(2);
|
||||
assertThat(names.size()).isEqualTo(2);
|
||||
assertThat(names.contains("annotatedBean")).isTrue();
|
||||
assertThat(names.contains("anotherAnnotatedBean")).isTrue();
|
||||
}
|
||||
|
||||
+10
-10
@@ -1075,12 +1075,12 @@ class DefaultListableBeanFactoryTests {
|
||||
assertThat(test.getSpouse()).isEqualTo(singletonObject);
|
||||
|
||||
Map<?, ?> beansOfType = lbf.getBeansOfType(TestBean.class, false, true);
|
||||
assertThat(beansOfType).hasSize(2);
|
||||
assertThat(beansOfType.size()).isEqualTo(2);
|
||||
assertThat(beansOfType.containsValue(test)).isTrue();
|
||||
assertThat(beansOfType.containsValue(singletonObject)).isTrue();
|
||||
|
||||
beansOfType = lbf.getBeansOfType(null, false, true);
|
||||
assertThat(beansOfType).hasSize(2);
|
||||
assertThat(beansOfType.size()).isEqualTo(2);
|
||||
|
||||
Iterator<String> beanNames = lbf.getBeanNamesIterator();
|
||||
assertThat(beanNames.next()).isEqualTo("test");
|
||||
@@ -1113,7 +1113,7 @@ class DefaultListableBeanFactoryTests {
|
||||
assertThat(test.getSpouse()).isEqualTo(singletonObject);
|
||||
|
||||
Map<?, ?> beansOfType = lbf.getBeansOfType(TestBean.class, false, true);
|
||||
assertThat(beansOfType).hasSize(2);
|
||||
assertThat(beansOfType.size()).isEqualTo(2);
|
||||
assertThat(beansOfType.containsValue(test)).isTrue();
|
||||
assertThat(beansOfType.containsValue(singletonObject)).isTrue();
|
||||
|
||||
@@ -1123,7 +1123,7 @@ class DefaultListableBeanFactoryTests {
|
||||
assertThat(beanNames.next()).isEqualTo("test");
|
||||
assertThat(beanNames.next()).isEqualTo("singletonObject");
|
||||
assertThat(beanNames.hasNext()).isFalse();
|
||||
assertThat(beansOfType).hasSize(2);
|
||||
assertThat(beansOfType.size()).isEqualTo(2);
|
||||
|
||||
assertThat(lbf.containsSingleton("test")).isTrue();
|
||||
assertThat(lbf.containsSingleton("singletonObject")).isTrue();
|
||||
@@ -1669,18 +1669,18 @@ class DefaultListableBeanFactoryTests {
|
||||
for (ConstructorDependency instance : provider) {
|
||||
resolved.add(instance);
|
||||
}
|
||||
assertThat(resolved).hasSize(2);
|
||||
assertThat(resolved.size()).isEqualTo(2);
|
||||
assertThat(resolved.contains(lbf.getBean("bd1"))).isTrue();
|
||||
assertThat(resolved.contains(lbf.getBean("bd2"))).isTrue();
|
||||
|
||||
resolved = new HashSet<>();
|
||||
provider.forEach(resolved::add);
|
||||
assertThat(resolved).hasSize(2);
|
||||
assertThat(resolved.size()).isEqualTo(2);
|
||||
assertThat(resolved.contains(lbf.getBean("bd1"))).isTrue();
|
||||
assertThat(resolved.contains(lbf.getBean("bd2"))).isTrue();
|
||||
|
||||
resolved = provider.stream().collect(Collectors.toSet());
|
||||
assertThat(resolved).hasSize(2);
|
||||
assertThat(resolved.size()).isEqualTo(2);
|
||||
assertThat(resolved.contains(lbf.getBean("bd1"))).isTrue();
|
||||
assertThat(resolved.contains(lbf.getBean("bd2"))).isTrue();
|
||||
}
|
||||
@@ -1718,18 +1718,18 @@ class DefaultListableBeanFactoryTests {
|
||||
for (ConstructorDependency instance : provider) {
|
||||
resolved.add(instance);
|
||||
}
|
||||
assertThat(resolved).hasSize(2);
|
||||
assertThat(resolved.size()).isEqualTo(2);
|
||||
assertThat(resolved.contains(lbf.getBean("bd1"))).isTrue();
|
||||
assertThat(resolved.contains(lbf.getBean("bd2"))).isTrue();
|
||||
|
||||
resolved = new HashSet<>();
|
||||
provider.forEach(resolved::add);
|
||||
assertThat(resolved).hasSize(2);
|
||||
assertThat(resolved.size()).isEqualTo(2);
|
||||
assertThat(resolved.contains(lbf.getBean("bd1"))).isTrue();
|
||||
assertThat(resolved.contains(lbf.getBean("bd2"))).isTrue();
|
||||
|
||||
resolved = provider.stream().collect(Collectors.toSet());
|
||||
assertThat(resolved).hasSize(2);
|
||||
assertThat(resolved.size()).isEqualTo(2);
|
||||
assertThat(resolved.contains(lbf.getBean("bd1"))).isTrue();
|
||||
assertThat(resolved.contains(lbf.getBean("bd2"))).isTrue();
|
||||
}
|
||||
|
||||
+64
-64
@@ -159,7 +159,7 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
assertThat(bean.getBeanFactory()).isSameAs(bf);
|
||||
|
||||
String[] depBeans = bf.getDependenciesForBean("annotatedBean");
|
||||
assertThat(depBeans).hasSize(2);
|
||||
assertThat(depBeans.length).isEqualTo(2);
|
||||
assertThat(depBeans[0]).isEqualTo("testBean");
|
||||
assertThat(depBeans[1]).isEqualTo("nestedTestBean");
|
||||
}
|
||||
@@ -266,10 +266,10 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
assertThat(bean.getTestBean3()).isSameAs(tb);
|
||||
assertThat(bean.getTestBean4()).isSameAs(tb);
|
||||
assertThat(bean.getIndexedTestBean()).isSameAs(itb);
|
||||
assertThat(bean.getNestedTestBeans()).hasSize(2);
|
||||
assertThat(bean.getNestedTestBeans().length).isEqualTo(2);
|
||||
assertThat(bean.getNestedTestBeans()[0]).isSameAs(ntb1);
|
||||
assertThat(bean.getNestedTestBeans()[1]).isSameAs(ntb2);
|
||||
assertThat(bean.nestedTestBeansField).hasSize(2);
|
||||
assertThat(bean.nestedTestBeansField.length).isEqualTo(2);
|
||||
assertThat(bean.nestedTestBeansField[0]).isSameAs(ntb1);
|
||||
assertThat(bean.nestedTestBeansField[1]).isSameAs(ntb2);
|
||||
}
|
||||
@@ -294,10 +294,10 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
assertThat(bean.getTestBean3()).isSameAs(tb);
|
||||
assertThat(bean.getTestBean4()).isSameAs(tb);
|
||||
assertThat(bean.getIndexedTestBean()).isSameAs(itb);
|
||||
assertThat(bean.getNestedTestBeans()).hasSize(2);
|
||||
assertThat(bean.getNestedTestBeans().length).isEqualTo(2);
|
||||
assertThat(bean.getNestedTestBeans()[0]).isSameAs(ntb1);
|
||||
assertThat(bean.getNestedTestBeans()[1]).isSameAs(ntb2);
|
||||
assertThat(bean.nestedTestBeansField).hasSize(2);
|
||||
assertThat(bean.nestedTestBeansField.length).isEqualTo(2);
|
||||
assertThat(bean.nestedTestBeansField[0]).isSameAs(ntb1);
|
||||
assertThat(bean.nestedTestBeansField[1]).isSameAs(ntb2);
|
||||
|
||||
@@ -309,10 +309,10 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
assertThat(bean.getTestBean3()).isNull();
|
||||
assertThat(bean.getTestBean4()).isNull();
|
||||
assertThat(bean.getIndexedTestBean()).isSameAs(itb);
|
||||
assertThat(bean.getNestedTestBeans()).hasSize(2);
|
||||
assertThat(bean.getNestedTestBeans().length).isEqualTo(2);
|
||||
assertThat(bean.getNestedTestBeans()[0]).isSameAs(ntb1);
|
||||
assertThat(bean.getNestedTestBeans()[1]).isSameAs(ntb2);
|
||||
assertThat(bean.nestedTestBeansField).hasSize(2);
|
||||
assertThat(bean.nestedTestBeansField.length).isEqualTo(2);
|
||||
assertThat(bean.nestedTestBeansField[0]).isSameAs(ntb1);
|
||||
assertThat(bean.nestedTestBeansField[1]).isSameAs(ntb2);
|
||||
|
||||
@@ -324,10 +324,10 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
assertThat(bean.getTestBean3()).isSameAs(tb);
|
||||
assertThat(bean.getTestBean4()).isSameAs(tb);
|
||||
assertThat(bean.getIndexedTestBean()).isSameAs(itb);
|
||||
assertThat(bean.getNestedTestBeans()).hasSize(2);
|
||||
assertThat(bean.getNestedTestBeans().length).isEqualTo(2);
|
||||
assertThat(bean.getNestedTestBeans()[0]).isSameAs(ntb1);
|
||||
assertThat(bean.getNestedTestBeans()[1]).isSameAs(ntb2);
|
||||
assertThat(bean.nestedTestBeansField).hasSize(2);
|
||||
assertThat(bean.nestedTestBeansField.length).isEqualTo(2);
|
||||
assertThat(bean.nestedTestBeansField[0]).isSameAs(ntb1);
|
||||
assertThat(bean.nestedTestBeansField[1]).isSameAs(ntb2);
|
||||
}
|
||||
@@ -351,10 +351,10 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
assertThat(bean.getTestBean3()).isSameAs(bf.getBean("testBean"));
|
||||
assertThat(bean.getTestBean4()).isSameAs(bf.getBean("testBean"));
|
||||
assertThat(bean.getIndexedTestBean()).isSameAs(itb);
|
||||
assertThat(bean.getNestedTestBeans()).hasSize(2);
|
||||
assertThat(bean.getNestedTestBeans().length).isEqualTo(2);
|
||||
assertThat(bean.getNestedTestBeans()[0]).isSameAs(ntb1);
|
||||
assertThat(bean.getNestedTestBeans()[1]).isSameAs(ntb2);
|
||||
assertThat(bean.nestedTestBeansField).hasSize(2);
|
||||
assertThat(bean.nestedTestBeansField.length).isEqualTo(2);
|
||||
assertThat(bean.nestedTestBeansField[0]).isSameAs(ntb1);
|
||||
assertThat(bean.nestedTestBeansField[1]).isSameAs(ntb2);
|
||||
|
||||
@@ -366,10 +366,10 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
assertThat(bean.getTestBean3()).isNull();
|
||||
assertThat(bean.getTestBean4()).isNull();
|
||||
assertThat(bean.getIndexedTestBean()).isSameAs(itb);
|
||||
assertThat(bean.getNestedTestBeans()).hasSize(2);
|
||||
assertThat(bean.getNestedTestBeans().length).isEqualTo(2);
|
||||
assertThat(bean.getNestedTestBeans()[0]).isSameAs(ntb1);
|
||||
assertThat(bean.getNestedTestBeans()[1]).isSameAs(ntb2);
|
||||
assertThat(bean.nestedTestBeansField).hasSize(2);
|
||||
assertThat(bean.nestedTestBeansField.length).isEqualTo(2);
|
||||
assertThat(bean.nestedTestBeansField[0]).isSameAs(ntb1);
|
||||
assertThat(bean.nestedTestBeansField[1]).isSameAs(ntb2);
|
||||
|
||||
@@ -381,10 +381,10 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
assertThat(bean.getTestBean3()).isSameAs(bf.getBean("testBean"));
|
||||
assertThat(bean.getTestBean4()).isSameAs(bf.getBean("testBean"));
|
||||
assertThat(bean.getIndexedTestBean()).isSameAs(itb);
|
||||
assertThat(bean.getNestedTestBeans()).hasSize(2);
|
||||
assertThat(bean.getNestedTestBeans().length).isEqualTo(2);
|
||||
assertThat(bean.getNestedTestBeans()[0]).isSameAs(ntb1);
|
||||
assertThat(bean.getNestedTestBeans()[1]).isSameAs(ntb2);
|
||||
assertThat(bean.nestedTestBeansField).hasSize(2);
|
||||
assertThat(bean.nestedTestBeansField.length).isEqualTo(2);
|
||||
assertThat(bean.nestedTestBeansField[0]).isSameAs(ntb1);
|
||||
assertThat(bean.nestedTestBeansField[1]).isSameAs(ntb2);
|
||||
}
|
||||
@@ -411,13 +411,13 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
assertThat(bean.getTestBean3()).isSameAs(tb);
|
||||
assertThat(bean.getTestBean4()).isSameAs(tb);
|
||||
assertThat(bean.getIndexedTestBean()).isSameAs(itb);
|
||||
assertThat(bean.getNestedTestBeans()).hasSize(2);
|
||||
assertThat(bean.getNestedTestBeans().size()).isEqualTo(2);
|
||||
assertThat(bean.getNestedTestBeans().get(0)).isSameAs(ntb1);
|
||||
assertThat(bean.getNestedTestBeans().get(1)).isSameAs(ntb2);
|
||||
assertThat(bean.nestedTestBeansSetter).hasSize(2);
|
||||
assertThat(bean.nestedTestBeansSetter.size()).isEqualTo(2);
|
||||
assertThat(bean.nestedTestBeansSetter.get(0)).isSameAs(ntb1);
|
||||
assertThat(bean.nestedTestBeansSetter.get(1)).isSameAs(ntb2);
|
||||
assertThat(bean.nestedTestBeansField).hasSize(2);
|
||||
assertThat(bean.nestedTestBeansField.size()).isEqualTo(2);
|
||||
assertThat(bean.nestedTestBeansField.get(0)).isSameAs(ntb1);
|
||||
assertThat(bean.nestedTestBeansField.get(1)).isSameAs(ntb2);
|
||||
}
|
||||
@@ -442,11 +442,11 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
assertThat(bean.getTestBean3()).isSameAs(tb);
|
||||
assertThat(bean.getTestBean4()).isSameAs(tb);
|
||||
assertThat(bean.getIndexedTestBean()).isSameAs(itb);
|
||||
assertThat(bean.getNestedTestBeans()).hasSize(1);
|
||||
assertThat(bean.getNestedTestBeans().size()).isEqualTo(1);
|
||||
assertThat(bean.getNestedTestBeans().get(0)).isSameAs(ntb1);
|
||||
assertThat(bean.nestedTestBeansSetter).hasSize(1);
|
||||
assertThat(bean.nestedTestBeansSetter.size()).isEqualTo(1);
|
||||
assertThat(bean.nestedTestBeansSetter.get(0)).isSameAs(ntb1);
|
||||
assertThat(bean.nestedTestBeansField).hasSize(1);
|
||||
assertThat(bean.nestedTestBeansField.size()).isEqualTo(1);
|
||||
assertThat(bean.nestedTestBeansField.get(0)).isSameAs(ntb1);
|
||||
}
|
||||
|
||||
@@ -496,10 +496,10 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
assertThat(bean.getTestBean3()).isSameAs(tb);
|
||||
assertThat(bean.getTestBean4()).isSameAs(tb);
|
||||
assertThat(bean.getIndexedTestBean()).isSameAs(itb);
|
||||
assertThat(bean.getNestedTestBeans()).hasSize(2);
|
||||
assertThat(bean.getNestedTestBeans().length).isEqualTo(2);
|
||||
assertThat(bean.getNestedTestBeans()[0]).isSameAs(ntb2);
|
||||
assertThat(bean.getNestedTestBeans()[1]).isSameAs(ntb1);
|
||||
assertThat(bean.nestedTestBeansField).hasSize(2);
|
||||
assertThat(bean.nestedTestBeansField.length).isEqualTo(2);
|
||||
assertThat(bean.nestedTestBeansField[0]).isSameAs(ntb2);
|
||||
assertThat(bean.nestedTestBeansField[1]).isSameAs(ntb1);
|
||||
}
|
||||
@@ -522,10 +522,10 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
assertThat(bean.getTestBean3()).isSameAs(tb);
|
||||
assertThat(bean.getTestBean4()).isSameAs(tb);
|
||||
assertThat(bean.getIndexedTestBean()).isSameAs(itb);
|
||||
assertThat(bean.getNestedTestBeans()).hasSize(2);
|
||||
assertThat(bean.getNestedTestBeans().length).isEqualTo(2);
|
||||
assertThat(bean.getNestedTestBeans()[0]).isSameAs(ntb2);
|
||||
assertThat(bean.getNestedTestBeans()[1]).isSameAs(ntb1);
|
||||
assertThat(bean.nestedTestBeansField).hasSize(2);
|
||||
assertThat(bean.nestedTestBeansField.length).isEqualTo(2);
|
||||
assertThat(bean.nestedTestBeansField[0]).isSameAs(ntb2);
|
||||
assertThat(bean.nestedTestBeansField[1]).isSameAs(ntb1);
|
||||
}
|
||||
@@ -554,13 +554,13 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
assertThat(bean.getTestBean3()).isSameAs(tb);
|
||||
assertThat(bean.getTestBean4()).isSameAs(tb);
|
||||
assertThat(bean.getIndexedTestBean()).isSameAs(itb);
|
||||
assertThat(bean.getNestedTestBeans()).hasSize(2);
|
||||
assertThat(bean.getNestedTestBeans().size()).isEqualTo(2);
|
||||
assertThat(bean.getNestedTestBeans().get(0)).isSameAs(ntb2);
|
||||
assertThat(bean.getNestedTestBeans().get(1)).isSameAs(ntb1);
|
||||
assertThat(bean.nestedTestBeansSetter).hasSize(2);
|
||||
assertThat(bean.nestedTestBeansSetter.size()).isEqualTo(2);
|
||||
assertThat(bean.nestedTestBeansSetter.get(0)).isSameAs(ntb2);
|
||||
assertThat(bean.nestedTestBeansSetter.get(1)).isSameAs(ntb1);
|
||||
assertThat(bean.nestedTestBeansField).hasSize(2);
|
||||
assertThat(bean.nestedTestBeansField.size()).isEqualTo(2);
|
||||
assertThat(bean.nestedTestBeansField.get(0)).isSameAs(ntb2);
|
||||
assertThat(bean.nestedTestBeansField.get(1)).isSameAs(ntb1);
|
||||
}
|
||||
@@ -587,13 +587,13 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
assertThat(bean.getTestBean3()).isSameAs(tb);
|
||||
assertThat(bean.getTestBean4()).isSameAs(tb);
|
||||
assertThat(bean.getIndexedTestBean()).isSameAs(itb);
|
||||
assertThat(bean.getNestedTestBeans()).hasSize(2);
|
||||
assertThat(bean.getNestedTestBeans().size()).isEqualTo(2);
|
||||
assertThat(bean.getNestedTestBeans().get(0)).isSameAs(ntb2);
|
||||
assertThat(bean.getNestedTestBeans().get(1)).isSameAs(ntb1);
|
||||
assertThat(bean.nestedTestBeansSetter).hasSize(2);
|
||||
assertThat(bean.nestedTestBeansSetter.size()).isEqualTo(2);
|
||||
assertThat(bean.nestedTestBeansSetter.get(0)).isSameAs(ntb2);
|
||||
assertThat(bean.nestedTestBeansSetter.get(1)).isSameAs(ntb1);
|
||||
assertThat(bean.nestedTestBeansField).hasSize(2);
|
||||
assertThat(bean.nestedTestBeansField.size()).isEqualTo(2);
|
||||
assertThat(bean.nestedTestBeansField.get(0)).isSameAs(ntb2);
|
||||
assertThat(bean.nestedTestBeansField.get(1)).isSameAs(ntb1);
|
||||
}
|
||||
@@ -772,7 +772,7 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
ConstructorsResourceInjectionBean bean = (ConstructorsResourceInjectionBean) bf.getBean("annotatedBean");
|
||||
assertThat(bean.getTestBean3()).isNull();
|
||||
assertThat(bean.getTestBean4()).isSameAs(tb);
|
||||
assertThat(bean.getNestedTestBeans()).hasSize(2);
|
||||
assertThat(bean.getNestedTestBeans().length).isEqualTo(2);
|
||||
assertThat(bean.getNestedTestBeans()[0]).isSameAs(ntb1);
|
||||
assertThat(bean.getNestedTestBeans()[1]).isSameAs(ntb2);
|
||||
}
|
||||
@@ -798,7 +798,7 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
ConstructorsCollectionResourceInjectionBean bean = (ConstructorsCollectionResourceInjectionBean) bf.getBean("annotatedBean");
|
||||
assertThat(bean.getTestBean3()).isNull();
|
||||
assertThat(bean.getTestBean4()).isSameAs(tb);
|
||||
assertThat(bean.getNestedTestBeans()).hasSize(1);
|
||||
assertThat(bean.getNestedTestBeans().size()).isEqualTo(1);
|
||||
assertThat(bean.getNestedTestBeans().get(0)).isSameAs(ntb2);
|
||||
|
||||
Map<String, NestedTestBean> map = bf.getBeansOfType(NestedTestBean.class);
|
||||
@@ -820,7 +820,7 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
ConstructorsCollectionResourceInjectionBean bean = (ConstructorsCollectionResourceInjectionBean) bf.getBean("annotatedBean");
|
||||
assertThat(bean.getTestBean3()).isNull();
|
||||
assertThat(bean.getTestBean4()).isSameAs(tb);
|
||||
assertThat(bean.getNestedTestBeans()).hasSize(2);
|
||||
assertThat(bean.getNestedTestBeans().size()).isEqualTo(2);
|
||||
assertThat(bean.getNestedTestBeans().get(0)).isSameAs(ntb1);
|
||||
assertThat(bean.getNestedTestBeans().get(1)).isSameAs(ntb2);
|
||||
}
|
||||
@@ -838,7 +838,7 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
ConstructorsResourceInjectionBean bean = (ConstructorsResourceInjectionBean) bf.getBean("annotatedBean");
|
||||
assertThat(bean.getTestBean3()).isNull();
|
||||
assertThat(bean.getTestBean4()).isSameAs(tb);
|
||||
assertThat(bean.getNestedTestBeans()).hasSize(2);
|
||||
assertThat(bean.getNestedTestBeans().length).isEqualTo(2);
|
||||
assertThat(bean.getNestedTestBeans()[0]).isSameAs(ntb2);
|
||||
assertThat(bean.getNestedTestBeans()[1]).isSameAs(ntb1);
|
||||
}
|
||||
@@ -856,7 +856,7 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
ConstructorsCollectionResourceInjectionBean bean = (ConstructorsCollectionResourceInjectionBean) bf.getBean("annotatedBean");
|
||||
assertThat(bean.getTestBean3()).isNull();
|
||||
assertThat(bean.getTestBean4()).isSameAs(tb);
|
||||
assertThat(bean.getNestedTestBeans()).hasSize(2);
|
||||
assertThat(bean.getNestedTestBeans().size()).isEqualTo(2);
|
||||
assertThat(bean.getNestedTestBeans().get(0)).isSameAs(ntb2);
|
||||
assertThat(bean.getNestedTestBeans().get(1)).isSameAs(ntb1);
|
||||
}
|
||||
@@ -873,7 +873,7 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
|
||||
SingleConstructorVarargBean bean = (SingleConstructorVarargBean) bf.getBean("annotatedBean");
|
||||
assertThat(bean.getTestBean()).isSameAs(tb);
|
||||
assertThat(bean.getNestedTestBeans()).hasSize(2);
|
||||
assertThat(bean.getNestedTestBeans().size()).isEqualTo(2);
|
||||
assertThat(bean.getNestedTestBeans().get(0)).isSameAs(ntb2);
|
||||
assertThat(bean.getNestedTestBeans().get(1)).isSameAs(ntb1);
|
||||
}
|
||||
@@ -902,7 +902,7 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
|
||||
SingleConstructorRequiredCollectionBean bean = (SingleConstructorRequiredCollectionBean) bf.getBean("annotatedBean");
|
||||
assertThat(bean.getTestBean()).isSameAs(tb);
|
||||
assertThat(bean.getNestedTestBeans()).hasSize(2);
|
||||
assertThat(bean.getNestedTestBeans().size()).isEqualTo(2);
|
||||
assertThat(bean.getNestedTestBeans().get(0)).isSameAs(ntb2);
|
||||
assertThat(bean.getNestedTestBeans().get(1)).isSameAs(ntb1);
|
||||
}
|
||||
@@ -931,7 +931,7 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
|
||||
SingleConstructorOptionalCollectionBean bean = (SingleConstructorOptionalCollectionBean) bf.getBean("annotatedBean");
|
||||
assertThat(bean.getTestBean()).isSameAs(tb);
|
||||
assertThat(bean.getNestedTestBeans()).hasSize(2);
|
||||
assertThat(bean.getNestedTestBeans().size()).isEqualTo(2);
|
||||
assertThat(bean.getNestedTestBeans().get(0)).isSameAs(ntb2);
|
||||
assertThat(bean.getNestedTestBeans().get(1)).isSameAs(ntb1);
|
||||
}
|
||||
@@ -996,12 +996,12 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
bf.registerBeanDefinition("testBean2", tb2);
|
||||
|
||||
MapConstructorInjectionBean bean = (MapConstructorInjectionBean) bf.getBean("annotatedBean");
|
||||
assertThat(bean.getTestBeanMap()).hasSize(1);
|
||||
assertThat(bean.getTestBeanMap().size()).isEqualTo(1);
|
||||
assertThat(bean.getTestBeanMap().get("testBean1")).isSameAs(tb1);
|
||||
assertThat(bean.getTestBeanMap().get("testBean2")).isNull();
|
||||
|
||||
bean = (MapConstructorInjectionBean) bf.getBean("annotatedBean");
|
||||
assertThat(bean.getTestBeanMap()).hasSize(1);
|
||||
assertThat(bean.getTestBeanMap().size()).isEqualTo(1);
|
||||
assertThat(bean.getTestBeanMap().get("testBean1")).isSameAs(tb1);
|
||||
assertThat(bean.getTestBeanMap().get("testBean2")).isNull();
|
||||
}
|
||||
@@ -1017,14 +1017,14 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
bf.registerSingleton("testBean2", tb2);
|
||||
|
||||
MapFieldInjectionBean bean = (MapFieldInjectionBean) bf.getBean("annotatedBean");
|
||||
assertThat(bean.getTestBeanMap()).hasSize(2);
|
||||
assertThat(bean.getTestBeanMap().size()).isEqualTo(2);
|
||||
assertThat(bean.getTestBeanMap().keySet().contains("testBean1")).isTrue();
|
||||
assertThat(bean.getTestBeanMap().keySet().contains("testBean2")).isTrue();
|
||||
assertThat(bean.getTestBeanMap().values().contains(tb1)).isTrue();
|
||||
assertThat(bean.getTestBeanMap().values().contains(tb2)).isTrue();
|
||||
|
||||
bean = (MapFieldInjectionBean) bf.getBean("annotatedBean");
|
||||
assertThat(bean.getTestBeanMap()).hasSize(2);
|
||||
assertThat(bean.getTestBeanMap().size()).isEqualTo(2);
|
||||
assertThat(bean.getTestBeanMap().keySet().contains("testBean1")).isTrue();
|
||||
assertThat(bean.getTestBeanMap().keySet().contains("testBean2")).isTrue();
|
||||
assertThat(bean.getTestBeanMap().values().contains(tb1)).isTrue();
|
||||
@@ -1040,13 +1040,13 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
bf.registerSingleton("testBean", tb);
|
||||
|
||||
MapMethodInjectionBean bean = (MapMethodInjectionBean) bf.getBean("annotatedBean");
|
||||
assertThat(bean.getTestBeanMap()).hasSize(1);
|
||||
assertThat(bean.getTestBeanMap().size()).isEqualTo(1);
|
||||
assertThat(bean.getTestBeanMap().keySet().contains("testBean")).isTrue();
|
||||
assertThat(bean.getTestBeanMap().values().contains(tb)).isTrue();
|
||||
assertThat(bean.getTestBean()).isSameAs(tb);
|
||||
|
||||
bean = (MapMethodInjectionBean) bf.getBean("annotatedBean");
|
||||
assertThat(bean.getTestBeanMap()).hasSize(1);
|
||||
assertThat(bean.getTestBeanMap().size()).isEqualTo(1);
|
||||
assertThat(bean.getTestBeanMap().keySet().contains("testBean")).isTrue();
|
||||
assertThat(bean.getTestBeanMap().values().contains(tb)).isTrue();
|
||||
assertThat(bean.getTestBean()).isSameAs(tb);
|
||||
@@ -1072,7 +1072,7 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
|
||||
MapMethodInjectionBean bean = (MapMethodInjectionBean) bf.getBean("annotatedBean");
|
||||
TestBean tb = (TestBean) bf.getBean("testBean1");
|
||||
assertThat(bean.getTestBeanMap()).hasSize(1);
|
||||
assertThat(bean.getTestBeanMap().size()).isEqualTo(1);
|
||||
assertThat(bean.getTestBeanMap().keySet().contains("testBean1")).isTrue();
|
||||
assertThat(bean.getTestBeanMap().values().contains(tb)).isTrue();
|
||||
assertThat(bean.getTestBean()).isSameAs(tb);
|
||||
@@ -1215,7 +1215,7 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
SelfInjectionBean bean = (SelfInjectionBean) bf.getBean("annotatedBean");
|
||||
SelfInjectionBean bean2 = (SelfInjectionBean) bf.getBean("annotatedBean2");
|
||||
assertThat(bean.reference).isSameAs(bean2);
|
||||
assertThat(bean.referenceCollection).hasSize(1);
|
||||
assertThat(bean.referenceCollection.size()).isEqualTo(1);
|
||||
assertThat(bean.referenceCollection.get(0)).isSameAs(bean2);
|
||||
}
|
||||
|
||||
@@ -1326,16 +1326,16 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
assertThat(bean.consumeUniqueTestBean()).isEqualTo(bf.getBean("testBean"));
|
||||
|
||||
List<?> testBeans = bean.iterateTestBeans();
|
||||
assertThat(testBeans).hasSize(1);
|
||||
assertThat(testBeans.size()).isEqualTo(1);
|
||||
assertThat(testBeans.contains(bf.getBean("testBean"))).isTrue();
|
||||
testBeans = bean.forEachTestBeans();
|
||||
assertThat(testBeans).hasSize(1);
|
||||
assertThat(testBeans.size()).isEqualTo(1);
|
||||
assertThat(testBeans.contains(bf.getBean("testBean"))).isTrue();
|
||||
testBeans = bean.streamTestBeans();
|
||||
assertThat(testBeans).hasSize(1);
|
||||
assertThat(testBeans.size()).isEqualTo(1);
|
||||
assertThat(testBeans.contains(bf.getBean("testBean"))).isTrue();
|
||||
testBeans = bean.sortedTestBeans();
|
||||
assertThat(testBeans).hasSize(1);
|
||||
assertThat(testBeans.size()).isEqualTo(1);
|
||||
assertThat(testBeans.contains(bf.getBean("testBean"))).isTrue();
|
||||
}
|
||||
|
||||
@@ -1354,16 +1354,16 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
assertThat(bean.consumeUniqueTestBean()).isEqualTo(bf.getBean("testBean"));
|
||||
|
||||
List<?> testBeans = bean.iterateTestBeans();
|
||||
assertThat(testBeans).hasSize(1);
|
||||
assertThat(testBeans.size()).isEqualTo(1);
|
||||
assertThat(testBeans.contains(bf.getBean("testBean"))).isTrue();
|
||||
testBeans = bean.forEachTestBeans();
|
||||
assertThat(testBeans).hasSize(1);
|
||||
assertThat(testBeans.size()).isEqualTo(1);
|
||||
assertThat(testBeans.contains(bf.getBean("testBean"))).isTrue();
|
||||
testBeans = bean.streamTestBeans();
|
||||
assertThat(testBeans).hasSize(1);
|
||||
assertThat(testBeans.size()).isEqualTo(1);
|
||||
assertThat(testBeans.contains(bf.getBean("testBean"))).isTrue();
|
||||
testBeans = bean.sortedTestBeans();
|
||||
assertThat(testBeans).hasSize(1);
|
||||
assertThat(testBeans.size()).isEqualTo(1);
|
||||
assertThat(testBeans.contains(bf.getBean("testBean"))).isTrue();
|
||||
}
|
||||
|
||||
@@ -1405,19 +1405,19 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
assertThat(bean.consumeUniqueTestBean()).isNull();
|
||||
|
||||
List<?> testBeans = bean.iterateTestBeans();
|
||||
assertThat(testBeans).hasSize(2);
|
||||
assertThat(testBeans.size()).isEqualTo(2);
|
||||
assertThat(testBeans.get(0)).isSameAs(bf.getBean("testBean1"));
|
||||
assertThat(testBeans.get(1)).isSameAs(bf.getBean("testBean2"));
|
||||
testBeans = bean.forEachTestBeans();
|
||||
assertThat(testBeans).hasSize(2);
|
||||
assertThat(testBeans.size()).isEqualTo(2);
|
||||
assertThat(testBeans.get(0)).isSameAs(bf.getBean("testBean1"));
|
||||
assertThat(testBeans.get(1)).isSameAs(bf.getBean("testBean2"));
|
||||
testBeans = bean.streamTestBeans();
|
||||
assertThat(testBeans).hasSize(2);
|
||||
assertThat(testBeans.size()).isEqualTo(2);
|
||||
assertThat(testBeans.get(0)).isSameAs(bf.getBean("testBean1"));
|
||||
assertThat(testBeans.get(1)).isSameAs(bf.getBean("testBean2"));
|
||||
testBeans = bean.sortedTestBeans();
|
||||
assertThat(testBeans).hasSize(2);
|
||||
assertThat(testBeans.size()).isEqualTo(2);
|
||||
assertThat(testBeans.get(0)).isSameAs(bf.getBean("testBean1"));
|
||||
assertThat(testBeans.get(1)).isSameAs(bf.getBean("testBean2"));
|
||||
}
|
||||
@@ -1443,19 +1443,19 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
assertThat(bf.containsSingleton("testBean2")).isFalse();
|
||||
|
||||
List<?> testBeans = bean.iterateTestBeans();
|
||||
assertThat(testBeans).hasSize(2);
|
||||
assertThat(testBeans.size()).isEqualTo(2);
|
||||
assertThat(testBeans.get(0)).isSameAs(bf.getBean("testBean1"));
|
||||
assertThat(testBeans.get(1)).isSameAs(bf.getBean("testBean2"));
|
||||
testBeans = bean.forEachTestBeans();
|
||||
assertThat(testBeans).hasSize(2);
|
||||
assertThat(testBeans.size()).isEqualTo(2);
|
||||
assertThat(testBeans.get(0)).isSameAs(bf.getBean("testBean1"));
|
||||
assertThat(testBeans.get(1)).isSameAs(bf.getBean("testBean2"));
|
||||
testBeans = bean.streamTestBeans();
|
||||
assertThat(testBeans).hasSize(2);
|
||||
assertThat(testBeans.size()).isEqualTo(2);
|
||||
assertThat(testBeans.get(0)).isSameAs(bf.getBean("testBean1"));
|
||||
assertThat(testBeans.get(1)).isSameAs(bf.getBean("testBean2"));
|
||||
testBeans = bean.sortedTestBeans();
|
||||
assertThat(testBeans).hasSize(2);
|
||||
assertThat(testBeans.size()).isEqualTo(2);
|
||||
assertThat(testBeans.get(0)).isSameAs(bf.getBean("testBean2"));
|
||||
assertThat(testBeans.get(1)).isSameAs(bf.getBean("testBean1"));
|
||||
}
|
||||
@@ -1474,7 +1474,7 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
|
||||
ObjectProviderInjectionBean bean = (ObjectProviderInjectionBean) bf.getBean("annotatedBean");
|
||||
List<?> testBeans = bean.sortedTestBeans();
|
||||
assertThat(testBeans).hasSize(2);
|
||||
assertThat(testBeans.size()).isEqualTo(2);
|
||||
assertThat(testBeans.get(0)).isSameAs(bf.getBean("testBean2"));
|
||||
assertThat(testBeans.get(1)).isSameAs(bf.getBean("testBean1"));
|
||||
}
|
||||
|
||||
+8
-8
@@ -195,7 +195,7 @@ public class InjectAnnotationBeanPostProcessorTests {
|
||||
ConstructorsCollectionResourceInjectionBean bean = (ConstructorsCollectionResourceInjectionBean) bf.getBean("annotatedBean");
|
||||
assertThat(bean.getTestBean3()).isNull();
|
||||
assertThat(bean.getTestBean4()).isSameAs(tb);
|
||||
assertThat(bean.getNestedTestBeans()).hasSize(2);
|
||||
assertThat(bean.getNestedTestBeans().size()).isEqualTo(2);
|
||||
assertThat(bean.getNestedTestBeans().get(0)).isSameAs(ntb1);
|
||||
assertThat(bean.getNestedTestBeans().get(1)).isSameAs(ntb2);
|
||||
}
|
||||
@@ -222,14 +222,14 @@ public class InjectAnnotationBeanPostProcessorTests {
|
||||
bf.registerSingleton("testBean2", tb1);
|
||||
|
||||
MapConstructorInjectionBean bean = (MapConstructorInjectionBean) bf.getBean("annotatedBean");
|
||||
assertThat(bean.getTestBeanMap()).hasSize(2);
|
||||
assertThat(bean.getTestBeanMap().size()).isEqualTo(2);
|
||||
assertThat(bean.getTestBeanMap().keySet().contains("testBean1")).isTrue();
|
||||
assertThat(bean.getTestBeanMap().keySet().contains("testBean2")).isTrue();
|
||||
assertThat(bean.getTestBeanMap().values().contains(tb1)).isTrue();
|
||||
assertThat(bean.getTestBeanMap().values().contains(tb2)).isTrue();
|
||||
|
||||
bean = (MapConstructorInjectionBean) bf.getBean("annotatedBean");
|
||||
assertThat(bean.getTestBeanMap()).hasSize(2);
|
||||
assertThat(bean.getTestBeanMap().size()).isEqualTo(2);
|
||||
assertThat(bean.getTestBeanMap().keySet().contains("testBean1")).isTrue();
|
||||
assertThat(bean.getTestBeanMap().keySet().contains("testBean2")).isTrue();
|
||||
assertThat(bean.getTestBeanMap().values().contains(tb1)).isTrue();
|
||||
@@ -247,14 +247,14 @@ public class InjectAnnotationBeanPostProcessorTests {
|
||||
bf.registerSingleton("testBean2", tb1);
|
||||
|
||||
MapFieldInjectionBean bean = (MapFieldInjectionBean) bf.getBean("annotatedBean");
|
||||
assertThat(bean.getTestBeanMap()).hasSize(2);
|
||||
assertThat(bean.getTestBeanMap().size()).isEqualTo(2);
|
||||
assertThat(bean.getTestBeanMap().keySet().contains("testBean1")).isTrue();
|
||||
assertThat(bean.getTestBeanMap().keySet().contains("testBean2")).isTrue();
|
||||
assertThat(bean.getTestBeanMap().values().contains(tb1)).isTrue();
|
||||
assertThat(bean.getTestBeanMap().values().contains(tb2)).isTrue();
|
||||
|
||||
bean = (MapFieldInjectionBean) bf.getBean("annotatedBean");
|
||||
assertThat(bean.getTestBeanMap()).hasSize(2);
|
||||
assertThat(bean.getTestBeanMap().size()).isEqualTo(2);
|
||||
assertThat(bean.getTestBeanMap().keySet().contains("testBean1")).isTrue();
|
||||
assertThat(bean.getTestBeanMap().keySet().contains("testBean2")).isTrue();
|
||||
assertThat(bean.getTestBeanMap().values().contains(tb1)).isTrue();
|
||||
@@ -270,13 +270,13 @@ public class InjectAnnotationBeanPostProcessorTests {
|
||||
bf.registerSingleton("testBean", tb);
|
||||
|
||||
MapMethodInjectionBean bean = (MapMethodInjectionBean) bf.getBean("annotatedBean");
|
||||
assertThat(bean.getTestBeanMap()).hasSize(1);
|
||||
assertThat(bean.getTestBeanMap().size()).isEqualTo(1);
|
||||
assertThat(bean.getTestBeanMap().keySet().contains("testBean")).isTrue();
|
||||
assertThat(bean.getTestBeanMap().values().contains(tb)).isTrue();
|
||||
assertThat(bean.getTestBean()).isSameAs(tb);
|
||||
|
||||
bean = (MapMethodInjectionBean) bf.getBean("annotatedBean");
|
||||
assertThat(bean.getTestBeanMap()).hasSize(1);
|
||||
assertThat(bean.getTestBeanMap().size()).isEqualTo(1);
|
||||
assertThat(bean.getTestBeanMap().keySet().contains("testBean")).isTrue();
|
||||
assertThat(bean.getTestBeanMap().values().contains(tb)).isTrue();
|
||||
assertThat(bean.getTestBean()).isSameAs(tb);
|
||||
@@ -301,7 +301,7 @@ public class InjectAnnotationBeanPostProcessorTests {
|
||||
|
||||
MapMethodInjectionBean bean = (MapMethodInjectionBean) bf.getBean("annotatedBean");
|
||||
TestBean tb = (TestBean) bf.getBean("testBean1");
|
||||
assertThat(bean.getTestBeanMap()).hasSize(1);
|
||||
assertThat(bean.getTestBeanMap().size()).isEqualTo(1);
|
||||
assertThat(bean.getTestBeanMap().keySet().contains("testBean1")).isTrue();
|
||||
assertThat(bean.getTestBeanMap().values().contains(tb)).isTrue();
|
||||
assertThat(bean.getTestBean()).isSameAs(tb);
|
||||
|
||||
+6
-6
@@ -399,19 +399,19 @@ public class PropertyResourceConfigurerTests {
|
||||
assertThat(tb1.getName()).isEqualTo("namemyvarmyvar${");
|
||||
assertThat(tb2.getName()).isEqualTo("myvarname98");
|
||||
assertThat(tb1.getSpouse()).isEqualTo(tb2);
|
||||
assertThat(tb1.getSomeMap()).hasSize(1);
|
||||
assertThat(tb1.getSomeMap().size()).isEqualTo(1);
|
||||
assertThat(tb1.getSomeMap().get("myKey")).isEqualTo("myValue");
|
||||
assertThat(tb2.getStringArray()).hasSize(2);
|
||||
assertThat(tb2.getStringArray().length).isEqualTo(2);
|
||||
assertThat(tb2.getStringArray()[0]).isEqualTo(System.getProperty("os.name"));
|
||||
assertThat(tb2.getStringArray()[1]).isEqualTo("98");
|
||||
assertThat(tb2.getFriends()).hasSize(2);
|
||||
assertThat(tb2.getFriends().size()).isEqualTo(2);
|
||||
assertThat(tb2.getFriends().iterator().next()).isEqualTo("na98me");
|
||||
assertThat(tb2.getFriends().toArray()[1]).isEqualTo(tb2);
|
||||
assertThat(tb2.getSomeSet()).hasSize(3);
|
||||
assertThat(tb2.getSomeSet().size()).isEqualTo(3);
|
||||
assertThat(tb2.getSomeSet().contains("na98me")).isTrue();
|
||||
assertThat(tb2.getSomeSet().contains(tb2)).isTrue();
|
||||
assertThat(tb2.getSomeSet().contains(98)).isTrue();
|
||||
assertThat(tb2.getSomeMap()).hasSize(6);
|
||||
assertThat(tb2.getSomeMap().size()).isEqualTo(6);
|
||||
assertThat(tb2.getSomeMap().get("key98")).isEqualTo("98");
|
||||
assertThat(tb2.getSomeMap().get("key98ref")).isEqualTo(tb2);
|
||||
assertThat(tb2.getSomeMap().get("key1")).isEqualTo(tb2);
|
||||
@@ -577,7 +577,7 @@ public class PropertyResourceConfigurerTests {
|
||||
|
||||
TestBean tb = (TestBean) factory.getBean("tb");
|
||||
assertThat(tb).isNotNull();
|
||||
assertThat(factory.getAliases("tb")).isEmpty();
|
||||
assertThat(factory.getAliases("tb").length).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+1
-1
@@ -63,7 +63,7 @@ public class SimpleScopeTests {
|
||||
beanFactory.registerScope("myScope", scope);
|
||||
|
||||
String[] scopeNames = beanFactory.getRegisteredScopeNames();
|
||||
assertThat(scopeNames).hasSize(1);
|
||||
assertThat(scopeNames.length).isEqualTo(1);
|
||||
assertThat(scopeNames[0]).isEqualTo("myScope");
|
||||
assertThat(beanFactory.getRegisteredScope("myScope")).isSameAs(scope);
|
||||
|
||||
|
||||
+8
-8
@@ -47,7 +47,7 @@ public class YamlMapFactoryBeanTests {
|
||||
public void testSetIgnoreResourceNotFound() {
|
||||
this.factory.setResolutionMethod(YamlMapFactoryBean.ResolutionMethod.OVERRIDE_AND_IGNORE);
|
||||
this.factory.setResources(new FileSystemResource("non-exsitent-file.yml"));
|
||||
assertThat(this.factory.getObject()).isEmpty();
|
||||
assertThat(this.factory.getObject().size()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -61,7 +61,7 @@ public class YamlMapFactoryBeanTests {
|
||||
@Test
|
||||
public void testGetObject() {
|
||||
this.factory.setResources(new ByteArrayResource("foo: bar".getBytes()));
|
||||
assertThat(this.factory.getObject()).hasSize(1);
|
||||
assertThat(this.factory.getObject().size()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -70,8 +70,8 @@ public class YamlMapFactoryBeanTests {
|
||||
this.factory.setResources(new ByteArrayResource("foo:\n bar: spam".getBytes()),
|
||||
new ByteArrayResource("foo:\n spam: bar".getBytes()));
|
||||
|
||||
assertThat(this.factory.getObject()).hasSize(1);
|
||||
assertThat(((Map<String, Object>) this.factory.getObject().get("foo"))).hasSize(2);
|
||||
assertThat(this.factory.getObject().size()).isEqualTo(1);
|
||||
assertThat(((Map<String, Object>) this.factory.getObject().get("foo")).size()).isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -88,7 +88,7 @@ public class YamlMapFactoryBeanTests {
|
||||
}
|
||||
}, new ByteArrayResource("foo:\n spam: bar".getBytes()));
|
||||
|
||||
assertThat(this.factory.getObject()).hasSize(1);
|
||||
assertThat(this.factory.getObject().size()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -96,7 +96,7 @@ public class YamlMapFactoryBeanTests {
|
||||
this.factory.setResources(new ByteArrayResource("foo:\n ? key1.key2\n : value".getBytes()));
|
||||
Map<String, Object> map = this.factory.getObject();
|
||||
|
||||
assertThat(map).hasSize(1);
|
||||
assertThat(map.size()).isEqualTo(1);
|
||||
assertThat(map.containsKey("foo")).isTrue();
|
||||
Object object = map.get("foo");
|
||||
boolean condition = object instanceof LinkedHashMap;
|
||||
@@ -112,14 +112,14 @@ public class YamlMapFactoryBeanTests {
|
||||
this.factory.setResources(new ByteArrayResource("foo:\n ? key1.key2\n : 3".getBytes()));
|
||||
Map<String, Object> map = this.factory.getObject();
|
||||
|
||||
assertThat(map).hasSize(1);
|
||||
assertThat(map.size()).isEqualTo(1);
|
||||
assertThat(map.containsKey("foo")).isTrue();
|
||||
Object object = map.get("foo");
|
||||
boolean condition = object instanceof LinkedHashMap;
|
||||
assertThat(condition).isTrue();
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> sub = (Map<String, Object>) object;
|
||||
assertThat(sub).hasSize(1);
|
||||
assertThat(sub.size()).isEqualTo(1);
|
||||
assertThat(sub.get("key1.key2")).isEqualTo(3);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -52,7 +52,7 @@ class YamlProcessorTests {
|
||||
void arrayConvertedToIndexedBeanReference() {
|
||||
setYaml("foo: bar\nbar: [1,2,3]");
|
||||
this.processor.process((properties, map) -> {
|
||||
assertThat(properties).hasSize(4);
|
||||
assertThat(properties.size()).isEqualTo(4);
|
||||
assertThat(properties.get("foo")).isEqualTo("bar");
|
||||
assertThat(properties.getProperty("foo")).isEqualTo("bar");
|
||||
assertThat(properties.get("bar[0]")).isEqualTo(1);
|
||||
|
||||
+1
-1
@@ -181,7 +181,7 @@ public class BeanDefinitionTests {
|
||||
RootBeanDefinition mergedBd = new RootBeanDefinition(bd);
|
||||
mergedBd.overrideFrom(childBd);
|
||||
assertThat(mergedBd.getConstructorArgumentValues().getArgumentCount()).isEqualTo(2);
|
||||
assertThat(mergedBd.getPropertyValues()).hasSize(2);
|
||||
assertThat(mergedBd.getPropertyValues().size()).isEqualTo(2);
|
||||
assertThat(mergedBd).isEqualTo(bd);
|
||||
|
||||
mergedBd.getConstructorArgumentValues().getArgumentValue(1, null).setValue(9);
|
||||
|
||||
+22
-22
@@ -166,7 +166,7 @@ class BeanFactoryGenericsTests {
|
||||
new ClassPathResource("genericBeanTests.xml", getClass()));
|
||||
GenericBean<?> gb = (GenericBean<?>) bf.getBean("listOfArrays");
|
||||
|
||||
assertThat(gb.getListOfArrays()).hasSize(1);
|
||||
assertThat(gb.getListOfArrays().size()).isEqualTo(1);
|
||||
String[] array = gb.getListOfArrays().get(0);
|
||||
assertThat(array).hasSize(2);
|
||||
assertThat(array[0]).isEqualTo("value1");
|
||||
@@ -338,7 +338,7 @@ class BeanFactoryGenericsTests {
|
||||
assertThat(gb.getPlainMap()).hasSize(2);
|
||||
assertThat(gb.getPlainMap().get("1")).isEqualTo("0");
|
||||
assertThat(gb.getPlainMap().get("2")).isEqualTo("3");
|
||||
assertThat(gb.getShortMap()).hasSize(2);
|
||||
assertThat(gb.getShortMap().size()).isEqualTo(2);
|
||||
assertThat(gb.getShortMap().get(Short.valueOf("4"))).isEqualTo(5);
|
||||
assertThat(gb.getShortMap().get(Short.valueOf("6"))).isEqualTo(7);
|
||||
}
|
||||
@@ -361,7 +361,7 @@ class BeanFactoryGenericsTests {
|
||||
assertThat(gb.getPlainMap()).hasSize(2);
|
||||
assertThat(gb.getPlainMap().get("1")).isEqualTo("0");
|
||||
assertThat(gb.getPlainMap().get("2")).isEqualTo("3");
|
||||
assertThat(gb.getShortMap()).hasSize(2);
|
||||
assertThat(gb.getShortMap().size()).isEqualTo(2);
|
||||
assertThat(gb.getShortMap().get(Short.valueOf("1"))).isEqualTo(0);
|
||||
assertThat(gb.getShortMap().get(Short.valueOf("2"))).isEqualTo(3);
|
||||
}
|
||||
@@ -589,7 +589,7 @@ class BeanFactoryGenericsTests {
|
||||
new XmlBeanDefinitionReader(bf).loadBeanDefinitions(
|
||||
new ClassPathResource("genericBeanTests.xml", getClass()));
|
||||
List<?> list = (List<?>) bf.getBean("list");
|
||||
assertThat(list).hasSize(1);
|
||||
assertThat(list.size()).isEqualTo(1);
|
||||
assertThat(list.get(0)).isEqualTo(new URL("http://localhost:8080"));
|
||||
}
|
||||
|
||||
@@ -599,7 +599,7 @@ class BeanFactoryGenericsTests {
|
||||
new XmlBeanDefinitionReader(bf).loadBeanDefinitions(
|
||||
new ClassPathResource("genericBeanTests.xml", getClass()));
|
||||
Set<?> set = (Set<?>) bf.getBean("set");
|
||||
assertThat(set).hasSize(1);
|
||||
assertThat(set.size()).isEqualTo(1);
|
||||
assertThat(set.iterator().next()).isEqualTo(new URL("http://localhost:8080"));
|
||||
}
|
||||
|
||||
@@ -643,7 +643,7 @@ class BeanFactoryGenericsTests {
|
||||
new XmlBeanDefinitionReader(bf).loadBeanDefinitions(
|
||||
new ClassPathResource("genericBeanTests.xml", getClass()));
|
||||
UrlSet us = (UrlSet) bf.getBean("setBean");
|
||||
assertThat(us).hasSize(1);
|
||||
assertThat(us.size()).isEqualTo(1);
|
||||
assertThat(us.iterator().next()).isEqualTo(new URL("https://www.springframework.org"));
|
||||
}
|
||||
|
||||
@@ -762,7 +762,7 @@ class BeanFactoryGenericsTests {
|
||||
assertThat(bf.getType("mock")).isNull();
|
||||
assertThat(bf.getType("mock")).isNull();
|
||||
Map<String, Runnable> beans = bf.getBeansOfType(Runnable.class);
|
||||
assertThat(beans).isEmpty();
|
||||
assertThat(beans).hasSize(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -828,8 +828,8 @@ class BeanFactoryGenericsTests {
|
||||
assertThat(numberStoreNames).hasSize(2);
|
||||
assertThat(numberStoreNames[0]).isEqualTo("doubleStore");
|
||||
assertThat(numberStoreNames[1]).isEqualTo("floatStore");
|
||||
assertThat(doubleStoreNames).isEmpty();
|
||||
assertThat(floatStoreNames).isEmpty();
|
||||
assertThat(doubleStoreNames).hasSize(0);
|
||||
assertThat(floatStoreNames).hasSize(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -879,17 +879,17 @@ class BeanFactoryGenericsTests {
|
||||
for (NumberStore<?> instance : numberStoreProvider) {
|
||||
resolved.add(instance);
|
||||
}
|
||||
assertThat(resolved).hasSize(2);
|
||||
assertThat(resolved.size()).isEqualTo(2);
|
||||
assertThat(resolved.get(0)).isSameAs(bf.getBean("store1"));
|
||||
assertThat(resolved.get(1)).isSameAs(bf.getBean("store2"));
|
||||
|
||||
resolved = numberStoreProvider.stream().toList();
|
||||
assertThat(resolved).hasSize(2);
|
||||
assertThat(resolved.size()).isEqualTo(2);
|
||||
assertThat(resolved.get(0)).isSameAs(bf.getBean("store1"));
|
||||
assertThat(resolved.get(1)).isSameAs(bf.getBean("store2"));
|
||||
|
||||
resolved = numberStoreProvider.orderedStream().toList();
|
||||
assertThat(resolved).hasSize(2);
|
||||
assertThat(resolved.size()).isEqualTo(2);
|
||||
assertThat(resolved.get(0)).isSameAs(bf.getBean("store2"));
|
||||
assertThat(resolved.get(1)).isSameAs(bf.getBean("store1"));
|
||||
|
||||
@@ -897,30 +897,30 @@ class BeanFactoryGenericsTests {
|
||||
for (NumberStore<Double> instance : doubleStoreProvider) {
|
||||
resolved.add(instance);
|
||||
}
|
||||
assertThat(resolved).hasSize(1);
|
||||
assertThat(resolved.size()).isEqualTo(1);
|
||||
assertThat(resolved.contains(bf.getBean("store1"))).isTrue();
|
||||
|
||||
resolved = doubleStoreProvider.stream().collect(Collectors.toList());
|
||||
assertThat(resolved).hasSize(1);
|
||||
assertThat(resolved.size()).isEqualTo(1);
|
||||
assertThat(resolved.contains(bf.getBean("store1"))).isTrue();
|
||||
|
||||
resolved = doubleStoreProvider.orderedStream().collect(Collectors.toList());
|
||||
assertThat(resolved).hasSize(1);
|
||||
assertThat(resolved.size()).isEqualTo(1);
|
||||
assertThat(resolved.contains(bf.getBean("store1"))).isTrue();
|
||||
|
||||
resolved = new ArrayList<>();
|
||||
for (NumberStore<Float> instance : floatStoreProvider) {
|
||||
resolved.add(instance);
|
||||
}
|
||||
assertThat(resolved).hasSize(1);
|
||||
assertThat(resolved.size()).isEqualTo(1);
|
||||
assertThat(resolved.contains(bf.getBean("store2"))).isTrue();
|
||||
|
||||
resolved = floatStoreProvider.stream().collect(Collectors.toList());
|
||||
assertThat(resolved).hasSize(1);
|
||||
assertThat(resolved.size()).isEqualTo(1);
|
||||
assertThat(resolved.contains(bf.getBean("store2"))).isTrue();
|
||||
|
||||
resolved = floatStoreProvider.orderedStream().collect(Collectors.toList());
|
||||
assertThat(resolved).hasSize(1);
|
||||
assertThat(resolved.size()).isEqualTo(1);
|
||||
assertThat(resolved.contains(bf.getBean("store2"))).isTrue();
|
||||
}
|
||||
|
||||
@@ -939,7 +939,7 @@ class BeanFactoryGenericsTests {
|
||||
|
||||
ObjectProvider<NumberStore<?>> numberStoreProvider = bf.getBeanProvider(ResolvableType.forClass(NumberStore.class));
|
||||
List<NumberStore<?>> resolved = numberStoreProvider.orderedStream().toList();
|
||||
assertThat(resolved).hasSize(2);
|
||||
assertThat(resolved.size()).isEqualTo(2);
|
||||
assertThat(resolved.get(0)).isSameAs(bf.getBean("store2"));
|
||||
assertThat(resolved.get(1)).isSameAs(bf.getBean("store1"));
|
||||
}
|
||||
@@ -963,9 +963,9 @@ class BeanFactoryGenericsTests {
|
||||
public static class CollectionDependentBean {
|
||||
|
||||
public CollectionDependentBean(NamedUrlList list, NamedUrlSet set, NamedUrlMap map) {
|
||||
assertThat(list).hasSize(1);
|
||||
assertThat(set).hasSize(1);
|
||||
assertThat(map).hasSize(1);
|
||||
assertThat(list.size()).isEqualTo(1);
|
||||
assertThat(set.size()).isEqualTo(1);
|
||||
assertThat(map.size()).isEqualTo(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -45,13 +45,13 @@ public class DefaultSingletonBeanRegistryTests {
|
||||
assertThat(beanRegistry.getSingleton("tb2")).isSameAs(tb2);
|
||||
assertThat(beanRegistry.getSingletonCount()).isEqualTo(2);
|
||||
String[] names = beanRegistry.getSingletonNames();
|
||||
assertThat(names).hasSize(2);
|
||||
assertThat(names.length).isEqualTo(2);
|
||||
assertThat(names[0]).isEqualTo("tb");
|
||||
assertThat(names[1]).isEqualTo("tb2");
|
||||
|
||||
beanRegistry.destroySingletons();
|
||||
assertThat(beanRegistry.getSingletonCount()).isEqualTo(0);
|
||||
assertThat(beanRegistry.getSingletonNames()).isEmpty();
|
||||
assertThat(beanRegistry.getSingletonNames().length).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -66,13 +66,13 @@ public class DefaultSingletonBeanRegistryTests {
|
||||
assertThat(beanRegistry.getSingleton("tb")).isSameAs(tb);
|
||||
assertThat(beanRegistry.getSingletonCount()).isEqualTo(1);
|
||||
String[] names = beanRegistry.getSingletonNames();
|
||||
assertThat(names).hasSize(1);
|
||||
assertThat(names.length).isEqualTo(1);
|
||||
assertThat(names[0]).isEqualTo("tb");
|
||||
assertThat(tb.wasDestroyed()).isFalse();
|
||||
|
||||
beanRegistry.destroySingletons();
|
||||
assertThat(beanRegistry.getSingletonCount()).isEqualTo(0);
|
||||
assertThat(beanRegistry.getSingletonNames()).isEmpty();
|
||||
assertThat(beanRegistry.getSingletonNames().length).isEqualTo(0);
|
||||
assertThat(tb.wasDestroyed()).isTrue();
|
||||
}
|
||||
|
||||
|
||||
+5
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -27,7 +27,7 @@ import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.config.ConstructorArgumentValues;
|
||||
import org.springframework.beans.factory.config.DependencyDescriptor;
|
||||
import org.springframework.core.DefaultParameterNameDiscoverer;
|
||||
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
@@ -148,7 +148,7 @@ public class QualifierAnnotationAutowireBeanFactoryTests {
|
||||
lbf.registerBeanDefinition(MARK, person2);
|
||||
MethodParameter param = new MethodParameter(QualifiedTestBean.class.getDeclaredConstructor(Person.class), 0);
|
||||
DependencyDescriptor qualifiedDescriptor = new DependencyDescriptor(param, false);
|
||||
param.initParameterNameDiscovery(new DefaultParameterNameDiscoverer());
|
||||
param.initParameterNameDiscovery(new LocalVariableTableParameterNameDiscoverer());
|
||||
assertThat(param.getParameterName()).isEqualTo("tpb");
|
||||
assertThat(lbf.isAutowireCandidate(JUERGEN, null)).isTrue();
|
||||
assertThat(lbf.isAutowireCandidate(JUERGEN, qualifiedDescriptor)).isTrue();
|
||||
@@ -174,9 +174,9 @@ public class QualifierAnnotationAutowireBeanFactoryTests {
|
||||
new MethodParameter(QualifiedTestBean.class.getDeclaredMethod("autowireNonqualified", Person.class), 0);
|
||||
DependencyDescriptor qualifiedDescriptor = new DependencyDescriptor(qualifiedParam, false);
|
||||
DependencyDescriptor nonqualifiedDescriptor = new DependencyDescriptor(nonqualifiedParam, false);
|
||||
qualifiedParam.initParameterNameDiscovery(new DefaultParameterNameDiscoverer());
|
||||
qualifiedParam.initParameterNameDiscovery(new LocalVariableTableParameterNameDiscoverer());
|
||||
assertThat(qualifiedParam.getParameterName()).isEqualTo("tpb");
|
||||
nonqualifiedParam.initParameterNameDiscovery(new DefaultParameterNameDiscoverer());
|
||||
nonqualifiedParam.initParameterNameDiscovery(new LocalVariableTableParameterNameDiscoverer());
|
||||
assertThat(nonqualifiedParam.getParameterName()).isEqualTo("tpb");
|
||||
assertThat(lbf.isAutowireCandidate(JUERGEN, null)).isTrue();
|
||||
assertThat(lbf.isAutowireCandidate(JUERGEN, nonqualifiedDescriptor)).isTrue();
|
||||
|
||||
+6
-6
@@ -65,7 +65,7 @@ public class CollectionMergingTests {
|
||||
TestBean bean = (TestBean) this.beanFactory.getBean("childWithListOfRefs");
|
||||
List<?> list = bean.getSomeList();
|
||||
assertThat(list).isNotNull();
|
||||
assertThat(list).hasSize(3);
|
||||
assertThat(list.size()).isEqualTo(3);
|
||||
assertThat(list.get(2)).isNotNull();
|
||||
boolean condition = list.get(2) instanceof TestBean;
|
||||
assertThat(condition).isTrue();
|
||||
@@ -85,7 +85,7 @@ public class CollectionMergingTests {
|
||||
TestBean bean = (TestBean) this.beanFactory.getBean("childWithSetOfRefs");
|
||||
Set<?> set = bean.getSomeSet();
|
||||
assertThat(set).isNotNull();
|
||||
assertThat(set).hasSize(2);
|
||||
assertThat(set.size()).isEqualTo(2);
|
||||
Iterator it = set.iterator();
|
||||
it.next();
|
||||
Object o = it.next();
|
||||
@@ -110,7 +110,7 @@ public class CollectionMergingTests {
|
||||
TestBean bean = (TestBean) this.beanFactory.getBean("childWithMapOfRefs");
|
||||
Map<?, ?> map = bean.getSomeMap();
|
||||
assertThat(map).isNotNull();
|
||||
assertThat(map).hasSize(2);
|
||||
assertThat(map.size()).isEqualTo(2);
|
||||
assertThat(map.get("Rob")).isNotNull();
|
||||
boolean condition = map.get("Rob") instanceof TestBean;
|
||||
assertThat(condition).isTrue();
|
||||
@@ -142,7 +142,7 @@ public class CollectionMergingTests {
|
||||
TestBean bean = (TestBean) this.beanFactory.getBean("childWithListOfRefsInConstructor");
|
||||
List<?> list = bean.getSomeList();
|
||||
assertThat(list).isNotNull();
|
||||
assertThat(list).hasSize(3);
|
||||
assertThat(list.size()).isEqualTo(3);
|
||||
assertThat(list.get(2)).isNotNull();
|
||||
boolean condition = list.get(2) instanceof TestBean;
|
||||
assertThat(condition).isTrue();
|
||||
@@ -162,7 +162,7 @@ public class CollectionMergingTests {
|
||||
TestBean bean = (TestBean) this.beanFactory.getBean("childWithSetOfRefsInConstructor");
|
||||
Set<?> set = bean.getSomeSet();
|
||||
assertThat(set).isNotNull();
|
||||
assertThat(set).hasSize(2);
|
||||
assertThat(set.size()).isEqualTo(2);
|
||||
Iterator it = set.iterator();
|
||||
it.next();
|
||||
Object o = it.next();
|
||||
@@ -187,7 +187,7 @@ public class CollectionMergingTests {
|
||||
TestBean bean = (TestBean) this.beanFactory.getBean("childWithMapOfRefsInConstructor");
|
||||
Map<?, ?> map = bean.getSomeMap();
|
||||
assertThat(map).isNotNull();
|
||||
assertThat(map).hasSize(2);
|
||||
assertThat(map.size()).isEqualTo(2);
|
||||
assertThat(map.get("Rob")).isNotNull();
|
||||
boolean condition = map.get("Rob") instanceof TestBean;
|
||||
assertThat(condition).isTrue();
|
||||
|
||||
+41
-32
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -27,7 +27,6 @@ import org.springframework.beans.factory.config.TypedStringValue;
|
||||
import org.springframework.beans.factory.parsing.AliasDefinition;
|
||||
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
|
||||
import org.springframework.beans.factory.parsing.ComponentDefinition;
|
||||
import org.springframework.beans.factory.parsing.DefaultsDefinition;
|
||||
import org.springframework.beans.factory.parsing.ImportDefinition;
|
||||
import org.springframework.beans.factory.parsing.PassThroughSourceExtractor;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
@@ -41,7 +40,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
class EventPublicationTests {
|
||||
public class EventPublicationTests {
|
||||
|
||||
private final DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
|
||||
|
||||
@@ -50,7 +49,7 @@ class EventPublicationTests {
|
||||
|
||||
|
||||
@BeforeEach
|
||||
void setUp() throws Exception {
|
||||
public void setUp() throws Exception {
|
||||
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this.beanFactory);
|
||||
reader.setEventListener(this.eventListener);
|
||||
reader.setSourceExtractor(new PassThroughSourceExtractor());
|
||||
@@ -58,64 +57,74 @@ class EventPublicationTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void defaultsEventReceived() throws Exception {
|
||||
List<DefaultsDefinition> defaultsList = this.eventListener.getDefaults();
|
||||
assertThat(defaultsList).isNotEmpty();
|
||||
assertThat(defaultsList.get(0)).isInstanceOf(DocumentDefaultsDefinition.class);
|
||||
public void defaultsEventReceived() throws Exception {
|
||||
List defaultsList = this.eventListener.getDefaults();
|
||||
boolean condition2 = !defaultsList.isEmpty();
|
||||
assertThat(condition2).isTrue();
|
||||
boolean condition1 = defaultsList.get(0) instanceof DocumentDefaultsDefinition;
|
||||
assertThat(condition1).isTrue();
|
||||
DocumentDefaultsDefinition defaults = (DocumentDefaultsDefinition) defaultsList.get(0);
|
||||
assertThat(defaults.getLazyInit()).isEqualTo("true");
|
||||
assertThat(defaults.getAutowire()).isEqualTo("constructor");
|
||||
assertThat(defaults.getInitMethod()).isEqualTo("myInit");
|
||||
assertThat(defaults.getDestroyMethod()).isEqualTo("myDestroy");
|
||||
assertThat(defaults.getMerge()).isEqualTo("true");
|
||||
assertThat(defaults.getSource()).isInstanceOf(Element.class);
|
||||
boolean condition = defaults.getSource() instanceof Element;
|
||||
assertThat(condition).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void beanEventReceived() throws Exception {
|
||||
public void beanEventReceived() throws Exception {
|
||||
ComponentDefinition componentDefinition1 = this.eventListener.getComponentDefinition("testBean");
|
||||
assertThat(componentDefinition1).isInstanceOf(BeanComponentDefinition.class);
|
||||
assertThat(componentDefinition1.getBeanDefinitions()).hasSize(1);
|
||||
boolean condition3 = componentDefinition1 instanceof BeanComponentDefinition;
|
||||
assertThat(condition3).isTrue();
|
||||
assertThat(componentDefinition1.getBeanDefinitions().length).isEqualTo(1);
|
||||
BeanDefinition beanDefinition1 = componentDefinition1.getBeanDefinitions()[0];
|
||||
assertThat(beanDefinition1.getConstructorArgumentValues().getGenericArgumentValue(String.class).getValue()).isEqualTo(new TypedStringValue("Rob Harrop"));
|
||||
assertThat(componentDefinition1.getBeanReferences()).hasSize(1);
|
||||
assertThat(componentDefinition1.getBeanReferences().length).isEqualTo(1);
|
||||
assertThat(componentDefinition1.getBeanReferences()[0].getBeanName()).isEqualTo("testBean2");
|
||||
assertThat(componentDefinition1.getInnerBeanDefinitions()).hasSize(1);
|
||||
assertThat(componentDefinition1.getInnerBeanDefinitions().length).isEqualTo(1);
|
||||
BeanDefinition innerBd1 = componentDefinition1.getInnerBeanDefinitions()[0];
|
||||
assertThat(innerBd1.getConstructorArgumentValues().getGenericArgumentValue(String.class).getValue()).isEqualTo(new TypedStringValue("ACME"));
|
||||
assertThat(componentDefinition1.getSource()).isInstanceOf(Element.class);
|
||||
boolean condition2 = componentDefinition1.getSource() instanceof Element;
|
||||
assertThat(condition2).isTrue();
|
||||
|
||||
ComponentDefinition componentDefinition2 = this.eventListener.getComponentDefinition("testBean2");
|
||||
assertThat(componentDefinition2).isInstanceOf(BeanComponentDefinition.class);
|
||||
assertThat(componentDefinition1.getBeanDefinitions()).hasSize(1);
|
||||
boolean condition1 = componentDefinition2 instanceof BeanComponentDefinition;
|
||||
assertThat(condition1).isTrue();
|
||||
assertThat(componentDefinition1.getBeanDefinitions().length).isEqualTo(1);
|
||||
BeanDefinition beanDefinition2 = componentDefinition2.getBeanDefinitions()[0];
|
||||
assertThat(beanDefinition2.getPropertyValues().getPropertyValue("name").getValue()).isEqualTo(new TypedStringValue("Juergen Hoeller"));
|
||||
assertThat(componentDefinition2.getBeanReferences()).isEmpty();
|
||||
assertThat(componentDefinition2.getInnerBeanDefinitions()).hasSize(1);
|
||||
assertThat(componentDefinition2.getBeanReferences().length).isEqualTo(0);
|
||||
assertThat(componentDefinition2.getInnerBeanDefinitions().length).isEqualTo(1);
|
||||
BeanDefinition innerBd2 = componentDefinition2.getInnerBeanDefinitions()[0];
|
||||
assertThat(innerBd2.getPropertyValues().getPropertyValue("name").getValue()).isEqualTo(new TypedStringValue("Eva Schallmeiner"));
|
||||
assertThat(componentDefinition2.getSource()).isInstanceOf(Element.class);
|
||||
boolean condition = componentDefinition2.getSource() instanceof Element;
|
||||
assertThat(condition).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void aliasEventReceived() throws Exception {
|
||||
List<AliasDefinition> aliases = this.eventListener.getAliases("testBean");
|
||||
assertThat(aliases).hasSize(2);
|
||||
AliasDefinition aliasDefinition1 = aliases.get(0);
|
||||
public void aliasEventReceived() throws Exception {
|
||||
List aliases = this.eventListener.getAliases("testBean");
|
||||
assertThat(aliases.size()).isEqualTo(2);
|
||||
AliasDefinition aliasDefinition1 = (AliasDefinition) aliases.get(0);
|
||||
assertThat(aliasDefinition1.getAlias()).isEqualTo("testBeanAlias1");
|
||||
assertThat(aliasDefinition1.getSource()).isInstanceOf(Element.class);
|
||||
AliasDefinition aliasDefinition2 = aliases.get(1);
|
||||
boolean condition1 = aliasDefinition1.getSource() instanceof Element;
|
||||
assertThat(condition1).isTrue();
|
||||
AliasDefinition aliasDefinition2 = (AliasDefinition) aliases.get(1);
|
||||
assertThat(aliasDefinition2.getAlias()).isEqualTo("testBeanAlias2");
|
||||
assertThat(aliasDefinition2.getSource()).isInstanceOf(Element.class);
|
||||
boolean condition = aliasDefinition2.getSource() instanceof Element;
|
||||
assertThat(condition).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void importEventReceived() throws Exception {
|
||||
List<ImportDefinition> imports = this.eventListener.getImports();
|
||||
assertThat(imports).hasSize(1);
|
||||
ImportDefinition importDefinition = imports.get(0);
|
||||
public void importEventReceived() throws Exception {
|
||||
List imports = this.eventListener.getImports();
|
||||
assertThat(imports.size()).isEqualTo(1);
|
||||
ImportDefinition importDefinition = (ImportDefinition) imports.get(0);
|
||||
assertThat(importDefinition.getImportedResource()).isEqualTo("beanEventsImported.xml");
|
||||
assertThat(importDefinition.getSource()).isInstanceOf(Element.class);
|
||||
boolean condition = importDefinition.getSource() instanceof Element;
|
||||
assertThat(condition).isTrue();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+93
-90
@@ -54,7 +54,7 @@ public class UtilNamespaceHandlerTests {
|
||||
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
public void setUp() {
|
||||
this.beanFactory = new DefaultListableBeanFactory();
|
||||
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this.beanFactory);
|
||||
reader.setEventListener(this.listener);
|
||||
@@ -63,19 +63,19 @@ public class UtilNamespaceHandlerTests {
|
||||
|
||||
|
||||
@Test
|
||||
void testConstant() {
|
||||
public void testConstant() {
|
||||
Integer min = (Integer) this.beanFactory.getBean("min");
|
||||
assertThat(min.intValue()).isEqualTo(Integer.MIN_VALUE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testConstantWithDefaultName() {
|
||||
public void testConstantWithDefaultName() {
|
||||
Integer max = (Integer) this.beanFactory.getBean("java.lang.Integer.MAX_VALUE");
|
||||
assertThat(max.intValue()).isEqualTo(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEvents() {
|
||||
public void testEvents() {
|
||||
ComponentDefinition propertiesComponent = this.listener.getComponentDefinition("myProperties");
|
||||
assertThat(propertiesComponent).as("Event for 'myProperties' not sent").isNotNull();
|
||||
AbstractBeanDefinition propertiesBean = (AbstractBeanDefinition) propertiesComponent.getBeanDefinitions()[0];
|
||||
@@ -88,106 +88,109 @@ public class UtilNamespaceHandlerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNestedProperties() {
|
||||
public void testNestedProperties() {
|
||||
TestBean bean = (TestBean) this.beanFactory.getBean("testBean");
|
||||
Properties props = bean.getSomeProperties();
|
||||
assertThat(props.get("foo")).as("Incorrect property value").isEqualTo("bar");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPropertyPath() {
|
||||
public void testPropertyPath() {
|
||||
String name = (String) this.beanFactory.getBean("name");
|
||||
assertThat(name).isEqualTo("Rob Harrop");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNestedPropertyPath() {
|
||||
public void testNestedPropertyPath() {
|
||||
TestBean bean = (TestBean) this.beanFactory.getBean("testBean");
|
||||
assertThat(bean.getName()).isEqualTo("Rob Harrop");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSimpleMap() {
|
||||
Map<?, ?> map = (Map) this.beanFactory.getBean("simpleMap");
|
||||
public void testSimpleMap() {
|
||||
Map map = (Map) this.beanFactory.getBean("simpleMap");
|
||||
assertThat(map.get("foo")).isEqualTo("bar");
|
||||
Map<?, ?> map2 = (Map) this.beanFactory.getBean("simpleMap");
|
||||
Map map2 = (Map) this.beanFactory.getBean("simpleMap");
|
||||
assertThat(map == map2).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testScopedMap() {
|
||||
Map<?, ?> map = (Map) this.beanFactory.getBean("scopedMap");
|
||||
public void testScopedMap() {
|
||||
Map map = (Map) this.beanFactory.getBean("scopedMap");
|
||||
assertThat(map.get("foo")).isEqualTo("bar");
|
||||
Map<?, ?> map2 = (Map) this.beanFactory.getBean("scopedMap");
|
||||
Map map2 = (Map) this.beanFactory.getBean("scopedMap");
|
||||
assertThat(map2.get("foo")).isEqualTo("bar");
|
||||
assertThat(map != map2).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSimpleList() {
|
||||
List<?> list = (List) this.beanFactory.getBean("simpleList");
|
||||
public void testSimpleList() {
|
||||
List list = (List) this.beanFactory.getBean("simpleList");
|
||||
assertThat(list.get(0)).isEqualTo("Rob Harrop");
|
||||
List<?> list2 = (List) this.beanFactory.getBean("simpleList");
|
||||
List list2 = (List) this.beanFactory.getBean("simpleList");
|
||||
assertThat(list == list2).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testScopedList() {
|
||||
List<?> list = (List) this.beanFactory.getBean("scopedList");
|
||||
public void testScopedList() {
|
||||
List list = (List) this.beanFactory.getBean("scopedList");
|
||||
assertThat(list.get(0)).isEqualTo("Rob Harrop");
|
||||
List<?> list2 = (List) this.beanFactory.getBean("scopedList");
|
||||
List list2 = (List) this.beanFactory.getBean("scopedList");
|
||||
assertThat(list2.get(0)).isEqualTo("Rob Harrop");
|
||||
assertThat(list != list2).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSimpleSet() {
|
||||
Set<?> set = (Set) this.beanFactory.getBean("simpleSet");
|
||||
public void testSimpleSet() {
|
||||
Set set = (Set) this.beanFactory.getBean("simpleSet");
|
||||
assertThat(set.contains("Rob Harrop")).isTrue();
|
||||
Set<?> set2 = (Set) this.beanFactory.getBean("simpleSet");
|
||||
Set set2 = (Set) this.beanFactory.getBean("simpleSet");
|
||||
assertThat(set == set2).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testScopedSet() {
|
||||
Set<?> set = (Set) this.beanFactory.getBean("scopedSet");
|
||||
public void testScopedSet() {
|
||||
Set set = (Set) this.beanFactory.getBean("scopedSet");
|
||||
assertThat(set.contains("Rob Harrop")).isTrue();
|
||||
Set<?> set2 = (Set) this.beanFactory.getBean("scopedSet");
|
||||
Set set2 = (Set) this.beanFactory.getBean("scopedSet");
|
||||
assertThat(set2.contains("Rob Harrop")).isTrue();
|
||||
assertThat(set != set2).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMapWithRef() {
|
||||
Map<?, ?> map = (Map) this.beanFactory.getBean("mapWithRef");
|
||||
assertThat(map).isInstanceOf(TreeMap.class);
|
||||
public void testMapWithRef() {
|
||||
Map map = (Map) this.beanFactory.getBean("mapWithRef");
|
||||
boolean condition = map instanceof TreeMap;
|
||||
assertThat(condition).isTrue();
|
||||
assertThat(map.get("bean")).isEqualTo(this.beanFactory.getBean("testBean"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMapWithTypes() {
|
||||
Map<?, ?> map = (Map) this.beanFactory.getBean("mapWithTypes");
|
||||
assertThat(map).isInstanceOf(LinkedCaseInsensitiveMap.class);
|
||||
public void testMapWithTypes() {
|
||||
Map map = (Map) this.beanFactory.getBean("mapWithTypes");
|
||||
boolean condition = map instanceof LinkedCaseInsensitiveMap;
|
||||
assertThat(condition).isTrue();
|
||||
assertThat(map.get("bean")).isEqualTo(this.beanFactory.getBean("testBean"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNestedCollections() {
|
||||
public void testNestedCollections() {
|
||||
TestBean bean = (TestBean) this.beanFactory.getBean("nestedCollectionsBean");
|
||||
|
||||
List<?> list = bean.getSomeList();
|
||||
assertThat(list).hasSize(1);
|
||||
List list = bean.getSomeList();
|
||||
assertThat(list.size()).isEqualTo(1);
|
||||
assertThat(list.get(0)).isEqualTo("foo");
|
||||
|
||||
Set<?> set = bean.getSomeSet();
|
||||
assertThat(set).hasSize(1);
|
||||
Set set = bean.getSomeSet();
|
||||
assertThat(set.size()).isEqualTo(1);
|
||||
assertThat(set.contains("bar")).isTrue();
|
||||
|
||||
Map<?, ?> map = bean.getSomeMap();
|
||||
assertThat(map).hasSize(1);
|
||||
assertThat(map.get("foo")).isInstanceOf(Set.class);
|
||||
Set<?> innerSet = (Set) map.get("foo");
|
||||
assertThat(innerSet).hasSize(1);
|
||||
Map map = bean.getSomeMap();
|
||||
assertThat(map.size()).isEqualTo(1);
|
||||
boolean condition = map.get("foo") instanceof Set;
|
||||
assertThat(condition).isTrue();
|
||||
Set innerSet = (Set) map.get("foo");
|
||||
assertThat(innerSet.size()).isEqualTo(1);
|
||||
assertThat(innerSet.contains("bar")).isTrue();
|
||||
|
||||
TestBean bean2 = (TestBean) this.beanFactory.getBean("nestedCollectionsBean");
|
||||
@@ -200,18 +203,18 @@ public class UtilNamespaceHandlerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNestedShortcutCollections() {
|
||||
public void testNestedShortcutCollections() {
|
||||
TestBean bean = (TestBean) this.beanFactory.getBean("nestedShortcutCollections");
|
||||
|
||||
assertThat(bean.getStringArray()).hasSize(1);
|
||||
assertThat(bean.getStringArray().length).isEqualTo(1);
|
||||
assertThat(bean.getStringArray()[0]).isEqualTo("fooStr");
|
||||
|
||||
List<?> list = bean.getSomeList();
|
||||
assertThat(list).hasSize(1);
|
||||
List list = bean.getSomeList();
|
||||
assertThat(list.size()).isEqualTo(1);
|
||||
assertThat(list.get(0)).isEqualTo("foo");
|
||||
|
||||
Set<?> set = bean.getSomeSet();
|
||||
assertThat(set).hasSize(1);
|
||||
Set set = bean.getSomeSet();
|
||||
assertThat(set.size()).isEqualTo(1);
|
||||
assertThat(set.contains("bar")).isTrue();
|
||||
|
||||
TestBean bean2 = (TestBean) this.beanFactory.getBean("nestedShortcutCollections");
|
||||
@@ -224,20 +227,20 @@ public class UtilNamespaceHandlerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNestedInCollections() {
|
||||
public void testNestedInCollections() {
|
||||
TestBean bean = (TestBean) this.beanFactory.getBean("nestedCustomTagBean");
|
||||
|
||||
List<?> list = bean.getSomeList();
|
||||
assertThat(list).hasSize(1);
|
||||
List list = bean.getSomeList();
|
||||
assertThat(list.size()).isEqualTo(1);
|
||||
assertThat(list.get(0)).isEqualTo(Integer.MIN_VALUE);
|
||||
|
||||
Set<?> set = bean.getSomeSet();
|
||||
assertThat(set).hasSize(2);
|
||||
Set set = bean.getSomeSet();
|
||||
assertThat(set.size()).isEqualTo(2);
|
||||
assertThat(set.contains(Thread.State.NEW)).isTrue();
|
||||
assertThat(set.contains(Thread.State.RUNNABLE)).isTrue();
|
||||
|
||||
Map<?, ?> map = bean.getSomeMap();
|
||||
assertThat(map).hasSize(1);
|
||||
Map map = bean.getSomeMap();
|
||||
assertThat(map.size()).isEqualTo(1);
|
||||
assertThat(map.get("min")).isEqualTo(CustomEnum.VALUE_1);
|
||||
|
||||
TestBean bean2 = (TestBean) this.beanFactory.getBean("nestedCustomTagBean");
|
||||
@@ -250,93 +253,93 @@ public class UtilNamespaceHandlerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCircularCollections() {
|
||||
public void testCircularCollections() {
|
||||
TestBean bean = (TestBean) this.beanFactory.getBean("circularCollectionsBean");
|
||||
|
||||
List<?> list = bean.getSomeList();
|
||||
assertThat(list).hasSize(1);
|
||||
List list = bean.getSomeList();
|
||||
assertThat(list.size()).isEqualTo(1);
|
||||
assertThat(list.get(0)).isEqualTo(bean);
|
||||
|
||||
Set<?> set = bean.getSomeSet();
|
||||
assertThat(set).hasSize(1);
|
||||
Set set = bean.getSomeSet();
|
||||
assertThat(set.size()).isEqualTo(1);
|
||||
assertThat(set.contains(bean)).isTrue();
|
||||
|
||||
Map<?, ?> map = bean.getSomeMap();
|
||||
assertThat(map).hasSize(1);
|
||||
Map map = bean.getSomeMap();
|
||||
assertThat(map.size()).isEqualTo(1);
|
||||
assertThat(map.get("foo")).isEqualTo(bean);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCircularCollectionBeansStartingWithList() {
|
||||
public void testCircularCollectionBeansStartingWithList() {
|
||||
this.beanFactory.getBean("circularList");
|
||||
TestBean bean = (TestBean) this.beanFactory.getBean("circularCollectionBeansBean");
|
||||
|
||||
List<?> list = bean.getSomeList();
|
||||
List list = bean.getSomeList();
|
||||
assertThat(Proxy.isProxyClass(list.getClass())).isTrue();
|
||||
assertThat(list).hasSize(1);
|
||||
assertThat(list.size()).isEqualTo(1);
|
||||
assertThat(list.get(0)).isEqualTo(bean);
|
||||
|
||||
Set<?> set = bean.getSomeSet();
|
||||
Set set = bean.getSomeSet();
|
||||
assertThat(Proxy.isProxyClass(set.getClass())).isFalse();
|
||||
assertThat(set).hasSize(1);
|
||||
assertThat(set.size()).isEqualTo(1);
|
||||
assertThat(set.contains(bean)).isTrue();
|
||||
|
||||
Map<?, ?> map = bean.getSomeMap();
|
||||
Map map = bean.getSomeMap();
|
||||
assertThat(Proxy.isProxyClass(map.getClass())).isFalse();
|
||||
assertThat(map).hasSize(1);
|
||||
assertThat(map.size()).isEqualTo(1);
|
||||
assertThat(map.get("foo")).isEqualTo(bean);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCircularCollectionBeansStartingWithSet() {
|
||||
public void testCircularCollectionBeansStartingWithSet() {
|
||||
this.beanFactory.getBean("circularSet");
|
||||
TestBean bean = (TestBean) this.beanFactory.getBean("circularCollectionBeansBean");
|
||||
|
||||
List<?> list = bean.getSomeList();
|
||||
List list = bean.getSomeList();
|
||||
assertThat(Proxy.isProxyClass(list.getClass())).isFalse();
|
||||
assertThat(list).hasSize(1);
|
||||
assertThat(list.size()).isEqualTo(1);
|
||||
assertThat(list.get(0)).isEqualTo(bean);
|
||||
|
||||
Set<?> set = bean.getSomeSet();
|
||||
Set set = bean.getSomeSet();
|
||||
assertThat(Proxy.isProxyClass(set.getClass())).isTrue();
|
||||
assertThat(set).hasSize(1);
|
||||
assertThat(set.size()).isEqualTo(1);
|
||||
assertThat(set.contains(bean)).isTrue();
|
||||
|
||||
Map<?, ?> map = bean.getSomeMap();
|
||||
Map map = bean.getSomeMap();
|
||||
assertThat(Proxy.isProxyClass(map.getClass())).isFalse();
|
||||
assertThat(map).hasSize(1);
|
||||
assertThat(map.size()).isEqualTo(1);
|
||||
assertThat(map.get("foo")).isEqualTo(bean);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCircularCollectionBeansStartingWithMap() {
|
||||
public void testCircularCollectionBeansStartingWithMap() {
|
||||
this.beanFactory.getBean("circularMap");
|
||||
TestBean bean = (TestBean) this.beanFactory.getBean("circularCollectionBeansBean");
|
||||
|
||||
List<?> list = bean.getSomeList();
|
||||
List list = bean.getSomeList();
|
||||
assertThat(Proxy.isProxyClass(list.getClass())).isFalse();
|
||||
assertThat(list).hasSize(1);
|
||||
assertThat(list.size()).isEqualTo(1);
|
||||
assertThat(list.get(0)).isEqualTo(bean);
|
||||
|
||||
Set<?> set = bean.getSomeSet();
|
||||
Set set = bean.getSomeSet();
|
||||
assertThat(Proxy.isProxyClass(set.getClass())).isFalse();
|
||||
assertThat(set).hasSize(1);
|
||||
assertThat(set.size()).isEqualTo(1);
|
||||
assertThat(set.contains(bean)).isTrue();
|
||||
|
||||
Map<?, ?> map = bean.getSomeMap();
|
||||
Map map = bean.getSomeMap();
|
||||
assertThat(Proxy.isProxyClass(map.getClass())).isTrue();
|
||||
assertThat(map).hasSize(1);
|
||||
assertThat(map.size()).isEqualTo(1);
|
||||
assertThat(map.get("foo")).isEqualTo(bean);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNestedInConstructor() {
|
||||
public void testNestedInConstructor() {
|
||||
TestBean bean = (TestBean) this.beanFactory.getBean("constructedTestBean");
|
||||
assertThat(bean.getName()).isEqualTo("Rob Harrop");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoadProperties() {
|
||||
public void testLoadProperties() {
|
||||
Properties props = (Properties) this.beanFactory.getBean("myProperties");
|
||||
assertThat(props.get("foo")).as("Incorrect property value").isEqualTo("bar");
|
||||
assertThat(props.get("foo2")).as("Incorrect property value").isNull();
|
||||
@@ -345,7 +348,7 @@ public class UtilNamespaceHandlerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testScopedProperties() {
|
||||
public void testScopedProperties() {
|
||||
Properties props = (Properties) this.beanFactory.getBean("myScopedProperties");
|
||||
assertThat(props.get("foo")).as("Incorrect property value").isEqualTo("bar");
|
||||
assertThat(props.get("foo2")).as("Incorrect property value").isNull();
|
||||
@@ -356,35 +359,35 @@ public class UtilNamespaceHandlerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLocalProperties() {
|
||||
public void testLocalProperties() {
|
||||
Properties props = (Properties) this.beanFactory.getBean("myLocalProperties");
|
||||
assertThat(props.get("foo")).as("Incorrect property value").isNull();
|
||||
assertThat(props.get("foo2")).as("Incorrect property value").isEqualTo("bar2");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMergedProperties() {
|
||||
public void testMergedProperties() {
|
||||
Properties props = (Properties) this.beanFactory.getBean("myMergedProperties");
|
||||
assertThat(props.get("foo")).as("Incorrect property value").isEqualTo("bar");
|
||||
assertThat(props.get("foo2")).as("Incorrect property value").isEqualTo("bar2");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLocalOverrideDefault() {
|
||||
public void testLocalOverrideDefault() {
|
||||
Properties props = (Properties) this.beanFactory.getBean("defaultLocalOverrideProperties");
|
||||
assertThat(props.get("foo")).as("Incorrect property value").isEqualTo("bar");
|
||||
assertThat(props.get("foo2")).as("Incorrect property value").isEqualTo("local2");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLocalOverrideFalse() {
|
||||
public void testLocalOverrideFalse() {
|
||||
Properties props = (Properties) this.beanFactory.getBean("falseLocalOverrideProperties");
|
||||
assertThat(props.get("foo")).as("Incorrect property value").isEqualTo("bar");
|
||||
assertThat(props.get("foo2")).as("Incorrect property value").isEqualTo("local2");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLocalOverrideTrue() {
|
||||
public void testLocalOverrideTrue() {
|
||||
Properties props = (Properties) this.beanFactory.getBean("trueLocalOverrideProperties");
|
||||
assertThat(props.get("foo")).as("Incorrect property value").isEqualTo("local");
|
||||
assertThat(props.get("foo2")).as("Incorrect property value").isEqualTo("local2");
|
||||
|
||||
+3
-3
@@ -356,12 +356,12 @@ public class XmlBeanCollectionTests {
|
||||
@Test
|
||||
public void testProps() throws Exception {
|
||||
HasMap hasMap = (HasMap) this.beanFactory.getBean("props");
|
||||
assertThat(hasMap.getProps()).hasSize(2);
|
||||
assertThat(hasMap.getProps().size()).isEqualTo(2);
|
||||
assertThat(hasMap.getProps().getProperty("foo")).isEqualTo("bar");
|
||||
assertThat(hasMap.getProps().getProperty("2")).isEqualTo("TWO");
|
||||
|
||||
HasMap hasMap2 = (HasMap) this.beanFactory.getBean("propsViaMap");
|
||||
assertThat(hasMap2.getProps()).hasSize(2);
|
||||
assertThat(hasMap2.getProps().size()).isEqualTo(2);
|
||||
assertThat(hasMap2.getProps().getProperty("foo")).isEqualTo("bar");
|
||||
assertThat(hasMap2.getProps().getProperty("2")).isEqualTo("TWO");
|
||||
}
|
||||
@@ -432,7 +432,7 @@ public class XmlBeanCollectionTests {
|
||||
boolean condition = sam.getObject() instanceof Map;
|
||||
assertThat(condition).as("Didn't choose constructor with Map argument").isTrue();
|
||||
Map map = (Map) sam.getObject();
|
||||
assertThat(map).hasSize(3);
|
||||
assertThat(map.size()).isEqualTo(3);
|
||||
assertThat(map.get("key1")).isEqualTo("val1");
|
||||
assertThat(map.get("key2")).isEqualTo("val2");
|
||||
assertThat(map.get("key3")).isEqualTo("val3");
|
||||
|
||||
+2
-2
@@ -109,7 +109,7 @@ public class XmlBeanDefinitionReaderTests {
|
||||
|
||||
private void testBeanDefinitions(BeanDefinitionRegistry registry) {
|
||||
assertThat(registry.getBeanDefinitionCount()).isEqualTo(24);
|
||||
assertThat(registry.getBeanDefinitionNames()).hasSize(24);
|
||||
assertThat(registry.getBeanDefinitionNames().length).isEqualTo(24);
|
||||
assertThat(Arrays.asList(registry.getBeanDefinitionNames()).contains("rod")).isTrue();
|
||||
assertThat(Arrays.asList(registry.getBeanDefinitionNames()).contains("aliased")).isTrue();
|
||||
assertThat(registry.containsBeanDefinition("rod")).isTrue();
|
||||
@@ -118,7 +118,7 @@ public class XmlBeanDefinitionReaderTests {
|
||||
assertThat(registry.getBeanDefinition("aliased").getBeanClassName()).isEqualTo(TestBean.class.getName());
|
||||
assertThat(registry.isAlias("youralias")).isTrue();
|
||||
String[] aliases = registry.getAliases("aliased");
|
||||
assertThat(aliases).hasSize(2);
|
||||
assertThat(aliases.length).isEqualTo(2);
|
||||
assertThat(ObjectUtils.containsElement(aliases, "myalias")).isTrue();
|
||||
assertThat(ObjectUtils.containsElement(aliases, "youralias")).isTrue();
|
||||
}
|
||||
|
||||
+4
-4
@@ -138,7 +138,7 @@ public class XmlListableBeanFactoryTests extends AbstractListableBeanFactoryTest
|
||||
TestBean alias1 = (TestBean) getBeanFactory().getBean("myalias");
|
||||
assertThat(tb1 == alias1).isTrue();
|
||||
List tb1Aliases = Arrays.asList(getBeanFactory().getAliases("aliased"));
|
||||
assertThat(tb1Aliases).hasSize(2);
|
||||
assertThat(tb1Aliases.size()).isEqualTo(2);
|
||||
assertThat(tb1Aliases.contains("myalias")).isTrue();
|
||||
assertThat(tb1Aliases.contains("youralias")).isTrue();
|
||||
assertThat(beanNames.contains("aliased")).isTrue();
|
||||
@@ -156,7 +156,7 @@ public class XmlListableBeanFactoryTests extends AbstractListableBeanFactoryTest
|
||||
assertThat(tb2 == alias3b).isTrue();
|
||||
|
||||
List tb2Aliases = Arrays.asList(getBeanFactory().getAliases("multiAliased"));
|
||||
assertThat(tb2Aliases).hasSize(4);
|
||||
assertThat(tb2Aliases.size()).isEqualTo(4);
|
||||
assertThat(tb2Aliases.contains("alias1")).isTrue();
|
||||
assertThat(tb2Aliases.contains("alias2")).isTrue();
|
||||
assertThat(tb2Aliases.contains("alias3")).isTrue();
|
||||
@@ -173,7 +173,7 @@ public class XmlListableBeanFactoryTests extends AbstractListableBeanFactoryTest
|
||||
assertThat(tb3 == alias4).isTrue();
|
||||
assertThat(tb3 == alias5).isTrue();
|
||||
List tb3Aliases = Arrays.asList(getBeanFactory().getAliases("aliasWithoutId1"));
|
||||
assertThat(tb3Aliases).hasSize(2);
|
||||
assertThat(tb3Aliases.size()).isEqualTo(2);
|
||||
assertThat(tb3Aliases.contains("aliasWithoutId2")).isTrue();
|
||||
assertThat(tb3Aliases.contains("aliasWithoutId3")).isTrue();
|
||||
assertThat(beanNames.contains("aliasWithoutId1")).isTrue();
|
||||
@@ -184,7 +184,7 @@ public class XmlListableBeanFactoryTests extends AbstractListableBeanFactoryTest
|
||||
assertThat(tb4.getName()).isNull();
|
||||
|
||||
Map drs = getListableBeanFactory().getBeansOfType(DummyReferencer.class, false, false);
|
||||
assertThat(drs).hasSize(5);
|
||||
assertThat(drs.size()).isEqualTo(5);
|
||||
assertThat(drs.containsKey(DummyReferencer.class.getName() + "#0")).isTrue();
|
||||
assertThat(drs.containsKey(DummyReferencer.class.getName() + "#1")).isTrue();
|
||||
assertThat(drs.containsKey(DummyReferencer.class.getName() + "#2")).isTrue();
|
||||
|
||||
+3
-3
@@ -1357,12 +1357,12 @@ class CustomEditorTests {
|
||||
bw.registerCustomEditor(Hashtable.class, new CustomMapEditor(Hashtable.class));
|
||||
|
||||
bw.setPropertyValue("vector", new String[] {"a", "b"});
|
||||
assertThat(tb.getVector()).hasSize(2);
|
||||
assertThat(tb.getVector().size()).isEqualTo(2);
|
||||
assertThat(tb.getVector().get(0)).isEqualTo("a");
|
||||
assertThat(tb.getVector().get(1)).isEqualTo("b");
|
||||
|
||||
bw.setPropertyValue("hashtable", Collections.singletonMap("foo", "bar"));
|
||||
assertThat(tb.getHashtable()).hasSize(1);
|
||||
assertThat(tb.getHashtable().size()).isEqualTo(1);
|
||||
assertThat(tb.getHashtable().get("foo")).isEqualTo("bar");
|
||||
}
|
||||
|
||||
@@ -1393,7 +1393,7 @@ class CustomEditorTests {
|
||||
}
|
||||
});
|
||||
bw.setPropertyValue("array", new String[] {"a", "b"});
|
||||
assertThat(tb.getArray()).hasSize(2);
|
||||
assertThat(tb.getArray().length).isEqualTo(2);
|
||||
assertThat(tb.getArray()[0].getName()).isEqualTo("a");
|
||||
assertThat(tb.getArray()[1].getName()).isEqualTo("b");
|
||||
}
|
||||
|
||||
+2
-2
@@ -139,7 +139,7 @@ public class PropertiesEditorTests {
|
||||
PropertiesEditor pe= new PropertiesEditor();
|
||||
pe.setAsText(null);
|
||||
Properties p = (Properties) pe.getValue();
|
||||
assertThat(p).isEmpty();
|
||||
assertThat(p.size()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -163,7 +163,7 @@ public class PropertiesEditorTests {
|
||||
boolean condition = value instanceof Properties;
|
||||
assertThat(condition).isTrue();
|
||||
Properties props = (Properties) value;
|
||||
assertThat(props).hasSize(3);
|
||||
assertThat(props.size()).isEqualTo(3);
|
||||
assertThat(props.getProperty("one")).isEqualTo("1");
|
||||
assertThat(props.getProperty("two")).isEqualTo("2");
|
||||
assertThat(props.getProperty("three")).isEqualTo("3");
|
||||
|
||||
+3
-3
@@ -82,13 +82,13 @@ class CandidateComponentsIndexerTests {
|
||||
@Test
|
||||
void noCandidate() {
|
||||
CandidateComponentsMetadata metadata = compile(SampleNone.class);
|
||||
assertThat(metadata.getItems()).isEmpty();
|
||||
assertThat(metadata.getItems()).hasSize(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void noAnnotation() {
|
||||
CandidateComponentsMetadata metadata = compile(CandidateComponentsIndexerTests.class);
|
||||
assertThat(metadata.getItems()).isEmpty();
|
||||
assertThat(metadata.getItems()).hasSize(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -214,7 +214,7 @@ class CandidateComponentsIndexerTests {
|
||||
@Test
|
||||
void embeddedNonStaticCandidateAreIgnored() {
|
||||
CandidateComponentsMetadata metadata = compile(SampleNonStaticEmbedded.class);
|
||||
assertThat(metadata.getItems()).isEmpty();
|
||||
assertThat(metadata.getItems()).hasSize(0);
|
||||
}
|
||||
|
||||
private void testComponent(Class<?>... classes) {
|
||||
|
||||
+7
-7
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -527,8 +527,8 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
|
||||
if (schedulerFactory == null) {
|
||||
// Create local SchedulerFactory instance (typically a StdSchedulerFactory)
|
||||
schedulerFactory = BeanUtils.instantiateClass(this.schedulerFactoryClass);
|
||||
if (schedulerFactory instanceof StdSchedulerFactory stdSchedulerFactory) {
|
||||
initSchedulerFactory(stdSchedulerFactory);
|
||||
if (schedulerFactory instanceof StdSchedulerFactory) {
|
||||
initSchedulerFactory((StdSchedulerFactory) schedulerFactory);
|
||||
}
|
||||
else if (this.configLocation != null || this.quartzProperties != null ||
|
||||
this.taskExecutor != null || this.dataSource != null) {
|
||||
@@ -622,11 +622,11 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
|
||||
this.jobFactory = new AdaptableJobFactory();
|
||||
}
|
||||
if (this.jobFactory != null) {
|
||||
if (this.applicationContext != null && this.jobFactory instanceof ApplicationContextAware applicationContextAware) {
|
||||
applicationContextAware.setApplicationContext(this.applicationContext);
|
||||
if (this.applicationContext != null && this.jobFactory instanceof ApplicationContextAware) {
|
||||
((ApplicationContextAware) this.jobFactory).setApplicationContext(this.applicationContext);
|
||||
}
|
||||
if (this.jobFactory instanceof SchedulerContextAware schedulerContextAware) {
|
||||
schedulerContextAware.setSchedulerContext(scheduler.getContext());
|
||||
if (this.jobFactory instanceof SchedulerContextAware) {
|
||||
((SchedulerContextAware) this.jobFactory).setSchedulerContext(scheduler.getContext());
|
||||
}
|
||||
scheduler.setJobFactory(this.jobFactory);
|
||||
}
|
||||
|
||||
+1
-1
@@ -45,7 +45,7 @@ public class CachePutOperationTests extends AbstractCacheOperationTests<CachePut
|
||||
CachePutOperation operation = createSimpleOperation();
|
||||
|
||||
CacheInvocationParameter[] allParameters = operation.getAllParameters(2L, sampleInstance);
|
||||
assertThat(allParameters).hasSize(2);
|
||||
assertThat(allParameters.length).isEqualTo(2);
|
||||
assertCacheInvocationParameter(allParameters[0], Long.class, 2L, 0);
|
||||
assertCacheInvocationParameter(allParameters[1], SampleObject.class, sampleInstance, 1);
|
||||
|
||||
|
||||
+1
-1
@@ -42,7 +42,7 @@ public class CacheRemoveAllOperationTests extends AbstractCacheOperationTests<Ca
|
||||
CacheRemoveAllOperation operation = createSimpleOperation();
|
||||
|
||||
CacheInvocationParameter[] allParameters = operation.getAllParameters();
|
||||
assertThat(allParameters).isEmpty();
|
||||
assertThat(allParameters.length).isEqualTo(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -42,7 +42,7 @@ public class CacheRemoveOperationTests extends AbstractCacheOperationTests<Cache
|
||||
CacheRemoveOperation operation = createSimpleOperation();
|
||||
|
||||
CacheInvocationParameter[] allParameters = operation.getAllParameters(2L);
|
||||
assertThat(allParameters).hasSize(1);
|
||||
assertThat(allParameters.length).isEqualTo(1);
|
||||
assertCacheInvocationParameter(allParameters[0], Long.class, 2L, 0);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@ public class CacheResolverAdapterTests extends AbstractJCacheTests {
|
||||
CacheResolverAdapter adapter = new CacheResolverAdapter(getCacheResolver(dummyContext, "testCache"));
|
||||
Collection<? extends Cache> caches = adapter.resolveCaches(dummyContext);
|
||||
assertThat(caches).isNotNull();
|
||||
assertThat(caches).hasSize(1);
|
||||
assertThat(caches.size()).isEqualTo(1);
|
||||
assertThat(caches.iterator().next().getName()).isEqualTo("testCache");
|
||||
}
|
||||
|
||||
|
||||
+5
-5
@@ -57,11 +57,11 @@ public class CacheResultOperationTests extends AbstractCacheOperationTests<Cache
|
||||
assertThat(operation.getExceptionCacheResolver()).isEqualTo(defaultExceptionCacheResolver);
|
||||
|
||||
CacheInvocationParameter[] allParameters = operation.getAllParameters(2L);
|
||||
assertThat(allParameters).hasSize(1);
|
||||
assertThat(allParameters.length).isEqualTo(1);
|
||||
assertCacheInvocationParameter(allParameters[0], Long.class, 2L, 0);
|
||||
|
||||
CacheInvocationParameter[] keyParameters = operation.getKeyParameters(2L);
|
||||
assertThat(keyParameters).hasSize(1);
|
||||
assertThat(keyParameters.length).isEqualTo(1);
|
||||
assertCacheInvocationParameter(keyParameters[0], Long.class, 2L, 0);
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ public class CacheResultOperationTests extends AbstractCacheOperationTests<Cache
|
||||
CacheResultOperation operation = createDefaultOperation(methodDetails);
|
||||
|
||||
CacheInvocationParameter[] keyParameters = operation.getKeyParameters(3L, Boolean.TRUE, "Foo");
|
||||
assertThat(keyParameters).hasSize(2);
|
||||
assertThat(keyParameters.length).isEqualTo(2);
|
||||
assertCacheInvocationParameter(keyParameters[0], Long.class, 3L, 0);
|
||||
assertCacheInvocationParameter(keyParameters[1], String.class, "Foo", 2);
|
||||
}
|
||||
@@ -107,11 +107,11 @@ public class CacheResultOperationTests extends AbstractCacheOperationTests<Cache
|
||||
CacheInvocationParameter[] parameters = operation.getAllParameters(2L, "foo");
|
||||
|
||||
Set<Annotation> firstParameterAnnotations = parameters[0].getAnnotations();
|
||||
assertThat(firstParameterAnnotations).hasSize(1);
|
||||
assertThat(firstParameterAnnotations.size()).isEqualTo(1);
|
||||
assertThat(firstParameterAnnotations.iterator().next().annotationType()).isEqualTo(CacheKey.class);
|
||||
|
||||
Set<Annotation> secondParameterAnnotations = parameters[1].getAnnotations();
|
||||
assertThat(secondParameterAnnotations).hasSize(1);
|
||||
assertThat(secondParameterAnnotations.size()).isEqualTo(1);
|
||||
assertThat(secondParameterAnnotations.iterator().next().annotationType()).isEqualTo(Value.class);
|
||||
}
|
||||
|
||||
|
||||
+21
-21
@@ -79,22 +79,22 @@ public class JavaMailSenderTests {
|
||||
assertThat(sender.transport.getConnectedPassword()).isEqualTo("password");
|
||||
assertThat(sender.transport.isCloseCalled()).isTrue();
|
||||
|
||||
assertThat(sender.transport.getSentMessages()).hasSize(1);
|
||||
assertThat(sender.transport.getSentMessages().size()).isEqualTo(1);
|
||||
MimeMessage sentMessage = sender.transport.getSentMessage(0);
|
||||
List<Address> froms = Arrays.asList(sentMessage.getFrom());
|
||||
assertThat(froms).hasSize(1);
|
||||
assertThat(froms.size()).isEqualTo(1);
|
||||
assertThat(((InternetAddress) froms.get(0)).getAddress()).isEqualTo("me@mail.org");
|
||||
List<Address> replyTos = Arrays.asList(sentMessage.getReplyTo());
|
||||
assertThat(((InternetAddress) replyTos.get(0)).getAddress()).isEqualTo("reply@mail.org");
|
||||
List<Address> tos = Arrays.asList(sentMessage.getRecipients(Message.RecipientType.TO));
|
||||
assertThat(tos).hasSize(1);
|
||||
assertThat(tos.size()).isEqualTo(1);
|
||||
assertThat(((InternetAddress) tos.get(0)).getAddress()).isEqualTo("you@mail.org");
|
||||
List<Address> ccs = Arrays.asList(sentMessage.getRecipients(Message.RecipientType.CC));
|
||||
assertThat(ccs).hasSize(2);
|
||||
assertThat(ccs.size()).isEqualTo(2);
|
||||
assertThat(((InternetAddress) ccs.get(0)).getAddress()).isEqualTo("he@mail.org");
|
||||
assertThat(((InternetAddress) ccs.get(1)).getAddress()).isEqualTo("she@mail.org");
|
||||
List<Address> bccs = Arrays.asList(sentMessage.getRecipients(Message.RecipientType.BCC));
|
||||
assertThat(bccs).hasSize(2);
|
||||
assertThat(bccs.size()).isEqualTo(2);
|
||||
assertThat(((InternetAddress) bccs.get(0)).getAddress()).isEqualTo("us@mail.org");
|
||||
assertThat(((InternetAddress) bccs.get(1)).getAddress()).isEqualTo("them@mail.org");
|
||||
assertThat(sentMessage.getSentDate().getTime()).isEqualTo(sentDate.getTime());
|
||||
@@ -120,14 +120,14 @@ public class JavaMailSenderTests {
|
||||
assertThat(sender.transport.getConnectedPassword()).isEqualTo("password");
|
||||
assertThat(sender.transport.isCloseCalled()).isTrue();
|
||||
|
||||
assertThat(sender.transport.getSentMessages()).hasSize(2);
|
||||
assertThat(sender.transport.getSentMessages().size()).isEqualTo(2);
|
||||
MimeMessage sentMessage1 = sender.transport.getSentMessage(0);
|
||||
List<Address> tos1 = Arrays.asList(sentMessage1.getRecipients(Message.RecipientType.TO));
|
||||
assertThat(tos1).hasSize(1);
|
||||
assertThat(tos1.size()).isEqualTo(1);
|
||||
assertThat(((InternetAddress) tos1.get(0)).getAddress()).isEqualTo("he@mail.org");
|
||||
MimeMessage sentMessage2 = sender.transport.getSentMessage(1);
|
||||
List<Address> tos2 = Arrays.asList(sentMessage2.getRecipients(Message.RecipientType.TO));
|
||||
assertThat(tos2).hasSize(1);
|
||||
assertThat(tos2.size()).isEqualTo(1);
|
||||
assertThat(((InternetAddress) tos2.get(0)).getAddress()).isEqualTo("she@mail.org");
|
||||
}
|
||||
|
||||
@@ -146,7 +146,7 @@ public class JavaMailSenderTests {
|
||||
assertThat(sender.transport.getConnectedUsername()).isEqualTo("username");
|
||||
assertThat(sender.transport.getConnectedPassword()).isEqualTo("password");
|
||||
assertThat(sender.transport.isCloseCalled()).isTrue();
|
||||
assertThat(sender.transport.getSentMessages()).hasSize(1);
|
||||
assertThat(sender.transport.getSentMessages().size()).isEqualTo(1);
|
||||
assertThat(sender.transport.getSentMessage(0)).isEqualTo(mimeMessage);
|
||||
}
|
||||
|
||||
@@ -167,7 +167,7 @@ public class JavaMailSenderTests {
|
||||
assertThat(sender.transport.getConnectedUsername()).isEqualTo("username");
|
||||
assertThat(sender.transport.getConnectedPassword()).isEqualTo("password");
|
||||
assertThat(sender.transport.isCloseCalled()).isTrue();
|
||||
assertThat(sender.transport.getSentMessages()).hasSize(2);
|
||||
assertThat(sender.transport.getSentMessages().size()).isEqualTo(2);
|
||||
assertThat(sender.transport.getSentMessage(0)).isEqualTo(mimeMessage1);
|
||||
assertThat(sender.transport.getSentMessage(1)).isEqualTo(mimeMessage2);
|
||||
}
|
||||
@@ -191,7 +191,7 @@ public class JavaMailSenderTests {
|
||||
assertThat(sender.transport.getConnectedUsername()).isEqualTo("username");
|
||||
assertThat(sender.transport.getConnectedPassword()).isEqualTo("password");
|
||||
assertThat(sender.transport.isCloseCalled()).isTrue();
|
||||
assertThat(sender.transport.getSentMessages()).hasSize(1);
|
||||
assertThat(sender.transport.getSentMessages().size()).isEqualTo(1);
|
||||
assertThat(sender.transport.getSentMessage(0)).isEqualTo(messages.get(0));
|
||||
}
|
||||
|
||||
@@ -218,7 +218,7 @@ public class JavaMailSenderTests {
|
||||
assertThat(sender.transport.getConnectedUsername()).isEqualTo("username");
|
||||
assertThat(sender.transport.getConnectedPassword()).isEqualTo("password");
|
||||
assertThat(sender.transport.isCloseCalled()).isTrue();
|
||||
assertThat(sender.transport.getSentMessages()).hasSize(2);
|
||||
assertThat(sender.transport.getSentMessages().size()).isEqualTo(2);
|
||||
assertThat(sender.transport.getSentMessage(0)).isEqualTo(messages.get(0));
|
||||
assertThat(sender.transport.getSentMessage(1)).isEqualTo(messages.get(1));
|
||||
}
|
||||
@@ -242,7 +242,7 @@ public class JavaMailSenderTests {
|
||||
assertThat(sender.transport.getConnectedUsername()).isEqualTo("username");
|
||||
assertThat(sender.transport.getConnectedPassword()).isEqualTo("password");
|
||||
assertThat(sender.transport.isCloseCalled()).isTrue();
|
||||
assertThat(sender.transport.getSentMessages()).hasSize(1);
|
||||
assertThat(sender.transport.getSentMessages().size()).isEqualTo(1);
|
||||
assertThat(sender.transport.getSentMessage(0)).isEqualTo(message.getMimeMessage());
|
||||
}
|
||||
|
||||
@@ -266,7 +266,7 @@ public class JavaMailSenderTests {
|
||||
assertThat(sender.transport.getConnectedUsername()).isEqualTo("username");
|
||||
assertThat(sender.transport.getConnectedPassword()).isEqualTo("password");
|
||||
assertThat(sender.transport.isCloseCalled()).isTrue();
|
||||
assertThat(sender.transport.getSentMessages()).hasSize(1);
|
||||
assertThat(sender.transport.getSentMessages().size()).isEqualTo(1);
|
||||
assertThat(sender.transport.getSentMessage(0)).isEqualTo(message.getMimeMessage());
|
||||
}
|
||||
|
||||
@@ -291,7 +291,7 @@ public class JavaMailSenderTests {
|
||||
assertThat(sender.transport.getConnectedUsername()).isEqualTo("username");
|
||||
assertThat(sender.transport.getConnectedPassword()).isEqualTo("password");
|
||||
assertThat(sender.transport.isCloseCalled()).isTrue();
|
||||
assertThat(sender.transport.getSentMessages()).hasSize(1);
|
||||
assertThat(sender.transport.getSentMessages().size()).isEqualTo(1);
|
||||
assertThat(sender.transport.getSentMessage(0)).isEqualTo(message.getMimeMessage());
|
||||
}
|
||||
|
||||
@@ -349,7 +349,7 @@ public class JavaMailSenderTests {
|
||||
assertThat(sender.transport.getConnectedUsername()).isEqualTo("username");
|
||||
assertThat(sender.transport.getConnectedPassword()).isEqualTo("password");
|
||||
assertThat(sender.transport.isCloseCalled()).isTrue();
|
||||
assertThat(sender.transport.getSentMessages()).hasSize(1);
|
||||
assertThat(sender.transport.getSentMessages().size()).isEqualTo(1);
|
||||
assertThat(sender.transport.getSentMessage(0)).isEqualTo(mimeMessage);
|
||||
}
|
||||
|
||||
@@ -377,7 +377,7 @@ public class JavaMailSenderTests {
|
||||
assertThat(sender.transport.getConnectedUsername()).isEqualTo("username");
|
||||
assertThat(sender.transport.getConnectedPassword()).isEqualTo("password");
|
||||
assertThat(sender.transport.isCloseCalled()).isTrue();
|
||||
assertThat(sender.transport.getSentMessages()).hasSize(1);
|
||||
assertThat(sender.transport.getSentMessages().size()).isEqualTo(1);
|
||||
assertThat(sender.transport.getSentMessage(0)).isEqualTo(mimeMessage);
|
||||
}
|
||||
|
||||
@@ -427,9 +427,9 @@ public class JavaMailSenderTests {
|
||||
assertThat(sender.transport.getConnectedUsername()).isEqualTo("username");
|
||||
assertThat(sender.transport.getConnectedPassword()).isEqualTo("password");
|
||||
assertThat(sender.transport.isCloseCalled()).isTrue();
|
||||
assertThat(sender.transport.getSentMessages()).hasSize(1);
|
||||
assertThat(sender.transport.getSentMessages().size()).isEqualTo(1);
|
||||
assertThat(sender.transport.getSentMessage(0).getAllRecipients()[0]).isEqualTo(new InternetAddress("she@mail.org"));
|
||||
assertThat(ex.getFailedMessages()).hasSize(1);
|
||||
assertThat(ex.getFailedMessages().size()).isEqualTo(1);
|
||||
assertThat(ex.getFailedMessages().keySet().iterator().next()).isEqualTo(simpleMessage1);
|
||||
Object subEx = ex.getFailedMessages().values().iterator().next();
|
||||
boolean condition = subEx instanceof MessagingException;
|
||||
@@ -460,9 +460,9 @@ public class JavaMailSenderTests {
|
||||
assertThat(sender.transport.getConnectedUsername()).isEqualTo("username");
|
||||
assertThat(sender.transport.getConnectedPassword()).isEqualTo("password");
|
||||
assertThat(sender.transport.isCloseCalled()).isTrue();
|
||||
assertThat(sender.transport.getSentMessages()).hasSize(1);
|
||||
assertThat(sender.transport.getSentMessages().size()).isEqualTo(1);
|
||||
assertThat(sender.transport.getSentMessage(0)).isEqualTo(mimeMessage2);
|
||||
assertThat(ex.getFailedMessages()).hasSize(1);
|
||||
assertThat(ex.getFailedMessages().size()).isEqualTo(1);
|
||||
assertThat(ex.getFailedMessages().keySet().iterator().next()).isEqualTo(mimeMessage1);
|
||||
Object subEx = ex.getFailedMessages().values().iterator().next();
|
||||
boolean condition = subEx instanceof MessagingException;
|
||||
|
||||
+8
-5
@@ -17,6 +17,7 @@
|
||||
package org.springframework.context.annotation;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -65,12 +66,14 @@ public abstract class ConfigurationClassUtils {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(ConfigurationClassUtils.class);
|
||||
|
||||
private static final Set<String> candidateIndicators = Set.of(
|
||||
Component.class.getName(),
|
||||
ComponentScan.class.getName(),
|
||||
Import.class.getName(),
|
||||
ImportResource.class.getName());
|
||||
private static final Set<String> candidateIndicators = new HashSet<>(8);
|
||||
|
||||
static {
|
||||
candidateIndicators.add(Component.class.getName());
|
||||
candidateIndicators.add(ComponentScan.class.getName());
|
||||
candidateIndicators.add(Import.class.getName());
|
||||
candidateIndicators.add(ImportResource.class.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize a configuration class proxy for the specified class.
|
||||
|
||||
+11
-12
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -60,8 +60,8 @@ abstract class ParserStrategyUtils {
|
||||
if (clazz.isInterface()) {
|
||||
throw new BeanInstantiationException(clazz, "Specified class is an interface");
|
||||
}
|
||||
ClassLoader classLoader = (registry instanceof ConfigurableBeanFactory cbf ?
|
||||
cbf.getBeanClassLoader() : resourceLoader.getClassLoader());
|
||||
ClassLoader classLoader = (registry instanceof ConfigurableBeanFactory ?
|
||||
((ConfigurableBeanFactory) registry).getBeanClassLoader() : resourceLoader.getClassLoader());
|
||||
T instance = (T) createInstance(clazz, environment, resourceLoader, registry, classLoader);
|
||||
ParserStrategyUtils.invokeAwareMethods(instance, environment, resourceLoader, registry, classLoader);
|
||||
return instance;
|
||||
@@ -122,18 +122,17 @@ abstract class ParserStrategyUtils {
|
||||
ResourceLoader resourceLoader, BeanDefinitionRegistry registry, @Nullable ClassLoader classLoader) {
|
||||
|
||||
if (parserStrategyBean instanceof Aware) {
|
||||
if (parserStrategyBean instanceof BeanClassLoaderAware beanClassLoaderAware && classLoader != null) {
|
||||
beanClassLoaderAware.setBeanClassLoader(classLoader);
|
||||
if (parserStrategyBean instanceof BeanClassLoaderAware && classLoader != null) {
|
||||
((BeanClassLoaderAware) parserStrategyBean).setBeanClassLoader(classLoader);
|
||||
}
|
||||
if (parserStrategyBean instanceof BeanFactoryAware beanFactoryAware &&
|
||||
registry instanceof BeanFactory beanFactory) {
|
||||
beanFactoryAware.setBeanFactory(beanFactory);
|
||||
if (parserStrategyBean instanceof BeanFactoryAware && registry instanceof BeanFactory) {
|
||||
((BeanFactoryAware) parserStrategyBean).setBeanFactory((BeanFactory) registry);
|
||||
}
|
||||
if (parserStrategyBean instanceof EnvironmentAware environmentAware) {
|
||||
environmentAware.setEnvironment(environment);
|
||||
if (parserStrategyBean instanceof EnvironmentAware) {
|
||||
((EnvironmentAware) parserStrategyBean).setEnvironment(environment);
|
||||
}
|
||||
if (parserStrategyBean instanceof ResourceLoaderAware resourceLoaderAware) {
|
||||
resourceLoaderAware.setResourceLoader(resourceLoader);
|
||||
if (parserStrategyBean instanceof ResourceLoaderAware) {
|
||||
((ResourceLoaderAware) parserStrategyBean).setResourceLoader(resourceLoader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -36,7 +36,7 @@ public class BeanExpressionContextAccessor implements PropertyAccessor {
|
||||
|
||||
@Override
|
||||
public boolean canRead(EvaluationContext context, @Nullable Object target, String name) throws AccessException {
|
||||
return (target instanceof BeanExpressionContext bec && bec.containsObject(name));
|
||||
return (target instanceof BeanExpressionContext && ((BeanExpressionContext) target).containsObject(name));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -41,7 +41,7 @@ public class BeanFactoryAccessor implements PropertyAccessor {
|
||||
|
||||
@Override
|
||||
public boolean canRead(EvaluationContext context, @Nullable Object target, String name) throws AccessException {
|
||||
return (target instanceof BeanFactory beanFactory && beanFactory.containsBean(name));
|
||||
return (target instanceof BeanFactory && ((BeanFactory) target).containsBean(name));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+16
-15
@@ -395,8 +395,8 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
||||
|
||||
// Decorate event as an ApplicationEvent if necessary
|
||||
ApplicationEvent applicationEvent;
|
||||
if (event instanceof ApplicationEvent applEvent) {
|
||||
applicationEvent = applEvent;
|
||||
if (event instanceof ApplicationEvent) {
|
||||
applicationEvent = (ApplicationEvent) event;
|
||||
}
|
||||
else {
|
||||
applicationEvent = new PayloadApplicationEvent<>(this, event, eventType);
|
||||
@@ -415,8 +415,8 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
||||
|
||||
// Publish event via parent context as well...
|
||||
if (this.parent != null) {
|
||||
if (this.parent instanceof AbstractApplicationContext abstractApplicationContext) {
|
||||
abstractApplicationContext.publishEvent(event, eventType);
|
||||
if (this.parent instanceof AbstractApplicationContext) {
|
||||
((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
|
||||
}
|
||||
else {
|
||||
this.parent.publishEvent(event);
|
||||
@@ -497,8 +497,8 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
||||
this.parent = parent;
|
||||
if (parent != null) {
|
||||
Environment parentEnvironment = parent.getEnvironment();
|
||||
if (parentEnvironment instanceof ConfigurableEnvironment configurableEnvironment) {
|
||||
getEnvironment().merge(configurableEnvironment);
|
||||
if (parentEnvironment instanceof ConfigurableEnvironment) {
|
||||
getEnvironment().merge((ConfigurableEnvironment) parentEnvironment);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -770,11 +770,12 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
||||
if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
|
||||
this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
|
||||
// Make MessageSource aware of parent MessageSource.
|
||||
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource hms &&
|
||||
hms.getParentMessageSource() == null) {
|
||||
// Only set parent context as parent MessageSource if no parent MessageSource
|
||||
// registered already.
|
||||
hms.setParentMessageSource(getInternalParentMessageSource());
|
||||
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource hms) {
|
||||
if (hms.getParentMessageSource() == null) {
|
||||
// Only set parent context as parent MessageSource if no parent MessageSource
|
||||
// registered already.
|
||||
hms.setParentMessageSource(getInternalParentMessageSource());
|
||||
}
|
||||
}
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Using MessageSource [" + this.messageSource + "]");
|
||||
@@ -1349,8 +1350,8 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
||||
*/
|
||||
@Nullable
|
||||
protected BeanFactory getInternalParentBeanFactory() {
|
||||
return (getParent() instanceof ConfigurableApplicationContext cac ?
|
||||
cac.getBeanFactory() : getParent());
|
||||
return (getParent() instanceof ConfigurableApplicationContext ?
|
||||
((ConfigurableApplicationContext) getParent()).getBeanFactory() : getParent());
|
||||
}
|
||||
|
||||
|
||||
@@ -1392,8 +1393,8 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
||||
*/
|
||||
@Nullable
|
||||
protected MessageSource getInternalParentMessageSource() {
|
||||
return (getParent() instanceof AbstractApplicationContext abstractApplicationContext ?
|
||||
abstractApplicationContext.messageSource : getParent());
|
||||
return (getParent() instanceof AbstractApplicationContext ?
|
||||
((AbstractApplicationContext) getParent()).messageSource : getParent());
|
||||
}
|
||||
|
||||
|
||||
|
||||
+7
-7
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -255,10 +255,10 @@ public abstract class AbstractMessageSource extends MessageSourceSupport impleme
|
||||
protected String getMessageFromParent(String code, @Nullable Object[] args, Locale locale) {
|
||||
MessageSource parent = getParentMessageSource();
|
||||
if (parent != null) {
|
||||
if (parent instanceof AbstractMessageSource abstractMessageSource) {
|
||||
if (parent instanceof AbstractMessageSource) {
|
||||
// Call internal method to avoid getting the default code back
|
||||
// in case of "useCodeAsDefaultMessage" being activated.
|
||||
return abstractMessageSource.getMessageInternal(code, args, locale);
|
||||
return ((AbstractMessageSource) parent).getMessageInternal(code, args, locale);
|
||||
}
|
||||
else {
|
||||
// Check parent MessageSource, returning null if not found there.
|
||||
@@ -287,8 +287,8 @@ public abstract class AbstractMessageSource extends MessageSourceSupport impleme
|
||||
String defaultMessage = resolvable.getDefaultMessage();
|
||||
String[] codes = resolvable.getCodes();
|
||||
if (defaultMessage != null) {
|
||||
if (resolvable instanceof DefaultMessageSourceResolvable defaultMessageSourceResolvable &&
|
||||
!defaultMessageSourceResolvable.shouldRenderDefaultMessage()) {
|
||||
if (resolvable instanceof DefaultMessageSourceResolvable &&
|
||||
!((DefaultMessageSourceResolvable) resolvable).shouldRenderDefaultMessage()) {
|
||||
// Given default message does not contain any argument placeholders
|
||||
// (and isn't escaped for alwaysUseMessageFormat either) -> return as-is.
|
||||
return defaultMessage;
|
||||
@@ -336,8 +336,8 @@ public abstract class AbstractMessageSource extends MessageSourceSupport impleme
|
||||
}
|
||||
List<Object> resolvedArgs = new ArrayList<>(args.length);
|
||||
for (Object arg : args) {
|
||||
if (arg instanceof MessageSourceResolvable messageSourceResolvable) {
|
||||
resolvedArgs.add(getMessage(messageSourceResolvable, locale));
|
||||
if (arg instanceof MessageSourceResolvable) {
|
||||
resolvedArgs.add(getMessage((MessageSourceResolvable) arg, locale));
|
||||
}
|
||||
else {
|
||||
resolvedArgs.add(arg);
|
||||
|
||||
+21
-25
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,7 +17,6 @@
|
||||
package org.springframework.context.support;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.Aware;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.beans.factory.config.EmbeddedValueResolver;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
@@ -48,7 +47,6 @@ import org.springframework.util.StringValueResolver;
|
||||
* @author Juergen Hoeller
|
||||
* @author Costin Leau
|
||||
* @author Chris Beams
|
||||
* @author Sam Brannen
|
||||
* @since 10.10.2003
|
||||
* @see org.springframework.context.EnvironmentAware
|
||||
* @see org.springframework.context.EmbeddedValueResolverAware
|
||||
@@ -89,28 +87,26 @@ class ApplicationContextAwareProcessor implements BeanPostProcessor {
|
||||
}
|
||||
|
||||
private void invokeAwareInterfaces(Object bean) {
|
||||
if (bean instanceof Aware) {
|
||||
if (bean instanceof EnvironmentAware environmentAware) {
|
||||
environmentAware.setEnvironment(this.applicationContext.getEnvironment());
|
||||
}
|
||||
if (bean instanceof EmbeddedValueResolverAware embeddedValueResolverAware) {
|
||||
embeddedValueResolverAware.setEmbeddedValueResolver(this.embeddedValueResolver);
|
||||
}
|
||||
if (bean instanceof ResourceLoaderAware resourceLoaderAware) {
|
||||
resourceLoaderAware.setResourceLoader(this.applicationContext);
|
||||
}
|
||||
if (bean instanceof ApplicationEventPublisherAware applicationEventPublisherAware) {
|
||||
applicationEventPublisherAware.setApplicationEventPublisher(this.applicationContext);
|
||||
}
|
||||
if (bean instanceof MessageSourceAware messageSourceAware) {
|
||||
messageSourceAware.setMessageSource(this.applicationContext);
|
||||
}
|
||||
if (bean instanceof ApplicationStartupAware applicationStartupAware) {
|
||||
applicationStartupAware.setApplicationStartup(this.applicationContext.getApplicationStartup());
|
||||
}
|
||||
if (bean instanceof ApplicationContextAware applicationContextAware) {
|
||||
applicationContextAware.setApplicationContext(this.applicationContext);
|
||||
}
|
||||
if (bean instanceof EnvironmentAware) {
|
||||
((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
|
||||
}
|
||||
if (bean instanceof EmbeddedValueResolverAware) {
|
||||
((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
|
||||
}
|
||||
if (bean instanceof ResourceLoaderAware) {
|
||||
((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
|
||||
}
|
||||
if (bean instanceof ApplicationEventPublisherAware) {
|
||||
((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
|
||||
}
|
||||
if (bean instanceof MessageSourceAware) {
|
||||
((MessageSourceAware) bean).setMessageSource(this.applicationContext);
|
||||
}
|
||||
if (bean instanceof ApplicationStartupAware) {
|
||||
((ApplicationStartupAware) bean).setApplicationStartup(this.applicationContext.getApplicationStartup());
|
||||
}
|
||||
if (bean instanceof ApplicationContextAware) {
|
||||
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+7
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -71,12 +71,12 @@ class ApplicationListenerDetector implements DestructionAwareBeanPostProcessor,
|
||||
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) {
|
||||
if (bean instanceof ApplicationListener<?> applicationListener) {
|
||||
if (bean instanceof ApplicationListener) {
|
||||
// potentially not detected as a listener by getBeanNamesForType retrieval
|
||||
Boolean flag = this.singletonNames.get(beanName);
|
||||
if (Boolean.TRUE.equals(flag)) {
|
||||
// singleton bean (top-level or inner): register on the fly
|
||||
this.applicationContext.addApplicationListener(applicationListener);
|
||||
this.applicationContext.addApplicationListener((ApplicationListener<?>) bean);
|
||||
}
|
||||
else if (Boolean.FALSE.equals(flag)) {
|
||||
if (logger.isWarnEnabled() && !this.applicationContext.containsBean(beanName)) {
|
||||
@@ -94,10 +94,10 @@ class ApplicationListenerDetector implements DestructionAwareBeanPostProcessor,
|
||||
|
||||
@Override
|
||||
public void postProcessBeforeDestruction(Object bean, String beanName) {
|
||||
if (bean instanceof ApplicationListener<?> applicationListener) {
|
||||
if (bean instanceof ApplicationListener) {
|
||||
try {
|
||||
ApplicationEventMulticaster multicaster = this.applicationContext.getApplicationEventMulticaster();
|
||||
multicaster.removeApplicationListener(applicationListener);
|
||||
multicaster.removeApplicationListener((ApplicationListener<?>) bean);
|
||||
multicaster.removeApplicationListenerBean(beanName);
|
||||
}
|
||||
catch (IllegalStateException ex) {
|
||||
@@ -114,9 +114,8 @@ class ApplicationListenerDetector implements DestructionAwareBeanPostProcessor,
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object other) {
|
||||
return (this == other ||
|
||||
(other instanceof ApplicationListenerDetector applicationListenerDectector &&
|
||||
this.applicationContext == applicationListenerDectector.applicationContext));
|
||||
return (this == other || (other instanceof ApplicationListenerDetector &&
|
||||
this.applicationContext == ((ApplicationListenerDetector) other).applicationContext));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+10
-10
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -74,11 +74,11 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor
|
||||
|
||||
@Override
|
||||
public void setBeanFactory(BeanFactory beanFactory) {
|
||||
if (!(beanFactory instanceof ConfigurableListableBeanFactory clbf)) {
|
||||
if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
|
||||
throw new IllegalArgumentException(
|
||||
"DefaultLifecycleProcessor requires a ConfigurableListableBeanFactory: " + beanFactory);
|
||||
}
|
||||
this.beanFactory = clbf;
|
||||
this.beanFactory = (ConfigurableListableBeanFactory) beanFactory;
|
||||
}
|
||||
|
||||
private ConfigurableListableBeanFactory getBeanFactory() {
|
||||
@@ -143,7 +143,7 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor
|
||||
Map<Integer, LifecycleGroup> phases = new TreeMap<>();
|
||||
|
||||
lifecycleBeans.forEach((beanName, bean) -> {
|
||||
if (!autoStartupOnly || (bean instanceof SmartLifecycle smartLifecycle && smartLifecycle.isAutoStartup())) {
|
||||
if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {
|
||||
int phase = getPhase(bean);
|
||||
phases.computeIfAbsent(
|
||||
phase,
|
||||
@@ -170,7 +170,7 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor
|
||||
doStart(lifecycleBeans, dependency, autoStartupOnly);
|
||||
}
|
||||
if (!bean.isRunning() &&
|
||||
(!autoStartupOnly || !(bean instanceof SmartLifecycle smartLifecycle) || smartLifecycle.isAutoStartup())) {
|
||||
(!autoStartupOnly || !(bean instanceof SmartLifecycle) || ((SmartLifecycle) bean).isAutoStartup())) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Starting bean '" + beanName + "' of type [" + bean.getClass().getName() + "]");
|
||||
}
|
||||
@@ -225,13 +225,13 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor
|
||||
}
|
||||
try {
|
||||
if (bean.isRunning()) {
|
||||
if (bean instanceof SmartLifecycle smartLifecycle) {
|
||||
if (bean instanceof SmartLifecycle) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Asking bean '" + beanName + "' of type [" +
|
||||
bean.getClass().getName() + "] to stop");
|
||||
}
|
||||
countDownBeanNames.add(beanName);
|
||||
smartLifecycle.stop(() -> {
|
||||
((SmartLifecycle) bean).stop(() -> {
|
||||
latch.countDown();
|
||||
countDownBeanNames.remove(beanName);
|
||||
if (logger.isDebugEnabled()) {
|
||||
@@ -283,8 +283,8 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor
|
||||
(!isFactoryBean || matchesBeanType(Lifecycle.class, beanNameToCheck, beanFactory))) ||
|
||||
matchesBeanType(SmartLifecycle.class, beanNameToCheck, beanFactory)) {
|
||||
Object bean = beanFactory.getBean(beanNameToCheck);
|
||||
if (bean != this && bean instanceof Lifecycle lifecycle) {
|
||||
beans.put(beanNameToRegister, lifecycle);
|
||||
if (bean != this && bean instanceof Lifecycle) {
|
||||
beans.put(beanNameToRegister, (Lifecycle) bean);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -306,7 +306,7 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor
|
||||
* @see SmartLifecycle
|
||||
*/
|
||||
protected int getPhase(Lifecycle bean) {
|
||||
return (bean instanceof Phased phased ? phased.getPhase() : 0);
|
||||
return (bean instanceof Phased ? ((Phased) bean).getPhase() : 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+2
-2
@@ -272,8 +272,8 @@ public class GenericApplicationContext extends AbstractApplicationContext implem
|
||||
*/
|
||||
@Override
|
||||
public Resource[] getResources(String locationPattern) throws IOException {
|
||||
if (this.resourceLoader instanceof ResourcePatternResolver resourcePatternResolver) {
|
||||
return resourcePatternResolver.getResources(locationPattern);
|
||||
if (this.resourceLoader instanceof ResourcePatternResolver) {
|
||||
return ((ResourcePatternResolver) this.resourceLoader).getResources(locationPattern);
|
||||
}
|
||||
return super.getResources(locationPattern);
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -242,8 +242,8 @@ public class GenericGroovyApplicationContext extends GenericApplicationContext i
|
||||
|
||||
@Override
|
||||
public void setProperty(String property, Object newValue) {
|
||||
if (newValue instanceof BeanDefinition beanDefinition) {
|
||||
registerBeanDefinition(property, beanDefinition);
|
||||
if (newValue instanceof BeanDefinition) {
|
||||
registerBeanDefinition(property, (BeanDefinition) newValue);
|
||||
}
|
||||
else {
|
||||
this.metaClass.setProperty(this, property, newValue);
|
||||
|
||||
+4
-4
@@ -323,8 +323,8 @@ final class PostProcessorRegistrationDelegate {
|
||||
return;
|
||||
}
|
||||
Comparator<Object> comparatorToUse = null;
|
||||
if (beanFactory instanceof DefaultListableBeanFactory dlbf) {
|
||||
comparatorToUse = dlbf.getDependencyComparator();
|
||||
if (beanFactory instanceof DefaultListableBeanFactory) {
|
||||
comparatorToUse = ((DefaultListableBeanFactory) beanFactory).getDependencyComparator();
|
||||
}
|
||||
if (comparatorToUse == null) {
|
||||
comparatorToUse = OrderComparator.INSTANCE;
|
||||
@@ -366,9 +366,9 @@ final class PostProcessorRegistrationDelegate {
|
||||
private static void registerBeanPostProcessors(
|
||||
ConfigurableListableBeanFactory beanFactory, List<? extends BeanPostProcessor> postProcessors) {
|
||||
|
||||
if (beanFactory instanceof AbstractBeanFactory abstractBeanFactory) {
|
||||
if (beanFactory instanceof AbstractBeanFactory) {
|
||||
// Bulk addition is more efficient against our CopyOnWriteArrayList there
|
||||
abstractBeanFactory.addBeanPostProcessors(postProcessors);
|
||||
((AbstractBeanFactory) beanFactory).addBeanPostProcessors(postProcessors);
|
||||
}
|
||||
else {
|
||||
for (BeanPostProcessor postProcessor : postProcessors) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user