From 3f78bfa51bf87fc64300d21d38b79ed70f406c4d Mon Sep 17 00:00:00 2001 From: Miykaelxxm Date: Thu, 3 Mar 2022 19:15:39 +0800 Subject: [PATCH] add spring framework --- docs/.vuepress/config.js | 79 +- docs/en/spring-boot/build-tool-plugins.md | 2 +- docs/en/spring-boot/documentation.md | 4 +- docs/en/spring-framework/READEME.md | 0 docs/en/spring-framework/README.md | 2 +- docs/en/spring-framework/core.md | 1263 +++++++-------------- docs/en/spring-framework/data-access.md | 571 +++------- docs/en/spring-framework/integration.md | 561 +++------ docs/en/spring-framework/languages.md | 191 +--- docs/en/spring-framework/overview.md | 28 +- docs/en/spring-framework/testing.md | 491 +++----- docs/en/spring-framework/web-reactive.md | 583 +++------- docs/en/spring-framework/web-servlet.md | 805 +++++-------- 13 files changed, 1489 insertions(+), 3091 deletions(-) delete mode 100644 docs/en/spring-framework/READEME.md diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index 3bcfb84..1922868 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -148,21 +148,52 @@ module.exports = { } ], sidebar: { + '/en/spring-framework/': [ + { + title: 'Spring Framework', + sidebarDepth: 2, + collapsable: false, + children: [ + "/en/spring-framework/overview.md", + "/en/spring-framework/core.md", + "/en/spring-framework/testing.md", + "/en/spring-framework/data-access.md", + "/en/spring-framework/web-servlet.md", + "/en/spring-framework/web-reactive.md", + "/en/spring-framework/integration.md", + "/en/spring-framework/languages.md" + ], + initialOpenGroupIndex: 0 // 可选的, 默认值是 0 + } + ], '/en/spring-boot/': [ { title: 'Spring Boot', sidebarDepth: 2, collapsable: false, children: [ - "/en/spring-boot/build-tool-plugins.md", - "/en/spring-boot/container-images.md", - "/en/spring-boot/core-features.md", + "/en/spring-boot/legal.md", + "/en/spring-boot/getting-help.md", + "/en/spring-boot/documentation.md", + "/en/spring-boot/getting-started.md", + "/en/spring-boot/upgrading.md", + "/en/spring-boot/using.md", + "/en/spring-boot/features.md", + "/en/spring-boot/web.md", "/en/spring-boot/data.md", - "/en/spring-boot/deploying-spring-boot-applications.md" + "/en/spring-boot/io.md", + "/en/spring-boot/messaging.md", + "/en/spring-boot/container-images.md", + "/en/spring-boot/actuator.md", + "/en/spring-boot/deployment.md", + "/en/spring-boot/cli.md", + "/en/spring-boot/build-tool-plugins.md", + "/en/spring-boot/howto.md" ], initialOpenGroupIndex: 0 // 可选的, 默认值是 0 } ], + // fallback '/en/': [{ @@ -278,15 +309,45 @@ module.exports = { '/spring-boot/': [ { - title: '介绍', + title: 'Spring Boot 文档', sidebarDepth: 2, collapsable: false, children: [ - "/spring-boot/build-tool-plugins.md", - "/spring-boot/container-images.md", - "/spring-boot/core-features.md", + "/spring-boot/legal.md", + "/spring-boot/getting-help.md", + "/spring-boot/documentation.md", + "/spring-boot/getting-started.md", + "/spring-boot/upgrading.md", + "/spring-boot/using.md", + "/spring-boot/features.md", + "/spring-boot/web.md", "/spring-boot/data.md", - "/spring-boot/deploying-spring-boot-applications.md" + "/spring-boot/io.md", + "/spring-boot/messaging.md", + "/spring-boot/container-images.md", + "/spring-boot/actuator.md", + "/spring-boot/deployment.md", + "/spring-boot/cli.md", + "/spring-boot/build-tool-plugins.md", + "/spring-boot/howto.md" + ], + initialOpenGroupIndex: 0 // 可选的, 默认值是 0 + } + ], + '/spring-framework/': [ + { + title: 'Spring Framework 文档', + sidebarDepth: 2, + collapsable: false, + children: [ + "/spring-framework/overview.md", + "/spring-framework/core.md", + "/spring-framework/testing.md", + "/spring-framework/data-access.md", + "/spring-framework/web-servlet.md", + "/spring-framework/web-reactive.md", + "/spring-framework/integration.md", + "/spring-framework/languages.md" ], initialOpenGroupIndex: 0 // 可选的, 默认值是 0 } diff --git a/docs/en/spring-boot/build-tool-plugins.md b/docs/en/spring-boot/build-tool-plugins.md index f9c149e..abeb91f 100644 --- a/docs/en/spring-boot/build-tool-plugins.md +++ b/docs/en/spring-boot/build-tool-plugins.md @@ -1,4 +1,4 @@ -# 1. Build Tool Plugins +# Build Tool Plugins Spring Boot provides build tool plugins for Maven and Gradle. The plugins offer a variety of features, including the packaging of executable jars. diff --git a/docs/en/spring-boot/documentation.md b/docs/en/spring-boot/documentation.md index 3c484c4..e3f939a 100644 --- a/docs/en/spring-boot/documentation.md +++ b/docs/en/spring-boot/documentation.md @@ -53,7 +53,7 @@ Need more details about Spring Boot’s core features?[The following content is * **Logging:** [Logging](features.html#features.logging) -## 5. Web- +## 5. Web If you develop Spring Boot web applications, take a look at the following content: @@ -91,7 +91,7 @@ If your application uses any messaging protocol, see one or more of the followin * **Spring Integration:** [Auto-configuration for Spring Integration](messaging.html#messaging.spring-integration) -## 8. IO-- +## 8. IO If your application needs IO capabilities, see one or more of the following sections: diff --git a/docs/en/spring-framework/READEME.md b/docs/en/spring-framework/READEME.md deleted file mode 100644 index e69de29..0000000 diff --git a/docs/en/spring-framework/README.md b/docs/en/spring-framework/README.md index 5edac6a..a0fa33a 100644 --- a/docs/en/spring-framework/README.md +++ b/docs/en/spring-framework/README.md @@ -1 +1 @@ -# Spring Framework \ No newline at end of file +# Spring Framework diff --git a/docs/en/spring-framework/core.md b/docs/en/spring-framework/core.md index 2feb74a..8ee51af 100644 --- a/docs/en/spring-framework/core.md +++ b/docs/en/spring-framework/core.md @@ -1,455 +1,4 @@ -Core Technologies -========== - -version 5.3.16 - -Table of Contents - -* [1. The IoC Container](#beans) - * [1.1. Introduction to the Spring IoC Container and Beans](#beans-introduction) - * [1.2. Container Overview](#beans-basics) - * [1.2.1. Configuration Metadata](#beans-factory-metadata) - * [1.2.2. Instantiating a Container](#beans-factory-instantiation) - * [Composing XML-based Configuration Metadata](#beans-factory-xml-import) - * [The Groovy Bean Definition DSL](#groovy-bean-definition-dsl) - - * [1.2.3. Using the Container](#beans-factory-client) - - * [1.3. Bean Overview](#beans-definition) - * [1.3.1. Naming Beans](#beans-beanname) - * [Aliasing a Bean outside the Bean Definition](#beans-beanname-alias) - - * [1.3.2. Instantiating Beans](#beans-factory-class) - * [Instantiation with a Constructor](#beans-factory-class-ctor) - * [Instantiation with a Static Factory Method](#beans-factory-class-static-factory-method) - * [Instantiation by Using an Instance Factory Method](#beans-factory-class-instance-factory-method) - * [Determining a Bean’s Runtime Type](#beans-factory-type-determination) - - * [1.4. Dependencies](#beans-dependencies) - * [1.4.1. Dependency Injection](#beans-factory-collaborators) - * [Constructor-based Dependency Injection](#beans-constructor-injection) - * [Setter-based Dependency Injection](#beans-setter-injection) - * [Dependency Resolution Process](#beans-dependency-resolution) - * [Examples of Dependency Injection](#beans-some-examples) - - * [1.4.2. Dependencies and Configuration in Detail](#beans-factory-properties-detailed) - * [Straight Values (Primitives, Strings, and so on)](#beans-value-element) - * [References to Other Beans (Collaborators)](#beans-ref-element) - * [Inner Beans](#beans-inner-beans) - * [Collections](#beans-collection-elements) - * [Null and Empty String Values](#beans-null-element) - * [XML Shortcut with the p-namespace](#beans-p-namespace) - * [XML Shortcut with the c-namespace](#beans-c-namespace) - * [Compound Property Names](#beans-compound-property-names) - - * [1.4.3. Using `depends-on`](#beans-factory-dependson) - * [1.4.4. Lazy-initialized Beans](#beans-factory-lazy-init) - * [1.4.5. Autowiring Collaborators](#beans-factory-autowire) - * [Limitations and Disadvantages of Autowiring](#beans-autowired-exceptions) - * [Excluding a Bean from Autowiring](#beans-factory-autowire-candidate) - - * [1.4.6. Method Injection](#beans-factory-method-injection) - * [Lookup Method Injection](#beans-factory-lookup-method-injection) - * [Arbitrary Method Replacement](#beans-factory-arbitrary-method-replacement) - - * [1.5. Bean Scopes](#beans-factory-scopes) - * [1.5.1. The Singleton Scope](#beans-factory-scopes-singleton) - * [1.5.2. The Prototype Scope](#beans-factory-scopes-prototype) - * [1.5.3. Singleton Beans with Prototype-bean Dependencies](#beans-factory-scopes-sing-prot-interaction) - * [1.5.4. Request, Session, Application, and WebSocket Scopes](#beans-factory-scopes-other) - * [Initial Web Configuration](#beans-factory-scopes-other-web-configuration) - * [Request scope](#beans-factory-scopes-request) - * [Session Scope](#beans-factory-scopes-session) - * [Application Scope](#beans-factory-scopes-application) - * [WebSocket Scope](#beans-factory-scopes-websocket) - * [Scoped Beans as Dependencies](#beans-factory-scopes-other-injection) - - * [1.5.5. Custom Scopes](#beans-factory-scopes-custom) - * [Creating a Custom Scope](#beans-factory-scopes-custom-creating) - * [Using a Custom Scope](#beans-factory-scopes-custom-using) - - * [1.6. Customizing the Nature of a Bean](#beans-factory-nature) - * [1.6.1. Lifecycle Callbacks](#beans-factory-lifecycle) - * [Initialization Callbacks](#beans-factory-lifecycle-initializingbean) - * [Destruction Callbacks](#beans-factory-lifecycle-disposablebean) - * [Default Initialization and Destroy Methods](#beans-factory-lifecycle-default-init-destroy-methods) - * [Combining Lifecycle Mechanisms](#beans-factory-lifecycle-combined-effects) - * [Startup and Shutdown Callbacks](#beans-factory-lifecycle-processor) - * [Shutting Down the Spring IoC Container Gracefully in Non-Web Applications](#beans-factory-shutdown) - - * [1.6.2. `ApplicationContextAware` and `BeanNameAware`](#beans-factory-aware) - * [1.6.3. Other `Aware` Interfaces](#aware-list) - - * [1.7. Bean Definition Inheritance](#beans-child-bean-definitions) - * [1.8. Container Extension Points](#beans-factory-extension) - * [1.8.1. Customizing Beans by Using a `BeanPostProcessor`](#beans-factory-extension-bpp) - * [Example: Hello World, `BeanPostProcessor`-style](#beans-factory-extension-bpp-examples-hw) - * [Example: The `AutowiredAnnotationBeanPostProcessor`](#beans-factory-extension-bpp-examples-aabpp) - - * [1.8.2. Customizing Configuration Metadata with a `BeanFactoryPostProcessor`](#beans-factory-extension-factory-postprocessors) - * [Example: The Class Name Substitution `PropertySourcesPlaceholderConfigurer`](#beans-factory-placeholderconfigurer) - * [Example: The `PropertyOverrideConfigurer`](#beans-factory-overrideconfigurer) - - * [1.8.3. Customizing Instantiation Logic with a `FactoryBean`](#beans-factory-extension-factorybean) - - * [1.9. Annotation-based Container Configuration](#beans-annotation-config) - * [1.9.1. @Required](#beans-required-annotation) - * [1.9.2. Using `@Autowired`](#beans-autowired-annotation) - * [1.9.3. Fine-tuning Annotation-based Autowiring with `@Primary`](#beans-autowired-annotation-primary) - * [1.9.4. Fine-tuning Annotation-based Autowiring with Qualifiers](#beans-autowired-annotation-qualifiers) - * [1.9.5. Using Generics as Autowiring Qualifiers](#beans-generics-as-qualifiers) - * [1.9.6. Using `CustomAutowireConfigurer`](#beans-custom-autowire-configurer) - * [1.9.7. Injection with `@Resource`](#beans-resource-annotation) - * [1.9.8. Using `@Value`](#beans-value-annotations) - * [1.9.9. Using `@PostConstruct` and `@PreDestroy`](#beans-postconstruct-and-predestroy-annotations) - - * [1.10. Classpath Scanning and Managed Components](#beans-classpath-scanning) - * [1.10.1. `@Component` and Further Stereotype Annotations](#beans-stereotype-annotations) - * [1.10.2. Using Meta-annotations and Composed Annotations](#beans-meta-annotations) - * [1.10.3. Automatically Detecting Classes and Registering Bean Definitions](#beans-scanning-autodetection) - * [1.10.4. Using Filters to Customize Scanning](#beans-scanning-filters) - * [1.10.5. Defining Bean Metadata within Components](#beans-factorybeans-annotations) - * [1.10.6. Naming Autodetected Components](#beans-scanning-name-generator) - * [1.10.7. Providing a Scope for Autodetected Components](#beans-scanning-scope-resolver) - * [1.10.8. Providing Qualifier Metadata with Annotations](#beans-scanning-qualifiers) - * [1.10.9. Generating an Index of Candidate Components](#beans-scanning-index) - - * [1.11. Using JSR 330 Standard Annotations](#beans-standard-annotations) - * [1.11.1. Dependency Injection with `@Inject` and `@Named`](#beans-inject-named) - * [1.11.2. `@Named` and `@ManagedBean`: Standard Equivalents to the `@Component` Annotation](#beans-named) - * [1.11.3. Limitations of JSR-330 Standard Annotations](#beans-standard-annotations-limitations) - - * [1.12. Java-based Container Configuration](#beans-java) - * [1.12.1. Basic Concepts: `@Bean` and `@Configuration`](#beans-java-basic-concepts) - * [1.12.2. Instantiating the Spring Container by Using `AnnotationConfigApplicationContext`](#beans-java-instantiating-container) - * [Simple Construction](#beans-java-instantiating-container-constructor) - * [Building the Container Programmatically by Using `register(Class…​)`](#beans-java-instantiating-container-register) - * [Enabling Component Scanning with `scan(String…​)`](#beans-java-instantiating-container-scan) - * [Support for Web Applications with `AnnotationConfigWebApplicationContext`](#beans-java-instantiating-container-web) - - * [1.12.3. Using the `@Bean` Annotation](#beans-java-bean-annotation) - * [Declaring a Bean](#beans-java-declaring-a-bean) - * [Bean Dependencies](#beans-java-dependencies) - * [Receiving Lifecycle Callbacks](#beans-java-lifecycle-callbacks) - * [Specifying Bean Scope](#beans-java-specifying-bean-scope) - * [Customizing Bean Naming](#beans-java-customizing-bean-naming) - * [Bean Aliasing](#beans-java-bean-aliasing) - * [Bean Description](#beans-java-bean-description) - - * [1.12.4. Using the `@Configuration` annotation](#beans-java-configuration-annotation) - * [Injecting Inter-bean Dependencies](#beans-java-injecting-dependencies) - * [Lookup Method Injection](#beans-java-method-injection) - * [Further Information About How Java-based Configuration Works Internally](#beans-java-further-information-java-config) - - * [1.12.5. Composing Java-based Configurations](#beans-java-composing-configuration-classes) - * [Using the `@Import` Annotation](#beans-java-using-import) - * [Conditionally Include `@Configuration` Classes or `@Bean` Methods](#beans-java-conditional) - * [Combining Java and XML Configuration](#beans-java-combining) - - * [1.13. Environment Abstraction](#beans-environment) - * [1.13.1. Bean Definition Profiles](#beans-definition-profiles) - * [Using `@Profile`](#beans-definition-profiles-java) - * [XML Bean Definition Profiles](#beans-definition-profiles-xml) - * [Activating a Profile](#beans-definition-profiles-enable) - * [Default Profile](#beans-definition-profiles-default) - - * [1.13.2. `PropertySource` Abstraction](#beans-property-source-abstraction) - * [1.13.3. Using `@PropertySource`](#beans-using-propertysource) - * [1.13.4. Placeholder Resolution in Statements](#beans-placeholder-resolution-in-statements) - - * [1.14. Registering a `LoadTimeWeaver`](#context-load-time-weaver) - * [1.15. Additional Capabilities of the `ApplicationContext`](#context-introduction) - * [1.15.1. Internationalization using `MessageSource`](#context-functionality-messagesource) - * [1.15.2. Standard and Custom Events](#context-functionality-events) - * [Annotation-based Event Listeners](#context-functionality-events-annotation) - * [Asynchronous Listeners](#context-functionality-events-async) - * [Ordering Listeners](#context-functionality-events-order) - * [Generic Events](#context-functionality-events-generics) - - * [1.15.3. Convenient Access to Low-level Resources](#context-functionality-resources) - * [1.15.4. Application Startup Tracking](#context-functionality-startup) - * [1.15.5. Convenient ApplicationContext Instantiation for Web Applications](#context-create) - * [1.15.6. Deploying a Spring `ApplicationContext` as a Java EE RAR File](#context-deploy-rar) - - * [1.16. The `BeanFactory`](#beans-beanfactory) - * [1.16.1. `BeanFactory` or `ApplicationContext`?](#context-introduction-ctx-vs-beanfactory) - -* [2. Resources](#resources) - * [2.1. Introduction](#resources-introduction) - * [2.2. The `Resource` Interface](#resources-resource) - * [2.3. Built-in `Resource` Implementations](#resources-implementations) - * [2.3.1. `UrlResource`](#resources-implementations-urlresource) - * [2.3.2. `ClassPathResource`](#resources-implementations-classpathresource) - * [2.3.3. `FileSystemResource`](#resources-implementations-filesystemresource) - * [2.3.4. `PathResource`](#resources-implementations-pathresource) - * [2.3.5. `ServletContextResource`](#resources-implementations-servletcontextresource) - * [2.3.6. `InputStreamResource`](#resources-implementations-inputstreamresource) - * [2.3.7. `ByteArrayResource`](#resources-implementations-bytearrayresource) - - * [2.4. The `ResourceLoader` Interface](#resources-resourceloader) - * [2.5. The `ResourcePatternResolver` Interface](#resources-resourcepatternresolver) - * [2.6. The `ResourceLoaderAware` Interface](#resources-resourceloaderaware) - * [2.7. Resources as Dependencies](#resources-as-dependencies) - * [2.8. Application Contexts and Resource Paths](#resources-app-ctx) - * [2.8.1. Constructing Application Contexts](#resources-app-ctx-construction) - * [Constructing `ClassPathXmlApplicationContext` Instances — Shortcuts](#resources-app-ctx-classpathxml) - - * [2.8.2. Wildcards in Application Context Constructor Resource Paths](#resources-app-ctx-wildcards-in-resource-paths) - * [Ant-style Patterns](#resources-app-ctx-ant-patterns-in-paths) - * [The `classpath*:` Prefix](#resources-classpath-wildcards) - * [Other Notes Relating to Wildcards](#resources-wildcards-in-path-other-stuff) - - * [2.8.3. `FileSystemResource` Caveats](#resources-filesystemresource-caveats) - -* [3. Validation, Data Binding, and Type Conversion](#validation) - * [3.1. Validation by Using Spring’s Validator Interface](#validator) - * [3.2. Resolving Codes to Error Messages](#validation-conversion) - * [3.3. Bean Manipulation and the `BeanWrapper`](#beans-beans) - * [3.3.1. Setting and Getting Basic and Nested Properties](#beans-beans-conventions) - * [3.3.2. Built-in `PropertyEditor` Implementations](#beans-beans-conversion) - * [Registering Additional Custom `PropertyEditor` Implementations](#beans-beans-conversion-customeditor-registration) - - * [3.4. Spring Type Conversion](#core-convert) - * [3.4.1. Converter SPI](#core-convert-Converter-API) - * [3.4.2. Using `ConverterFactory`](#core-convert-ConverterFactory-SPI) - * [3.4.3. Using `GenericConverter`](#core-convert-GenericConverter-SPI) - * [Using `ConditionalGenericConverter`](#core-convert-ConditionalGenericConverter-SPI) - - * [3.4.4. The `ConversionService` API](#core-convert-ConversionService-API) - * [3.4.5. Configuring a `ConversionService`](#core-convert-Spring-config) - * [3.4.6. Using a `ConversionService` Programmatically](#core-convert-programmatic-usage) - - * [3.5. Spring Field Formatting](#format) - * [3.5.1. The `Formatter` SPI](#format-Formatter-SPI) - * [3.5.2. Annotation-driven Formatting](#format-CustomFormatAnnotations) - * [Format Annotation API](#format-annotations-api) - - * [3.5.3. The `FormatterRegistry` SPI](#format-FormatterRegistry-SPI) - * [3.5.4. The `FormatterRegistrar` SPI](#format-FormatterRegistrar-SPI) - * [3.5.5. Configuring Formatting in Spring MVC](#format-configuring-formatting-mvc) - - * [3.6. Configuring a Global Date and Time Format](#format-configuring-formatting-globaldatetimeformat) - * [3.7. Java Bean Validation](#validation-beanvalidation) - * [3.7.1. Overview of Bean Validation](#validation-beanvalidation-overview) - * [3.7.2. Configuring a Bean Validation Provider](#validation-beanvalidation-spring) - * [Injecting a Validator](#validation-beanvalidation-spring-inject) - * [Configuring Custom Constraints](#validation-beanvalidation-spring-constraints) - * [Spring-driven Method Validation](#validation-beanvalidation-spring-method) - * [Additional Configuration Options](#validation-beanvalidation-spring-other) - - * [3.7.3. Configuring a `DataBinder`](#validation-binder) - * [3.7.4. Spring MVC 3 Validation](#validation-mvc) - -* [4. Spring Expression Language (SpEL)](#expressions) - * [4.1. Evaluation](#expressions-evaluation) - * [4.1.1. Understanding `EvaluationContext`](#expressions-evaluation-context) - * [Type Conversion](#expressions-type-conversion) - - * [4.1.2. Parser Configuration](#expressions-parser-configuration) - * [4.1.3. SpEL Compilation](#expressions-spel-compilation) - * [Compiler Configuration](#expressions-compiler-configuration) - * [Compiler Limitations](#expressions-compiler-limitations) - - * [4.2. Expressions in Bean Definitions](#expressions-beandef) - * [4.2.1. XML Configuration](#expressions-beandef-xml-based) - * [4.2.2. Annotation Configuration](#expressions-beandef-annotation-based) - - * [4.3. Language Reference](#expressions-language-ref) - * [4.3.1. Literal Expressions](#expressions-ref-literal) - * [4.3.2. Properties, Arrays, Lists, Maps, and Indexers](#expressions-properties-arrays) - * [4.3.3. Inline Lists](#expressions-inline-lists) - * [4.3.4. Inline Maps](#expressions-inline-maps) - * [4.3.5. Array Construction](#expressions-array-construction) - * [4.3.6. Methods](#expressions-methods) - * [4.3.7. Operators](#expressions-operators) - * [Relational Operators](#expressions-operators-relational) - * [Logical Operators](#expressions-operators-logical) - * [Mathematical Operators](#expressions-operators-mathematical) - * [The Assignment Operator](#expressions-assignment) - - * [4.3.8. Types](#expressions-types) - * [4.3.9. Constructors](#expressions-constructors) - * [4.3.10. Variables](#expressions-ref-variables) - * [The `#this` and `#root` Variables](#expressions-this-root) - - * [4.3.11. Functions](#expressions-ref-functions) - * [4.3.12. Bean References](#expressions-bean-references) - * [4.3.13. Ternary Operator (If-Then-Else)](#expressions-operator-ternary) - * [4.3.14. The Elvis Operator](#expressions-operator-elvis) - * [4.3.15. Safe Navigation Operator](#expressions-operator-safe-navigation) - * [4.3.16. Collection Selection](#expressions-collection-selection) - * [4.3.17. Collection Projection](#expressions-collection-projection) - * [4.3.18. Expression templating](#expressions-templating) - - * [4.4. Classes Used in the Examples](#expressions-example-classes) - -* [5. Aspect Oriented Programming with Spring](#aop) - * [5.1. AOP Concepts](#aop-introduction-defn) - * [5.2. Spring AOP Capabilities and Goals](#aop-introduction-spring-defn) - * [5.3. AOP Proxies](#aop-introduction-proxies) - * [5.4. @AspectJ support](#aop-ataspectj) - * [5.4.1. Enabling @AspectJ Support](#aop-aspectj-support) - * [Enabling @AspectJ Support with Java Configuration](#aop-enable-aspectj-java) - * [Enabling @AspectJ Support with XML Configuration](#aop-enable-aspectj-xml) - - * [5.4.2. Declaring an Aspect](#aop-at-aspectj) - * [5.4.3. Declaring a Pointcut](#aop-pointcuts) - * [Supported Pointcut Designators](#aop-pointcuts-designators) - * [Combining Pointcut Expressions](#aop-pointcuts-combining) - * [Sharing Common Pointcut Definitions](#aop-common-pointcuts) - * [Examples](#aop-pointcuts-examples) - * [Writing Good Pointcuts](#writing-good-pointcuts) - - * [5.4.4. Declaring Advice](#aop-advice) - * [Before Advice](#aop-advice-before) - * [After Returning Advice](#aop-advice-after-returning) - * [After Throwing Advice](#aop-advice-after-throwing) - * [After (Finally) Advice](#aop-advice-after-finally) - * [Around Advice](#aop-ataspectj-around-advice) - * [Advice Parameters](#aop-ataspectj-advice-params) - * [Advice Ordering](#aop-ataspectj-advice-ordering) - - * [5.4.5. Introductions](#aop-introductions) - * [5.4.6. Aspect Instantiation Models](#aop-instantiation-models) - * [5.4.7. An AOP Example](#aop-ataspectj-example) - - * [5.5. Schema-based AOP Support](#aop-schema) - * [5.5.1. Declaring an Aspect](#aop-schema-declaring-an-aspect) - * [5.5.2. Declaring a Pointcut](#aop-schema-pointcuts) - * [5.5.3. Declaring Advice](#aop-schema-advice) - * [Before Advice](#aop-schema-advice-before) - * [After Returning Advice](#aop-schema-advice-after-returning) - * [After Throwing Advice](#aop-schema-advice-after-throwing) - * [After (Finally) Advice](#aop-schema-advice-after-finally) - * [Around Advice](#aop-schema-advice-around) - * [Advice Parameters](#aop-schema-params) - * [Advice Ordering](#aop-ordering) - - * [5.5.4. Introductions](#aop-schema-introductions) - * [5.5.5. Aspect Instantiation Models](#aop-schema-instatiation-models) - * [5.5.6. Advisors](#aop-schema-advisors) - * [5.5.7. An AOP Schema Example](#aop-schema-example) - - * [5.6. Choosing which AOP Declaration Style to Use](#aop-choosing) - * [5.6.1. Spring AOP or Full AspectJ?](#aop-spring-or-aspectj) - * [5.6.2. @AspectJ or XML for Spring AOP?](#aop-ataspectj-or-xml) - - * [5.7. Mixing Aspect Types](#aop-mixing-styles) - * [5.8. Proxying Mechanisms](#aop-proxying) - * [5.8.1. Understanding AOP Proxies](#aop-understanding-aop-proxies) - - * [5.9. Programmatic Creation of @AspectJ Proxies](#aop-aspectj-programmatic) - * [5.10. Using AspectJ with Spring Applications](#aop-using-aspectj) - * [5.10.1. Using AspectJ to Dependency Inject Domain Objects with Spring](#aop-atconfigurable) - * [Unit Testing `@Configurable` Objects](#aop-configurable-testing) - * [Working with Multiple Application Contexts](#aop-configurable-container) - - * [5.10.2. Other Spring aspects for AspectJ](#aop-ajlib-other) - * [5.10.3. Configuring AspectJ Aspects by Using Spring IoC](#aop-aj-configure) - * [5.10.4. Load-time Weaving with AspectJ in the Spring Framework](#aop-aj-ltw) - * [A First Example](#aop-aj-ltw-first-example) - * [Aspects](#aop-aj-ltw-the-aspects) - * ['META-INF/aop.xml'](#aop-aj-ltw-aop_dot_xml) - * [Required libraries (JARS)](#aop-aj-ltw-libraries) - * [Spring Configuration](#aop-aj-ltw-spring) - * [Environment-specific Configuration](#aop-aj-ltw-environments) - - * [5.11. Further Resources](#aop-resources) - -* [6. Spring AOP APIs](#aop-api) - * [6.1. Pointcut API in Spring](#aop-api-pointcuts) - * [6.1.1. Concepts](#aop-api-concepts) - * [6.1.2. Operations on Pointcuts](#aop-api-pointcut-ops) - * [6.1.3. AspectJ Expression Pointcuts](#aop-api-pointcuts-aspectj) - * [6.1.4. Convenience Pointcut Implementations](#aop-api-pointcuts-impls) - * [Static Pointcuts](#aop-api-pointcuts-static) - * [Dynamic pointcuts](#aop-api-pointcuts-dynamic) - - * [6.1.5. Pointcut Superclasses](#aop-api-pointcuts-superclasses) - * [6.1.6. Custom Pointcuts](#aop-api-pointcuts-custom) - - * [6.2. Advice API in Spring](#aop-api-advice) - * [6.2.1. Advice Lifecycles](#aop-api-advice-lifecycle) - * [6.2.2. Advice Types in Spring](#aop-api-advice-types) - * [Interception Around Advice](#aop-api-advice-around) - * [Before Advice](#aop-api-advice-before) - * [Throws Advice](#aop-api-advice-throws) - * [After Returning Advice](#aop-api-advice-after-returning) - * [Introduction Advice](#aop-api-advice-introduction) - - * [6.3. The Advisor API in Spring](#aop-api-advisor) - * [6.4. Using the `ProxyFactoryBean` to Create AOP Proxies](#aop-pfb) - * [6.4.1. Basics](#aop-pfb-1) - * [6.4.2. JavaBean Properties](#aop-pfb-2) - * [6.4.3. JDK- and CGLIB-based proxies](#aop-pfb-proxy-types) - * [6.4.4. Proxying Interfaces](#aop-api-proxying-intf) - * [6.4.5. Proxying Classes](#aop-api-proxying-class) - * [6.4.6. Using “Global” Advisors](#aop-global-advisors) - - * [6.5. Concise Proxy Definitions](#aop-concise-proxy) - * [6.6. Creating AOP Proxies Programmatically with the `ProxyFactory`](#aop-prog) - * [6.7. Manipulating Advised Objects](#aop-api-advised) - * [6.8. Using the "auto-proxy" facility](#aop-autoproxy) - * [6.8.1. Auto-proxy Bean Definitions](#aop-autoproxy-choices) - * [`BeanNameAutoProxyCreator`](#aop-api-autoproxy) - * [`DefaultAdvisorAutoProxyCreator`](#aop-api-autoproxy-default) - - * [6.9. Using `TargetSource` Implementations](#aop-targetsource) - * [6.9.1. Hot-swappable Target Sources](#aop-ts-swap) - * [6.9.2. Pooling Target Sources](#aop-ts-pool) - * [6.9.3. Prototype Target Sources](#aop-ts-prototype) - * [6.9.4. `ThreadLocal` Target Sources](#aop-ts-threadlocal) - - * [6.10. Defining New Advice Types](#aop-extensibility) - -* [7. Null-safety](#null-safety) - * [7.1. Use cases](#use-cases) - * [7.2. JSR-305 meta-annotations](#jsr-305-meta-annotations) - -* [8. Data Buffers and Codecs](#databuffers) - * [8.1. `DataBufferFactory`](#databuffers-factory) - * [8.2. `DataBuffer`](#databuffers-buffer) - * [8.3. `PooledDataBuffer`](#databuffers-buffer-pooled) - * [8.4. `DataBufferUtils`](#databuffers-utils) - * [8.5. Codecs](#codecs) - * [8.6. Using `DataBuffer`](#databuffers-using) - -* [9. Logging](#spring-jcl) -* [10. Appendix](#appendix) - * [10.1. XML Schemas](#xsd-schemas) - * [10.1.1. The `util` Schema](#xsd-schemas-util) - * [Using ``](#xsd-schemas-util-constant) - * [Using ``](#xsd-schemas-util-property-path) - * [Using ``](#xsd-schemas-util-properties) - * [Using ``](#xsd-schemas-util-list) - * [Using ``](#xsd-schemas-util-map) - * [Using ``](#xsd-schemas-util-set) - - * [10.1.2. The `aop` Schema](#xsd-schemas-aop) - * [10.1.3. The `context` Schema](#xsd-schemas-context) - * [Using ``](#xsd-schemas-context-pphc) - * [Using ``](#xsd-schemas-context-ac) - * [Using ``](#xsd-schemas-context-component-scan) - * [Using ``](#xsd-schemas-context-ltw) - * [Using ``](#xsd-schemas-context-sc) - * [Using ``](#xsd-schemas-context-mbe) - - * [10.1.4. The Beans Schema](#xsd-schemas-beans) - - * [10.2. XML Schema Authoring](#xml-custom) - * [10.2.1. Authoring the Schema](#xsd-custom-schema) - * [10.2.2. Coding a `NamespaceHandler`](#xsd-custom-namespacehandler) - * [10.2.3. Using `BeanDefinitionParser`](#xsd-custom-parser) - * [10.2.4. Registering the Handler and the Schema](#xsd-custom-registration) - * [Writing `META-INF/spring.handlers`](#xsd-custom-registration-spring-handlers) - * [Writing 'META-INF/spring.schemas'](#xsd-custom-registration-spring-schemas) - - * [10.2.5. Using a Custom Extension in Your Spring XML Configuration](#xsd-custom-using) - * [10.2.6. More Detailed Examples](#xsd-custom-meat) - * [Nesting Custom Elements within Custom Elements](#xsd-custom-custom-nested) - * [Custom Attributes on “Normal” Elements](#xsd-custom-custom-just-attributes) - - * [10.3. Application Startup Steps](#application-startup-steps) +# Core Technologies This part of the reference documentation covers all the technologies that are absolutely integral to the Spring Framework. @@ -465,12 +14,11 @@ Coverage of Spring’s integration with AspectJ (currently the richest — i features — and certainly most mature AOP implementation in the Java enterprise space) is also provided. -[](#beans)1. The IoC Container ----------- +## 1. The IoC Container This chapter covers Spring’s Inversion of Control (IoC) container. -### [](#beans-introduction)1.1. Introduction to the Spring IoC Container and Beans ### +### 1.1. Introduction to the Spring IoC Container and Beans This chapter covers the Spring Framework implementation of the Inversion of Control (IoC) principle. IoC is also known as dependency injection (DI). It is a process whereby @@ -506,7 +54,7 @@ instantiated, assembled, and managed by a Spring IoC container. Otherwise, a bean is simply one of many objects in your application. Beans, and the dependencies among them, are reflected in the configuration metadata used by a container. -### [](#beans-basics)1.2. Container Overview ### +### 1.2. Container Overview The `org.springframework.context.ApplicationContext` interface represents the Spring IoC container and is responsible for instantiating, configuring, and assembling the @@ -540,7 +88,7 @@ application. Figure 1. The Spring IoC container -#### [](#beans-factory-metadata)1.2.1. Configuration Metadata #### +#### 1.2.1. Configuration Metadata As the preceding diagram shows, the Spring IoC container consumes a form of configuration metadata. This configuration metadata represents how you, as an @@ -608,7 +156,7 @@ The following example shows the basic structure of XML-based configuration metad The value of the `id` attribute refers to collaborating objects. The XML for referring to collaborating objects is not shown in this example. See[Dependencies](#beans-dependencies) for more information. -#### [](#beans-factory-instantiation)1.2.2. Instantiating a Container #### +#### 1.2.2. Instantiating a Container The location path or paths supplied to an `ApplicationContext` constructor are resource strings that let @@ -682,7 +230,7 @@ name of the JavaBean property, and the `ref` element refers to the name of anoth definition. This linkage between `id` and `ref` elements expresses the dependency between collaborating objects. For details of configuring an object’s dependencies, see[Dependencies](#beans-dependencies). -##### [](#beans-factory-xml-import)Composing XML-based Configuration Metadata ##### +##### Composing XML-based Configuration Metadata It can be useful to have bean definitions span multiple XML files. Often, each individual XML configuration file represents a logical layer or module in your architecture. @@ -718,7 +266,7 @@ The namespace itself provides the import directive feature. Further configuration features beyond plain bean definitions are available in a selection of XML namespaces provided by Spring — for example, the `context` and `util` namespaces. -##### [](#groovy-bean-definition-dsl)The Groovy Bean Definition DSL ##### +##### The Groovy Bean Definition DSL As a further example for externalized configuration metadata, bean definitions can also be expressed in Spring’s Groovy Bean Definition DSL, as known from the Grails framework. @@ -749,7 +297,7 @@ This configuration style is largely equivalent to XML bean definitions and even supports Spring’s XML configuration namespaces. It also allows for importing XML bean definition files through an `importBeans` directive. -#### [](#beans-factory-client)1.2.3. Using the Container #### +#### 1.2.3. Using the Container The `ApplicationContext` is the interface for an advanced factory capable of maintaining a registry of different beans and their dependencies. By using the method`T getBean(String name, Class requiredType)`, you can retrieve instances of your beans. @@ -849,7 +397,7 @@ Spring’s integration with web frameworks provides dependency injection for var framework components such as controllers and JSF-managed beans, letting you declare a dependency on a specific bean through metadata (such as an autowiring annotation). -### [](#beans-definition)1.3. Bean Overview ### +### 1.3. Bean Overview A Spring IoC container manages one or more beans. These beans are created with the configuration metadata that you supply to the container (for example, in the form of XML`` definitions). @@ -894,7 +442,7 @@ defined through regular bean definition metadata. | |Bean metadata and manually supplied singleton instances need to be registered as early
as possible, in order for the container to properly reason about them during autowiring
and other introspection steps. While overriding existing metadata and existing
singleton instances is supported to some degree, the registration of new beans at
runtime (concurrently with live access to the factory) is not officially supported and may
lead to concurrent access exceptions, inconsistent state in the bean container, or both.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#beans-beanname)1.3.1. Naming Beans #### +#### 1.3.1. Naming Beans Every bean has one or more identifiers. These identifiers must be unique within the container that hosts the bean. A bean usually has only one identifier. However, if it @@ -929,7 +477,7 @@ related by name. | |With component scanning in the classpath, Spring generates bean names for unnamed
components, following the rules described earlier: essentially, taking the simple class name
and turning its initial character to lower-case. However, in the (unusual) special
case when there is more than one character and both the first and second characters
are upper case, the original casing gets preserved. These are the same rules as
defined by `java.beans.Introspector.decapitalize` (which Spring uses here).| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#beans-beanname-alias)Aliasing a Bean outside the Bean Definition ##### +##### Aliasing a Bean outside the Bean Definition In a bean definition itself, you can supply more than one name for the bean, by using a combination of up to one name specified by the `id` attribute and any number of other @@ -973,7 +521,7 @@ Java-configuration If you use Javaconfiguration, the `@Bean` annotation can be used to provide aliases. See [Using the `@Bean` Annotation](#beans-java-bean-annotation) for details. -#### [](#beans-factory-class)1.3.2. Instantiating Beans #### +#### 1.3.2. Instantiating Beans A bean definition is essentially a recipe for creating one or more objects. The container looks at the recipe for a named bean when asked and uses the configuration @@ -1002,7 +550,7 @@ this `SomeThing` class has a `static` nested class called `OtherThing`, they can separated by a dollar sign (`$`) or a dot (`.`). So the value of the `class` attribute in a bean definition would be `com.example.SomeThing$OtherThing` or`com.example.SomeThing.OtherThing`. -##### [](#beans-factory-class-ctor)Instantiation with a Constructor ##### +##### Instantiation with a Constructor When you create a bean by the constructor approach, all normal classes are usable by and compatible with Spring. That is, the class being developed does not need to implement @@ -1029,7 +577,7 @@ With XML-based configuration metadata you can specify your bean class as follows For details about the mechanism for supplying arguments to the constructor (if required) and setting object instance properties after the object is constructed, see[Injecting Dependencies](#beans-factory-collaborators). -##### [](#beans-factory-class-static-factory-method)Instantiation with a Static Factory Method ##### +##### Instantiation with a Static Factory Method When defining a bean that you create with a static factory method, use the `class`attribute to specify the class that contains the `static` factory method and an attribute named `factory-method` to specify the name of the factory method itself. You should be @@ -1077,7 +625,7 @@ For details about the mechanism for supplying (optional) arguments to the factor and setting object instance properties after the object is returned from the factory, see [Dependencies and Configuration in Detail](#beans-factory-properties-detailed). -##### [](#beans-factory-class-instance-factory-method)Instantiation by Using an Instance Factory Method ##### +##### Instantiation by Using an Instance Factory Method Similar to instantiation through a [static factory method](#beans-factory-class-static-factory-method), instantiation with an instance factory method invokes a non-static @@ -1191,7 +739,7 @@ Configuration in Detail](#beans-factory-properties-detailed). | |In Spring documentation, "factory bean" refers to a bean that is configured in the
Spring container and that creates objects through an[instance](#beans-factory-class-instance-factory-method) or[static](#beans-factory-class-static-factory-method) factory method. By contrast,`FactoryBean` (notice the capitalization) refers to a Spring-specific[`FactoryBean`](#beans-factory-extension-factorybean) implementation class.| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#beans-factory-type-determination)Determining a Bean’s Runtime Type ##### +##### Determining a Bean’s Runtime Type The runtime type of a specific bean is non-trivial to determine. A specified class in the bean metadata definition is just an initial class reference, potentially combined @@ -1206,7 +754,7 @@ a `BeanFactory.getType` call for the specified bean name. This takes all of the cases into account and returns the type of object that a `BeanFactory.getBean` call is going to return for the same bean name. -### [](#beans-dependencies)1.4. Dependencies ### +### 1.4. Dependencies A typical enterprise application does not consist of a single object (or bean in the Spring parlance). Even the simplest application has a few objects that work together to @@ -1214,7 +762,7 @@ present what the end-user sees as a coherent application. This next section expl you go from defining a number of bean definitions that stand alone to a fully realized application where objects collaborate to achieve a goal. -#### [](#beans-factory-collaborators)1.4.1. Dependency Injection #### +#### 1.4.1. Dependency Injection Dependency injection (DI) is a process whereby objects define their dependencies (that is, the other objects with which they work) only through constructor arguments, @@ -1234,7 +782,7 @@ which allow for stub or mock implementations to be used in unit tests. DI exists in two major variants: [Constructor-based dependency injection](#beans-constructor-injection) and [Setter-based dependency injection](#beans-setter-injection). -##### [](#beans-constructor-injection)Constructor-based Dependency Injection ##### +##### Constructor-based Dependency Injection Constructor-based DI is accomplished by the container invoking a constructor with a number of arguments, each representing a dependency. Calling a `static` factory method @@ -1272,7 +820,7 @@ class SimpleMovieLister(private val movieFinder: MovieFinder) { Notice that there is nothing special about this class. It is a POJO that has no dependencies on container specific interfaces, base classes, or annotations. -###### [](#beans-factory-ctor-arguments-resolution)Constructor Argument Resolution ###### +###### Constructor Argument Resolution Constructor argument resolution matching occurs by using the argument’s type. If no potential ambiguity exists in the constructor arguments of a bean definition, the @@ -1428,7 +976,7 @@ class ExampleBean constructor(val years: Int, val ultimateAnswer: String) ``` -##### [](#beans-setter-injection)Setter-based Dependency Injection ##### +##### Setter-based Dependency Injection Setter-based DI is accomplished by the container calling setter methods on your beans after invoking a no-argument constructor or a no-argument `static` factory method to @@ -1502,7 +1050,7 @@ with third-party classes for which you do not have the source, the choice is mad For example, if a third-party class does not expose any setter methods, then constructor injection may be the only available form of DI. -##### [](#beans-dependency-resolution)Dependency Resolution Process ##### +##### Dependency Resolution Process The container performs bean dependency resolution as follows: @@ -1573,7 +1121,7 @@ pre-instantiated singleton), its dependencies are set, and the relevant lifecycl methods (such as a [configured init method](#beans-factory-lifecycle-initializingbean)or the [InitializingBean callback method](#beans-factory-lifecycle-initializingbean)) are invoked. -##### [](#beans-some-examples)Examples of Dependency Injection ##### +##### Examples of Dependency Injection The following example uses XML-based configuration metadata for setter-based DI. A small part of a Spring XML configuration file specifies some bean definitions as follows: @@ -1749,7 +1297,7 @@ contains the `static` factory method (although, in this example, it is). An inst from the use of the `factory-bean` attribute instead of the `class` attribute), so we do not discuss those details here. -#### [](#beans-factory-properties-detailed)1.4.2. Dependencies and Configuration in Detail #### +#### 1.4.2. Dependencies and Configuration in Detail As mentioned in the [previous section](#beans-factory-collaborators), you can define bean properties and constructor arguments as references to other managed beans (collaborators) @@ -1757,7 +1305,7 @@ or as values defined inline. Spring’s XML-based configuration metadata support sub-element types within its `` and `` elements for this purpose. -##### [](#beans-value-element)Straight Values (Primitives, Strings, and so on) ##### +##### Straight Values (Primitives, Strings, and so on) The `value` attribute of the `` element specifies a property or constructor argument as a human-readable string representation. Spring’s[conversion service](#core-convert-ConversionService-API) is used to convert these @@ -1820,7 +1368,7 @@ The Spring container converts the text inside the `` element into a`java is a nice shortcut, and is one of a few places where the Spring team do favor the use of the nested `` element over the `value` attribute style. -###### [](#beans-idref-element)The `idref` element ###### +###### The `idref` element The `idref` element is simply an error-proof way to pass the `id` (a string value - not a reference) of another bean in the container to a `` or ``element. The following example shows how to use it: @@ -1860,7 +1408,7 @@ A common place (at least in versions earlier than Spring 2.0) where the `` elements when you specify the interceptor names prevents you from misspelling an interceptor ID. -##### [](#beans-ref-element)References to Other Beans (Collaborators) ##### +##### References to Other Beans (Collaborators) The `ref` element is the final element inside a `` or ``definition element. Here, you set the value of the specified property of a bean to be a reference to another bean (a collaborator) managed by the container. The referenced bean @@ -1909,7 +1457,7 @@ listings shows how to use the `parent` attribute: | |The `local` attribute on the `ref` element is no longer supported in the 4.0 beans
XSD, since it does not provide value over a regular `bean` reference any more. Change
your existing `ref local` references to `ref bean` when upgrading to the 4.0 schema.| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#beans-inner-beans)Inner Beans ##### +##### Inner Beans A `` element inside the `` or `` elements defines an inner bean, as the following example shows: @@ -1937,7 +1485,7 @@ of the inner bean instance is tied to its containing bean, but destruction callb participate in the request scope’s lifecycle. This is not a common scenario. Inner beans typically simply share their containing bean’s scope. -##### [](#beans-collection-elements)Collections ##### +##### Collections The ``, ``, ``, and `` elements set the properties and arguments of the Java `Collection` types `List`, `Set`, `Map`, and `Properties`, @@ -1984,7 +1532,7 @@ following elements: bean | ref | idref | list | set | map | props | value | null ``` -###### [](#beans-collection-elements-merging)Collection Merging ###### +###### Collection Merging The Spring container also supports merging collections. An application developer can define a parent ``, ``, `` or `` element @@ -2041,14 +1589,14 @@ exists. Hence, no ordering semantics are in effect for the collection types that the associated `Map`, `Set`, and `Properties` implementation types that the container uses internally. -###### [](#beans-collection-merge-limitations)Limitations of Collection Merging ###### +###### Limitations of Collection Merging You cannot merge different collection types (such as a `Map` and a `List`). If you do attempt to do so, an appropriate `Exception` is thrown. The `merge` attribute must be specified on the lower, inherited, child definition. Specifying the `merge` attribute on a parent collection definition is redundant and does not result in the desired merging. -###### [](#beans-collection-elements-strongly-typed)Strongly-typed collection ###### +###### Strongly-typed collection With the introduction of generic types in Java 5, you can use strongly typed collections. That is, it is possible to declare a `Collection` type such that it can only contain @@ -2097,7 +1645,7 @@ information about the element type of the strongly-typed `Map` is available by reflection. Thus, Spring’s type conversion infrastructure recognizes the various value elements as being of type `Float`, and the string values (`9.99`, `2.75`, and`3.99`) are converted into an actual `Float` type. -##### [](#beans-null-element)Null and Empty String Values ##### +##### Null and Empty String Values Spring treats empty arguments for properties and the like as empty `Strings`. The following XML-based configuration metadata snippet sets the `email` property to the empty`String` value (""). @@ -2146,7 +1694,7 @@ Kotlin exampleBean.email = null ``` -##### [](#beans-p-namespace)XML Shortcut with the p-namespace ##### +##### XML Shortcut with the p-namespace The p-namespace lets you use the `bean` element’s attributes (instead of nested`` elements) to describe your property values collaborating beans, or both. @@ -2215,7 +1763,7 @@ reference to another bean. | |The p-namespace is not as flexible as the standard XML format. For example, the format
for declaring property references clashes with properties that end in `Ref`, whereas the
standard XML format does not. We recommend that you choose your approach carefully and
communicate this to your team members to avoid producing XML documents that use all
three approaches at the same time.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#beans-c-namespace)XML Shortcut with the c-namespace ##### +##### XML Shortcut with the c-namespace Similar to the [XML Shortcut with the p-namespace](#beans-p-namespace), the c-namespace, introduced in Spring 3.1, allows inlined attributes for configuring the constructor arguments rather @@ -2269,7 +1817,7 @@ In practice, the constructor resolution[mechanism](#beans-factory-ctor-arguments arguments, so unless you really need to, we recommend using the name notation throughout your configuration. -##### [](#beans-compound-property-names)Compound Property Names ##### +##### Compound Property Names You can use compound or nested property names when you set bean properties, as long as all components of the path except the final property name are not `null`. Consider the @@ -2285,7 +1833,7 @@ The `something` bean has a `fred` property, which has a `bob` property, which ha this to work, the `fred` property of `something` and the `bob` property of `fred` must not be `null` after the bean is constructed. Otherwise, a `NullPointerException` is thrown. -#### [](#beans-factory-dependson)1.4.3. Using `depends-on` #### +#### 1.4.3. Using `depends-on` If a bean is a dependency of another bean, that usually means that one bean is set as a property of another. Typically you accomplish this with the [``element](#beans-ref-element) in XML-based configuration metadata. However, sometimes dependencies between @@ -2316,7 +1864,7 @@ delimiters): | |The `depends-on` attribute can specify both an initialization-time dependency and,
in the case of [singleton](#beans-factory-scopes-singleton) beans only, a corresponding
destruction-time dependency. Dependent beans that define a `depends-on` relationship
with a given bean are destroyed first, prior to the given bean itself being destroyed.
Thus, `depends-on` can also control shutdown order.| |---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#beans-factory-lazy-init)1.4.4. Lazy-initialized Beans #### +#### 1.4.4. Lazy-initialized Beans By default, `ApplicationContext` implementations eagerly create and configure all[singleton](#beans-factory-scopes-singleton) beans as part of the initialization process. Generally, this pre-instantiation is desirable, because errors in the @@ -2350,7 +1898,7 @@ You can also control lazy-initialization at the container level by using the`def ``` -#### [](#beans-factory-autowire)1.4.5. Autowiring Collaborators #### +#### 1.4.5. Autowiring Collaborators The Spring container can autowire relationships between collaborating beans. You can let Spring resolve collaborators (other beans) automatically for your bean by @@ -2384,7 +1932,7 @@ typed collections. In such cases, all autowire candidates within the container t match the expected type are provided to satisfy the dependency. You can autowire strongly-typed `Map` instances if the expected key type is `String`. An autowired `Map`instance’s values consist of all bean instances that match the expected type, and the`Map` instance’s keys contain the corresponding bean names. -##### [](#beans-autowired-exceptions)Limitations and Disadvantages of Autowiring ##### +##### Limitations and Disadvantages of Autowiring Autowiring works best when it is used consistently across a project. If autowiring is not used in general, it might be confusing to developers to use it to wire only one or @@ -2421,7 +1969,7 @@ In the latter scenario, you have several options: * Implement the more fine-grained control available with annotation-based configuration, as described in [Annotation-based Container Configuration](#beans-annotation-config). -##### [](#beans-factory-autowire-candidate)Excluding a Bean from Autowiring ##### +##### Excluding a Bean from Autowiring On a per-bean basis, you can exclude a bean from autowiring. In Spring’s XML format, set the `autowire-candidate` attribute of the `` element to `false`. The container @@ -2441,7 +1989,7 @@ These techniques are useful for beans that you never want to be injected into ot beans by autowiring. It does not mean that an excluded bean cannot itself be configured by using autowiring. Rather, the bean itself is not a candidate for autowiring other beans. -#### [](#beans-factory-method-injection)1.4.6. Method Injection #### +#### 1.4.6. Method Injection In most application scenarios, most beans in the container are[singletons](#beans-factory-scopes-singleton). When a singleton bean needs to collaborate with another singleton bean or a non-singleton bean needs to collaborate @@ -2531,7 +2079,7 @@ container, lets you handle this use case cleanly. You can read more about the motivation for Method Injection in[this blog entry](https://spring.io/blog/2004/08/06/method-injection/). -##### [](#beans-factory-lookup-method-injection)Lookup Method Injection ##### +##### Lookup Method Injection Lookup method injection is the ability of the container to override methods on container-managed beans and return the lookup result for another named bean in the @@ -2697,7 +2245,7 @@ apply to explicitly registered or explicitly imported bean classes. | |Another way of accessing differently scoped target beans is an `ObjectFactory`/`Provider` injection point. See [Scoped Beans as Dependencies](#beans-factory-scopes-other-injection).

You may also find the `ServiceLocatorFactoryBean` (in the`org.springframework.beans.factory.config` package) to be useful.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#beans-factory-arbitrary-method-replacement)Arbitrary Method Replacement ##### +##### Arbitrary Method Replacement A less useful form of method injection than lookup method injection is the ability to replace arbitrary methods in a managed bean with another method implementation. You @@ -2800,7 +2348,7 @@ Because the number of arguments is often enough to distinguish between each poss choice, this shortcut can save a lot of typing, by letting you type only the shortest string that matches an argument type. -### [](#beans-factory-scopes)1.5. Bean Scopes ### +### 1.5. Bean Scopes When you create a bean definition, you create a recipe for creating actual instances of the class defined by that bean definition. The idea that a bean definition is a @@ -2830,7 +2378,7 @@ The following table describes the supported scopes: | |As of Spring 3.0, a thread scope is available but is not registered by default. For
more information, see the documentation for[`SimpleThreadScope`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/context/support/SimpleThreadScope.html).
For instructions on how to register this or any other custom scope, see[Using a Custom Scope](#beans-factory-scopes-custom-using).| |---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#beans-factory-scopes-singleton)1.5.1. The Singleton Scope #### +#### 1.5.1. The Singleton Scope Only one shared instance of a singleton bean is managed, and all requests for beans with an ID or IDs that match that bean definition result in that one specific bean @@ -2861,7 +2409,7 @@ following example: ``` -#### [](#beans-factory-scopes-prototype)1.5.2. The Prototype Scope #### +#### 1.5.2. The Prototype Scope The non-singleton prototype scope of bean deployment results in the creation of a new bean instance every time a request for that specific bean is made. That is, the bean @@ -2900,7 +2448,7 @@ replacement for the Java `new` operator. All lifecycle management past that poin be handled by the client. (For details on the lifecycle of a bean in the Spring container, see [Lifecycle Callbacks](#beans-factory-lifecycle).) -#### [](#beans-factory-scopes-sing-prot-interaction)1.5.3. Singleton Beans with Prototype-bean Dependencies #### +#### 1.5.3. Singleton Beans with Prototype-bean Dependencies When you use singleton-scoped beans with dependencies on prototype beans, be aware that dependencies are resolved at instantiation time. Thus, if you dependency-inject a @@ -2915,14 +2463,14 @@ once, when the Spring container instantiates the singleton bean and resolves and injects its dependencies. If you need a new instance of a prototype bean at runtime more than once, see [Method Injection](#beans-factory-method-injection). -#### [](#beans-factory-scopes-other)1.5.4. Request, Session, Application, and WebSocket Scopes #### +#### 1.5.4. Request, Session, Application, and WebSocket Scopes The `request`, `session`, `application`, and `websocket` scopes are available only if you use a web-aware Spring `ApplicationContext` implementation (such as`XmlWebApplicationContext`). If you use these scopes with regular Spring IoC containers, such as the `ClassPathXmlApplicationContext`, an `IllegalStateException` that complains about an unknown bean scope is thrown. -##### [](#beans-factory-scopes-other-web-configuration)Initial Web Configuration ##### +##### Initial Web Configuration To support the scoping of beans at the `request`, `session`, `application`, and`websocket` levels (web-scoped beans), some minor initial configuration is required before you define your beans. (This initial setup is not required @@ -2973,7 +2521,7 @@ the same thing, namely bind the HTTP request object to the `Thread` that is serv that request. This makes beans that are request- and session-scoped available further down the call chain. -##### [](#beans-factory-scopes-request)Request scope ##### +##### Request scope Consider the following XML configuration for a bean definition: @@ -3011,7 +2559,7 @@ class LoginAction { } ``` -##### [](#beans-factory-scopes-session)Session Scope ##### +##### Session Scope Consider the following XML configuration for a bean definition: @@ -3049,7 +2597,7 @@ class UserPreferences { } ``` -##### [](#beans-factory-scopes-application)Application Scope ##### +##### Application Scope Consider the following XML configuration for a bean definition: @@ -3084,12 +2632,12 @@ class AppPreferences { } ``` -##### [](#beans-factory-scopes-websocket)WebSocket Scope ##### +##### WebSocket Scope WebSocket scope is associated with the lifecycle of a WebSocket session and applies to STOMP over WebSocket applications, see[WebSocket scope](web.html#websocket-stomp-websocket-scope) for more details. -##### [](#beans-factory-scopes-other-injection)Scoped Beans as Dependencies ##### +##### Scoped Beans as Dependencies The Spring IoC container manages not only the instantiation of your objects (beans), but also the wiring up of collaborators (or dependencies). If you want to inject (for @@ -3176,7 +2724,7 @@ shows: ``` -###### [](#beans-factory-scopes-other-injection-proxies)Choosing the Type of Proxy to Create ###### +###### Choosing the Type of Proxy to Create By default, when the Spring container creates a proxy for a bean that is marked up with the `` element, a CGLIB-based class proxy is created. @@ -3207,13 +2755,13 @@ interfaces. The following example shows a proxy based on an interface: For more detailed information about choosing class-based or interface-based proxying, see [Proxying Mechanisms](#aop-proxying). -#### [](#beans-factory-scopes-custom)1.5.5. Custom Scopes #### +#### 1.5.5. Custom Scopes The bean scoping mechanism is extensible. You can define your own scopes or even redefine existing scopes, although the latter is considered bad practice and you cannot override the built-in `singleton` and `prototype` scopes. -##### [](#beans-factory-scopes-custom-creating)Creating a Custom Scope ##### +##### Creating a Custom Scope To integrate your custom scopes into the Spring container, you need to implement the`org.springframework.beans.factory.config.Scope` interface, which is described in this section. For an idea of how to implement your own scopes, see the `Scope`implementations that are supplied with the Spring Framework itself and the[`Scope`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/beans/factory/config/Scope.html) javadoc, @@ -3290,7 +2838,7 @@ fun getConversationId(): String This identifier is different for each scope. For a session scoped implementation, this identifier can be the session identifier. -##### [](#beans-factory-scopes-custom-using)Using a Custom Scope ##### +##### Using a Custom Scope After you write and test one or more custom `Scope` implementations, you need to make the Spring container aware of your new scopes. The following method is the central @@ -3379,7 +2927,7 @@ of the scope. You can also do the `Scope` registration declaratively, by using t | |When you place `` within a `` declaration for a`FactoryBean` implementation, it is the factory bean itself that is scoped, not the object
returned from `getObject()`.| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -### [](#beans-factory-nature)1.6. Customizing the Nature of a Bean ### +### 1.6. Customizing the Nature of a Bean The Spring Framework provides a number of interfaces you can use to customize the nature of a bean. This section groups them as follows: @@ -3390,7 +2938,7 @@ of a bean. This section groups them as follows: * [Other `Aware` Interfaces](#aware-list) -#### [](#beans-factory-lifecycle)1.6.1. Lifecycle Callbacks #### +#### 1.6.1. Lifecycle Callbacks To interact with the container’s management of the bean lifecycle, you can implement the Spring `InitializingBean` and `DisposableBean` interfaces. The container calls`afterPropertiesSet()` for the former and `destroy()` for the latter to let the bean @@ -3410,7 +2958,7 @@ startup and shutdown process, as driven by the container’s own lifecycle. The lifecycle callback interfaces are described in this section. -##### [](#beans-factory-lifecycle-initializingbean)Initialization Callbacks ##### +##### Initialization Callbacks The `org.springframework.beans.factory.InitializingBean` interface lets a bean perform initialization work after the container has set all necessary properties on the @@ -3485,7 +3033,7 @@ class AnotherExampleBean : InitializingBean { However, the first of the two preceding examples does not couple the code to Spring. -##### [](#beans-factory-lifecycle-disposablebean)Destruction Callbacks ##### +##### Destruction Callbacks Implementing the `org.springframework.beans.factory.DisposableBean` interface lets a bean get a callback when the container that contains it is destroyed. The`DisposableBean` interface specifies a single method: @@ -3561,7 +3109,7 @@ However, the first of the two preceding definitions does not couple the code to | |You can assign the `destroy-method` attribute of a `` element a special`(inferred)` value, which instructs Spring to automatically detect a public `close` or`shutdown` method on the specific bean class. (Any class that implements`java.lang.AutoCloseable` or `java.io.Closeable` would therefore match.) You can also set
this special `(inferred)` value on the `default-destroy-method` attribute of a`` element to apply this behavior to an entire set of beans (see[Default Initialization and Destroy Methods](#beans-factory-lifecycle-default-init-destroy-methods)). Note that this is the
default behavior with Java configuration.| |---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#beans-factory-lifecycle-default-init-destroy-methods)Default Initialization and Destroy Methods ##### +##### Default Initialization and Destroy Methods When you write initialization and destroy method callbacks that do not use the Spring-specific `InitializingBean` and `DisposableBean` callback interfaces, you @@ -3650,7 +3198,7 @@ interceptors to the `init` method, because doing so would couple the lifecycle o target bean to its proxy or interceptors and leave strange semantics when your code interacts directly with the raw target bean. -##### [](#beans-factory-lifecycle-combined-effects)Combining Lifecycle Mechanisms ##### +##### Combining Lifecycle Mechanisms As of Spring 2.5, you have three options for controlling bean lifecycle behavior: @@ -3680,7 +3228,7 @@ Destroy methods are called in the same order: 3. A custom configured `destroy()` method -##### [](#beans-factory-lifecycle-processor)Startup and Shutdown Callbacks ##### +##### Startup and Shutdown Callbacks The `Lifecycle` interface defines the essential methods for any object that has its own lifecycle requirements (such as starting and stopping some background process): @@ -3776,7 +3324,7 @@ its own `start()` method (unlike the context refresh, the context start does not automatically for a standard context implementation). The `phase` value and any “depends-on” relationships determine the startup order as described earlier. -##### [](#beans-factory-shutdown)Shutting Down the Spring IoC Container Gracefully in Non-Web Applications ##### +##### Shutting Down the Spring IoC Container Gracefully in Non-Web Applications | |This section applies only to non-web applications. Spring’s web-based`ApplicationContext` implementations already have code in place to gracefully shut down
the Spring IoC container when the relevant web application is shut down.| |---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| @@ -3828,7 +3376,7 @@ fun main() { } ``` -#### [](#beans-factory-aware)1.6.2. `ApplicationContextAware` and `BeanNameAware` #### +#### 1.6.2. `ApplicationContextAware` and `BeanNameAware` When an `ApplicationContext` creates an object instance that implements the`org.springframework.context.ApplicationContextAware` interface, the instance is provided with a reference to that `ApplicationContext`. The following listing shows the definition @@ -3873,7 +3421,7 @@ The callback is invoked after population of normal bean properties but before an initialization callback such as `InitializingBean.afterPropertiesSet()` or a custom init-method. -#### [](#aware-list)1.6.3. Other `Aware` Interfaces #### +#### 1.6.3. Other `Aware` Interfaces Besides `ApplicationContextAware` and `BeanNameAware` (discussed [earlier](#beans-factory-aware)), Spring offers a wide range of `Aware` callback interfaces that let beans indicate to the container @@ -3898,7 +3446,7 @@ Note again that using these interfaces ties your code to the Spring API and does follow the Inversion of Control style. As a result, we recommend them for infrastructure beans that require programmatic access to the container. -### [](#beans-child-bean-definitions)1.7. Bean Definition Inheritance ### +### 1.7. Bean Definition Inheritance A bean definition can contain a lot of configuration information, including constructor arguments, property values, and container-specific information, such as the initialization @@ -3974,13 +3522,13 @@ abstract. | |`ApplicationContext` pre-instantiates all singletons by default. Therefore, it is
important (at least for singleton beans) that if you have a (parent) bean definition
which you intend to use only as a template, and this definition specifies a class, you
must make sure to set the *abstract* attribute to *true*, otherwise the application
context will actually (attempt to) pre-instantiate the `abstract` bean.| |---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -### [](#beans-factory-extension)1.8. Container Extension Points ### +### 1.8. Container Extension Points Typically, an application developer does not need to subclass `ApplicationContext`implementation classes. Instead, the Spring IoC container can be extended by plugging in implementations of special integration interfaces. The next few sections describe these integration interfaces. -#### [](#beans-factory-extension-bpp)1.8.1. Customizing Beans by Using a `BeanPostProcessor` #### +#### 1.8.1. Customizing Beans by Using a `BeanPostProcessor` The `BeanPostProcessor` interface defines callback methods that you can implement to provide your own (or override the container’s default) instantiation logic, dependency @@ -4029,7 +3577,7 @@ initialization of other beans in the context, this early type detection is criti The following examples show how to write, register, and use `BeanPostProcessor` instances in an `ApplicationContext`. -##### [](#beans-factory-extension-bpp-examples-hw)Example: Hello World, `BeanPostProcessor`-style ##### +##### Example: Hello World, `BeanPostProcessor`-style This first example illustrates basic usage. The example shows a custom`BeanPostProcessor` implementation that invokes the `toString()` method of each bean as it is created by the container and prints the resulting string to the system console. @@ -4146,14 +3694,14 @@ Bean 'messenger' created : [email protected] [email protected] ``` -##### [](#beans-factory-extension-bpp-examples-aabpp)Example: The `AutowiredAnnotationBeanPostProcessor` ##### +##### Example: The `AutowiredAnnotationBeanPostProcessor` Using callback interfaces or annotations in conjunction with a custom `BeanPostProcessor`implementation is a common means of extending the Spring IoC container. An example is Spring’s `AutowiredAnnotationBeanPostProcessor` — a `BeanPostProcessor` implementation that ships with the Spring distribution and autowires annotated fields, setter methods, and arbitrary config methods. -#### [](#beans-factory-extension-factory-postprocessors)1.8.2. Customizing Configuration Metadata with a `BeanFactoryPostProcessor` #### +#### 1.8.2. Customizing Configuration Metadata with a `BeanFactoryPostProcessor` #### The next extension point that we look at is the`org.springframework.beans.factory.config.BeanFactoryPostProcessor`. The semantics of this interface are similar to those of the `BeanPostProcessor`, with one major @@ -4182,7 +3730,7 @@ you would any other bean. | |As with `BeanPostProcessor`s , you typically do not want to configure`BeanFactoryPostProcessor`s for lazy initialization. If no other bean references a`Bean(Factory)PostProcessor`, that post-processor will not get instantiated at all.
Thus, marking it for lazy initialization will be ignored, and the`Bean(Factory)PostProcessor` will be instantiated eagerly even if you set the`default-lazy-init` attribute to `true` on the declaration of your `` element.| |---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#beans-factory-placeholderconfigurer)Example: The Class Name Substitution `PropertySourcesPlaceholderConfigurer` ##### +##### Example: The Class Name Substitution `PropertySourcesPlaceholderConfigurer` ##### You can use the `PropertySourcesPlaceholderConfigurer` to externalize property values from a bean definition in a separate file by using the standard Java `Properties` format. @@ -4239,7 +3787,7 @@ it checks against Spring `Environment` properties and regular Java `System` prop | |You can use the `PropertySourcesPlaceholderConfigurer` to substitute class names, which
is sometimes useful when you have to pick a particular implementation class at runtime.
The following example shows how to do so:

```


classpath:com/something/strategy.properties


custom.strategy.class=com.something.DefaultStrategy




```

If the class cannot be resolved at runtime to a valid class, resolution of the bean
fails when it is about to be created, which is during the `preInstantiateSingletons()`phase of an `ApplicationContext` for a non-lazy-init bean.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#beans-factory-overrideconfigurer)Example: The `PropertyOverrideConfigurer` ##### +##### Example: The `PropertyOverrideConfigurer` The `PropertyOverrideConfigurer`, another bean factory post-processor, resembles the`PropertySourcesPlaceholderConfigurer`, but unlike the latter, the original definitions can have default values or no values at all for bean properties. If an overriding`Properties` file does not have an entry for a certain bean property, the default @@ -4284,7 +3832,7 @@ property overriding with a dedicated configuration element, as the following exa ``` -#### [](#beans-factory-extension-factorybean)1.8.3. Customizing Instantiation Logic with a `FactoryBean` #### +#### 1.8.3. Customizing Instantiation Logic with a `FactoryBean` You can implement the `org.springframework.beans.factory.FactoryBean` interface for objects that are themselves factories. @@ -4314,7 +3862,7 @@ the bean it produces, prefix the bean’s `id` with the ampersand symbol (`&`) w calling the `getBean()` method of the `ApplicationContext`. So, for a given `FactoryBean`with an `id` of `myBean`, invoking `getBean("myBean")` on the container returns the product of the `FactoryBean`, whereas invoking `getBean("&myBean")` returns the`FactoryBean` instance itself. -### [](#beans-annotation-config)1.9. Annotation-based Container Configuration ### +### 1.9. Annotation-based Container Configuration Are annotations better than XML for configuring Spring? @@ -4384,7 +3932,7 @@ The `` element implicitly registers the following po | |`` only looks for annotations on beans in the same
application context in which it is defined. This means that, if you put`` in a `WebApplicationContext` for a `DispatcherServlet`,
it only checks for `@Autowired` beans in your controllers, and not your services. See[The DispatcherServlet](web.html#mvc-servlet) for more information.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#beans-required-annotation)1.9.1. @Required #### +#### 1.9.1. @Required The `@Required` annotation applies to bean property setter methods, as in the following example: @@ -4430,7 +3978,7 @@ references and values even when you use the class outside of a container. | |The `@Required` annotation and `RequiredAnnotationBeanPostProcessor` are formally
deprecated as of Spring Framework 5.1, in favor of using constructor injection for
required settings (or a custom implementation of `InitializingBean.afterPropertiesSet()`or a custom `@PostConstruct` method along with bean property setter methods).| |---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#beans-autowired-annotation)1.9.2. Using `@Autowired` #### +#### 1.9.2. Using `@Autowired` | |JSR 330’s `@Inject` annotation can be used in place of Spring’s `@Autowired` annotation in the
examples included in this section. See [here](#beans-standard-annotations) for more details.| |---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| @@ -4798,7 +4346,7 @@ class MovieRecommender { | |The `@Autowired`, `@Inject`, `@Value`, and `@Resource` annotations are handled by Spring`BeanPostProcessor` implementations. This means that you cannot apply these annotations
within your own `BeanPostProcessor` or `BeanFactoryPostProcessor` types (if any).
These types must be 'wired up' explicitly by using XML or a Spring `@Bean` method.| |---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#beans-autowired-annotation-primary)1.9.3. Fine-tuning Annotation-based Autowiring with `@Primary` #### +#### 1.9.3. Fine-tuning Annotation-based Autowiring with `@Primary` Because autowiring by type may lead to multiple candidates, it is often necessary to have more control over the selection process. One way to accomplish this is with Spring’s`@Primary` annotation. `@Primary` indicates that a particular bean should be given @@ -4896,7 +4444,7 @@ The corresponding bean definitions follow:
``` -#### [](#beans-autowired-annotation-qualifiers)1.9.4. Fine-tuning Annotation-based Autowiring with Qualifiers #### +#### 1.9.4. Fine-tuning Annotation-based Autowiring with Qualifiers `@Primary` is an effective way to use autowiring by type with several instances when one primary candidate can be determined. When you need more control over the selection process, @@ -5384,7 +4932,7 @@ the following example:
``` -#### [](#beans-generics-as-qualifiers)1.9.5. Using Generics as Autowiring Qualifiers #### +#### 1.9.5. Using Generics as Autowiring Qualifiers In addition to the `@Qualifier` annotation, you can use Java generic types as an implicit form of qualification. For example, suppose you have the following @@ -5466,7 +5014,7 @@ Kotlin private lateinit var s: List> ``` -#### [](#beans-custom-autowire-configurer)1.9.6. Using `CustomAutowireConfigurer` #### +#### 1.9.6. Using `CustomAutowireConfigurer` [`CustomAutowireConfigurer`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/beans/factory/annotation/CustomAutowireConfigurer.html)is a `BeanFactoryPostProcessor` that lets you register your own custom qualifier annotation types, even if they are not annotated with Spring’s `@Qualifier` annotation. @@ -5495,7 +5043,7 @@ The `AutowireCandidateResolver` determines autowire candidates by: When multiple beans qualify as autowire candidates, the determination of a “primary” is as follows: If exactly one bean definition among the candidates has a `primary`attribute set to `true`, it is selected. -#### [](#beans-resource-annotation)1.9.7. Injection with `@Resource` #### +#### 1.9.7. Injection with `@Resource` Spring also supports injection by using the JSR-250 `@Resource` annotation (`javax.annotation.Resource`) on fields or bean property setter methods. @@ -5615,7 +5163,7 @@ class MovieRecommender { |**1**|The `context` field is injected based on the known resolvable dependency type:`ApplicationContext`.| |-----|---------------------------------------------------------------------------------------------------| -#### [](#beans-value-annotations)1.9.8. Using `@Value` #### +#### 1.9.8. Using `@Value` `@Value` is typically used to inject externalized properties: @@ -5815,7 +5363,7 @@ class MovieRecommender( @Value("#{{'Thriller': 100, 'Comedy': 300}}") private val countOfMoviesPerCatalog: Map) ``` -#### [](#beans-postconstruct-and-predestroy-annotations)1.9.9. Using `@PostConstruct` and `@PreDestroy` #### +#### 1.9.9. Using `@PostConstruct` and `@PreDestroy` The `CommonAnnotationBeanPostProcessor` not only recognizes the `@Resource` annotation but also the JSR-250 lifecycle annotations: `javax.annotation.PostConstruct` and`javax.annotation.PreDestroy`. Introduced in Spring 2.5, the support for these @@ -5864,7 +5412,7 @@ For details about the effects of combining various lifecycle mechanisms, see[Com | |Like `@Resource`, the `@PostConstruct` and `@PreDestroy` annotation types were a part
of the standard Java libraries from JDK 6 to 8. However, the entire `javax.annotation`package got separated from the core Java modules in JDK 9 and eventually removed in
JDK 11. If needed, the `javax.annotation-api` artifact needs to be obtained via Maven
Central now, simply to be added to the application’s classpath like any other library.| |---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -### [](#beans-classpath-scanning)1.10. Classpath Scanning and Managed Components ### +### 1.10. Classpath Scanning and Managed Components Most examples in this chapter use XML to specify the configuration metadata that produces each `BeanDefinition` within the Spring container. The previous section @@ -5882,7 +5430,7 @@ the container. | |Starting with Spring 3.0, many features provided by the Spring JavaConfig project are
part of the core Spring Framework. This allows you to define beans using Java rather
than using the traditional XML files. Take a look at the `@Configuration`, `@Bean`,`@Import`, and `@DependsOn` annotations for examples of how to use these new features.| |---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#beans-stereotype-annotations)1.10.1. `@Component` and Further Stereotype Annotations #### +#### 1.10.1. `@Component` and Further Stereotype Annotations The `@Repository` annotation is a marker for any class that fulfills the role or stereotype of a repository (also known as Data Access Object or DAO). Among the uses @@ -5898,7 +5446,7 @@ choosing between using `@Component` or `@Service` for your service layer, `@Serv clearly the better choice. Similarly, as stated earlier, `@Repository` is already supported as a marker for automatic exception translation in your persistence layer. -#### [](#beans-meta-annotations)1.10.2. Using Meta-annotations and Composed Annotations #### +#### 1.10.2. Using Meta-annotations and Composed Annotations Many of the annotations provided by Spring can be used as meta-annotations in your own code. A meta-annotation is an annotation that can be applied to another annotation. @@ -6022,7 +5570,7 @@ class SessionScopedUserService : UserService { For further details, see the[Spring Annotation Programming Model](https://github.com/spring-projects/spring-framework/wiki/Spring-Annotation-Programming-Model)wiki page. -#### [](#beans-scanning-autodetection)1.10.3. Automatically Detecting Classes and Registering Bean Definitions #### +#### 1.10.3. Automatically Detecting Classes and Registering Bean Definitions Spring can automatically detect stereotyped classes and register corresponding`BeanDefinition` instances with the `ApplicationContext`. For example, the following two classes are eligible for such autodetection: @@ -6123,7 +5671,7 @@ wired together — all without any bean configuration metadata provided in X | |You can disable the registration of `AutowiredAnnotationBeanPostProcessor` and`CommonAnnotationBeanPostProcessor` by including the `annotation-config` attribute
with a value of `false`.| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#beans-scanning-filters)1.10.4. Using Filters to Customize Scanning #### +#### 1.10.4. Using Filters to Customize Scanning By default, classes annotated with `@Component`, `@Repository`, `@Service`, `@Controller`,`@Configuration`, or a custom annotation that itself is annotated with `@Component` are the only detected candidate components. However, you can modify and extend this behavior @@ -6183,7 +5731,7 @@ The following listing shows the equivalent XML: | |You can also disable the default filters by setting `useDefaultFilters=false` on the
annotation or by providing `use-default-filters="false"` as an attribute of the`` element. This effectively disables automatic detection of classes
annotated or meta-annotated with `@Component`, `@Repository`, `@Service`, `@Controller`,`@RestController`, or `@Configuration`.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#beans-factorybeans-annotations)1.10.5. Defining Bean Metadata within Components #### +#### 1.10.5. Defining Bean Metadata within Components Spring components can also contribute bean definition metadata to the container. You can do this with the same `@Bean` annotation used to define bean metadata within `@Configuration`annotated classes. The following example shows how to do so: @@ -6356,7 +5904,7 @@ constraints applying. | |You may declare `@Bean` methods as `static`, allowing for them to be called without
creating their containing configuration class as an instance. This makes particular
sense when defining post-processor beans (for example, of type `BeanFactoryPostProcessor`or `BeanPostProcessor`), since such beans get initialized early in the container
lifecycle and should avoid triggering other parts of the configuration at that point.

Calls to static `@Bean` methods never get intercepted by the container, not even within`@Configuration` classes (as described earlier in this section), due to technical
limitations: CGLIB subclassing can override only non-static methods. As a consequence,
a direct call to another `@Bean` method has standard Java semantics, resulting
in an independent instance being returned straight from the factory method itself.

The Java language visibility of `@Bean` methods does not have an immediate impact on
the resulting bean definition in Spring’s container. You can freely declare your
factory methods as you see fit in non-`@Configuration` classes and also for static
methods anywhere. However, regular `@Bean` methods in `@Configuration` classes need
to be overridable — that is, they must not be declared as `private` or `final`.

`@Bean` methods are also discovered on base classes of a given component or
configuration class, as well as on Java 8 default methods declared in interfaces
implemented by the component or configuration class. This allows for a lot of
flexibility in composing complex configuration arrangements, with even multiple
inheritance being possible through Java 8 default methods as of Spring 4.2.

Finally, a single class may hold multiple `@Bean` methods for the same
bean, as an arrangement of multiple factory methods to use depending on available
dependencies at runtime. This is the same algorithm as for choosing the “greediest”
constructor or factory method in other configuration scenarios: The variant with
the largest number of satisfiable dependencies is picked at construction time,
analogous to how the container selects between multiple `@Autowired` constructors.| |---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#beans-scanning-name-generator)1.10.6. Naming Autodetected Components #### +#### 1.10.6. Naming Autodetected Components When a component is autodetected as part of the scanning process, its bean name is generated by the `BeanNameGenerator` strategy known to that scanner. By default, any @@ -6443,7 +5991,7 @@ As a general rule, consider specifying the name with the annotation whenever oth components may be making explicit references to it. On the other hand, the auto-generated names are adequate whenever the container is responsible for wiring. -#### [](#beans-scanning-scope-resolver)1.10.7. Providing a Scope for Autodetected Components #### +#### 1.10.7. Providing a Scope for Autodetected Components As with Spring-managed components in general, the default and most common scope for autodetected components is `singleton`. However, sometimes you need a different scope @@ -6540,7 +6088,7 @@ class AppConfig { ``` -#### [](#beans-scanning-qualifiers)1.10.8. Providing Qualifier Metadata with Annotations #### +#### 1.10.8. Providing Qualifier Metadata with Annotations The `@Qualifier` annotation is discussed in [Fine-tuning Annotation-based Autowiring with Qualifiers](#beans-autowired-annotation-qualifiers). The examples in that section demonstrate the use of the `@Qualifier` annotation and @@ -6612,7 +6160,7 @@ class CachingMovieCatalog : MovieCatalog { | |As with most annotation-based alternatives, keep in mind that the annotation metadata is
bound to the class definition itself, while the use of XML allows for multiple beans
of the same type to provide variations in their qualifier metadata, because that
metadata is provided per-instance rather than per-class.| |---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#beans-scanning-index)1.10.9. Generating an Index of Candidate Components #### +#### 1.10.9. Generating an Index of Candidate Components While classpath scanning is very fast, it is possible to improve the startup performance of large applications by creating a static list of candidates at compilation time. In this @@ -6661,7 +6209,7 @@ is included in the jar file. | |The index is enabled automatically when a `META-INF/spring.components` file is found
on the classpath. If an index is partially available for some libraries (or use cases)
but could not be built for the whole application, you can fall back to a regular classpath
arrangement (as though no index were present at all) by setting `spring.index.ignore` to`true`, either as a JVM system property or via the[`SpringProperties`](appendix.html#appendix-spring-properties) mechanism.| |---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -### [](#beans-standard-annotations)1.11. Using JSR 330 Standard Annotations ### +### 1.11. Using JSR 330 Standard Annotations Starting with Spring 3.0, Spring offers support for JSR-330 standard annotations (Dependency Injection). Those annotations are scanned in the same way as the Spring @@ -6670,7 +6218,7 @@ annotations. To use them, you need to have the relevant jars in your classpath. | |If you use Maven, the `javax.inject` artifact is available in the standard Maven
repository ([https://repo1.maven.org/maven2/javax/inject/javax.inject/1/](https://repo1.maven.org/maven2/javax/inject/javax.inject/1/)).
You can add the following dependency to your file pom.xml:

```

javax.inject
javax.inject
1

```| |---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#beans-inject-named)1.11.1. Dependency Injection with `@Inject` and `@Named` #### +#### 1.11.1. Dependency Injection with `@Inject` and `@Named` Instead of `@Autowired`, you can use `@javax.inject.Inject` as follows: @@ -6832,7 +6380,7 @@ class SimpleMovieLister { } ``` -#### [](#beans-named)1.11.2. `@Named` and `@ManagedBean`: Standard Equivalents to the `@Component` Annotation #### +#### 1.11.2. `@Named` and `@ManagedBean`: Standard Equivalents to the `@Component` Annotation Instead of `@Component`, you can use `@javax.inject.Named` or `javax.annotation.ManagedBean`, as the following example shows: @@ -6937,7 +6485,7 @@ class AppConfig { | |In contrast to `@Component`, the JSR-330 `@Named` and the JSR-250 `@ManagedBean`annotations are not composable. You should use Spring’s stereotype model for building
custom component annotations.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#beans-standard-annotations-limitations)1.11.3. Limitations of JSR-330 Standard Annotations #### +#### 1.11.3. Limitations of JSR-330 Standard Annotations When you work with standard annotations, you should know that some significant features are not available, as the following table shows: @@ -6953,7 +6501,7 @@ features are not available, as the following table shows: | @Lazy | \- | no equivalent | | ObjectFactory | Provider | `javax.inject.Provider` is a direct alternative to Spring’s `ObjectFactory`,
only with a shorter `get()` method name. It can also be used in combination with
Spring’s `@Autowired` or with non-annotated constructors and setter methods. | -### [](#beans-java)1.12. Java-based Container Configuration ### +### 1.12. Java-based Container Configuration This section covers how to use annotations in your Java code to configure the Spring container. It includes the following topics: @@ -6976,7 +6524,7 @@ container. It includes the following topics: * [Placeholder Resolution in Statements](#beans-placeholder-resolution-in-statements) -#### [](#beans-java-basic-concepts)1.12.1. Basic Concepts: `@Bean` and `@Configuration` #### +#### 1.12.1. Basic Concepts: `@Bean` and `@Configuration` The central artifacts in Spring’s new Java-configuration support are`@Configuration`-annotated classes and `@Bean`-annotated methods. @@ -7049,7 +6597,7 @@ The `@Bean` and `@Configuration` annotations are discussed in depth in the follo First, however, we cover the various ways of creating a spring container by using Java-based configuration. -#### [](#beans-java-instantiating-container)1.12.2. Instantiating the Spring Container by Using `AnnotationConfigApplicationContext` #### +#### 1.12.2. Instantiating the Spring Container by Using `AnnotationConfigApplicationContext` #### The following sections document Spring’s `AnnotationConfigApplicationContext`, introduced in Spring 3.0. This versatile `ApplicationContext` implementation is capable of accepting not only`@Configuration` classes as input but also plain `@Component` classes and classes @@ -7063,7 +6611,7 @@ When `@Component` and JSR-330 classes are provided, they are registered as bean definitions, and it is assumed that DI metadata such as `@Autowired` or `@Inject` are used within those classes where necessary. -##### [](#beans-java-instantiating-container-constructor)Simple Construction ##### +##### Simple Construction In much the same way that Spring XML files are used as input when instantiating a`ClassPathXmlApplicationContext`, you can use `@Configuration` classes as input when instantiating an `AnnotationConfigApplicationContext`. This allows for completely @@ -7120,7 +6668,7 @@ fun main() { The preceding example assumes that `MyServiceImpl`, `Dependency1`, and `Dependency2` use Spring dependency injection annotations such as `@Autowired`. -##### [](#beans-java-instantiating-container-register)Building the Container Programmatically by Using `register(Class…​)` ##### +##### Building the Container Programmatically by Using `register(Class…​)` ##### You can instantiate an `AnnotationConfigApplicationContext` by using a no-arg constructor and then configure it by using the `register()` method. This approach is particularly useful @@ -7155,7 +6703,7 @@ fun main() { } ``` -##### [](#beans-java-instantiating-container-scan)Enabling Component Scanning with `scan(String…​)` ##### +##### Enabling Component Scanning with `scan(String…​)` To enable component scanning, you can annotate your `@Configuration` class as follows: @@ -7217,7 +6765,7 @@ fun main() { | |Remember that `@Configuration` classes are [meta-annotated](#beans-meta-annotations)with `@Component`, so they are candidates for component-scanning. In the preceding example,
assuming that `AppConfig` is declared within the `com.acme` package (or any package
underneath), it is picked up during the call to `scan()`. Upon `refresh()`, all its `@Bean`methods are processed and registered as bean definitions within the container.| |---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#beans-java-instantiating-container-web)Support for Web Applications with `AnnotationConfigWebApplicationContext` ##### +##### Support for Web Applications with `AnnotationConfigWebApplicationContext` ##### A `WebApplicationContext` variant of `AnnotationConfigApplicationContext` is available with `AnnotationConfigWebApplicationContext`. You can use this implementation when @@ -7280,7 +6828,7 @@ init-param): | |For programmatic use cases, a `GenericWebApplicationContext` can be used as an
alternative to `AnnotationConfigWebApplicationContext`. See the[`GenericWebApplicationContext`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/web/context/support/GenericWebApplicationContext.html)javadoc for details.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#beans-java-bean-annotation)1.12.3. Using the `@Bean` Annotation #### +#### 1.12.3. Using the `@Bean` Annotation `@Bean` is a method-level annotation and a direct analog of the XML `` element. The annotation supports some of the attributes offered by ``, such as: @@ -7295,7 +6843,7 @@ The annotation supports some of the attributes offered by ``, such as: You can use the `@Bean` annotation in a `@Configuration`-annotated or in a`@Component`-annotated class. -##### [](#beans-java-declaring-a-bean)Declaring a Bean ##### +##### Declaring a Bean To declare a bean, you can annotate a method with the `@Bean` annotation. You use this method to register a bean definition within an `ApplicationContext` of the type @@ -7401,7 +6949,7 @@ which resolves only once the `transferService` bean has been instantiated). | |If you consistently refer to your types by a declared service interface, your`@Bean` return types may safely join that design decision. However, for components
that implement several interfaces or for components potentially referred to by their
implementation type, it is safer to declare the most specific return type possible
(at least as specific as required by the injection points that refer to your bean).| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#beans-java-dependencies)Bean Dependencies ##### +##### Bean Dependencies A `@Bean`-annotated method can have an arbitrary number of parameters that describe the dependencies required to build that bean. For instance, if our `TransferService`requires an `AccountRepository`, we can materialize that dependency with a method @@ -7436,7 +6984,7 @@ class AppConfig { The resolution mechanism is pretty much identical to constructor-based dependency injection. See [the relevant section](#beans-constructor-injection) for more details. -##### [](#beans-java-lifecycle-callbacks)Receiving Lifecycle Callbacks ##### +##### Receiving Lifecycle Callbacks Any classes defined with the `@Bean` annotation support the regular lifecycle callbacks and can use the `@PostConstruct` and `@PreDestroy` annotations from JSR-250. See[JSR-250 annotations](#beans-postconstruct-and-predestroy-annotations) for further @@ -7552,11 +7100,11 @@ class AppConfig { | |When you work directly in Java, you can do anything you like with your objects and do
not always need to rely on the container lifecycle.| |---|---------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#beans-java-specifying-bean-scope)Specifying Bean Scope ##### +##### Specifying Bean Scope Spring includes the `@Scope` annotation so that you can specify the scope of a bean. -###### [](#beans-java-available-scopes)Using the `@Scope` Annotation ###### +###### Using the `@Scope` Annotation You can specify that your beans defined with the `@Bean` annotation should have a specific scope. You can use any of the standard scopes specified in the[Bean Scopes](#beans-factory-scopes) section. @@ -7592,7 +7140,7 @@ class MyConfiguration { } ``` -###### [](#beans-java-scoped-proxy)`@Scope` and `scoped-proxy` ###### +###### `@Scope` and `scoped-proxy` Spring offers a convenient way of working with scoped dependencies through[scoped proxies](#beans-factory-scopes-other-injection). The easiest way to create such a proxy when using the XML configuration is the `` element. @@ -7640,7 +7188,7 @@ fun userService(): Service { } ``` -##### [](#beans-java-customizing-bean-naming)Customizing Bean Naming ##### +##### Customizing Bean Naming By default, configuration classes use a `@Bean` method’s name as the name of the resulting bean. This functionality can be overridden, however, with the `name` attribute, @@ -7670,7 +7218,7 @@ class AppConfig { } ``` -##### [](#beans-java-bean-aliasing)Bean Aliasing ##### +##### Bean Aliasing As discussed in [Naming Beans](#beans-beanname), it is sometimes desirable to give a single bean multiple names, otherwise known as bean aliasing. The `name` attribute of the `@Bean`annotation accepts a String array for this purpose. The following example shows how to set @@ -7702,7 +7250,7 @@ class AppConfig { } ``` -##### [](#beans-java-bean-description)Bean Description ##### +##### Bean Description Sometimes, it is helpful to provide a more detailed textual description of a bean. This can be particularly useful when beans are exposed (perhaps through JMX) for monitoring purposes. @@ -7735,14 +7283,14 @@ class AppConfig { } ``` -#### [](#beans-java-configuration-annotation)1.12.4. Using the `@Configuration` annotation #### +#### 1.12.4. Using the `@Configuration` annotation `@Configuration` is a class-level annotation indicating that an object is a source of bean definitions. `@Configuration` classes declare beans through `@Bean`-annotated methods. Calls to `@Bean` methods on `@Configuration` classes can also be used to define inter-bean dependencies. See [Basic Concepts: `@Bean` and `@Configuration`](#beans-java-basic-concepts) for a general introduction. -##### [](#beans-java-injecting-dependencies)Injecting Inter-bean Dependencies ##### +##### Injecting Inter-bean Dependencies When beans have dependencies on one another, expressing that dependency is as simple as having one bean method call another, as the following example shows: @@ -7785,7 +7333,7 @@ injection. | |This method of declaring inter-bean dependencies works only when the `@Bean` method
is declared within a `@Configuration` class. You cannot declare inter-bean dependencies
by using plain `@Component` classes.| |---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#beans-java-method-injection)Lookup Method Injection ##### +##### Lookup Method Injection As noted earlier, [lookup method injection](#beans-factory-method-injection) is an advanced feature that you should use rarely. It is useful in cases where a @@ -7877,7 +7425,7 @@ fun commandManager(): CommandManager { } ``` -##### [](#beans-java-further-information-java-config)Further Information About How Java-based Configuration Works Internally ##### +##### Further Information About How Java-based Configuration Works Internally ##### Consider the following example, which shows a `@Bean` annotated method being called twice: @@ -7952,12 +7500,12 @@ cached (scoped) beans before it calls the parent method and creates a new instan | |There are a few restrictions due to the fact that CGLIB dynamically adds features at
startup-time. In particular, configuration classes must not be final. However, as
of 4.3, any constructors are allowed on configuration classes, including the use of`@Autowired` or a single non-default constructor declaration for default injection.

If you prefer to avoid any CGLIB-imposed limitations, consider declaring your `@Bean`methods on non-`@Configuration` classes (for example, on plain `@Component` classes instead).
Cross-method calls between `@Bean` methods are not then intercepted, so you have
to exclusively rely on dependency injection at the constructor or method level there.| |---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#beans-java-composing-configuration-classes)1.12.5. Composing Java-based Configurations #### +#### 1.12.5. Composing Java-based Configurations Spring’s Java-based configuration feature lets you compose annotations, which can reduce the complexity of your configuration. -##### [](#beans-java-using-import)Using the `@Import` Annotation ##### +##### Using the `@Import` Annotation Much as the `` element is used within Spring XML files to aid in modularizing configurations, the `@Import` annotation allows for loading `@Bean` definitions from @@ -8041,7 +7589,7 @@ with, rather than requiring you to remember a potentially large number of`@Confi | |As of Spring Framework 4.2, `@Import` also supports references to regular component
classes, analogous to the `AnnotationConfigApplicationContext.register` method.
This is particularly useful if you want to avoid component scanning, by using a few
configuration classes as entry points to explicitly define all your components.| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -###### [](#beans-java-injecting-imported-beans)Injecting Dependencies on Imported `@Bean` Definitions ###### +###### Injecting Dependencies on Imported `@Bean` Definitions The preceding example works but is simplistic. In most practical scenarios, beans have dependencies on one another across configuration classes. When using XML, this is not an @@ -8398,7 +7946,7 @@ than the usual process of navigating interface-based code. | |If you want to influence the startup creation order of certain beans, consider
declaring some of them as `@Lazy` (for creation on first access instead of on startup)
or as `@DependsOn` certain other beans (making sure that specific other beans are
created before the current bean, beyond what the latter’s direct dependencies imply).| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#beans-java-conditional)Conditionally Include `@Configuration` Classes or `@Bean` Methods ##### +##### Conditionally Include `@Configuration` Classes or `@Bean` Methods It is often useful to conditionally enable or disable a complete `@Configuration` class or even individual `@Bean` methods, based on some arbitrary system state. One common @@ -8451,7 +7999,7 @@ override fun matches(context: ConditionContext, metadata: AnnotatedTypeMetadata) See the [`@Conditional`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/context/annotation/Conditional.html)javadoc for more detail. -##### [](#beans-java-combining)Combining Java and XML Configuration ##### +##### Combining Java and XML Configuration Spring’s `@Configuration` class support does not aim to be a 100% complete replacement for Spring XML. Some facilities, such as Spring XML namespaces, remain an ideal way to @@ -8459,7 +8007,7 @@ configure the container. In cases where XML is convenient or necessary, you have choice: either instantiate the container in an “XML-centric” way by using, for example,`ClassPathXmlApplicationContext`, or instantiate it in a “Java-centric” way by using`AnnotationConfigApplicationContext` and the `@ImportResource` annotation to import XML as needed. -###### [](#beans-java-combining-xml-centric)XML-centric Use of `@Configuration` Classes ###### +###### XML-centric Use of `@Configuration` Classes It may be preferable to bootstrap the Spring container from XML and include`@Configuration` classes in an ad-hoc fashion. For example, in a large existing codebase that uses Spring XML, it is easier to create `@Configuration` classes on an @@ -8587,7 +8135,7 @@ The following example shows the modified `system-test-config.xml` file: ``` -###### [](#beans-java-combining-java-centric)`@Configuration` Class-centric Use of XML with `@ImportResource` ###### +###### `@Configuration` Class-centric Use of XML with `@ImportResource` ###### In applications where `@Configuration` classes are the primary mechanism for configuring the container, it is still likely necessary to use at least some XML. In these @@ -8680,7 +8228,7 @@ fun main() { } ``` -### [](#beans-environment)1.13. Environment Abstraction ### +### 1.13. Environment Abstraction The [`Environment`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/core/env/Environment.html) interface is an abstraction integrated in the container that models two key @@ -8699,7 +8247,7 @@ on. The role of the `Environment` object with relation to properties is to provi user with a convenient service interface for configuring property sources and resolving properties from them. -#### [](#beans-definition-profiles)1.13.1. Bean Definition Profiles #### +#### 1.13.1. Bean Definition Profiles Bean definition profiles provide a mechanism in the core container that allows for registration of different beans in different environments. The word, “environment,” @@ -8782,7 +8330,7 @@ certain contexts but not in others. You could say that you want to register a certain profile of bean definitions in situation A and a different profile in situation B. We start by updating our configuration to reflect this need. -##### [](#beans-definition-profiles-java)Using `@Profile` ##### +##### Using `@Profile` The [`@Profile`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/context/annotation/Profile.html)annotation lets you indicate that a component is eligible for registration when one or more specified profiles are active. Using our preceding example, we @@ -8959,7 +8507,7 @@ class AppConfig { | |With `@Profile` on `@Bean` methods, a special scenario may apply: In the case of
overloaded `@Bean` methods of the same Java method name (analogous to constructor
overloading), a `@Profile` condition needs to be consistently declared on all
overloaded methods. If the conditions are inconsistent, only the condition on the
first declaration among the overloaded methods matters. Therefore, `@Profile` can
not be used to select an overloaded method with a particular argument signature over
another. Resolution between all factory methods for the same bean follows Spring’s
constructor resolution algorithm at creation time.

If you want to define alternative beans with different profile conditions,
use distinct Java method names that point to the same bean name by using the `@Bean` name
attribute, as shown in the preceding example. If the argument signatures are all
the same (for example, all of the variants have no-arg factory methods), this is the only
way to represent such an arrangement in a valid Java class in the first place
(since there can only be one method of a particular name and argument signature).| |---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#beans-definition-profiles-xml)XML Bean Definition Profiles ##### +##### XML Bean Definition Profiles The XML counterpart is the `profile` attribute of the `` element. Our preceding sample configuration can be rewritten in two XML files, as follows: @@ -9021,7 +8569,7 @@ clutter in the XML files. | |The XML counterpart does not support the profile expressions described earlier. It is possible,
however, to negate a profile by using the `!` operator. It is also possible to apply a logical
“and” by nesting the profiles, as the following example shows:

```
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="...">









```

In the preceding example, the `dataSource` bean is exposed if both the `production` and`us-east` profiles are active.| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#beans-definition-profiles-enable)Activating a Profile ##### +##### Activating a Profile Now that we have updated our configuration, we still need to instruct Spring which profile is active. If we started our sample application right now, we would see @@ -9078,7 +8626,7 @@ as the following example shows: -Dspring.profiles.active="profile1,profile2" ``` -##### [](#beans-definition-profiles-default)Default Profile ##### +##### Default Profile The default profile represents the profile that is enabled by default. Consider the following example: @@ -9124,7 +8672,7 @@ profile is enabled, the default profile does not apply. You can change the name of the default profile by using `setDefaultProfiles()` on the `Environment` or, declaratively, by using the `spring.profiles.default` property. -#### [](#beans-property-source-abstraction)1.13.2. `PropertySource` Abstraction #### +#### 1.13.2. `PropertySource` Abstraction Spring’s `Environment` abstraction provides search operations over a configurable hierarchy of property sources. Consider the following listing: @@ -9189,7 +8737,7 @@ search. If it contains a `my-property` property, the property is detected and re any `my-property` property in any other `PropertySource`. The[`MutablePropertySources`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/core/env/MutablePropertySources.html)API exposes a number of methods that allow for precise manipulation of the set of property sources. -#### [](#beans-using-propertysource)1.13.3. Using `@PropertySource` #### +#### 1.13.3. Using `@PropertySource` The [`@PropertySource`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/context/annotation/PropertySource.html)annotation provides a convenient and declarative mechanism for adding a `PropertySource`to Spring’s `Environment`. @@ -9281,7 +8829,7 @@ as a default. If no default is specified and a property cannot be resolved, an`I | |The `@PropertySource` annotation is repeatable, according to Java 8 conventions.
However, all such `@PropertySource` annotations need to be declared at the same
level, either directly on the configuration class or as meta-annotations within the
same custom annotation. Mixing direct annotations and meta-annotations is not
recommended, since direct annotations effectively override meta-annotations.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#beans-placeholder-resolution-in-statements)1.13.4. Placeholder Resolution in Statements #### +#### 1.13.4. Placeholder Resolution in Statements Historically, the value of placeholders in elements could be resolved only against JVM system properties or environment variables. This is no longer the case. Because @@ -9299,7 +8847,7 @@ Concretely, the following statement works regardless of where the `customer`prop
``` -### [](#context-load-time-weaver)1.14. Registering a `LoadTimeWeaver` ### +### 1.14. Registering a `LoadTimeWeaver` The `LoadTimeWeaver` is used by Spring to dynamically transform classes as they are loaded into the Java virtual machine (JVM). @@ -9336,7 +8884,7 @@ weaver instance. This is particularly useful in combination with[Spring’s JPA necessary for JPA class transformation. Consult the[`LocalContainerEntityManagerFactoryBean`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/orm/jpa/LocalContainerEntityManagerFactoryBean.html)javadoc for more detail. For more on AspectJ load-time weaving, see [Load-time Weaving with AspectJ in the Spring Framework](#aop-aj-ltw). -### [](#context-introduction)1.15. Additional Capabilities of the `ApplicationContext` ### +### 1.15. Additional Capabilities of the `ApplicationContext` As discussed in the [chapter introduction](#beans), the `org.springframework.beans.factory`package provides basic functionality for managing and manipulating beans, including in a programmatic way. The `org.springframework.context` package adds the[`ApplicationContext`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/context/ApplicationContext.html)interface, which extends the `BeanFactory` interface, in addition to extending other @@ -9358,7 +8906,7 @@ package also provides the following functionality: * Loading of multiple (hierarchical) contexts, letting each be focused on one particular layer, such as the web layer of an application, through the`HierarchicalBeanFactory` interface. -#### [](#context-functionality-messagesource)1.15.1. Internationalization using `MessageSource` #### +#### 1.15.1. Internationalization using `MessageSource` The `ApplicationContext` interface extends an interface called `MessageSource` and, therefore, provides internationalization (“i18n”) functionality. Spring also provides the`HierarchicalMessageSource` interface, which can resolve messages hierarchically. @@ -9562,7 +9110,7 @@ the application context’s `MessageSource` when the bean is created and configu | |As an alternative to `ResourceBundleMessageSource`, Spring provides a`ReloadableResourceBundleMessageSource` class. This variant supports the same bundle
file format but is more flexible than the standard JDK based`ResourceBundleMessageSource` implementation. In particular, it allows for reading
files from any Spring resource location (not only from the classpath) and supports hot
reloading of bundle property files (while efficiently caching them in between).
See the [`ReloadableResourceBundleMessageSource`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/context/support/ReloadableResourceBundleMessageSource.html)javadoc for details.| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#context-functionality-events)1.15.2. Standard and Custom Events #### +#### 1.15.2. Standard and Custom Events Event handling in the `ApplicationContext` is provided through the `ApplicationEvent`class and the `ApplicationListener` interface. If a bean that implements the`ApplicationListener` interface is deployed into the context, every time an`ApplicationEvent` gets published to the `ApplicationContext`, that bean is notified. Essentially, this is the standard Observer design pattern. @@ -9738,7 +9286,7 @@ notify appropriate parties. | |Spring’s eventing mechanism is designed for simple communication between Spring beans
within the same application context. However, for more sophisticated enterprise
integration needs, the separately maintained[Spring Integration](https://projects.spring.io/spring-integration/) project provides
complete support for building lightweight,[pattern-oriented](https://www.enterpriseintegrationpatterns.com), event-driven
architectures that build upon the well-known Spring programming model.| |---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#context-functionality-events-annotation)Annotation-based Event Listeners ##### +##### Annotation-based Event Listeners You can register an event listener on any method of a managed bean by using the`@EventListener` annotation. The `BlockedListNotifier` can be rewritten as follows: @@ -9866,7 +9414,7 @@ fun handleBlockedListEvent(event: BlockedListEvent): ListUpdateEvent { The `handleBlockedListEvent()` method publishes a new `ListUpdateEvent` for every`BlockedListEvent` that it handles. If you need to publish several events, you can return a `Collection` or an array of events instead. -##### [](#context-functionality-events-async)Asynchronous Listeners ##### +##### Asynchronous Listeners If you want a particular listener to process events asynchronously, you can reuse the[regular `@Async` support](integration.html#scheduling-annotation-support-async). The following example shows how to do so: @@ -9899,7 +9447,7 @@ Be aware of the following limitations when using asynchronous events: * Asynchronous event listener methods cannot publish a subsequent event by returning a value. If you need to publish another event as the result of the processing, inject an[`ApplicationEventPublisher`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/context/ApplicationEventPublisher.html)to publish the event manually. -##### [](#context-functionality-events-order)Ordering Listeners ##### +##### Ordering Listeners If you need one listener to be invoked before another one, you can add the `@Order`annotation to the method declaration, as the following example shows: @@ -9923,7 +9471,7 @@ fun processBlockedListEvent(event: BlockedListEvent) { } ``` -##### [](#context-functionality-events-generics)Generic Events ##### +##### Generic Events You can also use generics to further define the structure of your event. Consider using an`EntityCreatedEvent` where `T` is the type of the actual entity that got created. For example, you can create the following listener definition to receive only `EntityCreatedEvent` for a`Person`: @@ -9984,7 +9532,7 @@ class EntityCreatedEvent(entity: T) : ApplicationEvent(entity), ResolvableTyp | |This works not only for `ApplicationEvent` but any arbitrary object that you send as
an event.| |---|--------------------------------------------------------------------------------------------------| -#### [](#context-functionality-resources)1.15.3. Convenient Access to Low-level Resources #### +#### 1.15.3. Convenient Access to Low-level Resources For optimal usage and understanding of application contexts, you should familiarize yourself with Spring’s `Resource` abstraction, as described in [Resources](#resources). @@ -10012,7 +9560,7 @@ location path as a classpath location. You can also use location paths (resource with special prefixes to force loading of definitions from the classpath or a URL, regardless of the actual context type. -#### [](#context-functionality-startup)1.15.4. Application Startup Tracking #### +#### 1.15.4. Application Startup Tracking The `ApplicationContext` manages the lifecycle of Spring applications and provides a rich programming model around components. As a result, complex applications can have equally @@ -10078,7 +9626,7 @@ or ask for the `ApplicationStartup` type on any injection point. | |Developers should not use the `"spring.*"` namespace when creating custom startup steps.
This namespace is reserved for internal Spring usage and is subject to change.| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#context-create)1.15.5. Convenient ApplicationContext Instantiation for Web Applications #### +#### 1.15.5. Convenient ApplicationContext Instantiation for Web Applications You can create `ApplicationContext` instances declaratively by using, for example, a`ContextLoader`. Of course, you can also create `ApplicationContext` instances programmatically by using one of the `ApplicationContext` implementations. @@ -10104,7 +9652,7 @@ delimiters (comma, semicolon, and whitespace) and uses the values as locations w application contexts are searched. Ant-style path patterns are supported as well. Examples are `/WEB-INF/*Context.xml` (for all files with names that end with`Context.xml` and that reside in the `WEB-INF` directory) and `/WEB-INF/**/*Context.xml`(for all such files in any subdirectory of `WEB-INF`). -#### [](#context-deploy-rar)1.15.6. Deploying a Spring `ApplicationContext` as a Java EE RAR File #### +#### 1.15.6. Deploying a Spring `ApplicationContext` as a Java EE RAR File It is possible to deploy a Spring `ApplicationContext` as a RAR file, encapsulating the context and all of its required bean classes and library JARs in a Java EE RAR deployment @@ -10139,7 +9687,7 @@ For a simple deployment of a Spring ApplicationContext as a Java EE RAR file: | |Such RAR deployment units are usually self-contained. They do not expose components
to the outside world, not even to other modules of the same application. Interaction with a
RAR-based `ApplicationContext` usually occurs through JMS destinations that it shares with
other modules. A RAR-based `ApplicationContext` may also, for example, schedule some jobs
or react to new files in the file system (or the like). If it needs to allow synchronous
access from the outside, it could (for example) export RMI endpoints, which may be used
by other application modules on the same machine.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -### [](#beans-beanfactory)1.16. The `BeanFactory` ### +### 1.16. The `BeanFactory` The `BeanFactory` API provides the underlying basis for Spring’s IoC functionality. Its specific contracts are mostly used in integration with other parts of Spring and @@ -10158,7 +9706,7 @@ component annotations to be used. All of these flavors come in through extension operate on shared `BeanDefinition` objects as a core metadata representation. This is the essence of what makes Spring’s container so flexible and extensible. -#### [](#context-introduction-ctx-vs-beanfactory)1.16.1. `BeanFactory` or `ApplicationContext`? #### +#### 1.16.1. `BeanFactory` or `ApplicationContext`? This section explains the differences between the `BeanFactory` and`ApplicationContext` container levels and the implications on bootstrapping. @@ -10261,8 +9809,7 @@ container functionality in a typical enterprise setup. | |An `AnnotationConfigApplicationContext` has all common annotation post-processors
registered and may bring in additional processors underneath the
covers through configuration annotations, such as `@EnableTransactionManagement`.
At the abstraction level of Spring’s annotation-based configuration model,
the notion of bean post-processors becomes a mere internal container detail.| |---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -[](#resources)2. Resources ----------- +## 2. Resources This chapter covers how Spring handles resources and how you can work with resources in Spring. It includes the following topics: @@ -10283,7 +9830,7 @@ Spring. It includes the following topics: * [Application Contexts and Resource Paths](#resources-app-ctx) -### [](#resources-introduction)2.1. Introduction ### +### 2.1. Introduction Java’s standard `java.net.URL` class and standard handlers for various URL prefixes, unfortunately, are not quite adequate enough for all access to low-level resources. For @@ -10292,7 +9839,7 @@ resource that needs to be obtained from the classpath or relative to a`ServletCo quite complicated, and the `URL` interface still lacks some desirable functionality, such as a method to check for the existence of the resource being pointed to. -### [](#resources-resource)2.2. The `Resource` Interface ### +### 2.2. The `Resource` Interface Spring’s `Resource` interface located in the `org.springframework.core.io.` package is meant to be a more capable interface for abstracting access to low-level resources. The @@ -10378,7 +9925,7 @@ considered equivalent to any other library you would use for this purpose. | |The `Resource` abstraction does not replace functionality. It wraps it where
possible. For example, a `UrlResource` wraps a URL and uses the wrapped `URL` to do its
work.| |---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -### [](#resources-implementations)2.3. Built-in `Resource` Implementations ### +### 2.3. Built-in `Resource` Implementations Spring includes several built-in `Resource` implementations: @@ -10399,7 +9946,7 @@ Spring includes several built-in `Resource` implementations: For a complete list of `Resource` implementations available in Spring, consult the "All Known Implementing Classes" section of the[`Resource`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/core/io/Resource.html) javadoc. -#### [](#resources-implementations-urlresource)2.3.1. `UrlResource` #### +#### 2.3.1. `UrlResource` `UrlResource` wraps a `java.net.URL` and can be used to access any object that is normally accessible with a URL, such as files, an HTTPS target, an FTP target, and @@ -10413,7 +9960,7 @@ well-known (to property editor, that is) prefix (such as `classpath:`), it creat appropriate specialized `Resource` for that prefix. However, if it does not recognize the prefix, it assumes the string is a standard URL string and creates a `UrlResource`. -#### [](#resources-implementations-classpathresource)2.3.2. `ClassPathResource` #### +#### 2.3.2. `ClassPathResource` This class represents a resource that should be obtained from the classpath. It uses either the thread context class loader, a given class loader, or a given class for @@ -10428,19 +9975,19 @@ resolution as a `java.net.URL`. A `ClassPathResource` is created by Java code by explicitly using the `ClassPathResource`constructor but is often created implicitly when you call an API method that takes a`String` argument meant to represent a path. For the latter case, a JavaBeans`PropertyEditor` recognizes the special prefix, `classpath:`, on the string path and creates a `ClassPathResource` in that case. -#### [](#resources-implementations-filesystemresource)2.3.3. `FileSystemResource` #### +#### 2.3.3. `FileSystemResource` This is a `Resource` implementation for `java.io.File` handles. It also supports`java.nio.file.Path` handles, applying Spring’s standard String-based path transformations but performing all operations via the `java.nio.file.Files` API. For pure`java.nio.path.Path` based support use a `PathResource` instead. `FileSystemResource`supports resolution as a `File` and as a `URL`. -#### [](#resources-implementations-pathresource)2.3.4. `PathResource` #### +#### 2.3.4. `PathResource` This is a `Resource` implementation for `java.nio.file.Path` handles, performing all operations and transformations via the `Path` API. It supports resolution as a `File` and as a `URL` and also implements the extended `WritableResource` interface. `PathResource`is effectively a pure `java.nio.path.Path` based alternative to `FileSystemResource` with different `createRelative` behavior. -#### [](#resources-implementations-servletcontextresource)2.3.5. `ServletContextResource` #### +#### 2.3.5. `ServletContextResource` This is a `Resource` implementation for `ServletContext` resources that interprets relative paths within the relevant web application’s root directory. @@ -10451,7 +9998,7 @@ filesystem. Whether or not it is expanded and on the filesystem or accessed directly from the JAR or somewhere else like a database (which is conceivable) is actually dependent on the Servlet container. -#### [](#resources-implementations-inputstreamresource)2.3.6. `InputStreamResource` #### +#### 2.3.6. `InputStreamResource` An `InputStreamResource` is a `Resource` implementation for a given `InputStream`. It should be used only if no specific `Resource` implementation is applicable. In @@ -10462,14 +10009,14 @@ already-opened resource. Therefore, it returns `true` from `isOpen()`. Do not us you need to keep the resource descriptor somewhere or if you need to read a stream multiple times. -#### [](#resources-implementations-bytearrayresource)2.3.7. `ByteArrayResource` #### +#### 2.3.7. `ByteArrayResource` This is a `Resource` implementation for a given byte array. It creates a`ByteArrayInputStream` for the given byte array. It is useful for loading content from any given byte array without having to resort to a single-use `InputStreamResource`. -### [](#resources-resourceloader)2.4. The `ResourceLoader` Interface ### +### 2.4. The `ResourceLoader` Interface The `ResourceLoader` interface is meant to be implemented by objects that can return (that is, load) `Resource` instances. The following listing shows the `ResourceLoader`interface definition: @@ -10561,7 +10108,7 @@ The following table summarizes the strategy for converting `String` objects to ` | https: | `https://myserver/logo.png` | Loaded as a `URL`. | | (none) | `/data/config.xml` | Depends on the underlying `ApplicationContext`. | -### [](#resources-resourcepatternresolver)2.5. The `ResourcePatternResolver` Interface ### +### 2.5. The `ResourcePatternResolver` Interface The `ResourcePatternResolver` interface is an extension to the `ResourceLoader` interface which defines a strategy for resolving a location pattern (for example, an Ant-style path @@ -10596,7 +10143,7 @@ wildcards. | |The default `ResourceLoader` in any standard `ApplicationContext` is in fact an instance
of `PathMatchingResourcePatternResolver` which implements the `ResourcePatternResolver`interface. The same is true for the `ApplicationContext` instance itself which also
implements the `ResourcePatternResolver` interface and delegates to the default`PathMatchingResourcePatternResolver`.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -### [](#resources-resourceloaderaware)2.6. The `ResourceLoaderAware` Interface ### +### 2.6. The `ResourceLoaderAware` Interface The `ResourceLoaderAware` interface is a special callback interface which identifies components that expect to be provided a `ResourceLoader` reference. The following listing @@ -10632,7 +10179,7 @@ For more information, see [Using `@Autowired`](#beans-autowired-annotation). | |To load one or more `Resource` objects for a resource path that contains wildcards
or makes use of the special `classpath*:` resource prefix, consider having an instance of[`ResourcePatternResolver`](#resources-resourcepatternresolver) autowired into your
application components instead of `ResourceLoader`.| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -### [](#resources-as-dependencies)2.7. Resources as Dependencies ### +### 2.7. Resources as Dependencies If the bean itself is going to determine and supply the resource path through some sort of dynamic process, it probably makes sense for the bean to use the `ResourceLoader` or`ResourcePatternResolver` interface to load resources. For example, consider the loading @@ -10751,12 +10298,12 @@ Kotlin class MyBean(@Value("\${templates.path}") private val templates: Resource[]) ``` -### [](#resources-app-ctx)2.8. Application Contexts and Resource Paths ### +### 2.8. Application Contexts and Resource Paths This section covers how to create application contexts with resources, including shortcuts that work with XML, how to use wildcards, and other details. -#### [](#resources-app-ctx-construction)2.8.1. Constructing Application Contexts #### +#### 2.8.1. Constructing Application Contexts An application context constructor (for a specific application context type) generally takes a string or array of strings as the location paths of the resources, such as @@ -10817,7 +10364,7 @@ val ctx = FileSystemXmlApplicationContext("classpath:conf/appContext.xml") Using `FileSystemXmlApplicationContext` loads the bean definitions from the classpath. However, it is still a `FileSystemXmlApplicationContext`. If it is subsequently used as a`ResourceLoader`, any unprefixed paths are still treated as filesystem paths. -##### [](#resources-app-ctx-classpathxml)Constructing `ClassPathXmlApplicationContext` Instances — Shortcuts ##### +##### Constructing `ClassPathXmlApplicationContext` Instances — Shortcuts The `ClassPathXmlApplicationContext` exposes a number of constructors to enable convenient instantiation. The basic idea is that you can supply merely a string array @@ -10854,7 +10401,7 @@ val ctx = ClassPathXmlApplicationContext(arrayOf("services.xml", "repositories.x See the [`ClassPathXmlApplicationContext`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/context/support/ClassPathXmlApplicationContext.html)javadoc for details on the various constructors. -#### [](#resources-app-ctx-wildcards-in-resource-paths)2.8.2. Wildcards in Application Context Constructor Resource Paths #### +#### 2.8.2. Wildcards in Application Context Constructor Resource Paths #### The resource paths in application context constructor values may be simple paths (as shown earlier), each of which has a one-to-one mapping to a target `Resource` or, @@ -10872,7 +10419,7 @@ resolved at construction time. It has nothing to do with the `Resource` type its You cannot use the `classpath*:` prefix to construct an actual `Resource`, as a resource points to just one resource at a time. -##### [](#resources-app-ctx-ant-patterns-in-paths)Ant-style Patterns ##### +##### Ant-style Patterns Path locations can contain Ant-style patterns, as the following example shows: @@ -10891,7 +10438,7 @@ a `java.io.File` is obtained from it and used to resolve the wildcard by travers filesystem. In the case of a jar URL, the resolver either gets a`java.net.JarURLConnection` from it or manually parses the jar URL and then traverses the contents of the jar file to resolve the wildcards. -###### [](#resources-app-ctx-portability)Implications on Portability ###### +###### Implications on Portability If the specified path is already a `file` URL (either implicitly because the base`ResourceLoader` is a filesystem one or explicitly), wildcarding is guaranteed to work in a completely portable fashion. @@ -10909,7 +10456,7 @@ walk the contents of the jar and resolve the wildcard. This does work in most en but fails in others, and we strongly recommend that the wildcard resolution of resources coming from jars be thoroughly tested in your specific environment before you rely on it. -##### [](#resources-classpath-wildcards)The `classpath*:` Prefix ##### +##### The `classpath*:` Prefix When constructing an XML-based application context, a location string may use the special `classpath*:` prefix, as the following example shows: @@ -10941,7 +10488,7 @@ used on the last non-wildcard path segment to get all the matching resources in class loader hierarchy and then, off each resource, the same `PathMatcher` resolution strategy described earlier is used for the wildcard subpath. -##### [](#resources-wildcards-in-path-other-stuff)Other Notes Relating to Wildcards ##### +##### Other Notes Relating to Wildcards Note that `classpath*:`, when combined with Ant-style patterns, only works reliably with at least one root directory before the pattern starts, unless the actual @@ -10976,7 +10523,7 @@ multiple `ClassLoader` locations, the desired resource may not exist in the firs location found. Therefore, in such cases you should prefer using `classpath*:` with the same Ant-style pattern, which searches all classpath locations that contain the`com.mycompany` base package: `classpath*:com/mycompany/**/service-context.xml`. -#### [](#resources-filesystemresource-caveats)2.8.3. `FileSystemResource` Caveats #### +#### 2.8.3. `FileSystemResource` Caveats A `FileSystemResource` that is not attached to a `FileSystemApplicationContext` (that is, when a `FileSystemApplicationContext` is not the actual `ResourceLoader`) treats @@ -11079,8 +10626,7 @@ Kotlin val ctx = FileSystemXmlApplicationContext("file:///conf/context.xml") ``` -[](#validation)3. Validation, Data Binding, and Type Conversion ----------- +## 3. Validation, Data Binding, and Type Conversion# There are pros and cons for considering validation as business logic, and Spring offers a design for validation (and data binding) that does not exclude either one of them. @@ -11110,7 +10656,7 @@ as described in [Java Bean Validation](#validation-beanvalidation), and use it e needs. In the web layer, applications can further register controller-local Spring`Validator` instances per `DataBinder`, as described in [Configuring a `DataBinder`](#validation-binder), which can be useful for plugging in custom validation logic. -### [](#validator)3.1. Validation by Using Spring’s Validator Interface ### +### 3.1. Validation by Using Spring’s Validator Interface Spring features a `Validator` interface that you can use to validate objects. The`Validator` interface works by using an `Errors` object so that, while validating, validators can report validation failures to the `Errors` object. @@ -11287,7 +10833,7 @@ of Spring Web MVC, you can use the `` tag to inspect the error mes you can also inspect the `Errors` object yourself. More information about the methods it offers can be found in the [javadoc](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/validation/Errors.html). -### [](#validation-conversion)3.2. Resolving Codes to Error Messages ### +### 3.2. Resolving Codes to Error Messages We covered databinding and validation. This section covers outputting messages that correspond to validation errors. In the example shown in the [preceding section](#validator), @@ -11305,7 +10851,7 @@ More information on the `MessageCodesResolver` and the default strategy can be f in the javadoc of[`MessageCodesResolver`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/validation/MessageCodesResolver.html) and[`DefaultMessageCodesResolver`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/validation/DefaultMessageCodesResolver.html), respectively. -### [](#beans-beans)3.3. Bean Manipulation and the `BeanWrapper` ### +### 3.3. Bean Manipulation and the `BeanWrapper` The `org.springframework.beans` package adheres to the JavaBeans standard. A JavaBean is a class with a default no-argument constructor and that follows @@ -11324,7 +10870,7 @@ The `BeanWrapper` usually is not used by application code directly but is used b The way the `BeanWrapper` works is partly indicated by its name: it wraps a bean to perform actions on that bean, such as setting and retrieving properties. -#### [](#beans-beans-conventions)3.3.1. Setting and Getting Basic and Nested Properties #### +#### 3.3.1. Setting and Getting Basic and Nested Properties Setting and getting properties is done through the `setPropertyValue` and`getPropertyValue` overloaded method variants of `BeanWrapper`. See their Javadoc for details. The below table shows some examples of these conventions: @@ -11454,7 +11000,7 @@ company.setPropertyValue("managingDirector", jim.wrappedInstance) val salary = company.getPropertyValue("managingDirector.salary") as Float? ``` -#### [](#beans-beans-conversion)3.3.2. Built-in `PropertyEditor` Implementations #### +#### 3.3.2. Built-in `PropertyEditor` Implementations Spring uses the concept of a `PropertyEditor` to effect the conversion between an`Object` and a `String`. It can be handy to represent properties in a different way than the object itself. For example, a `Date`can be represented in a human readable way (as the `String`: `'2007-14-09'`), while @@ -11572,7 +11118,7 @@ class SomethingBeanInfo : SimpleBeanInfo() { } ``` -##### [](#beans-beans-conversion-customeditor-registration)Registering Additional Custom `PropertyEditor` Implementations ##### +##### Registering Additional Custom `PropertyEditor` Implementations ##### When setting bean properties as string values, a Spring IoC container ultimately uses standard JavaBeans `PropertyEditor` implementations to convert these strings to the complex type of the @@ -11693,7 +11239,7 @@ Finally, the following example shows how to use `CustomEditorConfigurer` to regi
``` -###### [](#beans-beans-conversion-customeditor-registration-per)Using `PropertyEditorRegistrar` ###### +###### Using `PropertyEditorRegistrar` Another mechanism for registering property editors with the Spring container is to create and use a `PropertyEditorRegistrar`. This interface is particularly useful when @@ -11805,7 +11351,7 @@ class RegisterUserController( This style of `PropertyEditor` registration can lead to concise code (the implementation of `initBinder(..)` is only one line long) and lets common `PropertyEditor`registration code be encapsulated in a class and then shared amongst as many`Controllers` as needed. -### [](#core-convert)3.4. Spring Type Conversion ### +### 3.4. Spring Type Conversion Spring 3 introduced a `core.convert` package that provides a general type conversion system. The system defines an SPI to implement type conversion logic and an API @@ -11814,7 +11360,7 @@ as an alternative to `PropertyEditor` implementations to convert externalized be strings to the required property types. You can also use the public API anywhere in your application where type conversion is needed. -#### [](#core-convert-Converter-API)3.4.1. Converter SPI #### +#### 3.4.1. Converter SPI The SPI to implement type conversion logic is simple and strongly typed, as the following interface definition shows: @@ -11851,7 +11397,7 @@ final class StringToInteger implements Converter { } ``` -#### [](#core-convert-ConverterFactory-SPI)3.4.2. Using `ConverterFactory` #### +#### 3.4.2. Using `ConverterFactory` When you need to centralize the conversion logic for an entire class hierarchy (for example, when converting from `String` to `Enum` objects), you can implement`ConverterFactory`, as the following example shows: @@ -11895,7 +11441,7 @@ final class StringToEnumConverterFactory implements ConverterFactoryit only when you need it. Favor `Converter` or `ConverterFactory` for basic type
conversion needs.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#core-convert-ConditionalGenericConverter-SPI)Using `ConditionalGenericConverter` ##### +##### Using `ConditionalGenericConverter` Sometimes, you want a `Converter` to run only if a specific condition holds true. For example, you might want to run a `Converter` only if a specific annotation is present @@ -11949,7 +11495,7 @@ public interface ConditionalGenericConverter extends GenericConverter, Condition A good example of a `ConditionalGenericConverter` is an `IdToEntityConverter` that converts between a persistent entity identifier and an entity reference. Such an `IdToEntityConverter`might match only if the target entity type declares a static finder method (for example,`findAccount(Long)`). You might perform such a finder method check in the implementation of`matches(TypeDescriptor, TypeDescriptor)`. -#### [](#core-convert-ConversionService-API)3.4.4. The `ConversionService` API #### +#### 3.4.4. The `ConversionService` API `ConversionService` defines a unified API for executing type conversion logic at runtime. Converters are often run behind the following facade interface: @@ -11976,7 +11522,7 @@ A robust `ConversionService` implementation is provided in the `core.convert.sup use in most environments. `ConversionServiceFactory` provides a convenient factory for creating common `ConversionService` configurations. -#### [](#core-convert-Spring-config)3.4.5. Configuring a `ConversionService` #### +#### 3.4.5. Configuring a `ConversionService` A `ConversionService` is a stateless object designed to be instantiated at application startup and then shared between multiple threads. In a Spring application, you typically @@ -12015,7 +11561,7 @@ It is also common to use a `ConversionService` within a Spring MVC application. In certain situations, you may wish to apply formatting during conversion. See[The `FormatterRegistry` SPI](#format-FormatterRegistry-SPI) for details on using `FormattingConversionServiceFactoryBean`. -#### [](#core-convert-programmatic-usage)3.4.6. Using a `ConversionService` Programmatically #### +#### 3.4.6. Using a `ConversionService` Programmatically To work with a `ConversionService` instance programmatically, you can inject a reference to it like you would for any other bean. The following example shows how to do so: @@ -12086,7 +11632,7 @@ with any `ConverterRegistry` by using the static `addDefaultConverters`method on Converters for value types are reused for arrays and collections, so there is no need to create a specific converter to convert from a `Collection` of `S` to a`Collection` of `T`, assuming that standard collection handling is appropriate. -### [](#format)3.5. Spring Field Formatting ### +### 3.5. Spring Field Formatting As discussed in the previous section, [`core.convert`](#core-convert) is a general-purpose type conversion system. It provides a unified `ConversionService` API as @@ -12108,7 +11654,7 @@ conversion logic — for example, for converting between a `java.util.Date` You can use the `Formatter` SPI when you work in a client environment (such as a web application) and need to parse and print localized field values. The `ConversionService`provides a unified type conversion API for both SPIs. -#### [](#format-Formatter-SPI)3.5.1. The `Formatter` SPI #### +#### 3.5.1. The `Formatter` SPI The `Formatter` SPI to implement field formatting logic is simple and strongly typed. The following listing shows the `Formatter` interface definition: @@ -12208,7 +11754,7 @@ class DateFormatter(private val pattern: String) : Formatter { The Spring team welcomes community-driven `Formatter` contributions. See[GitHub Issues](https://github.com/spring-projects/spring-framework/issues) to contribute. -#### [](#format-CustomFormatAnnotations)3.5.2. Annotation-driven Formatting #### +#### 3.5.2. Annotation-driven Formatting Field formatting can be configured by field type or annotation. To bind an annotation to a `Formatter`, implement `AnnotationFormatterFactory`. The following @@ -12331,7 +11877,7 @@ class MyModel( ) ``` -##### [](#format-annotations-api)Format Annotation API ##### +##### Format Annotation API A portable format annotation API exists in the `org.springframework.format.annotation`package. You can use `@NumberFormat` to format `Number` fields such as `Double` and`Long`, and `@DateTimeFormat` to format `java.util.Date`, `java.util.Calendar`, `Long`(for millisecond timestamps) as well as JSR-310 `java.time`. @@ -12356,7 +11902,7 @@ class MyModel( ) ``` -#### [](#format-FormatterRegistry-SPI)3.5.3. The `FormatterRegistry` SPI #### +#### 3.5.3. The `FormatterRegistry` SPI The `FormatterRegistry` is an SPI for registering formatters and converters.`FormattingConversionService` is an implementation of `FormatterRegistry` suitable for most environments. You can programmatically or declaratively configure this variant @@ -12393,7 +11939,7 @@ enforce that all date fields are formatted a certain way or that fields with a s annotation are formatted in a certain way. With a shared `FormatterRegistry`, you define these rules once, and they are applied whenever formatting is needed. -#### [](#format-FormatterRegistrar-SPI)3.5.4. The `FormatterRegistrar` SPI #### +#### 3.5.4. The `FormatterRegistrar` SPI `FormatterRegistrar` is an SPI for registering formatters and converters through the FormatterRegistry. The following listing shows its interface definition: @@ -12414,11 +11960,11 @@ needs to be indexed under a specific field type different from its own `` or registering a `Printer`/`Parser` pair. The next section provides more information on converter and formatter registration. -#### [](#format-configuring-formatting-mvc)3.5.5. Configuring Formatting in Spring MVC #### +#### 3.5.5. Configuring Formatting in Spring MVC See [Conversion and Formatting](web.html#mvc-config-conversion) in the Spring MVC chapter. -### [](#format-configuring-formatting-globaldatetimeformat)3.6. Configuring a Global Date and Time Format ### +### 3.6. Configuring a Global Date and Time Format By default, date and time fields not annotated with `@DateTimeFormat` are converted from strings by using the `DateFormat.SHORT` style. If you prefer, you can change this by @@ -12526,11 +12072,11 @@ If you prefer XML-based configuration, you can use a`FormattingConversionService Note there are extra considerations when configuring date and time formats in web applications. Please see[WebMVC Conversion and Formatting](web.html#mvc-config-conversion) or[WebFlux Conversion and Formatting](web-reactive.html#webflux-config-conversion). -### [](#validation-beanvalidation)3.7. Java Bean Validation ### +### 3.7. Java Bean Validation The Spring Framework provides support for the[Java Bean Validation](https://beanvalidation.org/) API. -#### [](#validation-beanvalidation-overview)3.7.1. Overview of Bean Validation #### +#### 3.7.1. Overview of Bean Validation Bean Validation provides a common way of validation through constraint declaration and metadata for Java applications. To use it, you annotate domain model properties with @@ -12590,7 +12136,7 @@ the API. See the [Hibernate Validator](https://hibernate.org/validator/) documen specific constraints. To learn how to set up a bean validation provider as a Spring bean, keep reading. -#### [](#validation-beanvalidation-spring)3.7.2. Configuring a Bean Validation Provider #### +#### 3.7.2. Configuring a Bean Validation Provider Spring provides full support for the Bean Validation API including the bootstrapping of a Bean Validation provider as a Spring bean. This lets you inject a`javax.validation.ValidatorFactory` or `javax.validation.Validator` wherever validation is @@ -12625,7 +12171,7 @@ The basic configuration in the preceding example triggers bean validation to ini using its default bootstrap mechanism. A Bean Validation provider, such as the Hibernate Validator, is expected to be present in the classpath and is automatically detected. -##### [](#validation-beanvalidation-spring-inject)Injecting a Validator ##### +##### Injecting a Validator `LocalValidatorFactoryBean` implements both `javax.validation.ValidatorFactory` and`javax.validation.Validator`, as well as Spring’s `org.springframework.validation.Validator`. You can inject a reference to either of these interfaces into beans that need to invoke @@ -12681,7 +12227,7 @@ import org.springframework.validation.Validator class MyService(@Autowired private val validator: Validator) ``` -##### [](#validation-beanvalidation-spring-constraints)Configuring Custom Constraints ##### +##### Configuring Custom Constraints Each bean validation constraint consists of two parts: @@ -12744,7 +12290,7 @@ class MyConstraintValidator(private val aDependency: Foo) : ConstraintValidator As the preceding example shows, a `ConstraintValidator` implementation can have its dependencies`@Autowired` as any other Spring bean. -##### [](#validation-beanvalidation-spring-method)Spring-driven Method Validation ##### +##### Spring-driven Method Validation You can integrate the method validation feature supported by Bean Validation 1.1 (and, as a custom extension, also by Hibernate Validator 4.3) into a Spring context through a`MethodValidationPostProcessor` bean definition: @@ -12777,13 +12323,13 @@ groups to use. See[`MethodValidationPostProcessor`](https://docs.spring.io/sprin | |Method validation relies on [AOP Proxies](#aop-introduction-proxies) around the
target classes, either JDK dynamic proxies for methods on interfaces or CGLIB proxies.
There are certain limitations with the use of proxies, some of which are described in[Understanding AOP Proxies](#aop-understanding-aop-proxies). In addition remember
to always use methods and accessors on proxied classes; direct field access will not work.| |---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#validation-beanvalidation-spring-other)Additional Configuration Options ##### +##### Additional Configuration Options The default `LocalValidatorFactoryBean` configuration suffices for most cases. There are a number of configuration options for various Bean Validation constructs, from message interpolation to traversal resolution. See the[`LocalValidatorFactoryBean`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.html)javadoc for more information on these options. -#### [](#validation-binder)3.7.3. Configuring a `DataBinder` #### +#### 3.7.3. Configuring a `DataBinder` Since Spring 3, you can configure a `DataBinder` instance with a `Validator`. Once configured, you can invoke the `Validator` by calling `binder.validate()`. Any validation`Errors` are automatically added to the binder’s `BindingResult`. @@ -12829,12 +12375,11 @@ You can also configure a `DataBinder` with multiple `Validator` instances throug combining globally configured bean validation with a Spring `Validator` configured locally on a DataBinder instance. See[Spring MVC Validation Configuration](web.html#mvc-config-validation). -#### [](#validation-mvc)3.7.4. Spring MVC 3 Validation #### +#### 3.7.4. Spring MVC 3 Validation See [Validation](web.html#mvc-config-validation) in the Spring MVC chapter. -[](#expressions)4. Spring Expression Language (SpEL) ----------- +## 4. Spring Expression Language (SpEL) The Spring Expression Language (“SpEL” for short) is a powerful expression language that supports querying and manipulating an object graph at runtime. The language syntax is @@ -12904,7 +12449,7 @@ The expression language supports the following functionality: * Templated expressions -### [](#expressions-evaluation)4.1. Evaluation ### +### 4.1. Evaluation This section introduces the simple use of SpEL interfaces and its expression language. The complete language reference can be found in[Language Reference](#expressions-language-ref). @@ -13104,7 +12649,7 @@ val result = exp.getValue(tesla, Boolean::class.java) // result == true ``` -#### [](#expressions-evaluation-context)4.1.1. Understanding `EvaluationContext` #### +#### 4.1.1. Understanding `EvaluationContext` The `EvaluationContext` interface is used when evaluating an expression to resolve properties, methods, or fields and to help perform type conversion. Spring provides two @@ -13132,7 +12677,7 @@ one or some combination of the following: * Data binding properties for read and write -##### [](#expressions-type-conversion)Type Conversion ##### +##### Type Conversion By default, SpEL uses the conversion service available in Spring core (`org.springframework.core.convert.ConversionService`). This conversion service comes @@ -13187,7 +12732,7 @@ parser.parseExpression("booleanList[0]").setValue(context, simple, "false") val b = simple.booleanList[0] ``` -#### [](#expressions-parser-configuration)4.1.2. Parser Configuration #### +#### 4.1.2. Parser Configuration It is possible to configure the SpEL expression parser by using a parser configuration object (`org.springframework.expression.spel.SpelParserConfiguration`). The configuration @@ -13252,7 +12797,7 @@ val o = expression.getValue(demo) // Each entry is a new empty String ``` -#### [](#expressions-spel-compilation)4.1.3. SpEL Compilation #### +#### 4.1.3. SpEL Compilation Spring Framework 4.1 includes a basic expression compiler. Expressions are usually interpreted, which provides a lot of dynamic flexibility during evaluation but @@ -13282,7 +12827,7 @@ and numeric operations, the performance gain can be very noticeable. In an examp micro benchmark run of 50000 iterations, it took 75ms to evaluate by using the interpreter and only 3ms using the compiled version of the expression. -##### [](#expressions-compiler-configuration)Compiler Configuration ##### +##### Compiler Configuration The compiler is not turned on by default, but you can turn it on in either of two different ways. You can turn it on by using the parser configuration process @@ -13355,7 +12900,7 @@ The second way to configure the compiler is for use when SpEL is embedded inside other component and it may not be possible to configure it through a configuration object. In these cases, it is possible to set the `spring.expression.compiler.mode`property via a JVM system property (or via the[`SpringProperties`](appendix.html#appendix-spring-properties) mechanism) to one of the`SpelCompilerMode` enum values (`off`, `immediate`, or `mixed`). -##### [](#expressions-compiler-limitations)Compiler Limitations ##### +##### Compiler Limitations Since Spring Framework 4.1, the basic compilation framework is in place. However, the framework does not yet support compiling every kind of expression. The initial focus has been on the @@ -13372,13 +12917,13 @@ kinds of expression cannot be compiled at the moment: More types of expressions will be compilable in the future. -### [](#expressions-beandef)4.2. Expressions in Bean Definitions ### +### 4.2. Expressions in Bean Definitions You can use SpEL expressions with XML-based or annotation-based configuration metadata for defining `BeanDefinition` instances. In both cases, the syntax to define the expression is of the form `#{ }`. -#### [](#expressions-beandef-xml-based)4.2.1. XML Configuration #### +#### 4.2.1. XML Configuration A property or constructor argument value can be set by using expressions, as the following example shows: @@ -13422,7 +12967,7 @@ You can also refer to other bean properties by name, as the following example sh
``` -#### [](#expressions-beandef-annotation-based)4.2.2. Annotation Configuration #### +#### 4.2.2. Annotation Configuration To specify a default value, you can place the `@Value` annotation on fields, methods, and method or constructor parameters. @@ -13556,7 +13101,7 @@ class MovieRecommender(private val customerPreferenceDao: CustomerPreferenceDao, } ``` -### [](#expressions-language-ref)4.3. Language Reference ### +### 4.3. Language Reference This section describes how the Spring Expression Language works. It covers the following topics: @@ -13591,7 +13136,7 @@ topics: * [Safe Navigation Operator](#expressions-operator-safe-navigation) -#### [](#expressions-ref-literal)4.3.1. Literal Expressions #### +#### 4.3.1. Literal Expressions The types of literal expressions supported are strings, numeric values (int, real, hex), boolean, and null. Strings are delimited by single quotation marks. To put a single quotation mark itself @@ -13640,7 +13185,7 @@ val nullValue = parser.parseExpression("null").value Numbers support the use of the negative sign, exponential notation, and decimal points. By default, real numbers are parsed by using `Double.parseDouble()`. -#### [](#expressions-properties-arrays)4.3.2. Properties, Arrays, Lists, Maps, and Indexers #### +#### 4.3.2. Properties, Arrays, Lists, Maps, and Indexers Navigating with property references is easy. To do so, use a period to indicate a nested property value. The instances of the `Inventor` class, `pupin` and `tesla`, were @@ -13758,7 +13303,7 @@ parser.parseExpression("officers['advisors'][0].placeOfBirth.country").setValue( societyContext, "Croatia") ``` -#### [](#expressions-inline-lists)4.3.3. Inline Lists #### +#### 4.3.3. Inline Lists You can directly express lists in an expression by using `{}` notation. @@ -13784,7 +13329,7 @@ val listOfLists = parser.parseExpression("{{'a','b'},{'x','y'}}").getValue(conte entirely composed of fixed literals, a constant list is created to represent the expression (rather than building a new list on each evaluation). -#### [](#expressions-inline-maps)4.3.4. Inline Maps #### +#### 4.3.4. Inline Maps You can also directly express maps in an expression by using `{key:value}` notation. The following example shows how to do so: @@ -13813,7 +13358,7 @@ constant map is created to represent the expression (rather than building a new each evaluation). Quoting of the map keys is optional (unless the key contains a period (`.`)). The examples above do not use quoted keys. -#### [](#expressions-array-construction)4.3.5. Array Construction #### +#### 4.3.5. Array Construction You can build arrays by using the familiar Java syntax, optionally supplying an initializer to have the array populated at construction time. The following example shows how to do so: @@ -13844,7 +13389,7 @@ val numbers3 = parser.parseExpression("new int[4][5]").getValue(context) as Arra You cannot currently supply an initializer when you construct a multi-dimensional array. -#### [](#expressions-methods)4.3.6. Methods #### +#### 4.3.6. Methods You can invoke methods by using typical Java programming syntax. You can also invoke methods on literals. Variable arguments are also supported. The following examples show how to @@ -13872,7 +13417,7 @@ val isMember = parser.parseExpression("isMember('Mihajlo Pupin')").getValue( societyContext, Boolean::class.java) ``` -#### [](#expressions-operators)4.3.7. Operators #### +#### 4.3.7. Operators The Spring Expression Language supports the following kinds of operators: @@ -13884,7 +13429,7 @@ The Spring Expression Language supports the following kinds of operators: * [The Assignment Operator](#expressions-assignment) -##### [](#expressions-operators-relational)Relational Operators ##### +##### Relational Operators The relational operators (equal, not equal, less than, less than or equal, greater than, and greater than or equal) are supported by using standard operator notation. The @@ -13981,7 +13526,7 @@ which the expression is embedded (such as in an XML document). The textual equiv All of the textual operators are case-insensitive. -##### [](#expressions-operators-logical)Logical Operators ##### +##### Logical Operators SpEL supports the following logical operators: @@ -14055,7 +13600,7 @@ val expression = "isMember('Nikola Tesla') and !isMember('Mihajlo Pupin')" val falseValue = parser.parseExpression(expression).getValue(societyContext, Boolean::class.java) ``` -##### [](#expressions-operators-mathematical)Mathematical Operators ##### +##### Mathematical Operators You can use the addition operator (`+`) on both numbers and strings. You can use the subtraction (`-`), multiplication (`*`), and division (`/`) operators only on numbers. @@ -14129,7 +13674,7 @@ val one = parser.parseExpression("8 / 5 % 2").getValue(Int::class.java) // 1 val minusTwentyOne = parser.parseExpression("1+2-3*8").getValue(Int::class.java) // -21 ``` -##### [](#expressions-assignment)The Assignment Operator ##### +##### The Assignment Operator To set a property, use the assignment operator (`=`). This is typically done within a call to `setValue` but can also be done inside a call to `getValue`. The following @@ -14161,7 +13706,7 @@ val aleks = parser.parseExpression( "name = 'Aleksandar Seovic'").getValue(context, inventor, String::class.java) ``` -#### [](#expressions-types)4.3.8. Types #### +#### 4.3.8. Types You can use the special `T` operator to specify an instance of `java.lang.Class` (the type). Static methods are invoked by using this operator as well. The`StandardEvaluationContext` uses a `TypeLocator` to find types, and the`StandardTypeLocator` (which can be replaced) is built with an understanding of the`java.lang` package. This means that `T()` references to types within the `java.lang`package do not need to be fully qualified, but all other type references must be. The @@ -14191,7 +13736,7 @@ val trueValue = parser.parseExpression( .getValue(Boolean::class.java) ``` -#### [](#expressions-constructors)4.3.9. Constructors #### +#### 4.3.9. Constructors You can invoke constructors by using the `new` operator. You should use the fully qualified class name for all types except those located in the `java.lang` package @@ -14223,7 +13768,7 @@ p.parseExpression( .getValue(societyContext) ``` -#### [](#expressions-ref-variables)4.3.10. Variables #### +#### 4.3.10. Variables You can reference variables in the expression by using the `#variableName` syntax. Variables are set by using the `setVariable` method on `EvaluationContext` implementations. @@ -14257,7 +13802,7 @@ parser.parseExpression("name = #newName").getValue(context, tesla) println(tesla.name) // "Mike Tesla" ``` -##### [](#expressions-this-root)The `#this` and `#root` Variables ##### +##### The `#this` and `#root` Variables The `#this` variable is always defined and refers to the current evaluation object (against which unqualified references are resolved). The `#root` variable is always @@ -14301,7 +13846,7 @@ val primesGreaterThanTen = parser.parseExpression( "#primes.?[#this>10]").getValue(context) as List ``` -#### [](#expressions-ref-functions)4.3.11. Functions #### +#### 4.3.11. Functions You can extend SpEL by registering user-defined functions that can be called within the expression string. The function is registered through the `EvaluationContext`. The @@ -14381,7 +13926,7 @@ val helloWorldReversed = parser.parseExpression( "#reverseString('hello')").getValue(context, String::class.java) ``` -#### [](#expressions-bean-references)4.3.12. Bean References #### +#### 4.3.12. Bean References If the evaluation context has been configured with a bean resolver, you can look up beans from an expression by using the `@` symbol. The following example shows how @@ -14434,7 +13979,7 @@ context.setBeanResolver(MyBeanResolver()) val bean = parser.parseExpression("&foo").getValue(context) ``` -#### [](#expressions-operator-ternary)4.3.13. Ternary Operator (If-Then-Else) #### +#### 4.3.13. Ternary Operator (If-Then-Else) You can use the ternary operator for performing if-then-else conditional logic inside the expression. The following listing shows a minimal example: @@ -14486,7 +14031,7 @@ val queryResultString = parser.parseExpression(expression) See the next section on the Elvis operator for an even shorter syntax for the ternary operator. -#### [](#expressions-operator-elvis)4.3.14. The Elvis Operator #### +#### 4.3.14. The Elvis Operator The Elvis operator is a shortening of the ternary operator syntax and is used in the[Groovy](http://www.groovy-lang.org/operators.html#_elvis_operator) language. With the ternary operator syntax, you usually have to repeat a variable twice, as the @@ -14553,7 +14098,7 @@ println(name) // Elvis Presley | |You can use the Elvis operator to apply default values in expressions. The following
example shows how to use the Elvis operator in a `@Value` expression:

```
@Value("#{systemProperties['pop3.port'] ?: 25}")
```

This will inject a system property `pop3.port` if it is defined or 25 if not.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#expressions-operator-safe-navigation)4.3.15. Safe Navigation Operator #### +#### 4.3.15. Safe Navigation Operator The safe navigation operator is used to avoid a `NullPointerException` and comes from the [Groovy](http://www.groovy-lang.org/operators.html#_safe_navigation_operator)language. Typically, when you have a reference to an object, you might need to verify that @@ -14595,7 +14140,7 @@ city = parser.parseExpression("placeOfBirth?.city").getValue(context, tesla, Str println(city) // null - does not throw NullPointerException!!! ``` -#### [](#expressions-collection-selection)4.3.16. Collection Selection #### +#### 4.3.16. Collection Selection Selection is a powerful expression language feature that lets you transform a source collection into another collection by selecting from its entries. @@ -14640,7 +14185,7 @@ val newMap = parser.parseExpression("map.?[value<27]").getValue() In addition to returning all the selected elements, you can retrieve only the first or the last element. To obtain the first element matching the selection, the syntax is`.^[selectionExpression]`. To obtain the last matching selection, the syntax is`.$[selectionExpression]`. -#### [](#expressions-collection-projection)4.3.17. Collection Projection #### +#### 4.3.17. Collection Projection Projection lets a collection drive the evaluation of a sub-expression, and the result is a new collection. The syntax for projection is `.![projectionExpression]`. For example, @@ -14667,7 +14212,7 @@ evaluated against each entry in the map (represented as a Java `Map.Entry`). The of a projection across a map is a list that consists of the evaluation of the projection expression against each map entry. -#### [](#expressions-templating)4.3.18. Expression templating #### +#### 4.3.18. Expression templating Expression templates allow mixing literal text with one or more evaluation blocks. Each evaluation block is delimited with prefix and suffix characters that you can @@ -14739,7 +14284,7 @@ class TemplateParserContext : ParserContext { } ``` -### [](#expressions-example-classes)4.4. Classes Used in the Examples ### +### 4.4. Classes Used in the Examples This section lists the classes used in the examples throughout this chapter. @@ -14943,8 +14488,7 @@ class Society { } ``` -[](#aop)5. Aspect Oriented Programming with Spring ----------- +## 5. Aspect Oriented Programming with Spring Aspect-oriented Programming (AOP) complements Object-oriented Programming (OOP) by providing another way of thinking about program structure. The key unit of modularity @@ -14975,7 +14519,7 @@ AOP is used in the Spring Framework to: | |If you are interested only in generic declarative services or other pre-packaged
declarative middleware services such as pooling, you do not need to work directly with
Spring AOP, and can skip most of this chapter.| |---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -### [](#aop-introduction-defn)5.1. AOP Concepts ### +### 5.1. AOP Concepts Let us begin by defining some central AOP concepts and terminology. These terms are not Spring-specific. Unfortunately, AOP terminology is not particularly intuitive. @@ -15058,7 +14602,7 @@ targeted independently of the object-oriented hierarchy. For example, you can ap around advice providing declarative transaction management to a set of methods that span multiple objects (such as all business operations in the service layer). -### [](#aop-introduction-spring-defn)5.2. Spring AOP Capabilities and Goals ### +### 5.2. Spring AOP Capabilities and Goals Spring AOP is implemented in pure Java. There is no need for a special compilation process. Spring AOP does not need to control the class loader hierarchy and is thus @@ -15094,7 +14638,7 @@ API. Spring AOP remains backward-compatible. See [the following chapter](#aop-ap | |One of the central tenets of the Spring Framework is that of non-invasiveness. This
is the idea that you should not be forced to introduce framework-specific classes and
interfaces into your business or domain model. However, in some places, the Spring Framework
does give you the option to introduce Spring Framework-specific dependencies into your
codebase. The rationale in giving you such options is because, in certain scenarios, it
might be just plain easier to read or code some specific piece of functionality in such
a way. However, the Spring Framework (almost) always offers you the choice: You have the
freedom to make an informed decision as to which option best suits your particular use
case or scenario.

One such choice that is relevant to this chapter is that of which AOP framework (and
which AOP style) to choose. You have the choice of AspectJ, Spring AOP, or both. You
also have the choice of either the @AspectJ annotation-style approach or the Spring XML
configuration-style approach. The fact that this chapter chooses to introduce the
@AspectJ-style approach first should not be taken as an indication that the Spring team
favors the @AspectJ annotation-style approach over the Spring XML configuration-style.

See [Choosing which AOP Declaration Style to Use](#aop-choosing) for a more complete discussion of the “whys and wherefores” of
each style.| |---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -### [](#aop-introduction-proxies)5.3. AOP Proxies ### +### 5.3. AOP Proxies Spring AOP defaults to using standard JDK dynamic proxies for AOP proxies. This enables any interface (or set of interfaces) to be proxied. @@ -15109,7 +14653,7 @@ pass a proxied object to a method as a concrete type. It is important to grasp the fact that Spring AOP is proxy-based. See[Understanding AOP Proxies](#aop-understanding-aop-proxies) for a thorough examination of exactly what this implementation detail actually means. -### [](#aop-ataspectj)5.4. @AspectJ support ### +### 5.4. @AspectJ support @AspectJ refers to a style of declaring aspects as regular Java classes annotated with annotations. The @AspectJ style was introduced by the[AspectJ project](https://www.eclipse.org/aspectj) as part of the AspectJ 5 release. Spring @@ -15120,7 +14664,7 @@ there is no dependency on the AspectJ compiler or weaver. | |Using the AspectJ compiler and weaver enables use of the full AspectJ language and
is discussed in [Using AspectJ with Spring Applications](#aop-using-aspectj).| |---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#aop-aspectj-support)5.4.1. Enabling @AspectJ Support #### +#### 5.4.1. Enabling @AspectJ Support To use @AspectJ aspects in a Spring configuration, you need to enable Spring support for configuring Spring AOP based on @AspectJ aspects and auto-proxying beans based on @@ -15133,7 +14677,7 @@ The @AspectJ support can be enabled with XML- or Java-style configuration. In ei case, you also need to ensure that AspectJ’s `aspectjweaver.jar` library is on the classpath of your application (version 1.8 or later). This library is available in the`lib` directory of an AspectJ distribution or from the Maven Central repository. -##### [](#aop-enable-aspectj-java)Enabling @AspectJ Support with Java Configuration ##### +##### Enabling @AspectJ Support with Java Configuration To enable @AspectJ support with Java `@Configuration`, add the `@EnableAspectJAutoProxy`annotation, as the following example shows: @@ -15155,7 +14699,7 @@ Kotlin class AppConfig ``` -##### [](#aop-enable-aspectj-xml)Enabling @AspectJ Support with XML Configuration ##### +##### Enabling @AspectJ Support with XML Configuration To enable @AspectJ support with XML-based configuration, use the `aop:aspectj-autoproxy`element, as the following example shows: @@ -15167,7 +14711,7 @@ This assumes that you use schema support as described in[XML Schema-based config See [the AOP schema](#xsd-schemas-aop) for how to import the tags in the `aop` namespace. -#### [](#aop-at-aspectj)5.4.2. Declaring an Aspect #### +#### 5.4.2. Declaring an Aspect With @AspectJ support enabled, any bean defined in your application context with a class that is an @AspectJ aspect (has the `@Aspect` annotation) is automatically @@ -15219,7 +14763,7 @@ declarations. | |Advising aspects with other aspects?

In Spring AOP, aspects themselves cannot be the targets of advice from other
aspects. The `@Aspect` annotation on a class marks it as an aspect and, hence, excludes
it from auto-proxying.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#aop-pointcuts)5.4.3. Declaring a Pointcut #### +#### 5.4.3. Declaring a Pointcut Pointcuts determine join points of interest and thus enable us to control when advice runs. Spring AOP only supports method execution join points for Spring @@ -15256,7 +14800,7 @@ Programming Guide](https://www.eclipse.org/aspectj/doc/released/progguide/index. Developer’s Notebook](https://www.eclipse.org/aspectj/doc/released/adk15notebook/index.html)) or one of the books on AspectJ (such as *Eclipse AspectJ*, by Colyer et al., or *AspectJ in Action*, by Ramnivas Laddad). -##### [](#aop-pointcuts-designators)Supported Pointcut Designators ##### +##### Supported Pointcut Designators Spring AOP supports the following AspectJ pointcut designators (PCD) for use in pointcut expressions: @@ -15337,7 +14881,7 @@ be used with the `&&` (and), `||` (or), and `!` (negation) operators, too. | |The `bean` PCD is supported only in Spring AOP and not in
native AspectJ weaving. It is a Spring-specific extension to the standard PCDs that
AspectJ defines and is, therefore, not available for aspects declared in the `@Aspect` model.

The `bean` PCD operates at the instance level (building on the Spring bean name
concept) rather than at the type level only (to which weaving-based AOP is limited).
Instance-based pointcut designators are a special capability of Spring’s
proxy-based AOP framework and its close integration with the Spring bean factory, where
it is natural and straightforward to identify specific beans by name.| |---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#aop-pointcuts-combining)Combining Pointcut Expressions ##### +##### Combining Pointcut Expressions You can combine pointcut expressions by using `&&,` `||` and `!`. You can also refer to pointcut expressions by name. The following example shows three pointcut expressions: @@ -15384,7 +14928,7 @@ rules apply (you can see private pointcuts in the same type, protected pointcuts hierarchy, public pointcuts anywhere, and so on). Visibility does not affect pointcut matching. -##### [](#aop-common-pointcuts)Sharing Common Pointcut Definitions ##### +##### Sharing Common Pointcut Definitions When working with enterprise applications, developers often want to refer to modules of the application and particular sets of operations from within several aspects. We @@ -15543,7 +15087,7 @@ write the following: The `` and `` elements are discussed in [Schema-based AOP Support](#aop-schema). The transaction elements are discussed in [Transaction Management](data-access.html#transaction). -##### [](#aop-pointcuts-examples)Examples ##### +##### Examples Spring AOP users are likely to use the `execution` pointcut designator the most often. The format of an execution expression follows: @@ -15695,7 +15239,7 @@ The following examples show some common pointcut expressions: bean(*Service) ``` -##### [](#writing-good-pointcuts)Writing Good Pointcuts ##### +##### Writing Good Pointcuts During compilation, AspectJ processes pointcuts in order to optimize matching performance. Examining code and determining if each join point matches (statically or @@ -15730,13 +15274,13 @@ designators are very fast to match, and using them means AspectJ can very quickl dismiss groups of join points that should not be further processed. A good pointcut should always include one if possible. -#### [](#aop-advice)5.4.4. Declaring Advice #### +#### 5.4.4. Declaring Advice Advice is associated with a pointcut expression and runs before, after, or around method executions matched by the pointcut. The pointcut expression may be either a simple reference to a named pointcut or a pointcut expression declared in place. -##### [](#aop-advice-before)Before Advice ##### +##### Before Advice You can declare before advice in an aspect by using the `@Before` annotation: @@ -15807,7 +15351,7 @@ class BeforeExample { } ``` -##### [](#aop-advice-after-returning)After Returning Advice ##### +##### After Returning Advice After returning advice runs when a matched method execution returns normally. You can declare it by using the `@AfterReturning` annotation: @@ -15896,7 +15440,7 @@ specified type (in this case, `Object`, which matches any return value). Please note that it is not possible to return a totally different reference when using after returning advice. -##### [](#aop-advice-after-throwing)After Throwing Advice ##### +##### After Throwing Advice After throwing advice runs when a matched method execution exits by throwing an exception. You can declare it by using the `@AfterThrowing` annotation, as the @@ -15984,7 +15528,7 @@ specified type (`DataAccessException`, in this case). | |Note that `@AfterThrowing` does not indicate a general exception handling callback.
Specifically, an `@AfterThrowing` advice method is only supposed to receive exceptions
from the join point (user-declared target method) itself but not from an accompanying`@After`/`@AfterReturning` method.| |---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#aop-advice-after-finally)After (Finally) Advice ##### +##### Advice After (finally) advice runs when a matched method execution exits. It is declared by using the `@After` annotation. After advice must be prepared to handle both normal and @@ -16026,7 +15570,7 @@ class AfterFinallyExample { | |Note that `@After` advice in AspectJ is defined as "after finally advice", analogous
to a finally block in a try-catch statement. It will be invoked for any outcome,
normal return or exception thrown from the join point (user-declared target method),
in contrast to `@AfterReturning` which only applies to successful normal returns.| |---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#aop-ataspectj-around-advice)Around Advice ##### +##### Around Advice The last kind of advice is *around* advice. Around advice runs "around" a matched method’s execution. It has the opportunity to do work both before and after the method @@ -16100,7 +15644,7 @@ class AroundExample { } ``` -##### [](#aop-ataspectj-advice-params)Advice Parameters ##### +##### Advice Parameters Spring offers fully typed advice, meaning that you declare the parameters you need in the advice signature (as we saw earlier for the returning and throwing examples) rather than @@ -16108,7 +15652,7 @@ work with `Object[]` arrays all the time. We see how to make argument and other values available to the advice body later in this section. First, we take a look at how to write generic advice that can find out about the method the advice is currently advising. -###### [](#aop-ataspectj-advice-params-the-joinpoint)Access to the Current `JoinPoint` ###### +###### Access to the Current `JoinPoint` Any advice method may declare, as its first parameter, a parameter of type`org.aspectj.lang.JoinPoint`. Note that around advice is required to declare a first parameter of type `ProceedingJoinPoint`, which is a subclass of `JoinPoint`. @@ -16127,7 +15671,7 @@ The `JoinPoint` interface provides a number of useful methods: See the [javadoc](https://www.eclipse.org/aspectj/doc/released/runtime-api/org/aspectj/lang/JoinPoint.html) for more detail. -###### [](#aop-ataspectj-advice-params-passing)Passing Parameters to Advice ###### +###### Passing Parameters to Advice We have already seen how to bind the returned value or exception value (using after returning and after throwing advice). To make argument values available to the advice @@ -16235,7 +15779,7 @@ fun audit(auditable: Auditable) { } ``` -###### [](#aop-ataspectj-advice-params-generics)Advice Parameters and Generics ###### +###### Advice Parameters and Generics Spring AOP can handle generics used in class declarations and method parameters. Suppose you have a generic type like the following: @@ -16305,7 +15849,7 @@ reasonable, as we also cannot decide how to treat `null` values in general. To a something similar to this, you have to type the parameter to `Collection` and manually check the type of the elements. -###### [](#aop-ataspectj-advice-params-names)Determining Argument Names ###### +###### Determining Argument Names The parameter binding in advice invocations relies on matching names used in pointcut expressions to declared parameter names in advice and pointcut method signatures. @@ -16409,7 +15953,7 @@ fun audit(jp: JoinPoint) { * If all of the above strategies fail, an `IllegalArgumentException` is thrown. -###### [](#aop-ataspectj-advice-proceeding-with-the-call)Proceeding with Arguments ###### +###### Proceeding with Arguments We remarked earlier that we would describe how to write a `proceed` call with arguments that works consistently across Spring AOP and AspectJ. The solution is @@ -16444,7 +15988,7 @@ fun preProcessQueryPattern(pjp: ProceedingJoinPoint, In many cases, you do this binding anyway (as in the preceding example). -##### [](#aop-ataspectj-advice-ordering)Advice Ordering ##### +##### Advice Ordering What happens when multiple pieces of advice all want to run at the same join point? Spring AOP follows the same precedence rules as AspectJ to determine the order of advice @@ -16464,7 +16008,7 @@ the higher precedence. | |Each of the distinct advice types of a particular aspect is conceptually meant to apply
to the join point directly. As a consequence, an `@AfterThrowing` advice method is not
supposed to receive an exception from an accompanying `@After`/`@AfterReturning` method.

As of Spring Framework 5.2.7, advice methods defined in the same `@Aspect` class that
need to run at the same join point are assigned precedence based on their advice type in
the following order, from highest to lowest precedence: `@Around`, `@Before`, `@After`,`@AfterReturning`, `@AfterThrowing`. Note, however, that an `@After` advice method will
effectively be invoked after any `@AfterReturning` or `@AfterThrowing` advice methods
in the same aspect, following AspectJ’s "after finally advice" semantics for `@After`.

When two pieces of the same type of advice (for example, two `@After` advice methods)
defined in the same `@Aspect` class both need to run at the same join point, the ordering
is undefined (since there is no way to retrieve the source code declaration order through
reflection for javac-compiled classes). Consider collapsing such advice methods into one
advice method per join point in each `@Aspect` class or refactor the pieces of advice into
separate `@Aspect` classes that you can order at the aspect level via `Ordered` or `@Order`.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#aop-introductions)5.4.5. Introductions #### +#### 5.4.5. Introductions Introductions (known as inter-type declarations in AspectJ) enable an aspect to declare that advised objects implement a given interface, and to provide an implementation of @@ -16528,7 +16072,7 @@ Kotlin val usageTracked = context.getBean("myService") as UsageTracked ``` -#### [](#aop-instantiation-models)5.4.6. Aspect Instantiation Models #### +#### 5.4.6. Aspect Instantiation Models | |This is an advanced topic. If you are just starting out with AOP, you can safely skip
it until later.| |---|---------------------------------------------------------------------------------------------------------| @@ -16583,7 +16127,7 @@ Programming Guide for more information on `per` clauses. The `pertarget` instantiation model works in exactly the same way as `perthis`, but it creates one aspect instance for each unique target object at matched join points. -#### [](#aop-ataspectj-example)5.4.7. An AOP Example #### +#### 5.4.7. An AOP Example Now that you have seen how all the constituent parts work, we can put them together to do something useful. @@ -16741,7 +16285,7 @@ fun doConcurrentOperation(pjp: ProceedingJoinPoint): Any { } ``` -### [](#aop-schema)5.5. Schema-based AOP Support ### +### 5.5. Schema-based AOP Support If you prefer an XML-based format, Spring also offers support for defining aspects using the `aop` namespace tags. The exact same pointcut expressions and advice kinds @@ -16760,7 +16304,7 @@ advisor, and aspect elements (note that these must be declared in that order). | |The `` style of configuration makes heavy use of Spring’s[auto-proxying](#aop-autoproxy) mechanism. This can cause issues (such as advice
not being woven) if you already use explicit auto-proxying through the use of`BeanNameAutoProxyCreator` or something similar. The recommended usage pattern is to
use either only the `` style or only the `AutoProxyCreator` style and
never mix them.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#aop-schema-declaring-an-aspect)5.5.1. Declaring an Aspect #### +#### 5.5.1. Declaring an Aspect When you use the schema support, an aspect is a regular Java object defined as a bean in your Spring application context. The state and behavior are captured in the fields and @@ -16784,7 +16328,7 @@ by using the `ref` attribute, as the following example shows: The bean that backs the aspect (`aBean` in this case) can of course be configured and dependency injected just like any other Spring bean. -#### [](#aop-schema-pointcuts)5.5.2. Declaring a Pointcut #### +#### 5.5.2. Declaring a Pointcut You can declare a named pointcut inside an `` element, letting the pointcut definition be shared across several aspects and advisors. @@ -16897,12 +16441,12 @@ used as named pointcuts to form composite pointcuts. The named pointcut support schema-based definition style is thus more limited than that offered by the @AspectJ style. -#### [](#aop-schema-advice)5.5.3. Declaring Advice #### +#### 5.5.3. Declaring Advice The schema-based AOP support uses the same five kinds of advice as the @AspectJ style, and they have exactly the same semantics. -##### [](#aop-schema-advice-before)Before Advice ##### +##### Before Advice Before advice runs before a matched method execution. It is declared inside an`` by using the `` element, as the following example shows: @@ -16942,7 +16486,7 @@ that contains the advice. Before a data access operation is performed (a method join point matched by the pointcut expression), the `doAccessCheck` method on the aspect bean is invoked. -##### [](#aop-schema-advice-after-returning)After Returning Advice ##### +##### After Returning Advice After returning advice runs when a matched method execution completes normally. It is declared inside an `` in the same way as before advice. The following example @@ -16991,7 +16535,7 @@ Kotlin fun doAccessCheck(retVal: Any) {... ``` -##### [](#aop-schema-advice-after-throwing)After Throwing Advice ##### +##### After Throwing Advice After throwing advice runs when a matched method execution exits by throwing an exception. It is declared inside an `` by using the `after-throwing` element, @@ -17039,7 +16583,7 @@ Kotlin fun doRecoveryActions(dataAccessEx: DataAccessException) {... ``` -##### [](#aop-schema-advice-after-finally)After (Finally) Advice ##### +##### After (Finally) Advice After (finally) advice runs no matter how a matched method execution exits. You can declare it by using the `after` element, as the following example shows: @@ -17055,7 +16599,7 @@ You can declare it by using the `after` element, as the following example shows: ``` -##### [](#aop-schema-advice-around)Around Advice ##### +##### Around Advice The last kind of advice is *around* advice. Around advice runs "around" a matched method’s execution. It has the opportunity to do work both before and after the method @@ -17113,7 +16657,7 @@ fun doBasicProfiling(pjp: ProceedingJoinPoint): Any { } ``` -##### [](#aop-schema-params)Advice Parameters ##### +##### Advice Parameters The schema-based declaration style supports fully typed advice in the same way as described for the @AspectJ support — by matching pointcut parameters by name against @@ -17290,7 +16834,7 @@ ms % Task name 00000 ? execution(getFoo) ``` -##### [](#aop-ordering)Advice Ordering ##### +##### Advice Ordering When multiple pieces of advice need to run at the same join point (executing method) the ordering rules are as described in [Advice Ordering](#aop-ataspectj-advice-ordering). The precedence @@ -17301,7 +16845,7 @@ the bean implement the `Ordered` interface. | |In contrast to the precedence rules for advice methods defined in the same `@Aspect`class, when two pieces of advice defined in the same `` element both need to
run at the same join point, the precedence is determined by the order in which the advice
elements are declared within the enclosing `` element, from highest to lowest
precedence.

For example, given an `around` advice and a `before` advice defined in the same`` element that apply to the same join point, to ensure that the `around`advice has higher precedence than the `before` advice, the `` element must be
declared before the `` element.

As a general rule of thumb, if you find that you have multiple pieces of advice defined
in the same `` element that apply to the same join point, consider collapsing
such advice methods into one advice method per join point in each `` element
or refactor the pieces of advice into separate `` elements that you can order
at the aspect level.| |---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#aop-schema-introductions)5.5.4. Introductions #### +#### 5.5.4. Introductions Introductions (known as inter-type declarations in AspectJ) let an aspect declare that advised objects implement a given interface and provide an implementation of @@ -17366,12 +16910,12 @@ Kotlin val usageTracked = context.getBean("myService") as UsageTracked ``` -#### [](#aop-schema-instatiation-models)5.5.5. Aspect Instantiation Models #### +#### 5.5.5. Aspect Instantiation Models The only supported instantiation model for schema-defined aspects is the singleton model. Other instantiation models may be supported in future releases. -#### [](#aop-schema-advisors)5.5.6. Advisors #### +#### 5.5.6. Advisors The concept of “advisors” comes from the AOP support defined in Spring and does not have a direct equivalent in AspectJ. An advisor is like a small @@ -17406,7 +16950,7 @@ As well as the `pointcut-ref` attribute used in the preceding example, you can a To define the precedence of an advisor so that the advice can participate in ordering, use the `order` attribute to define the `Ordered` value of the advisor. -#### [](#aop-schema-example)5.5.7. An AOP Schema Example #### +#### 5.5.7. An AOP Schema Example This section shows how the concurrent locking failure retry example from[An AOP Example](#aop-ataspectj-example) looks when rewritten with the schema support. @@ -17568,7 +17112,7 @@ pointcut expression so that only `@Idempotent` operations match, as follows: @annotation(com.xyz.myapp.service.Idempotent)"/> ``` -### [](#aop-choosing)5.6. Choosing which AOP Declaration Style to Use ### +### 5.6. Choosing which AOP Declaration Style to Use Once you have decided that an aspect is the best approach for implementing a given requirement, how do you decide between using Spring AOP or AspectJ and between the @@ -17576,7 +17120,7 @@ Aspect language (code) style, the @AspectJ annotation style, or the Spring XML s decisions are influenced by a number of factors including application requirements, development tools, and team familiarity with AOP. -#### [](#aop-spring-or-aspectj)5.6.1. Spring AOP or Full AspectJ? #### +#### 5.6.1. Spring AOP or Full AspectJ? Use the simplest thing that can work. Spring AOP is simpler than using full AspectJ, as there is no requirement to introduce the AspectJ compiler / weaver into your development @@ -17597,7 +17141,7 @@ that do not play a major role in your application, you may want to consider usin the @AspectJ style, sticking with regular Java compilation in your IDE, and adding an aspect weaving phase to your build script. -#### [](#aop-ataspectj-or-xml)5.6.2. @AspectJ or XML for Spring AOP? #### +#### 5.6.2. @AspectJ or XML for Spring AOP? If you have chosen to use Spring AOP, you have a choice of @AspectJ or XML style. There are various tradeoffs to consider. @@ -17665,14 +17209,14 @@ to implement additional requirements, you can easily migrate to a classic Aspect On balance, the Spring team prefers the @AspectJ style for custom aspects beyond simple configuration of enterprise services. -### [](#aop-mixing-styles)5.7. Mixing Aspect Types ### +### 5.7. Mixing Aspect Types It is perfectly possible to mix @AspectJ style aspects by using the auto-proxying support, schema-defined `` aspects, `` declared advisors, and even proxies and interceptors in other styles in the same configuration. All of these are implemented by using the same underlying support mechanism and can co-exist without any difficulty. -### [](#aop-proxying)5.8. Proxying Mechanisms ### +### 5.8. Proxying Mechanisms Spring AOP uses either JDK dynamic proxies or CGLIB to create the proxy for a given target object. JDK dynamic proxies are built into the JDK, whereas CGLIB is a common @@ -17713,7 +17257,7 @@ as follows: | |Multiple `` sections are collapsed into a single unified auto-proxy creator
at runtime, which applies the *strongest* proxy settings that any of the`` sections (typically from different XML bean definition files) specified.
This also applies to the `` and ``elements.

To be clear, using `proxy-target-class="true"` on ``,``, or `` elements forces the use of CGLIB
proxies *for all three of them*.| |---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#aop-understanding-aop-proxies)5.8.1. Understanding AOP Proxies #### +#### 5.8.1. Understanding AOP Proxies Spring AOP is proxy-based. It is vitally important that you grasp the semantics of what that last statement actually means before you write your own aspects or use any of @@ -17908,7 +17452,7 @@ fun main() { Finally, it must be noted that AspectJ does not have this self-invocation issue because it is not a proxy-based AOP framework. -### [](#aop-aspectj-programmatic)5.9. Programmatic Creation of @AspectJ Proxies ### +### 5.9. Programmatic Creation of @AspectJ Proxies In addition to declaring aspects in your configuration by using either ``or ``, it is also possible to programmatically create proxies that advise target objects. For the full details of Spring’s AOP API, see the[next chapter](#aop-api). Here, we want to focus on the ability to automatically @@ -17954,7 +17498,7 @@ val proxy = factory.getProxy() See the [javadoc](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/aop/aspectj/annotation/AspectJProxyFactory.html) for more information. -### [](#aop-using-aspectj)5.10. Using AspectJ with Spring Applications ### +### 5.10. Using AspectJ with Spring Applications Everything we have covered so far in this chapter is pure Spring AOP. In this section, we look at how you can use the AspectJ compiler or weaver instead of or in @@ -17968,7 +17512,7 @@ content of this library and how you can use it. [Configuring AspectJ Aspects by dependency inject AspectJ aspects that are woven using the AspectJ compiler. Finally,[Load-time Weaving with AspectJ in the Spring Framework](#aop-aj-ltw) provides an introduction to load-time weaving for Spring applications that use AspectJ. -#### [](#aop-atconfigurable)5.10.1. Using AspectJ to Dependency Inject Domain Objects with Spring #### +#### 5.10.1. Using AspectJ to Dependency Inject Domain Objects with Spring The Spring container instantiates and configures beans defined in your application context. It is also possible to ask a bean factory to configure a pre-existing @@ -18122,7 +17666,7 @@ configuration aspect. The following example shows how to use the `depends-on` at | |Do not activate `@Configurable` processing through the bean configurer aspect unless you
really mean to rely on its semantics at runtime. In particular, make sure that you do
not use `@Configurable` on bean classes that are registered as regular Spring beans
with the container. Doing so results in double initialization, once through the
container and once through the aspect.| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#aop-configurable-testing)Unit Testing `@Configurable` Objects ##### +##### Unit Testing `@Configurable` Objects One of the goals of the `@Configurable` support is to enable independent unit testing of domain objects without the difficulties associated with hard-coded lookups. @@ -18133,7 +17677,7 @@ you can still unit test outside of the container as normal, but you see a warnin message each time that you construct a `@Configurable` object indicating that it has not been configured by Spring. -##### [](#aop-configurable-container)Working with Multiple Application Contexts ##### +##### Working with Multiple Application Contexts The `AnnotationBeanConfigurerAspect` that is used to implement the `@Configurable` support is an AspectJ singleton aspect. The scope of a singleton aspect is the same as the scope @@ -18159,7 +17703,7 @@ web application loads the types in `spring-aspects.jar` by using its own classlo classloader), all web applications share the same aspect instance (which is probably not what you want). -#### [](#aop-ajlib-other)5.10.2. Other Spring aspects for AspectJ #### +#### 5.10.2. Other Spring aspects for AspectJ In addition to the `@Configurable` aspect, `spring-aspects.jar` contains an AspectJ aspect that you can use to drive Spring’s transaction management for types and methods @@ -18204,7 +17748,7 @@ public aspect DomainObjectConfiguration extends AbstractBeanConfigurerAspect { } ``` -#### [](#aop-aj-configure)5.10.3. Configuring AspectJ Aspects by Using Spring IoC #### +#### 5.10.3. Configuring AspectJ Aspects by Using Spring IoC When you use AspectJ aspects with Spring applications, it is natural to both want and expect to be able to configure such aspects with Spring. The AspectJ runtime itself is @@ -18252,7 +17796,7 @@ configuration. The following example shows how to use `` elements: | |Do not be misled by the name of the `` element. Using it
results in the creation of Spring AOP proxies. The @AspectJ style of aspect
declaration is being used here, but the AspectJ runtime is not involved.| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#aop-aj-ltw)5.10.4. Load-time Weaving with AspectJ in the Spring Framework #### +#### 5.10.4. Load-time Weaving with AspectJ in the Spring Framework Load-time weaving (LTW) refers to the process of weaving AspectJ aspects into an application’s class files as they are being loaded into the Java virtual machine (JVM). @@ -18282,7 +17826,7 @@ Now that the sales pitch is over, let us first walk through a quick example of A LTW that uses Spring, followed by detailed specifics about elements introduced in the example. For a complete example, see the[Petclinic sample application](https://github.com/spring-projects/spring-petclinic). -##### [](#aop-aj-ltw-first-example)A First Example ##### +##### A First Example Assume that you are an application developer who has been tasked with diagnosing the cause of some performance problems in a system. Rather than break out a @@ -18534,21 +18078,21 @@ the “why” behind each bit of configuration and usage in detail. | |The `ProfilingAspect` used in this example may be basic, but it is quite useful. It is a
nice example of a development-time aspect that developers can use during development
and then easily exclude from builds of the application being deployed
into UAT or production.| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#aop-aj-ltw-the-aspects)Aspects ##### +##### Aspects The aspects that you use in LTW have to be AspectJ aspects. You can write them in either the AspectJ language itself, or you can write your aspects in the @AspectJ-style. Your aspects are then both valid AspectJ and Spring AOP aspects. Furthermore, the compiled aspect classes need to be available on the classpath. -##### [](#aop-aj-ltw-aop_dot_xml)'META-INF/aop.xml' ##### +##### 'META-INF/aop.xml' The AspectJ LTW infrastructure is configured by using one or more `META-INF/aop.xml`files that are on the Java classpath (either directly or, more typically, in jar files). The structure and contents of this file is detailed in the LTW part of the[AspectJ reference documentation](https://www.eclipse.org/aspectj/doc/released/devguide/ltw-configuration.html). Because the `aop.xml` file is 100% AspectJ, we do not describe it further here. -##### [](#aop-aj-ltw-libraries)Required libraries (JARS) ##### +##### Required libraries (JARS) At minimum, you need the following libraries to use the Spring Framework’s support for AspectJ LTW: @@ -18562,7 +18106,7 @@ instrumentation](#aop-aj-ltw-environments-generic), you also need: * `spring-instrument.jar` -##### [](#aop-aj-ltw-spring)Spring Configuration ##### +##### Spring Configuration The key component in Spring’s LTW support is the `LoadTimeWeaver` interface (in the`org.springframework.instrument.classloading` package), and the numerous implementations of it that ship with the Spring distribution. A `LoadTimeWeaver` is responsible for @@ -18702,13 +18246,13 @@ possible values: | `DISABLED` | `off` | LTW is off. No aspect is woven at load-time. | | `AUTODETECT` |`autodetect`|If the Spring LTW infrastructure can find at least one `META-INF/aop.xml` file,
then AspectJ weaving is on. Otherwise, it is off. This is the default value.| -##### [](#aop-aj-ltw-environments)Environment-specific Configuration ##### +##### Environment-specific Configuration This last section contains any additional settings and configuration that you need when you use Spring’s LTW support in environments such as application servers and web containers. -###### [](#aop-aj-ltw-environments-tomcat-jboss-etc)Tomcat, JBoss, WebSphere, WebLogic ###### +###### Tomcat, JBoss, WebSphere, WebLogic Tomcat, JBoss/WildFly, IBM WebSphere Application Server and Oracle WebLogic Server all provide a general app `ClassLoader` that is capable of local instrumentation. Spring’s @@ -18724,7 +18268,7 @@ to your artifact a file named `WEB-INF/jboss-scanning.xml` with the following co ``` -###### [](#aop-aj-ltw-environments-generic)Generic Java Applications ###### +###### Generic Java Applications When class instrumentation is required in environments that are not supported by specific `LoadTimeWeaver` implementations, a JVM agent is the general solution. @@ -18744,7 +18288,7 @@ from using this in application server environments (depending on your server and operation policies). That said, for one-app-per-JVM deployments such as standalone Spring Boot applications, you typically control the entire JVM setup in any case. -### [](#aop-resources)5.11. Further Resources ### +### 5.11. Further Resources More information on AspectJ can be found on the [AspectJ website](https://www.eclipse.org/aspectj). @@ -18755,19 +18299,18 @@ comprehensive introduction and reference for the AspectJ language. recommended. The focus of the book is on AspectJ, but a lot of general AOP themes are explored (in some depth). -[](#aop-api)6. Spring AOP APIs ----------- +## 6. Spring AOP APIs The previous chapter described the Spring’s support for AOP with @AspectJ and schema-based aspect definitions. In this chapter, we discuss the lower-level Spring AOP APIs. For common applications, we recommend the use of Spring AOP with AspectJ pointcuts as described in the previous chapter. -### [](#aop-api-pointcuts)6.1. Pointcut API in Spring ### +### 6.1. Pointcut API in Spring This section describes how Spring handles the crucial pointcut concept. -#### [](#aop-api-concepts)6.1.1. Concepts #### +#### 6.1.1. Concepts Spring’s pointcut model enables pointcut reuse independent of advice types. You can target different advice with the same pointcut. @@ -18825,7 +18368,7 @@ returns `false`. In this case, the three-argument `matches` method is never invo | |If possible, try to make pointcuts static, allowing the AOP framework to cache the
results of pointcut evaluation when an AOP proxy is created.| |---|---------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#aop-api-pointcut-ops)6.1.2. Operations on Pointcuts #### +#### 6.1.2. Operations on Pointcuts Spring supports operations (notably, union and intersection) on pointcuts. @@ -18835,19 +18378,19 @@ Union is usually more useful. You can compose pointcuts by using the static methods in the`org.springframework.aop.support.Pointcuts` class or by using the`ComposablePointcut` class in the same package. However, using AspectJ pointcut expressions is usually a simpler approach. -#### [](#aop-api-pointcuts-aspectj)6.1.3. AspectJ Expression Pointcuts #### +#### 6.1.3. AspectJ Expression Pointcuts Since 2.0, the most important type of pointcut used by Spring is`org.springframework.aop.aspectj.AspectJExpressionPointcut`. This is a pointcut that uses an AspectJ-supplied library to parse an AspectJ pointcut expression string. See the [previous chapter](#aop) for a discussion of supported AspectJ pointcut primitives. -#### [](#aop-api-pointcuts-impls)6.1.4. Convenience Pointcut Implementations #### +#### 6.1.4. Convenience Pointcut Implementations Spring provides several convenient pointcut implementations. You can use some of them directly; others are intended to be subclassed in application-specific pointcuts. -##### [](#aop-api-pointcuts-static)Static Pointcuts ##### +##### Static Pointcuts Static pointcuts are based on the method and the target class and cannot take into account the method’s arguments. Static pointcuts suffice — and are best — for most usages. @@ -18857,7 +18400,7 @@ After that, there is no need to evaluate the pointcut again with each method inv The rest of this section describes some of the static pointcut implementations that are included with Spring. -###### [](#aop-api-pointcuts-regex)Regular Expression Pointcuts ###### +###### Regular Expression Pointcuts One obvious way to specify static pointcuts is regular expressions. Several AOP frameworks besides Spring make this possible.`org.springframework.aop.support.JdkRegexpMethodPointcut` is a generic regular @@ -18904,12 +18447,12 @@ pointcut and advice, as the following example shows: You can use `RegexpMethodPointcutAdvisor` with any `Advice` type. -###### [](#aop-api-pointcuts-attribute-driven)Attribute-driven Pointcuts ###### +###### Attribute-driven Pointcuts An important type of static pointcut is a metadata-driven pointcut. This uses the values of metadata attributes (typically, source-level metadata). -##### [](#aop-api-pointcuts-dynamic)Dynamic pointcuts ##### +##### Dynamic pointcuts Dynamic pointcuts are costlier to evaluate than static pointcuts. They take into account method arguments as well as static information. This means that they must be @@ -18918,7 +18461,7 @@ vary. The main example is the `control flow` pointcut. -###### [](#aop-api-pointcuts-cflow)Control Flow Pointcuts ###### +###### Control Flow Pointcuts Spring control flow pointcuts are conceptually similar to AspectJ `cflow` pointcuts, although less powerful. (There is currently no way to specify that a pointcut runs @@ -18930,7 +18473,7 @@ are specified by using the `org.springframework.aop.support.ControlFlowPointcut` | |Control flow pointcuts are significantly more expensive to evaluate at runtime than even
other dynamic pointcuts. In Java 1.4, the cost is about five times that of other dynamic
pointcuts.| |---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#aop-api-pointcuts-superclasses)6.1.5. Pointcut Superclasses #### +#### 6.1.5. Pointcut Superclasses Spring provides useful pointcut superclasses to help you to implement your own pointcuts. @@ -18963,7 +18506,7 @@ class TestStaticPointcut : StaticMethodMatcherPointcut() { There are also superclasses for dynamic pointcuts. You can use custom pointcuts with any advice type. -#### [](#aop-api-pointcuts-custom)6.1.6. Custom Pointcuts #### +#### 6.1.6. Custom Pointcuts Because pointcuts in Spring AOP are Java classes rather than language features (as in AspectJ), you can declare custom pointcuts, whether static or dynamic. Custom @@ -18973,11 +18516,11 @@ expression language, if you can. | |Later versions of Spring may offer support for “semantic pointcuts” as offered by JAC — for example, “all methods that change instance variables in the target object.”| |---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------| -### [](#aop-api-advice)6.2. Advice API in Spring ### +### 6.2. Advice API in Spring Now we can examine how Spring AOP handles advice. -#### [](#aop-api-advice-lifecycle)6.2.1. Advice Lifecycles #### +#### 6.2.1. Advice Lifecycles Each advice is a Spring bean. An advice instance can be shared across all advised objects or be unique to each advised object. This corresponds to per-class or @@ -18992,12 +18535,12 @@ the advice adds state to the proxied object. You can use a mix of shared and per-instance advice in the same AOP proxy. -#### [](#aop-api-advice-types)6.2.2. Advice Types in Spring #### +#### 6.2.2. Advice Types in Spring Spring provides several advice types and is extensible to support arbitrary advice types. This section describes the basic concepts and standard advice types. -##### [](#aop-api-advice-around)Interception Around Advice ##### +##### Interception Around Advice The most fundamental advice type in Spring is interception around advice. @@ -19055,7 +18598,7 @@ However, you do not want to do this without good reason. | |`MethodInterceptor` implementations offer interoperability with other AOP Alliance-compliant AOP
implementations. The other advice types discussed in the remainder of this section
implement common AOP concepts but in a Spring-specific way. While there is an advantage
in using the most specific advice type, stick with `MethodInterceptor` around advice if
you are likely to want to run the aspect in another AOP framework. Note that pointcuts
are not currently interoperable between frameworks, and the AOP Alliance does not
currently define pointcut interfaces.| |---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#aop-api-advice-before)Before Advice ##### +##### Before Advice A simpler advice type is a before advice. This does not need a `MethodInvocation`object, since it is called only before entering the method. @@ -19117,7 +18660,7 @@ class CountingBeforeAdvice : MethodBeforeAdvice { | |Before advice can be used with any pointcut.| |---|--------------------------------------------| -##### [](#aop-api-advice-throws)Throws Advice ##### +##### Throws Advice Throws advice is invoked after the return of the join point if the join point threw an exception. Spring offers typed throws advice. Note that this means that the`org.springframework.aop.ThrowsAdvice` interface does not contain any methods. It is a @@ -19222,7 +18765,7 @@ class CombinedThrowsAdvice : ThrowsAdvice { | |Throws advice can be used with any pointcut.| |---|--------------------------------------------| -##### [](#aop-api-advice-after-returning)After Returning Advice ##### +##### After Returning Advice An after returning advice in Spring must implement the`org.springframework.aop.AfterReturningAdvice` interface, which the following listing shows: @@ -19278,7 +18821,7 @@ thrown up the interceptor chain instead of the return value. | |After returning advice can be used with any pointcut.| |---|-----------------------------------------------------| -##### [](#aop-api-advice-introduction)Introduction Advice ##### +##### Introduction Advice Spring treats introduction advice as a special kind of interception advice. @@ -19469,7 +19012,7 @@ We can apply this advisor programmatically by using the `Advised.addAdvisor()` m choices discussed below, including “auto proxy creators,” correctly handle introductions and stateful mixins. -### [](#aop-api-advisor)6.3. The Advisor API in Spring ### +### 6.3. The Advisor API in Spring In Spring, an Advisor is an aspect that contains only a single advice object associated with a pointcut expression. @@ -19482,7 +19025,7 @@ example, you could use an interception around advice, throws advice, and before one proxy configuration. Spring automatically creates the necessary interceptor chain. -### [](#aop-pfb)6.4. Using the `ProxyFactoryBean` to Create AOP Proxies ### +### 6.4. Using the `ProxyFactoryBean` to Create AOP Proxies If you use the Spring IoC container (an `ApplicationContext` or `BeanFactory`) for your business objects (and you should be!), you want to use one of Spring’s AOP`FactoryBean` implementations. (Remember that a factory bean introduces a layer of indirection, letting @@ -19495,7 +19038,7 @@ The basic way to create an AOP proxy in Spring is to use the`org.springframework the pointcuts, any advice that applies, and their ordering. However, there are simpler options that are preferable if you do not need such control. -#### [](#aop-pfb-1)6.4.1. Basics #### +#### 6.4.1. Basics The `ProxyFactoryBean`, like other Spring `FactoryBean` implementations, introduces a level of indirection. If you define a `ProxyFactoryBean` named `foo`, objects that @@ -19510,7 +19053,7 @@ achieve with other AOP frameworks. For example, an advice may itself reference application objects (besides the target, which should be available in any AOP framework), benefiting from all the pluggability provided by Dependency Injection. -#### [](#aop-pfb-2)6.4.2. JavaBean Properties #### +#### 6.4.2. JavaBean Properties In common with most `FactoryBean` implementations provided with Spring, the`ProxyFactoryBean` class is itself a JavaBean. Its properties are used to: @@ -19559,7 +19102,7 @@ Other properties specific to `ProxyFactoryBean` include the following: such a method. The default value is `true`. If you want to use stateful advice - for example, for stateful mixins - use prototype advices along with a singleton value of`false`. -#### [](#aop-pfb-proxy-types)6.4.3. JDK- and CGLIB-based proxies #### +#### 6.4.3. JDK- and CGLIB-based proxies This section serves as the definitive documentation on how the `ProxyFactoryBean`chooses to create either a JDK-based proxy or a CGLIB-based proxy for a particular target object (which is to be proxied). @@ -19599,7 +19142,7 @@ implements. In effect, this is the same as supplying a list of each and every interface that the target class implements to the `proxyInterfaces` property. However, it is significantly less work and less prone to typographical errors. -#### [](#aop-api-proxying-intf)6.4.4. Proxying Interfaces #### +#### 6.4.4. Proxying Interfaces Consider a simple example of `ProxyFactoryBean` in action. This example involves: @@ -19713,7 +19256,7 @@ arguably, an advantage in that the `ProxyFactoryBean` definition is self-contain However, there are times when being able to obtain the un-advised target from the factory might actually be an advantage (for example, in certain test scenarios). -#### [](#aop-api-proxying-class)6.4.5. Proxying Classes #### +#### 6.4.5. Proxying Classes What if you need to proxy a class, rather than one or more interfaces? @@ -19744,7 +19287,7 @@ to consider: There is little performance difference between CGLIB proxying and dynamic proxies. Performance should not be a decisive consideration in this case. -#### [](#aop-global-advisors)6.4.6. Using “Global” Advisors #### +#### 6.4.6. Using “Global” Advisors By appending an asterisk to an interceptor name, all advisors with bean names that match the part before the asterisk are added to the advisor chain. This can come in handy @@ -19765,7 +19308,7 @@ two global advisors: ``` -### [](#aop-concise-proxy)6.5. Concise Proxy Definitions ### +### 6.5. Concise Proxy Definitions Especially when defining transactional proxies, you may end up with many similar proxy definitions. The use of parent and child bean definitions, along with inner bean @@ -19827,7 +19370,7 @@ that, if you have a (parent) bean definition that you intend to use only as a te and this definition specifies a class, you must make sure to set the `abstract`attribute to `true`. Otherwise, the application context actually tries to pre-instantiate it. -### [](#aop-prog)6.6. Creating AOP Proxies Programmatically with the `ProxyFactory` ### +### 6.6. Creating AOP Proxies Programmatically with the `ProxyFactory` It is easy to create AOP proxies programmatically with Spring. This lets you use Spring AOP without dependency on Spring IoC. @@ -19868,7 +19411,7 @@ that let you add other advice types, such as before and throws advice.`AdvisedSu | |Integrating AOP proxy creation with the IoC framework is best practice in most
applications. We recommend that you externalize configuration from Java code with AOP,
as you should in general.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -### [](#aop-api-advised)6.7. Manipulating Advised Objects ### +### 6.7. Manipulating Advised Objects However you create AOP proxies, you can manipulate them BY using the`org.springframework.aop.framework.Advised` interface. Any AOP proxy can be cast to this interface, no matter which other interfaces it implements. This interface includes the @@ -19995,7 +19538,7 @@ advice through addition or removal results in an `AopConfigException`. The abili to freeze the state of an advised object is useful in some cases (for example, to prevent calling code removing a security interceptor). -### [](#aop-autoproxy)6.8. Using the "auto-proxy" facility ### +### 6.8. Using the "auto-proxy" facility So far, we have considered explicit creation of AOP proxies by using a `ProxyFactoryBean` or similar factory bean. @@ -20015,11 +19558,11 @@ There are two ways to do this: * A special case of auto-proxy creation that deserves to be considered separately: auto-proxy creation driven by source-level metadata attributes. -#### [](#aop-autoproxy-choices)6.8.1. Auto-proxy Bean Definitions #### +#### 6.8.1. Auto-proxy Bean Definitions This section covers the auto-proxy creators provided by the`org.springframework.aop.framework.autoproxy` package. -##### [](#aop-api-autoproxy)`BeanNameAutoProxyCreator` ##### +##### `BeanNameAutoProxyCreator` The `BeanNameAutoProxyCreator` class is a `BeanPostProcessor` that automatically creates AOP proxies for beans with names that match literal values or wildcards. The following @@ -20051,7 +19594,7 @@ automatically created by the `BeanNameAutoProxyCreator`. The same advice is appl to all matching beans. Note that, if advisors are used (rather than the interceptor in the preceding example), the pointcuts may apply differently to different beans. -##### [](#aop-api-autoproxy-default)`DefaultAdvisorAutoProxyCreator` ##### +##### `DefaultAdvisorAutoProxyCreator` A more general and extremely powerful auto-proxy creator is`DefaultAdvisorAutoProxyCreator`. This automagically applies eligible advisors in the current context, without the need to include specific bean names in the auto-proxy @@ -20112,7 +19655,7 @@ Advisors can implement the `org.springframework.core.Ordered` interface to ensur correct ordering if this is an issue. The `TransactionAttributeSourceAdvisor` used in the preceding example has a configurable order value. The default setting is unordered. -### [](#aop-targetsource)6.9. Using `TargetSource` Implementations ### +### 6.9. Using `TargetSource` Implementations Spring offers the concept of a `TargetSource`, expressed in the`org.springframework.aop.TargetSource` interface. This interface is responsible for returning the “target object” that implements the join point. The `TargetSource`implementation is asked for a target instance each time the AOP proxy handles a method @@ -20131,7 +19674,7 @@ The rest of this section describes the standard target sources provided with Spr | |When using a custom target source, your target will usually need to be a prototype
rather than a singleton bean definition. This allows Spring to create a new target
instance when required.| |---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#aop-ts-swap)6.9.1. Hot-swappable Target Sources #### +#### 6.9.1. Hot-swappable Target Sources The `org.springframework.aop.target.HotSwappableTargetSource` exists to let the target of an AOP proxy be switched while letting callers keep their references to it. @@ -20176,7 +19719,7 @@ Although this example does not add any advice (it is not necessary to add advice use a `TargetSource`), any `TargetSource` can be used in conjunction with arbitrary advice. -#### [](#aop-ts-pool)6.9.2. Pooling Target Sources #### +#### 6.9.2. Pooling Target Sources Using a pooling target source provides a similar programming model to stateless session EJBs, in which a pool of identical instances is maintained, with method invocations @@ -20259,7 +19802,7 @@ println("Max pool size is " + conf.maxSize) Simpler pooling is available by using auto-proxying. You can set the `TargetSource` implementations used by any auto-proxy creator. -#### [](#aop-ts-prototype)6.9.3. Prototype Target Sources #### +#### 6.9.3. Prototype Target Sources Setting up a “prototype” target source is similar to setting up a pooling `TargetSource`. In this case, a new instance of the target is created on every method invocation. Although @@ -20279,7 +19822,7 @@ To do this, you could modify the `poolTargetSource` definition shown earlier as The only property is the name of the target bean. Inheritance is used in the`TargetSource` implementations to ensure consistent naming. As with the pooling target source, the target bean must be a prototype bean definition. -#### [](#aop-ts-threadlocal)6.9.4. `ThreadLocal` Target Sources #### +#### 6.9.4. `ThreadLocal` Target Sources `ThreadLocal` target sources are useful if you need an object to be created for each incoming request (per thread that is). The concept of a `ThreadLocal` provides a JDK-wide @@ -20295,7 +19838,7 @@ of target source, as the following example shows: | |`ThreadLocal` instances come with serious issues (potentially resulting in memory leaks) when
incorrectly using them in multi-threaded and multi-classloader environments. You
should always consider wrapping a threadlocal in some other class and never directly use
the `ThreadLocal` itself (except in the wrapper class). Also, you should
always remember to correctly set and unset (where the latter simply involves a call to`ThreadLocal.set(null)`) the resource local to the thread. Unsetting should be done in
any case, since not unsetting it might result in problematic behavior. Spring’s`ThreadLocal` support does this for you and should always be considered in favor of using`ThreadLocal` instances without other proper handling code.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -### [](#aop-extensibility)6.10. Defining New Advice Types ### +### 6.10. Defining New Advice Types Spring AOP is designed to be extensible. While the interception implementation strategy is presently used internally, it is possible to support arbitrary advice types in @@ -20308,8 +19851,7 @@ The only constraint on a custom `Advice` type is that it must implement the`org. See the [`org.springframework.aop.framework.adapter`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/aop/framework/adapter/package-frame.html)javadoc for further information. -[](#null-safety)7. Null-safety ----------- +## 7. Null-safety Although Java does not let you express null-safety with its type system, the Spring Framework now provides the following annotations in the `org.springframework.lang` package to let you @@ -20338,7 +19880,7 @@ bodies is outside of the scope of this feature. | |Other common libraries such as Reactor and Spring Data provide null-safe APIs that
use a similar nullability arrangement, delivering a consistent overall experience for
Spring application developers.| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -### [](#use-cases)7.1. Use cases ### +### 7.1. Use cases In addition to providing an explicit declaration for Spring Framework API nullability, these annotations can be used by an IDE (such as IDEA or Eclipse) to provide useful @@ -20348,7 +19890,7 @@ They are also used to make Spring API null-safe in Kotlin projects, since Kotlin supports [null-safety](https://kotlinlang.org/docs/reference/null-safety.html). More details are available in the [Kotlin support documentation](languages.html#kotlin-null-safety). -### [](#jsr-305-meta-annotations)7.2. JSR-305 meta-annotations ### +### 7.2. JSR-305 meta-annotations Spring annotations are meta-annotated with [JSR 305](https://jcp.org/en/jsr/detail?id=305)annotations (a dormant but wide-spread JSR). JSR-305 meta-annotations let tooling vendors like IDEA or Kotlin provide null-safety support in a generic way, without having to @@ -20358,8 +19900,7 @@ It is not necessary nor recommended to add a JSR-305 dependency to the project c take advantage of Spring null-safe API. Only projects such as Spring-based libraries that use null-safety annotations in their codebase should add `com.google.code.findbugs:jsr305:3.0.2`with `compileOnly` Gradle configuration or Maven `provided` scope to avoid compile warnings. -[](#databuffers)8. Data Buffers and Codecs ----------- +## 8. Data Buffers and Codecs Java NIO provides `ByteBuffer` but many libraries build their own byte buffer API on top, especially for network operations where reusing buffers and/or using direct buffers is @@ -20376,7 +19917,7 @@ APIs as follows: * [Codecs](#codecs) decode or encode data buffer streams into higher level objects. -### [](#databuffers-factory)8.1. `DataBufferFactory` ### +### 8.1. `DataBufferFactory` `DataBufferFactory` is used to create data buffers in one of two ways: @@ -20390,7 +19931,7 @@ Note that WebFlux applications do not create a `DataBufferFactory` directly but access it through the `ServerHttpResponse` or the `ClientHttpRequest` on the client side. The type of factory depends on the underlying client or server, e.g.`NettyDataBufferFactory` for Reactor Netty, `DefaultDataBufferFactory` for others. -### [](#databuffers-buffer)8.2. `DataBuffer` ### +### 8.2. `DataBuffer` The `DataBuffer` interface offers similar operations as `java.nio.ByteBuffer` but also brings a few additional benefits some of which are inspired by the Netty `ByteBuf`. @@ -20407,7 +19948,7 @@ Below is a partial list of benefits: * Determine the index, or the last index, for a given byte. -### [](#databuffers-buffer-pooled)8.3. `PooledDataBuffer` ### +### 8.3. `PooledDataBuffer` As explained in the Javadoc for[ByteBuffer](https://docs.oracle.com/javase/8/docs/api/java/nio/ByteBuffer.html), byte buffers can be direct or non-direct. Direct buffers may reside outside the Java heap @@ -20426,7 +19967,7 @@ the memory pool. Note that instead of operating on `PooledDataBuffer` directly, in most cases it’s better to use the convenience methods in `DataBufferUtils` that apply release or retain to a`DataBuffer` only if it is an instance of `PooledDataBuffer`. -### [](#databuffers-utils)8.4. `DataBufferUtils` ### +### 8.4. `DataBufferUtils` `DataBufferUtils` offers a number of utility methods to operate on data buffers: @@ -20439,7 +19980,7 @@ to use the convenience methods in `DataBufferUtils` that apply release or retain * Skip or take from a stream of bytes until a specific byte count. -### [](#codecs)8.5. Codecs ### +### 8.5. Codecs The `org.springframework.core.codec` package provides the following strategy interfaces: @@ -20450,7 +19991,7 @@ The `org.springframework.core.codec` package provides the following strategy int The `spring-core` module provides `byte[]`, `ByteBuffer`, `DataBuffer`, `Resource`, and`String` encoder and decoder implementations. The `spring-web` module adds Jackson JSON, Jackson Smile, JAXB2, Protocol Buffers and other encoders and decoders. See[Codecs](web-reactive.html#webflux-codecs) in the WebFlux section. -### [](#databuffers-using)8.6. Using `DataBuffer` ### +### 8.6. Using `DataBuffer` When working with data buffers, special care must be taken to ensure buffers are released since they may be [pooled](#databuffers-buffer-pooled). We’ll use codecs to illustrate @@ -20518,8 +20059,7 @@ responsibility of the code writing to the server response, or to the client requ Note that when running on Netty, there are debugging options for[troubleshooting buffer leaks](https://github.com/netty/netty/wiki/Reference-counted-objects#troubleshooting-buffer-leaks). -[](#spring-jcl)9. Logging ----------- +## 9. Logging Since Spring Framework 5.0, Spring comes with its own Commons Logging bridge implemented in the `spring-jcl` module. The implementation checks for the presence of the Log4j 2.x @@ -20555,14 +20095,13 @@ class MyBean { } ``` -[](#appendix)10. Appendix ----------- +## 10. Appendix -### [](#xsd-schemas)10.1. XML Schemas ### +### 10.1. XML Schemas This part of the appendix lists XML schemas related to the core container. -#### [](#xsd-schemas-util)10.1.1. The `util` Schema #### +#### 10.1.1. The `util` Schema As the name implies, the `util` tags deal with common, utility configuration issues, such as configuring collections, referencing constants, and so forth. @@ -20584,7 +20123,7 @@ correct schema so that the tags in the `util` namespace are available to you): ``` -##### [](#xsd-schemas-util-constant)Using `` ##### +##### Using `` Consider the following bean definition: @@ -20613,7 +20152,7 @@ developer’s intent (“inject this constant value”), and it reads better:
``` -###### [](#xsd-schemas-util-frfb)Setting a Bean Property or Constructor Argument from a Field Value ###### +###### Setting a Bean Property or Constructor Argument from a Field Value [`FieldRetrievingFactoryBean`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/beans/factory/config/FieldRetrievingFactoryBean.html)is a `FactoryBean` that retrieves a `static` or non-static field value. It is typically used for retrieving `public` `static` `final` constants, which may then be used to set a @@ -20716,7 +20255,7 @@ class Client {
``` -##### [](#xsd-schemas-util-property-path)Using `` ##### +##### Using `` Consider the following example: @@ -20757,7 +20296,7 @@ Now consider the following example, which adds a `` element The value of the `path` attribute of the `` element follows the form of`beanName.beanProperty`. In this case, it picks up the `age` property of the bean named`testBean`. The value of that `age` property is `10`. -###### [](#xsd-schemas-util-property-path-dependency)Using `` to Set a Bean Property or Constructor Argument ###### +###### Using `` to Set a Bean Property or Constructor Argument ###### `PropertyPathFactoryBean` is a `FactoryBean` that evaluates a property path on a given target object. The target object can be specified directly or by a bean name. You can then use this @@ -20826,7 +20365,7 @@ You can specifically set the result type in the actual definition. This is not n for most use cases, but it can sometimes be useful. See the javadoc for more info on this feature. -##### [](#xsd-schemas-util-properties)Using `` ##### +##### Using `` Consider the following example: @@ -20847,7 +20386,7 @@ The following example uses a `util:properties` element to make a more concise re ``` -##### [](#xsd-schemas-util-list)Using `` ##### +##### Using `` Consider the following example: @@ -20896,7 +20435,7 @@ following configuration: If no `list-class` attribute is supplied, the container chooses a `List` implementation. -##### [](#xsd-schemas-util-map)Using `` ##### +##### Using `` Consider the following example: @@ -20945,7 +20484,7 @@ following configuration: If no `'map-class'` attribute is supplied, the container chooses a `Map` implementation. -##### [](#xsd-schemas-util-set)Using `` ##### +##### Using `` Consider the following example: @@ -20994,7 +20533,7 @@ following configuration: If no `set-class` attribute is supplied, the container chooses a `Set` implementation. -#### [](#xsd-schemas-aop)10.1.2. The `aop` Schema #### +#### 10.1.2. The `aop` Schema The `aop` tags deal with configuring all things AOP in Spring, including Spring’s own proxy-based AOP framework and Spring’s integration with the AspectJ AOP framework. @@ -21019,7 +20558,7 @@ are available to you): ``` -#### [](#xsd-schemas-context)10.1.3. The `context` Schema #### +#### 10.1.3. The `context` Schema The `context` tags deal with `ApplicationContext` configuration that relates to plumbing — that is, not usually beans that are important to an end-user but rather beans that do a lot of the “grunt” work in Spring, such as `BeanfactoryPostProcessors`. The following @@ -21040,13 +20579,13 @@ available to you: ``` -##### [](#xsd-schemas-context-pphc)Using `` ##### +##### Using `` This element activates the replacement of `${…​}` placeholders, which are resolved against a specified properties file (as a [Spring resource location](#resources)). This element is a convenience mechanism that sets up a [`PropertySourcesPlaceholderConfigurer`](#beans-factory-placeholderconfigurer) for you. If you need more control over the specific`PropertySourcesPlaceholderConfigurer` setup, you can explicitly define it as a bean yourself. -##### [](#xsd-schemas-context-ac)Using `` ##### +##### Using `` This element activates the Spring infrastructure to detect annotations in bean classes: @@ -21067,23 +20606,23 @@ Alternatively, you can choose to explicitly activate the individual `BeanPostPro | |This element does not activate processing of Spring’s[`@Transactional`](data-access.html#transaction-declarative-annotations) annotation;
you can use the [``](data-access.html#tx-decl-explained)element for that purpose. Similarly, Spring’s[caching annotations](integration.html#cache-annotations) need to be explicitly[enabled](integration.html#cache-annotation-enable) as well.| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#xsd-schemas-context-component-scan)Using `` ##### +##### Using `` This element is detailed in the section on [annotation-based container configuration](#beans-annotation-config). -##### [](#xsd-schemas-context-ltw)Using `` ##### +##### Using `` This element is detailed in the section on [load-time weaving with AspectJ in the Spring Framework](#aop-aj-ltw). -##### [](#xsd-schemas-context-sc)Using `` ##### +##### Using `` This element is detailed in the section on [using AspectJ to dependency inject domain objects with Spring](#aop-atconfigurable). -##### [](#xsd-schemas-context-mbe)Using `` ##### +##### Using `` This element is detailed in the section on [configuring annotation-based MBean export](integration.html#jmx-context-mbeanexport). -#### [](#xsd-schemas-beans)10.1.4. The Beans Schema #### +#### 10.1.4. The Beans Schema Last but not least, we have the elements in the `beans` schema. These elements have been in Spring since the very dawn of the framework. Examples of the various elements @@ -21119,7 +20658,7 @@ as it stands). In the case of the preceding example, you could assume that there is some logic that consumes the bean definition and sets up some caching infrastructure that uses the supplied metadata. -### [](#xml-custom)10.2. XML Schema Authoring ### +### 10.2. XML Schema Authoring Since version 2.0, Spring has featured a mechanism for adding schema-based extensions to the basic Spring XML format for defining and configuring beans. This section covers @@ -21156,7 +20695,7 @@ we will be able to define bean definitions of type `SimpleDateFormat` as follows examples follow later in this appendix. The intent of this first simple example is to walk you through the basic steps of making a custom extension.) -#### [](#xsd-custom-schema)10.2.1. Authoring the Schema #### +#### 10.2.1. Authoring the Schema Creating an XML configuration extension for use with Spring’s IoC container starts with authoring an XML Schema to describe the extension. For our example, we use the following schema @@ -21217,7 +20756,7 @@ creates a bean in the container (identified by the name `dateFormat` of type`Sim | |The schema-based approach to creating configuration format allows for tight integration
with an IDE that has a schema-aware XML editor. By using a properly authored schema, you
can use autocompletion to let a user choose between several configuration options
defined in the enumeration.| |---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#xsd-custom-namespacehandler)10.2.2. Coding a `NamespaceHandler` #### +#### 10.2.2. Coding a `NamespaceHandler` In addition to the schema, we need a `NamespaceHandler` to parse all elements of this specific namespace that Spring encounters while parsing configuration files. For this example, the`NamespaceHandler` should take care of the parsing of the `myns:dateformat`element. @@ -21283,7 +20822,7 @@ delegating to `BeanDefinitionParsers` to do the grunt work of the XML parsing. T means that each `BeanDefinitionParser` contains only the logic for parsing a single custom element, as we can see in the next step. -#### [](#xsd-custom-parser)10.2.3. Using `BeanDefinitionParser` #### +#### 10.2.3. Using `BeanDefinitionParser` A `BeanDefinitionParser` is used if the `NamespaceHandler` encounters an XML element of the type that has been mapped to the specific bean definition parser @@ -21368,7 +20907,7 @@ class SimpleDateFormatBeanDefinitionParser : AbstractSingleBeanDefinitionParser( In this simple case, this is all that we need to do. The creation of our single`BeanDefinition` is handled by the `AbstractSingleBeanDefinitionParser` superclass, as is the extraction and setting of the bean definition’s unique identifier. -#### [](#xsd-custom-registration)10.2.4. Registering the Handler and the Schema #### +#### 10.2.4. Registering the Handler and the Schema The coding is finished. All that remains to be done is to make the Spring XML parsing infrastructure aware of our custom element. We do so by registering our custom`namespaceHandler` and custom XSD file in two special-purpose properties files. These @@ -21377,7 +20916,7 @@ can, for example, be distributed alongside your binary classes in a JAR file. Th XML parsing infrastructure automatically picks up your new extension by consuming these special properties files, the formats of which are detailed in the next two sections. -##### [](#xsd-custom-registration-spring-handlers)Writing `META-INF/spring.handlers` ##### +##### Writing `META-INF/spring.handlers` The properties file called `spring.handlers` contains a mapping of XML Schema URIs to namespace handler classes. For our example, we need to write the following: @@ -21391,7 +20930,7 @@ http\://www.mycompany.example/schema/myns=org.springframework.samples.xml.MyName The first part (the key) of the key-value pair is the URI associated with your custom namespace extension and needs to exactly match exactly the value of the `targetNamespace`attribute, as specified in your custom XSD schema. -##### [](#xsd-custom-registration-spring-schemas)Writing 'META-INF/spring.schemas' ##### +##### Writing 'META-INF/spring.schemas' The properties file called `spring.schemas` contains a mapping of XML Schema locations (referred to, along with the schema declaration, in XML files that use the schema as part @@ -21410,7 +20949,7 @@ http\://www.mycompany.example/schema/myns/myns.xsd=org/springframework/samples/x You are encouraged to deploy your XSD file (or files) right alongside the `NamespaceHandler` and `BeanDefinitionParser` classes on the classpath. -#### [](#xsd-custom-using)10.2.5. Using a Custom Extension in Your Spring XML Configuration #### +#### 10.2.5. Using a Custom Extension in Your Spring XML Configuration Using a custom extension that you yourself have implemented is no different from using one of the “custom” extensions that Spring provides. The following @@ -21442,11 +20981,11 @@ in a Spring XML configuration file: |**1**|Our custom bean.| |-----|----------------| -#### [](#xsd-custom-meat)10.2.6. More Detailed Examples #### +#### 10.2.6. More Detailed Examples This section presents some more detailed examples of custom XML extensions. -##### [](#xsd-custom-custom-nested)Nesting Custom Elements within Custom Elements ##### +##### Nesting Custom Elements within Custom Elements The example presented in this section shows how you to write the various artifacts required to satisfy a target of the following configuration: @@ -21794,7 +21333,7 @@ http\://www.foo.example/schema/component=com.foo.ComponentNamespaceHandler http\://www.foo.example/schema/component/component.xsd=com/foo/component.xsd ``` -##### [](#xsd-custom-custom-just-attributes)Custom Attributes on “Normal” Elements ##### +##### Custom Attributes on “Normal” Elements Writing your own custom parser and the associated artifacts is not hard. However, it is sometimes not the right thing to do. Consider a scenario where you need to @@ -22025,7 +21564,7 @@ http\://www.foo.example/schema/jcache=com.foo.JCacheNamespaceHandler http\://www.foo.example/schema/jcache/jcache.xsd=com/foo/jcache.xsd ``` -### [](#application-startup-steps)10.3. Application Startup Steps ### +### 10.3. Application Startup Steps This part of the appendix lists the existing `StartupSteps` that the core container is instrumented with. diff --git a/docs/en/spring-framework/data-access.md b/docs/en/spring-framework/data-access.md index 9942d6e..9b3b5f9 100644 --- a/docs/en/spring-framework/data-access.md +++ b/docs/en/spring-framework/data-access.md @@ -1,218 +1,4 @@ -Data Access -========== - -version 5.3.16 - -Table of Contents - -* [1. Transaction Management](#transaction) - * [1.1. Advantages of the Spring Framework’s Transaction Support Model](#transaction-motivation) - * [1.1.1. Global Transactions](#transaction-global) - * [1.1.2. Local Transactions](#transaction-local) - * [1.1.3. Spring Framework’s Consistent Programming Model](#transaction-programming-model) - - * [1.2. Understanding the Spring Framework Transaction Abstraction](#transaction-strategies) - * [1.2.1. Hibernate Transaction Setup](#transaction-strategies-hibernate) - - * [1.3. Synchronizing Resources with Transactions](#tx-resource-synchronization) - * [1.3.1. High-level Synchronization Approach](#tx-resource-synchronization-high) - * [1.3.2. Low-level Synchronization Approach](#tx-resource-synchronization-low) - * [1.3.3. `TransactionAwareDataSourceProxy`](#tx-resource-synchronization-tadsp) - - * [1.4. Declarative Transaction Management](#transaction-declarative) - * [1.4.1. Understanding the Spring Framework’s Declarative Transaction Implementation](#tx-decl-explained) - * [1.4.2. Example of Declarative Transaction Implementation](#transaction-declarative-first-example) - * [1.4.3. Rolling Back a Declarative Transaction](#transaction-declarative-rolling-back) - * [1.4.4. Configuring Different Transactional Semantics for Different Beans](#transaction-declarative-diff-tx) - * [1.4.5. \ Settings](#transaction-declarative-txadvice-settings) - * [1.4.6. Using `@Transactional`](#transaction-declarative-annotations) - * [`@Transactional` Settings](#transaction-declarative-attransactional-settings) - * [Multiple Transaction Managers with `@Transactional`](#tx-multiple-tx-mgrs-with-attransactional) - * [Custom Composed Annotations](#tx-custom-attributes) - - * [1.4.7. Transaction Propagation](#tx-propagation) - * [Understanding `PROPAGATION_REQUIRED`](#tx-propagation-required) - * [Understanding `PROPAGATION_REQUIRES_NEW`](#tx-propagation-requires_new) - * [Understanding `PROPAGATION_NESTED`](#tx-propagation-nested) - - * [1.4.8. Advising Transactional Operations](#transaction-declarative-applying-more-than-just-tx-advice) - * [1.4.9. Using `@Transactional` with AspectJ](#transaction-declarative-aspectj) - - * [1.5. Programmatic Transaction Management](#transaction-programmatic) - * [1.5.1. Using the `TransactionTemplate`](#tx-prog-template) - * [Specifying Transaction Settings](#tx-prog-template-settings) - - * [1.5.2. Using the `TransactionOperator`](#tx-prog-operator) - * [Cancel Signals](#tx-prog-operator-cancel) - * [Specifying Transaction Settings](#tx-prog-operator-settings) - - * [1.5.3. Using the `TransactionManager`](#transaction-programmatic-tm) - * [Using the `PlatformTransactionManager`](#transaction-programmatic-ptm) - * [Using the `ReactiveTransactionManager`](#transaction-programmatic-rtm) - - * [1.6. Choosing Between Programmatic and Declarative Transaction Management](#tx-decl-vs-prog) - * [1.7. Transaction-bound Events](#transaction-event) - * [1.8. Application server-specific integration](#transaction-application-server-integration) - * [1.8.1. IBM WebSphere](#transaction-application-server-integration-websphere) - * [1.8.2. Oracle WebLogic Server](#transaction-application-server-integration-weblogic) - - * [1.9. Solutions to Common Problems](#transaction-solutions-to-common-problems) - * [1.9.1. Using the Wrong Transaction Manager for a Specific `DataSource`](#transaction-solutions-to-common-problems-wrong-ptm) - - * [1.10. Further Resources](#transaction-resources) - -* [2. DAO Support](#dao) - * [2.1. Consistent Exception Hierarchy](#dao-exceptions) - * [2.2. Annotations Used to Configure DAO or Repository Classes](#dao-annotations) - -* [3. Data Access with JDBC](#jdbc) - * [3.1. Choosing an Approach for JDBC Database Access](#jdbc-choose-style) - * [3.2. Package Hierarchy](#jdbc-packages) - * [3.3. Using the JDBC Core Classes to Control Basic JDBC Processing and Error Handling](#jdbc-core) - * [3.3.1. Using `JdbcTemplate`](#jdbc-JdbcTemplate) - * [Querying (`SELECT`)](#jdbc-JdbcTemplate-examples-query) - * [Updating (`INSERT`, `UPDATE`, and `DELETE`) with `JdbcTemplate`](#jdbc-JdbcTemplate-examples-update) - * [Other `JdbcTemplate` Operations](#jdbc-JdbcTemplate-examples-other) - * [`JdbcTemplate` Best Practices](#jdbc-JdbcTemplate-idioms) - - * [3.3.2. Using `NamedParameterJdbcTemplate`](#jdbc-NamedParameterJdbcTemplate) - * [3.3.3. Using `SQLExceptionTranslator`](#jdbc-SQLExceptionTranslator) - * [3.3.4. Running Statements](#jdbc-statements-executing) - * [3.3.5. Running Queries](#jdbc-statements-querying) - * [3.3.6. Updating the Database](#jdbc-updates) - * [3.3.7. Retrieving Auto-generated Keys](#jdbc-auto-generated-keys) - - * [3.4. Controlling Database Connections](#jdbc-connections) - * [3.4.1. Using `DataSource`](#jdbc-datasource) - * [3.4.2. Using `DataSourceUtils`](#jdbc-DataSourceUtils) - * [3.4.3. Implementing `SmartDataSource`](#jdbc-SmartDataSource) - * [3.4.4. Extending `AbstractDataSource`](#jdbc-AbstractDataSource) - * [3.4.5. Using `SingleConnectionDataSource`](#jdbc-SingleConnectionDataSource) - * [3.4.6. Using `DriverManagerDataSource`](#jdbc-DriverManagerDataSource) - * [3.4.7. Using `TransactionAwareDataSourceProxy`](#jdbc-TransactionAwareDataSourceProxy) - * [3.4.8. Using `DataSourceTransactionManager`](#jdbc-DataSourceTransactionManager) - - * [3.5. JDBC Batch Operations](#jdbc-advanced-jdbc) - * [3.5.1. Basic Batch Operations with `JdbcTemplate`](#jdbc-batch-classic) - * [3.5.2. Batch Operations with a List of Objects](#jdbc-batch-list) - * [3.5.3. Batch Operations with Multiple Batches](#jdbc-batch-multi) - - * [3.6. Simplifying JDBC Operations with the `SimpleJdbc` Classes](#jdbc-simple-jdbc) - * [3.6.1. Inserting Data by Using `SimpleJdbcInsert`](#jdbc-simple-jdbc-insert-1) - * [3.6.2. Retrieving Auto-generated Keys by Using `SimpleJdbcInsert`](#jdbc-simple-jdbc-insert-2) - * [3.6.3. Specifying Columns for a `SimpleJdbcInsert`](#jdbc-simple-jdbc-insert-3) - * [3.6.4. Using `SqlParameterSource` to Provide Parameter Values](#jdbc-simple-jdbc-parameters) - * [3.6.5. Calling a Stored Procedure with `SimpleJdbcCall`](#jdbc-simple-jdbc-call-1) - * [3.6.6. Explicitly Declaring Parameters to Use for a `SimpleJdbcCall`](#jdbc-simple-jdbc-call-2) - * [3.6.7. How to Define `SqlParameters`](#jdbc-params) - * [3.6.8. Calling a Stored Function by Using `SimpleJdbcCall`](#jdbc-simple-jdbc-call-3) - * [3.6.9. Returning a `ResultSet` or REF Cursor from a `SimpleJdbcCall`](#jdbc-simple-jdbc-call-4) - - * [3.7. Modeling JDBC Operations as Java Objects](#jdbc-object) - * [3.7.1. Understanding `SqlQuery`](#jdbc-SqlQuery) - * [3.7.2. Using `MappingSqlQuery`](#jdbc-MappingSqlQuery) - * [3.7.3. Using `SqlUpdate`](#jdbc-SqlUpdate) - * [3.7.4. Using `StoredProcedure`](#jdbc-StoredProcedure) - - * [3.8. Common Problems with Parameter and Data Value Handling](#jdbc-parameter-handling) - * [3.8.1. Providing SQL Type Information for Parameters](#jdbc-type-information) - * [3.8.2. Handling BLOB and CLOB objects](#jdbc-lob) - * [3.8.3. Passing in Lists of Values for IN Clause](#jdbc-in-clause) - * [3.8.4. Handling Complex Types for Stored Procedure Calls](#jdbc-complex-types) - - * [3.9. Embedded Database Support](#jdbc-embedded-database-support) - * [3.9.1. Why Use an Embedded Database?](#jdbc-why-embedded-database) - * [3.9.2. Creating an Embedded Database by Using Spring XML](#jdbc-embedded-database-xml) - * [3.9.3. Creating an Embedded Database Programmatically](#jdbc-embedded-database-java) - * [3.9.4. Selecting the Embedded Database Type](#jdbc-embedded-database-types) - * [Using HSQL](#jdbc-embedded-database-using-HSQL) - * [Using H2](#jdbc-embedded-database-using-H2) - * [Using Derby](#jdbc-embedded-database-using-Derby) - - * [3.9.5. Testing Data Access Logic with an Embedded Database](#jdbc-embedded-database-dao-testing) - * [3.9.6. Generating Unique Names for Embedded Databases](#jdbc-embedded-database-unique-names) - * [3.9.7. Extending the Embedded Database Support](#jdbc-embedded-database-extension) - - * [3.10. Initializing a `DataSource`](#jdbc-initializing-datasource) - * [3.10.1. Initializing a Database by Using Spring XML](#jdbc-initializing-datasource-xml) - * [Initialization of Other Components that Depend on the Database](#jdbc-client-component-initialization) - -* [4. Data Access with R2DBC](#r2dbc) - * [4.1. Package Hierarchy](#r2dbc-packages) - * [4.2. Using the R2DBC Core Classes to Control Basic R2DBC Processing and Error Handling](#r2dbc-core) - * [4.2.1. Using `DatabaseClient`](#r2dbc-DatabaseClient) - * [Executing Statements](#r2dbc-DatabaseClient-examples-statement) - * [Querying (`SELECT`)](#r2dbc-DatabaseClient-examples-query) - * [Updating (`INSERT`, `UPDATE`, and `DELETE`) with `DatabaseClient`](#r2dbc-DatabaseClient-examples-update) - * [Binding Values to Queries](#r2dbc-DatabaseClient-named-parameters) - * [Statement Filters](#r2dbc-DatabaseClient-filter) - * [`DatabaseClient` Best Practices](#r2dbc-DatabaseClient-idioms) - - * [4.3. Retrieving Auto-generated Keys](#r2dbc-auto-generated-keys) - * [4.4. Controlling Database Connections](#r2dbc-connections) - * [4.4.1. Using `ConnectionFactory`](#r2dbc-ConnectionFactory) - * [4.4.2. Using `ConnectionFactoryUtils`](#r2dbc-ConnectionFactoryUtils) - * [4.4.3. Using `SingleConnectionFactory`](#r2dbc-SingleConnectionFactory) - * [4.4.4. Using `TransactionAwareConnectionFactoryProxy`](#r2dbc-TransactionAwareConnectionFactoryProxy) - * [4.4.5. Using `R2dbcTransactionManager`](#r2dbc-R2dbcTransactionManager) - -* [5. Object Relational Mapping (ORM) Data Access](#orm) - * [5.1. Introduction to ORM with Spring](#orm-introduction) - * [5.2. General ORM Integration Considerations](#orm-general) - * [5.2.1. Resource and Transaction Management](#orm-resource-mngmnt) - * [5.2.2. Exception Translation](#orm-exception-translation) - - * [5.3. Hibernate](#orm-hibernate) - * [5.3.1. `SessionFactory` Setup in a Spring Container](#orm-session-factory-setup) - * [5.3.2. Implementing DAOs Based on the Plain Hibernate API](#orm-hibernate-straight) - * [5.3.3. Declarative Transaction Demarcation](#orm-hibernate-tx-declarative) - * [5.3.4. Programmatic Transaction Demarcation](#orm-hibernate-tx-programmatic) - * [5.3.5. Transaction Management Strategies](#orm-hibernate-tx-strategies) - * [5.3.6. Comparing Container-managed and Locally Defined Resources](#orm-hibernate-resources) - * [5.3.7. Spurious Application Server Warnings with Hibernate](#orm-hibernate-invalid-jdbc-access-error) - - * [5.4. JPA](#orm-jpa) - * [5.4.1. Three Options for JPA Setup in a Spring Environment](#orm-jpa-setup) - * [Using `LocalEntityManagerFactoryBean`](#orm-jpa-setup-lemfb) - * [Obtaining an EntityManagerFactory from JNDI](#orm-jpa-setup-jndi) - * [Using `LocalContainerEntityManagerFactoryBean`](#orm-jpa-setup-lcemfb) - * [Dealing with Multiple Persistence Units](#orm-jpa-setup-multiple) - * [Background Bootstrapping](#orm-jpa-setup-background) - - * [5.4.2. Implementing DAOs Based on JPA: `EntityManagerFactory` and `EntityManager`](#orm-jpa-dao) - * [5.4.3. Spring-driven JPA transactions](#orm-jpa-tx) - * [5.4.4. Understanding `JpaDialect` and `JpaVendorAdapter`](#orm-jpa-dialect) - * [5.4.5. Setting up JPA with JTA Transaction Management](#orm-jpa-jta) - * [5.4.6. Native Hibernate Setup and Native Hibernate Transactions for JPA Interaction](#orm-jpa-hibernate) - -* [6. Marshalling XML by Using Object-XML Mappers](#oxm) - * [6.1. Introduction](#oxm-introduction) - * [6.1.1. Ease of configuration](#oxm-ease-of-configuration) - * [6.1.2. Consistent Interfaces](#oxm-consistent-interfaces) - * [6.1.3. Consistent Exception Hierarchy](#oxm-consistent-exception-hierarchy) - - * [6.2. `Marshaller` and `Unmarshaller`](#oxm-marshaller-unmarshaller) - * [6.2.1. Understanding `Marshaller`](#oxm-marshaller) - * [6.2.2. Understanding `Unmarshaller`](#oxm-unmarshaller) - * [6.2.3. Understanding `XmlMappingException`](#oxm-xmlmappingexception) - - * [6.3. Using `Marshaller` and `Unmarshaller`](#oxm-usage) - * [6.4. XML Configuration Namespace](#oxm-schema-based-config) - * [6.5. JAXB](#oxm-jaxb) - * [6.5.1. Using `Jaxb2Marshaller`](#oxm-jaxb2) - * [XML Configuration Namespace](#oxm-jaxb2-xsd) - - * [6.6. JiBX](#oxm-jibx) - * [6.6.1. Using `JibxMarshaller`](#oxm-jibx-marshaller) - * [XML Configuration Namespace](#oxm-jibx-xsd) - - * [6.7. XStream](#oxm-xstream) - * [6.7.1. Using `XStreamMarshaller`](#oxm-xstream-marshaller) - -* [7. Appendix](#appendix) - * [7.1. XML Schemas](#xsd-schemas) - * [7.1.1. The `tx` Schema](#xsd-schemas-tx) - * [7.1.2. The `jdbc` Schema](#xsd-schemas-jdbc) +# Data Access 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. @@ -221,8 +7,7 @@ Spring’s comprehensive transaction management support is covered in some detai followed by thorough coverage of the various data access frameworks and technologies with which the Spring Framework integrates. -[](#transaction)1. Transaction Management ----------- +## 1. Transaction Management Comprehensive transaction support is among the most compelling reasons to use the Spring Framework. The Spring Framework provides a consistent abstraction for transaction @@ -264,7 +49,7 @@ technologies: The chapter also includes discussions of best practices,[application server integration](#transaction-application-server-integration), and [solutions to common problems](#transaction-solutions-to-common-problems). -### [](#transaction-motivation)1.1. Advantages of the Spring Framework’s Transaction Support Model ### +### 1.1. Advantages of the Spring Framework’s Transaction Support Model Traditionally, Java EE developers have had two choices for transaction management: global or local transactions, both of which have profound limitations. Global @@ -272,7 +57,7 @@ and local transaction management is reviewed in the next two sections, followed discussion of how the Spring Framework’s transaction management support addresses the limitations of the global and local transaction models. -#### [](#transaction-global)1.1.1. Global Transactions #### +#### 1.1.1. Global Transactions Global transactions let you work with multiple transactional resources, typically relational databases and message queues. The application server manages global @@ -293,7 +78,7 @@ implement business logic in EJBs (or at least behind a transactional EJB facade) negatives of EJB in general are so great that this is not an attractive proposition, especially in the face of compelling alternatives for declarative transaction management. -#### [](#transaction-local)1.1.2. Local Transactions #### +#### 1.1.2. Local Transactions Local transactions are resource-specific, such as a transaction associated with a JDBC connection. Local transactions may be easier to use but have a significant disadvantage: @@ -304,7 +89,7 @@ correctness across multiple resources. (It is worth noting that most application single transaction resource.) Another downside is that local transactions are invasive to the programming model. -#### [](#transaction-programming-model)1.1.3. Spring Framework’s Consistent Programming Model #### +#### 1.1.3. Spring Framework’s Consistent Programming Model Spring resolves the disadvantages of global and local transactions. It lets application developers use a consistent programming model in any environment. @@ -343,7 +128,7 @@ and face a hefty rework if you need that code to run within global, container-ma transactions. With the Spring Framework, only some of the bean definitions in your configuration file need to change (rather than your code). -### [](#transaction-strategies)1.2. Understanding the Spring Framework Transaction Abstraction ### +### 1.2. Understanding the Spring Framework Transaction Abstraction The key to the Spring transaction abstraction is the notion of a transaction strategy. A transaction strategy is defined by a `TransactionManager`, specifically the`org.springframework.transaction.PlatformTransactionManager` interface for imperative @@ -517,7 +302,7 @@ In all Spring transaction setups, application code does not need to change. You how transactions are managed merely by changing configuration, even if that change means moving from local to global transactions or vice versa. -#### [](#transaction-strategies-hibernate)1.2.1. Hibernate Transaction Setup #### +#### 1.2.1. Hibernate Transaction Setup You can also easily use Hibernate local transactions, as shown in the following examples. In this case, you need to define a Hibernate `LocalSessionFactoryBean`, which your @@ -599,7 +384,7 @@ Or alternatively, you may pass the `JtaTransactionManager` into your `LocalSessi ``` -### [](#tx-resource-synchronization)1.3. Synchronizing Resources with Transactions ### +### 1.3. Synchronizing Resources with Transactions How to create different transaction managers and how they are linked to related resources that need to be synchronized to transactions (for example `DataSourceTransactionManager`to a JDBC `DataSource`, `HibernateTransactionManager` to a Hibernate `SessionFactory`, @@ -609,7 +394,7 @@ ensures that these resources are created, reused, and cleaned up properly. The s also discusses how transaction synchronization is (optionally) triggered through the relevant `TransactionManager`. -#### [](#tx-resource-synchronization-high)1.3.1. High-level Synchronization Approach #### +#### 1.3.1. High-level Synchronization Approach The preferred approach is to use Spring’s highest-level template-based persistence integration APIs or to use native ORM APIs with transaction-aware factory beans or @@ -621,7 +406,7 @@ persistence logic. Generally, you use the native ORM API or take a template appr for JDBC access by using the `JdbcTemplate`. These solutions are detailed in subsequent sections of this reference documentation. -#### [](#tx-resource-synchronization-low)1.3.2. Low-level Synchronization Approach #### +#### 1.3.2. Low-level Synchronization Approach Classes such as `DataSourceUtils` (for JDBC), `EntityManagerFactoryUtils` (for JPA),`SessionFactoryUtils` (for Hibernate), and so on exist at a lower level. When you want the application code to deal directly with the resource types of the native persistence APIs, @@ -654,7 +439,7 @@ because you are much happier working through the Spring abstraction than directl with the relevant APIs. For example, if you use the Spring `JdbcTemplate` or`jdbc.object` package to simplify your use of JDBC, correct connection retrieval occurs behind the scenes and you need not write any special code. -#### [](#tx-resource-synchronization-tadsp)1.3.3. `TransactionAwareDataSourceProxy` #### +#### 1.3.3. `TransactionAwareDataSourceProxy` At the very lowest level exists the `TransactionAwareDataSourceProxy` class. This is a proxy for a target `DataSource`, which wraps the target `DataSource` to add awareness of @@ -666,7 +451,7 @@ that case, it is possible that this code is usable but is participating in Sprin transactions. You can write your new code by using the higher-level abstractions mentioned earlier. -### [](#transaction-declarative)1.4. Declarative Transaction Management ### +### 1.4. Declarative Transaction Management | |Most Spring Framework users choose declarative transaction management. This option has
the least impact on application code and, hence, is most consistent with the ideals of a
non-invasive lightweight container.| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| @@ -718,7 +503,7 @@ other than `java.rmi.RemoteException`). While the Spring default behavior for declarative transaction management follows EJB convention (roll back is automatic only on unchecked exceptions), it is often useful to customize this behavior. -#### [](#tx-decl-explained)1.4.1. Understanding the Spring Framework’s Declarative Transaction Implementation #### +#### 1.4.1. Understanding the Spring Framework’s Declarative Transaction Implementation It is not sufficient merely to tell you to annotate your classes with the`@Transactional` annotation, add `@EnableTransactionManagement` to your configuration, and expect you to understand how it all works. To provide a deeper understanding, this @@ -752,7 +537,7 @@ The following image shows a conceptual view of calling a method on a transaction ![tx](images/tx.png) -#### [](#transaction-declarative-first-example)1.4.2. Example of Declarative Transaction Implementation #### +#### 1.4.2. Example of Declarative Transaction Implementation Consider the following interface and its attendant implementation. This example uses`Foo` and `Bar` classes as placeholders so that you can concentrate on the transaction usage without focusing on a particular domain model. For the purposes of this example, @@ -1137,7 +922,7 @@ A `Publisher` can emit data while a transaction is ongoing but not necessarily c Therefore, methods that depend upon successful completion of an entire transaction need to ensure completion and buffer results in the calling code. -#### [](#transaction-declarative-rolling-back)1.4.3. Rolling Back a Declarative Transaction #### +#### 1.4.3. Rolling Back a Declarative Transaction The previous section outlined the basics of how to specify transactional settings for classes, typically service layer classes, declaratively in your application. This @@ -1232,7 +1017,7 @@ You are strongly encouraged to use the declarative approach to rollback, if at a possible. Programmatic rollback is available should you absolutely need it, but its usage flies in the face of achieving a clean POJO-based architecture. -#### [](#transaction-declarative-diff-tx)1.4.4. Configuring Different Transactional Semantics for Different Beans #### +#### 1.4.4. Configuring Different Transactional Semantics for Different Beans #### Consider the scenario where you have a number of service layer objects, and you want to apply a totally different transactional configuration to each of them. You can do so @@ -1341,7 +1126,7 @@ transactional settings: ``` -#### [](#transaction-declarative-txadvice-settings)1.4.5. \ Settings #### +#### 1.4.5. \ Settings This section summarizes the various transactional settings that you can specify by using the `` tag. The default `` settings are: @@ -1370,7 +1155,7 @@ that are nested within `` and `` tags: | `rollback-for` | No | | Comma-delimited list of `Exception` instances that trigger rollback. For example,`com.foo.MyBusinessException,ServletException`. | |`no-rollback-for`| No | | Comma-delimited list of `Exception` instances that do not trigger rollback. For example,`com.foo.MyBusinessException,ServletException`. | -#### [](#transaction-declarative-annotations)1.4.6. Using `@Transactional` #### +#### 1.4.6. Using `@Transactional` In addition to the XML-based declarative approach to transaction configuration, you can use an annotation-based approach. Declaring transaction semantics directly in the Java @@ -1631,7 +1416,7 @@ class DefaultFooService : FooService { } ``` -##### [](#transaction-declarative-attransactional-settings)`@Transactional` Settings ##### +##### `@Transactional` Settings The `@Transactional` annotation is metadata that specifies that an interface, class, or method must have transactional semantics (for example, "start a brand new read-only @@ -1671,7 +1456,7 @@ means the transaction name that appears in a transaction monitor, if applicable transactions, the transaction name is always the fully-qualified class name + `.`+ the method name of the transactionally advised class. For example, if the`handlePayment(..)` method of the `BusinessService` class started a transaction, the name of the transaction would be: `com.example.BusinessService.handlePayment`. -##### [](#tx-multiple-tx-mgrs-with-attransactional)Multiple Transaction Managers with `@Transactional` ##### +##### Multiple Transaction Managers with `@Transactional` Most Spring applications need only a single transaction manager, but there may be situations where you want multiple independent transaction managers in a single @@ -1743,7 +1528,7 @@ In this case, the individual methods on `TransactionalService` run under separat transaction managers, differentiated by the `order`, `account`, and `reactive-account`qualifiers. The default `` target bean name, `transactionManager`, is still used if no specifically qualified `TransactionManager` bean is found. -##### [](#tx-custom-attributes)Custom Composed Annotations ##### +##### Custom Composed Annotations If you find you repeatedly use the same attributes with `@Transactional` on many different methods, [Spring’s meta-annotation support](core.html#beans-meta-annotations) lets you @@ -1820,7 +1605,7 @@ In the preceding example, we used the syntax to define the transaction manager q and transactional labels, but we could also have included propagation behavior, rollback rules, timeouts, and other features. -#### [](#tx-propagation)1.4.7. Transaction Propagation #### +#### 1.4.7. Transaction Propagation This section describes some semantics of transaction propagation in Spring. Note that this section is not a proper introduction to transaction propagation. Rather, it @@ -1829,7 +1614,7 @@ details some of the semantics regarding transaction propagation in Spring. In Spring-managed transactions, be aware of the difference between physical and logical transactions, and how the propagation setting applies to this difference. -##### [](#tx-propagation-required)Understanding `PROPAGATION_REQUIRED` ##### +##### Understanding `PROPAGATION_REQUIRED` ![tx prop required](images/tx_prop_required.png) @@ -1859,7 +1644,7 @@ is not aware) silently marks a transaction as rollback-only, the outer caller st calls commit. The outer caller needs to receive an `UnexpectedRollbackException` to indicate clearly that a rollback was performed instead. -##### [](#tx-propagation-requires_new)Understanding `PROPAGATION_REQUIRES_NEW` ##### +##### Understanding `PROPAGATION_REQUIRES_NEW` ![tx prop requires new](images/tx_prop_requires_new.png) @@ -1872,7 +1657,7 @@ status and with an inner transaction’s locks released immediately after its co Such an independent inner transaction can also declare its own isolation level, timeout, and read-only settings and not inherit an outer transaction’s characteristics. -##### [](#tx-propagation-nested)Understanding `PROPAGATION_NESTED` ##### +##### Understanding `PROPAGATION_NESTED` `PROPAGATION_NESTED` uses a single physical transaction with multiple savepoints that it can roll back to. Such partial rollbacks let an inner transaction scope @@ -1881,7 +1666,7 @@ the physical transaction despite some operations having been rolled back. This s is typically mapped onto JDBC savepoints, so it works only with JDBC resource transactions. See Spring’s [`DataSourceTransactionManager`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/jdbc/datasource/DataSourceTransactionManager.html). -#### [](#transaction-declarative-applying-more-than-just-tx-advice)1.4.8. Advising Transactional Operations #### +#### 1.4.8. Advising Transactional Operations Suppose you want to run both transactional operations and some basic profiling advice. How do you effect this in the context of ``? @@ -2090,7 +1875,7 @@ order value. You can configure additional aspects in similar fashion. -#### [](#transaction-declarative-aspectj)1.4.9. Using `@Transactional` with AspectJ #### +#### 1.4.9. Using `@Transactional` with AspectJ You can also use the Spring Framework’s `@Transactional` support outside of a Spring container by means of an AspectJ aspect. To do so, first annotate your classes @@ -2142,7 +1927,7 @@ your application with AspectJ (see the[AspectJ Development Guide](https://www.eclipse.org/aspectj/doc/released/devguide/index.html)) or use load-time weaving. See [Load-time weaving with AspectJ in the Spring Framework](core.html#aop-aj-ltw) for a discussion of load-time weaving with AspectJ. -### [](#transaction-programmatic)1.5. Programmatic Transaction Management ### +### 1.5. Programmatic Transaction Management The Spring Framework provides two means of programmatic transaction management, by using: @@ -2155,7 +1940,7 @@ transaction management in imperative flows and `TransactionalOperator` for react The second approach is similar to using the JTA `UserTransaction` API, although exception handling is less cumbersome. -#### [](#tx-prog-template)1.5.1. Using the `TransactionTemplate` #### +#### 1.5.1. Using the `TransactionTemplate` The `TransactionTemplate` adopts the same approach as other Spring templates, such as the `JdbcTemplate`. It uses a callback approach (to free application code from having to @@ -2271,7 +2056,7 @@ transactionTemplate.execute(object : TransactionCallbackWithoutResult() { }) ``` -##### [](#tx-prog-template-settings)Specifying Transaction Settings ##### +##### Specifying Transaction Settings You can specify transaction settings (such as the propagation mode, the isolation level, the timeout, and so forth) on the `TransactionTemplate` either programmatically or in @@ -2331,7 +2116,7 @@ of a `TransactionTemplate`, if a class needs to use a `TransactionTemplate` with different settings (for example, a different isolation level), you need to create two distinct `TransactionTemplate` instances. -#### [](#tx-prog-operator)1.5.2. Using the `TransactionOperator` #### +#### 1.5.2. Using the `TransactionOperator` The `TransactionOperator` follows an operator design that is similar to other reactive operators. It uses a callback approach (to free application code from having to do the @@ -2417,7 +2202,7 @@ transactionalOperator.execute(object : TransactionCallback() { }) ``` -##### [](#tx-prog-operator-cancel)Cancel Signals ##### +##### Cancel Signals In Reactive Streams, a `Subscriber` can cancel its `Subscription` and stop its`Publisher`. Operators in Project Reactor, as well as in other libraries, such as `next()`,`take(long)`, `timeout(Duration)`, and others can issue cancellations. There is no way to know the reason for the cancellation, whether it is due to an error or a simply lack of @@ -2425,7 +2210,7 @@ interest to consume further. Since version 5.3 cancel signals lead to a roll bac As a result it is important to consider the operators used downstream from a transaction`Publisher`. In particular in the case of a `Flux` or other multi-value `Publisher`, the full output must be consumed to allow the transaction to complete. -##### [](#tx-prog-operator-settings)Specifying Transaction Settings ##### +##### Specifying Transaction Settings You can specify transaction settings (such as the propagation mode, the isolation level, the timeout, and so forth) for the `TransactionalOperator`. By default,`TransactionalOperator` instances have[default transactional settings](#transaction-declarative-txadvice-settings). The @@ -2466,12 +2251,12 @@ class SimpleService(transactionManager: ReactiveTransactionManager) : Service { } ``` -#### [](#transaction-programmatic-tm)1.5.3. Using the `TransactionManager` #### +#### 1.5.3. Using the `TransactionManager` The following sections explain programmatic usage of imperative and reactive transaction managers. -##### [](#transaction-programmatic-ptm)Using the `PlatformTransactionManager` ##### +##### Using the `PlatformTransactionManager` For imperative transactions, you can use a`org.springframework.transaction.PlatformTransactionManager` directly to manage your transaction. To do so, pass the implementation of the `PlatformTransactionManager` you @@ -2515,7 +2300,7 @@ try { txManager.commit(status) ``` -##### [](#transaction-programmatic-rtm)Using the `ReactiveTransactionManager` ##### +##### Using the `ReactiveTransactionManager` When working with reactive transactions, you can use a`org.springframework.transaction.ReactiveTransactionManager` directly to manage your transaction. To do so, pass the implementation of the `ReactiveTransactionManager` you @@ -2559,7 +2344,7 @@ reactiveTx.flatMap { status -> } ``` -### [](#tx-decl-vs-prog)1.6. Choosing Between Programmatic and Declarative Transaction Management ### +### 1.6. Choosing Between Programmatic and Declarative Transaction Management Programmatic transaction management is usually a good idea only if you have a small number of transactional operations. For example, if you have a web application that @@ -2574,7 +2359,7 @@ management out of business logic and is not difficult to configure. When using t Spring Framework, rather than EJB CMT, the configuration cost of declarative transaction management is greatly reduced. -### [](#transaction-event)1.7. Transaction-bound Events ### +### 1.7. Transaction-bound Events As of Spring 4.2, the listener of an event can be bound to a phase of the transaction. The typical example is to handle the event when the transaction has completed successfully. @@ -2626,7 +2411,7 @@ required semantics. You can, however, override that behavior by setting the `fal | |`@TransactionalEventListener` only works with thread-bound transactions managed by`PlatformTransactionManager`. A reactive transaction managed by `ReactiveTransactionManager`uses the Reactor context instead of thread-local attributes, so from the perspective of
an event listener, there is no compatible active transaction that it can participate in.| |---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -### [](#transaction-application-server-integration)1.8. Application server-specific integration ### +### 1.8. Application server-specific integration Spring’s transaction abstraction is generally application server-agnostic. Additionally, Spring’s `JtaTransactionManager` class (which can optionally perform a JNDI lookup for @@ -2649,13 +2434,13 @@ transaction manager available for the platform. This means that you need not exp configure server-specific adapter classes (as discussed in the following sections). Rather, they are chosen automatically, with the standard`JtaTransactionManager` as the default fallback. -#### [](#transaction-application-server-integration-websphere)1.8.1. IBM WebSphere #### +#### 1.8.1. IBM WebSphere On WebSphere 6.1.0.9 and above, the recommended Spring JTA transaction manager to use is`WebSphereUowTransactionManager`. This special adapter uses IBM’s `UOWManager` API, which is available in WebSphere Application Server 6.1.0.9 and later. With this adapter, Spring-driven transaction suspension (suspend and resume as initiated by`PROPAGATION_REQUIRES_NEW`) is officially supported by IBM. -#### [](#transaction-application-server-integration-weblogic)1.8.2. Oracle WebLogic Server #### +#### 1.8.2. Oracle WebLogic Server On WebLogic Server 9.0 or above, you would typically use the`WebLogicJtaTransactionManager` instead of the stock `JtaTransactionManager` class. This special WebLogic-specific subclass of the normal `JtaTransactionManager` supports the @@ -2663,11 +2448,11 @@ full power of Spring’s transaction definitions in a WebLogic-managed transacti environment, beyond standard JTA semantics. Features include transaction names, per-transaction isolation levels, and proper resuming of transactions in all cases. -### [](#transaction-solutions-to-common-problems)1.9. Solutions to Common Problems ### +### 1.9. Solutions to Common Problems This section describes solutions to some common problems. -#### [](#transaction-solutions-to-common-problems-wrong-ptm)1.9.1. Using the Wrong Transaction Manager for a Specific `DataSource` #### +#### 1.9.1. Using the Wrong Transaction Manager for a Specific `DataSource` #### Use the correct `PlatformTransactionManager` implementation based on your choice of transactional technologies and requirements. Used properly, the Spring Framework merely @@ -2677,7 +2462,7 @@ it) for all your transactional operations. Otherwise, the transaction infrastruc tries to perform local transactions on such resources as container `DataSource`instances. Such local transactions do not make sense, and a good application server treats them as errors. -### [](#transaction-resources)1.10. Further Resources ### +### 1.10. Further Resources For more information about the Spring Framework’s transaction support, see: @@ -2691,8 +2476,7 @@ For more information about the Spring Framework’s transaction support, see: to transactions in Java. It also includes side-by-side examples of how to configure and use transactions with both the Spring Framework and EJB3. -[](#dao)2. DAO Support ----------- +## 2. DAO Support The Data Access Object (DAO) support in Spring is aimed at making it easy to work with data access technologies (such as JDBC, Hibernate, or JPA) in a consistent way. This @@ -2700,7 +2484,7 @@ lets you switch between the aforementioned persistence technologies fairly easil and it also lets you code without worrying about catching exceptions that are specific to each technology. -### [](#dao-exceptions)2.1. Consistent Exception Hierarchy ### +### 2.1. Consistent Exception Hierarchy Spring provides a convenient translation from technology-specific exceptions, such as`SQLException` to its own exception class hierarchy, which has `DataAccessException` as the root exception. These exceptions wrap the original exception so that there is never @@ -2727,7 +2511,7 @@ The following image shows the exception hierarchy that Spring provides. ![DataAccessException](images/DataAccessException.png) -### [](#dao-annotations)2.2. Annotations Used to Configure DAO or Repository Classes ### +### 2.2. Annotations Used to Configure DAO or Repository Classes The best way to guarantee that your Data Access Objects (DAOs) or repositories provide exception translation is to use the `@Repository` annotation. This annotation also @@ -2854,8 +2638,7 @@ class JdbcMovieFinder(dataSource: DataSource) : MovieFinder { | |See the specific coverage of each persistence technology for details on how to
configure the application context to take advantage of these annotations.| |---|------------------------------------------------------------------------------------------------------------------------------------------------------------| -[](#jdbc)3. Data Access with JDBC ----------- +## 3. Data Access with JDBC The value provided by the Spring Framework JDBC abstraction is perhaps best shown by the sequence of actions outlined in the following table below. The table shows which actions Spring @@ -2877,7 +2660,7 @@ takes care of and which actions are your responsibility. The Spring Framework takes care of all the low-level details that can make JDBC such a tedious API. -### [](#jdbc-choose-style)3.1. Choosing an Approach for JDBC Database Access ### +### 3.1. Choosing an Approach for JDBC Database Access You can choose among several approaches to form the basis for your JDBC database access. In addition to three flavors of `JdbcTemplate`, a new `SimpleJdbcInsert` and`SimpleJdbcCall` approach optimizes database metadata, and the RDBMS Object style takes a @@ -2906,7 +2689,7 @@ advanced features require a JDBC 3.0 driver. query string, declare parameters, and compile the query. Once you do that,`execute(…​)`, `update(…​)`, and `findObject(…​)` methods can be called multiple times with various parameter values. -### [](#jdbc-packages)3.2. Package Hierarchy ### +### 3.2. Package Hierarchy The Spring Framework’s JDBC abstraction framework consists of four different packages: @@ -2931,7 +2714,7 @@ The Spring Framework’s JDBC abstraction framework consists of four different p the option of catching the exceptions from which you can recover while letting other exceptions be propagated to the caller. See [Using `SQLExceptionTranslator`](#jdbc-SQLExceptionTranslator). -### [](#jdbc-core)3.3. Using the JDBC Core Classes to Control Basic JDBC Processing and Error Handling ### +### 3.3. Using the JDBC Core Classes to Control Basic JDBC Processing and Error Handling This section covers how to use the JDBC core classes to control basic JDBC processing, including error handling. It includes the following topics: @@ -2950,7 +2733,7 @@ including error handling. It includes the following topics: * [Retrieving Auto-generated Keys](#jdbc-auto-generated-keys) -#### [](#jdbc-JdbcTemplate)3.3.1. Using `JdbcTemplate` #### +#### 3.3.1. Using `JdbcTemplate` `JdbcTemplate` is the central class in the JDBC core package. It handles the creation and release of resources, which helps you avoid common errors, such as @@ -2985,7 +2768,7 @@ The following sections provide some examples of `JdbcTemplate` usage. These exam are not an exhaustive list of all of the functionality exposed by the `JdbcTemplate`. See the attendant [javadoc](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/jdbc/core/JdbcTemplate.html) for that. -##### [](#jdbc-JdbcTemplate-examples-query)Querying (`SELECT`) ##### +##### Querying (`SELECT`) The following query gets the number of rows in a relation: @@ -3115,7 +2898,7 @@ fun findAllActors(): List { } ``` -##### [](#jdbc-JdbcTemplate-examples-update)Updating (`INSERT`, `UPDATE`, and `DELETE`) with `JdbcTemplate` ##### +##### Updating (`INSERT`, `UPDATE`, and `DELETE`) with `JdbcTemplate` You can use the `update(..)` method to perform insert, update, and delete operations. Parameter values are usually provided as variable arguments or, alternatively, as an object array. @@ -3172,7 +2955,7 @@ Kotlin jdbcTemplate.update("delete from t_actor where id = ?", actorId.toLong()) ``` -##### [](#jdbc-JdbcTemplate-examples-other)Other `JdbcTemplate` Operations ##### +##### Other `JdbcTemplate` Operations You can use the `execute(..)` method to run any arbitrary SQL. Consequently, the method is often used for DDL statements. It is heavily overloaded with variants that take @@ -3211,7 +2994,7 @@ jdbcTemplate.update( More sophisticated stored procedure support is [covered later](#jdbc-StoredProcedure). -##### [](#jdbc-JdbcTemplate-idioms)`JdbcTemplate` Best Practices ##### +##### `JdbcTemplate` Best Practices Instances of the `JdbcTemplate` class are thread-safe, once configured. This is important because it means that you can configure a single instance of a `JdbcTemplate`and then safely inject this shared reference into multiple DAOs (or repositories). @@ -3359,7 +3142,7 @@ If your application accesses multiple databases, you may want multiple `JdbcTemplate` instances, which requires multiple `DataSources` and, subsequently, multiple differently configured `JdbcTemplate` instances. -#### [](#jdbc-NamedParameterJdbcTemplate)3.3.2. Using `NamedParameterJdbcTemplate` #### +#### 3.3.2. Using `NamedParameterJdbcTemplate` The `NamedParameterJdbcTemplate` class adds support for programming JDBC statements by using named parameters, as opposed to programming JDBC statements using only classic @@ -3531,7 +3314,7 @@ functionality that is present only in the `JdbcTemplate` class, you can use the` See also [`JdbcTemplate` Best Practices](#jdbc-JdbcTemplate-idioms) for guidelines on using the`NamedParameterJdbcTemplate` class in the context of an application. -#### [](#jdbc-SQLExceptionTranslator)3.3.3. Using `SQLExceptionTranslator` #### +#### 3.3.3. Using `SQLExceptionTranslator` `SQLExceptionTranslator` is an interface to be implemented by classes that can translate between `SQLException`s and Spring’s own `org.springframework.dao.DataAccessException`, @@ -3648,7 +3431,7 @@ fun updateShippingCharge(orderId: Long, pct: Long) { The custom translator is passed a data source in order to look up the error codes in`sql-error-codes.xml`. -#### [](#jdbc-statements-executing)3.3.4. Running Statements #### +#### 3.3.4. Running Statements Running an SQL statement requires very little code. You need a `DataSource` and a`JdbcTemplate`, including the convenience methods that are provided with the`JdbcTemplate`. The following example shows what you need to include for a minimal but fully functional class that creates a new table: @@ -3689,7 +3472,7 @@ class ExecuteAStatement(dataSource: DataSource) { } ``` -#### [](#jdbc-statements-querying)3.3.5. Running Queries #### +#### 3.3.5. Running Queries Some query methods return a single value. To retrieve a count or a specific value from one row, use `queryForObject(..)`. The latter converts the returned JDBC `Type` to the @@ -3774,7 +3557,7 @@ The returned list would resemble the following: [{name=Bob, id=1}, {name=Mary, id=2}] ``` -#### [](#jdbc-updates)3.3.6. Updating the Database #### +#### 3.3.6. Updating the Database The following example updates a column for a certain primary key: @@ -3819,7 +3602,7 @@ an SQL statement has placeholders for row parameters. You can pass the parameter in as varargs or, alternatively, as an array of objects. Thus, you should explicitly wrap primitives in the primitive wrapper classes, or you should use auto-boxing. -#### [](#jdbc-auto-generated-keys)3.3.7. Retrieving Auto-generated Keys #### +#### 3.3.7. Retrieving Auto-generated Keys An `update()` convenience method supports the retrieval of primary keys generated by the database. This support is part of the JDBC 3.0 standard. See Chapter 13.6 of the @@ -3859,7 +3642,7 @@ jdbcTemplate.update({ // keyHolder.getKey() now contains the generated key ``` -### [](#jdbc-connections)3.4. Controlling Database Connections ### +### 3.4. Controlling Database Connections This section covers: @@ -3879,7 +3662,7 @@ This section covers: * [Using `DataSourceTransactionManager`](#jdbc-DataSourceTransactionManager) -#### [](#jdbc-datasource)3.4.1. Using `DataSource` #### +#### 3.4.1. Using `DataSource` Spring obtains a connection to the database through a `DataSource`. A `DataSource` is part of the JDBC specification and is a generalized connection factory. It lets a @@ -3978,24 +3761,24 @@ The following example shows C3P0 configuration: ``` -#### [](#jdbc-DataSourceUtils)3.4.2. Using `DataSourceUtils` #### +#### 3.4.2. Using `DataSourceUtils` The `DataSourceUtils` class is a convenient and powerful helper class that provides`static` methods to obtain connections from JNDI and close connections if necessary. It supports thread-bound connections with, for example, `DataSourceTransactionManager`. -#### [](#jdbc-SmartDataSource)3.4.3. Implementing `SmartDataSource` #### +#### 3.4.3. Implementing `SmartDataSource` The `SmartDataSource` interface should be implemented by classes that can provide a connection to a relational database. It extends the `DataSource` interface to let classes that use it query whether the connection should be closed after a given operation. This usage is efficient when you know that you need to reuse a connection. -#### [](#jdbc-AbstractDataSource)3.4.4. Extending `AbstractDataSource` #### +#### 3.4.4. Extending `AbstractDataSource` `AbstractDataSource` is an `abstract` base class for Spring’s `DataSource`implementations. It implements code that is common to all `DataSource` implementations. You should extend the `AbstractDataSource` class if you write your own `DataSource`implementation. -#### [](#jdbc-SingleConnectionDataSource)3.4.5. Using `SingleConnectionDataSource` #### +#### 3.4.5. Using `SingleConnectionDataSource` The `SingleConnectionDataSource` class is an implementation of the `SmartDataSource`interface that wraps a single `Connection` that is not closed after each use. This is not multi-threading capable. @@ -4010,7 +3793,7 @@ of code outside an application server, in conjunction with a simple JNDI environ In contrast to `DriverManagerDataSource`, it reuses the same connection all the time, avoiding excessive creation of physical connections. -#### [](#jdbc-DriverManagerDataSource)3.4.6. Using `DriverManagerDataSource` #### +#### 3.4.6. Using `DriverManagerDataSource` The `DriverManagerDataSource` class is an implementation of the standard `DataSource`interface that configures a plain JDBC driver through bean properties and returns a new`Connection` every time. @@ -4021,7 +3804,7 @@ close the connection, so any `DataSource`-aware persistence code should work. Ho using JavaBean-style connection pools (such as `commons-dbcp`) is so easy, even in a test environment, that it is almost always preferable to use such a connection pool over`DriverManagerDataSource`. -#### [](#jdbc-TransactionAwareDataSourceProxy)3.4.7. Using `TransactionAwareDataSourceProxy` #### +#### 3.4.7. Using `TransactionAwareDataSourceProxy` `TransactionAwareDataSourceProxy` is a proxy for a target `DataSource`. The proxy wraps that target `DataSource` to add awareness of Spring-managed transactions. In this respect, it @@ -4032,7 +3815,7 @@ is similar to a transactional JNDI `DataSource`, as provided by a Java EE server See the [`TransactionAwareDataSourceProxy`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/jdbc/datasource/TransactionAwareDataSourceProxy.html)javadoc for more details. -#### [](#jdbc-DataSourceTransactionManager)3.4.8. Using `DataSourceTransactionManager` #### +#### 3.4.8. Using `DataSourceTransactionManager` The `DataSourceTransactionManager` class is a `PlatformTransactionManager`implementation for single JDBC datasources. It binds a JDBC connection from the specified data source to the currently executing thread, potentially allowing for one @@ -4052,13 +3835,13 @@ case, as it does not require the container to support JTA. Switching between both is just a matter of configuration, provided you stick to the required connection lookup pattern. JTA does not support custom isolation levels. -### [](#jdbc-advanced-jdbc)3.5. JDBC Batch Operations ### +### 3.5. JDBC Batch Operations Most JDBC drivers provide improved performance if you batch multiple calls to the same prepared statement. By grouping updates into batches, you limit the number of round trips to the database. -#### [](#jdbc-batch-classic)3.5.1. Basic Batch Operations with `JdbcTemplate` #### +#### 3.5.1. Basic Batch Operations with `JdbcTemplate` You accomplish `JdbcTemplate` batch processing by implementing two methods of a special interface, `BatchPreparedStatementSetter`, and passing that implementation in as the second parameter @@ -4130,7 +3913,7 @@ case, you can use the `InterruptibleBatchPreparedStatementSetter` interface, whi you interrupt a batch once the input source is exhausted. The `isBatchExhausted` method lets you signal the end of the batch. -#### [](#jdbc-batch-list)3.5.2. Batch Operations with a List of Objects #### +#### 3.5.2. Batch Operations with a List of Objects Both the `JdbcTemplate` and the `NamedParameterJdbcTemplate` provides an alternate way of providing the batch update. Instead of implementing a special batch interface, you @@ -4241,7 +4024,7 @@ the JDBC driver. If the count is not available, the JDBC driver returns a value | |In such a scenario, with automatic setting of values on an underlying `PreparedStatement`,
the corresponding JDBC type for each value needs to be derived from the given Java type.
While this usually works well, there is a potential for issues (for example, with Map-contained`null` values). Spring, by default, calls `ParameterMetaData.getParameterType` in such a
case, which can be expensive with your JDBC driver. You should use a recent driver
version and consider setting the `spring.jdbc.getParameterType.ignore` property to `true`(as a JVM system property or via the[`SpringProperties`](appendix.html#appendix-spring-properties) mechanism) if you encounter
a performance issue (as reported on Oracle 12c, JBoss, and PostgreSQL).

Alternatively, you might consider specifying the corresponding JDBC types explicitly,
either through a `BatchPreparedStatementSetter` (as shown earlier), through an explicit type
array given to a `List` based call, through `registerSqlType` calls on a
custom `MapSqlParameterSource` instance, or through a `BeanPropertySqlParameterSource`that derives the SQL type from the Java-declared property type even for a null value.| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#jdbc-batch-multi)3.5.3. Batch Operations with Multiple Batches #### +#### 3.5.3. Batch Operations with Multiple Batches The preceding example of a batch update deals with batches that are so large that you want to break them up into several smaller batches. You can do this with the methods @@ -4311,14 +4094,14 @@ that might be less), depending on the total number of update objects provided. T count for each update statement is the one reported by the JDBC driver. If the count is not available, the JDBC driver returns a value of `-2`. -### [](#jdbc-simple-jdbc)3.6. Simplifying JDBC Operations with the `SimpleJdbc` Classes ### +### 3.6. Simplifying JDBC Operations with the `SimpleJdbc` Classes The `SimpleJdbcInsert` and `SimpleJdbcCall` classes provide a simplified configuration by taking advantage of database metadata that can be retrieved through the JDBC driver. This means that you have less to configure up front, although you can override or turn off the metadata processing if you prefer to provide all the details in your code. -#### [](#jdbc-simple-jdbc-insert-1)3.6.1. Inserting Data by Using `SimpleJdbcInsert` #### +#### 3.6.1. Inserting Data by Using `SimpleJdbcInsert` We start by looking at the `SimpleJdbcInsert` class with the minimal amount of configuration options. You should instantiate the `SimpleJdbcInsert` in the data access @@ -4375,7 +4158,7 @@ important thing to note here is that the keys used for the `Map` must match the names of the table, as defined in the database. This is because we read the metadata to construct the actual insert statement. -#### [](#jdbc-simple-jdbc-insert-2)3.6.2. Retrieving Auto-generated Keys by Using `SimpleJdbcInsert` #### +#### 3.6.2. Retrieving Auto-generated Keys by Using `SimpleJdbcInsert` The next example uses the same insert as the preceding example, but, instead of passing in the `id`, it retrieves the auto-generated key and sets it on the new `Actor` object. When it creates @@ -4435,7 +4218,7 @@ class here. `java.lang.Number` is the base class that you can rely on. If you ha multiple auto-generated columns or the generated values are non-numeric, you can use a `KeyHolder` that is returned from the `executeAndReturnKeyHolder` method. -#### [](#jdbc-simple-jdbc-insert-3)3.6.3. Specifying Columns for a `SimpleJdbcInsert` #### +#### 3.6.3. Specifying Columns for a `SimpleJdbcInsert` You can limit the columns for an insert by specifying a list of column names with the`usingColumns` method, as the following example shows: @@ -4490,7 +4273,7 @@ class JdbcActorDao(dataSource: DataSource) : ActorDao { The execution of the insert is the same as if you had relied on the metadata to determine which columns to use. -#### [](#jdbc-simple-jdbc-parameters)3.6.4. Using `SqlParameterSource` to Provide Parameter Values #### +#### 3.6.4. Using `SqlParameterSource` to Provide Parameter Values Using a `Map` to provide parameter values works fine, but it is not the most convenient class to use. Spring provides a couple of implementations of the `SqlParameterSource`interface that you can use instead. The first one is `BeanPropertySqlParameterSource`, @@ -4592,7 +4375,7 @@ class JdbcActorDao(dataSource: DataSource) : ActorDao { As you can see, the configuration is the same. Only the executing code has to change to use these alternative input classes. -#### [](#jdbc-simple-jdbc-call-1)3.6.5. Calling a Stored Procedure with `SimpleJdbcCall` #### +#### 3.6.5. Calling a Stored Procedure with `SimpleJdbcCall` The `SimpleJdbcCall` class uses metadata in the database to look up names of `in`and `out` parameters so that you do not have to explicitly declare them. You can declare parameters if you prefer to do that or if you have parameters (such as `ARRAY`or `STRUCT`) that do not have an automatic mapping to a Java class. The first example @@ -4724,7 +4507,7 @@ class JdbcActorDao(dataSource: DataSource) : ActorDao { By taking this action, you avoid conflicts in the case used for the names of your returned `out` parameters. -#### [](#jdbc-simple-jdbc-call-2)3.6.6. Explicitly Declaring Parameters to Use for a `SimpleJdbcCall` #### +#### 3.6.6. Explicitly Declaring Parameters to Use for a `SimpleJdbcCall` Earlier in this chapter, we described how parameters are deduced from metadata, but you can declare them explicitly if you wish. You can do so by creating and configuring `SimpleJdbcCall` with @@ -4795,7 +4578,7 @@ class JdbcActorDao(dataSource: DataSource) : ActorDao { The execution and end results of the two examples are the same. The second example specifies all details explicitly rather than relying on metadata. -#### [](#jdbc-params)3.6.7. How to Define `SqlParameters` #### +#### 3.6.7. How to Define `SqlParameters` To define a parameter for the `SimpleJdbc` classes and also for the RDBMS operations classes (covered in [Modeling JDBC Operations as Java Objects](#jdbc-object)) you can use `SqlParameter` or one of its subclasses. @@ -4834,7 +4617,7 @@ provide a `RowMapper` to handle mapping of rows returned from a `REF` cursor. An option is to specify an `SqlReturnType` that provides an opportunity to define customized handling of the return values. -#### [](#jdbc-simple-jdbc-call-3)3.6.8. Calling a Stored Function by Using `SimpleJdbcCall` #### +#### 3.6.8. Calling a Stored Function by Using `SimpleJdbcCall` You can call a stored function in almost the same way as you call a stored procedure, except that you provide a function name rather than a procedure name. You use the`withFunctionName` method as part of the configuration to indicate that you want to make @@ -4907,7 +4690,7 @@ class JdbcActorDao(dataSource: DataSource) : ActorDao { The `executeFunction` method used returns a `String` that contains the return value from the function call. -#### [](#jdbc-simple-jdbc-call-4)3.6.9. Returning a `ResultSet` or REF Cursor from a `SimpleJdbcCall` #### +#### 3.6.9. Returning a `ResultSet` or REF Cursor from a `SimpleJdbcCall` Calling a stored procedure or function that returns a result set is a bit tricky. Some databases return result sets during the JDBC results processing, while others require an @@ -4981,7 +4764,7 @@ class JdbcActorDao(dataSource: DataSource) : ActorDao { The `execute` call passes in an empty `Map`, because this call does not take any parameters. The list of actors is then retrieved from the results map and returned to the caller. -### [](#jdbc-object)3.7. Modeling JDBC Operations as Java Objects ### +### 3.7. Modeling JDBC Operations as Java Objects The `org.springframework.jdbc.object` package contains classes that let you access the database in a more object-oriented manner. As an example, you can run queries @@ -4992,7 +4775,7 @@ procedures and run update, delete, and insert statements. | |Many Spring developers believe that the various RDBMS operation classes described below
(with the exception of the [`StoredProcedure`](#jdbc-StoredProcedure) class) can often
be replaced with straight `JdbcTemplate` calls. Often, it is simpler to write a DAO
method that calls a method on a `JdbcTemplate` directly (as opposed to
encapsulating a query as a full-blown class).

However, if you are getting measurable value from using the RDBMS operation classes,
you should continue to use these classes.| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#jdbc-SqlQuery)3.7.1. Understanding `SqlQuery` #### +#### 3.7.1. Understanding `SqlQuery` `SqlQuery` is a reusable, thread-safe class that encapsulates an SQL query. Subclasses must implement the `newRowMapper(..)` method to provide a `RowMapper` instance that can @@ -5001,7 +4784,7 @@ during the execution of the query. The `SqlQuery` class is rarely used directly, the `MappingSqlQuery` subclass provides a much more convenient implementation for mapping rows to Java classes. Other implementations that extend `SqlQuery` are`MappingSqlQueryWithParameters` and `UpdatableSqlQuery`. -#### [](#jdbc-MappingSqlQuery)3.7.2. Using `MappingSqlQuery` #### +#### 3.7.2. Using `MappingSqlQuery` `MappingSqlQuery` is a reusable query in which concrete subclasses must implement the abstract `mapRow(..)` method to convert each row of the supplied `ResultSet` into an @@ -5104,7 +4887,7 @@ fun searchForActors(age: Int, namePattern: String) = actorSearchMappingQuery.execute(age, namePattern) ``` -#### [](#jdbc-SqlUpdate)3.7.3. Using `SqlUpdate` #### +#### 3.7.3. Using `SqlUpdate` The `SqlUpdate` class encapsulates an SQL update. As with a query, an update object is reusable, and, as with all `RdbmsOperation` classes, an update can have parameters and is @@ -5171,7 +4954,7 @@ class UpdateCreditRating(ds: DataSource) : SqlUpdate() { } ``` -#### [](#jdbc-StoredProcedure)3.7.4. Using `StoredProcedure` #### +#### 3.7.4. Using `StoredProcedure` The `StoredProcedure` class is an `abstract` superclass for object abstractions of RDBMS stored procedures. @@ -5506,12 +5289,12 @@ class TitlesAfterDateStoredProcedure(dataSource: DataSource) : StoredProcedure(d } ``` -### [](#jdbc-parameter-handling)3.8. Common Problems with Parameter and Data Value Handling ### +### 3.8. Common Problems with Parameter and Data Value Handling Common problems with parameters and data values exist in the different approaches provided by Spring Framework’s JDBC support. This section covers how to address them. -#### [](#jdbc-type-information)3.8.1. Providing SQL Type Information for Parameters #### +#### 3.8.1. Providing SQL Type Information for Parameters Usually, Spring determines the SQL type of the parameters based on the type of parameter passed in. It is possible to explicitly provide the SQL type to be used when setting @@ -5532,7 +5315,7 @@ You can provide SQL type information in several ways: * For methods that work with named parameters, you can use the `SqlParameterSource` classes,`BeanPropertySqlParameterSource` or `MapSqlParameterSource`. They both have methods for registering the SQL type for any of the named parameter values. -#### [](#jdbc-lob)3.8.2. Handling BLOB and CLOB objects #### +#### 3.8.2. Handling BLOB and CLOB objects You can store images, other binary data, and large chunks of text in the database. These large objects are called BLOBs (Binary Large OBject) for binary data and CLOBs (Character @@ -5667,7 +5450,7 @@ val l = jdbcTemplate.query("select id, a_clob, a_blob from lob_table") { rs, _ - |-----|------------------------------------------------------------------------| |**2**|Using the method `getBlobAsBytes` to retrieve the contents of the BLOB. | -#### [](#jdbc-in-clause)3.8.3. Passing in Lists of Values for IN Clause #### +#### 3.8.3. Passing in Lists of Values for IN Clause The SQL standard allows for selecting rows based on an expression that includes a variable list of values. A typical example would be `select * from T_ACTOR where id in @@ -5686,7 +5469,7 @@ statement execution. In addition to the primitive values in the value list, you can create a `java.util.List`of object arrays. This list can support multiple expressions being defined for the `in`clause, such as `select * from T_ACTOR where (id, last_name) in ((1, 'Johnson'), (2, 'Harrop'))`. This, of course, requires that your database supports this syntax. -#### [](#jdbc-complex-types)3.8.4. Handling Complex Types for Stored Procedure Calls #### +#### 3.8.4. Handling Complex Types for Stored Procedure Calls When you call stored procedures, you can sometimes use complex types specific to the database. To accommodate these types, Spring provides a `SqlReturnType` for handling @@ -5814,19 +5597,19 @@ class TestItemStoredProcedure(dataSource: DataSource) : StoredProcedure() { } ``` -### [](#jdbc-embedded-database-support)3.9. Embedded Database Support ### +### 3.9. Embedded Database Support The `org.springframework.jdbc.datasource.embedded` package provides support for embedded Java database engines. Support for [HSQL](http://www.hsqldb.org),[H2](https://www.h2database.com), and [Derby](https://db.apache.org/derby) is provided natively. You can also use an extensible API to plug in new embedded database types and`DataSource` implementations. -#### [](#jdbc-why-embedded-database)3.9.1. Why Use an Embedded Database? #### +#### 3.9.1. Why Use an Embedded Database? An embedded database can be useful during the development phase of a project because of its lightweight nature. Benefits include ease of configuration, quick startup time, testability, and the ability to rapidly evolve your SQL during development. -#### [](#jdbc-embedded-database-xml)3.9.2. Creating an Embedded Database by Using Spring XML #### +#### 3.9.2. Creating an Embedded Database by Using Spring XML If you want to expose an embedded database instance as a bean in a Spring`ApplicationContext`, you can use the `embedded-database` tag in the `spring-jdbc` namespace: @@ -5842,7 +5625,7 @@ the `schema.sql` and `test-data.sql` resources in the root of the classpath. In a best practice, the embedded database is assigned a uniquely generated name. The embedded database is made available to the Spring container as a bean of type`javax.sql.DataSource` that can then be injected into data access objects as needed. -#### [](#jdbc-embedded-database-java)3.9.3. Creating an Embedded Database Programmatically #### +#### 3.9.3. Creating an Embedded Database Programmatically The `EmbeddedDatabaseBuilder` class provides a fluent API for constructing an embedded database programmatically. You can use this when you need to create an embedded database in a @@ -5927,7 +5710,7 @@ class DataSourceConfig { } ``` -#### [](#jdbc-embedded-database-types)3.9.4. Selecting the Embedded Database Type #### +#### 3.9.4. Selecting the Embedded Database Type This section covers how to select one of the three embedded databases that Spring supports. It includes the following topics: @@ -5938,21 +5721,21 @@ supports. It includes the following topics: * [Using Derby](#jdbc-embedded-database-using-Derby) -##### [](#jdbc-embedded-database-using-HSQL)Using HSQL ##### +##### Using HSQL Spring supports HSQL 1.8.0 and above. HSQL is the default embedded database if no type is explicitly specified. To specify HSQL explicitly, set the `type` attribute of the`embedded-database` tag to `HSQL`. If you use the builder API, call the`setType(EmbeddedDatabaseType)` method with `EmbeddedDatabaseType.HSQL`. -##### [](#jdbc-embedded-database-using-H2)Using H2 ##### +##### Using H2 Spring supports the H2 database. To enable H2, set the `type` attribute of the`embedded-database` tag to `H2`. If you use the builder API, call the`setType(EmbeddedDatabaseType)` method with `EmbeddedDatabaseType.H2`. -##### [](#jdbc-embedded-database-using-Derby)Using Derby ##### +##### Using Derby Spring supports Apache Derby 10.5 and above. To enable Derby, set the `type`attribute of the `embedded-database` tag to `DERBY`. If you use the builder API, call the `setType(EmbeddedDatabaseType)` method with `EmbeddedDatabaseType.DERBY`. -#### [](#jdbc-embedded-database-dao-testing)3.9.5. Testing Data Access Logic with an Embedded Database #### +#### 3.9.5. Testing Data Access Logic with an Embedded Database Embedded databases provide a lightweight way to test data access code. The next example is a data access integration test template that uses an embedded database. Using such a template @@ -6024,7 +5807,7 @@ class DataAccessIntegrationTestTemplate { } ``` -#### [](#jdbc-embedded-database-unique-names)3.9.6. Generating Unique Names for Embedded Databases #### +#### 3.9.6. Generating Unique Names for Embedded Databases Development teams often encounter errors with embedded databases if their test suite inadvertently attempts to recreate additional instances of the same database. This can @@ -6052,7 +5835,7 @@ the following options. * `` -#### [](#jdbc-embedded-database-extension)3.9.7. Extending the Embedded Database Support #### +#### 3.9.7. Extending the Embedded Database Support You can extend Spring JDBC embedded database support in two ways: @@ -6063,14 +5846,14 @@ You can extend Spring JDBC embedded database support in two ways: We encourage you to contribute extensions to the Spring community at[GitHub Issues](https://github.com/spring-projects/spring-framework/issues). -### [](#jdbc-initializing-datasource)3.10. Initializing a `DataSource` ### +### 3.10. Initializing a `DataSource` The `org.springframework.jdbc.datasource.init` package provides support for initializing an existing `DataSource`. The embedded database support provides one option for creating and initializing a `DataSource` for an application. However, you may sometimes need to initialize an instance that runs on a server somewhere. -#### [](#jdbc-initializing-datasource-xml)3.10.1. Initializing a Database by Using Spring XML #### +#### 3.10.1. Initializing a Database by Using Spring XML If you want to initialize a database and you can provide a reference to a `DataSource`bean, you can use the `initialize-database` tag in the `spring-jdbc` namespace: @@ -6152,7 +5935,7 @@ is `@@` and overrides that default for the `db-schema` script. If you need more control than you get from the XML namespace, you can use the`DataSourceInitializer` directly and define it as a component in your application. -##### [](#jdbc-client-component-initialization)Initialization of Other Components that Depend on the Database ##### +##### Initialization of Other Components that Depend on the Database A large class of applications (those that do not use the database until after the Spring context has started) can use the database initializer with no further @@ -6199,13 +5982,12 @@ Ensuring that the database initializer is initialized first can also be easy. So components). This structure is common in Spring web applications but can be more generally applied. -[](#r2dbc)4. Data Access with R2DBC ----------- +## 4. Data Access with R2DBC [R2DBC](https://r2dbc.io) ("Reactive Relational Database Connectivity") is a community-driven specification effort to standardize access to SQL databases using reactive patterns. -### [](#r2dbc-packages)4.1. Package Hierarchy ### +### 4.1. Package Hierarchy The Spring Framework’s R2DBC abstraction framework consists of two different packages: @@ -6215,7 +5997,7 @@ The Spring Framework’s R2DBC abstraction framework consists of two different p for easy `ConnectionFactory` access and various simple `ConnectionFactory` implementations that you can use for testing and running unmodified R2DBC. See [Controlling Database Connections](#r2dbc-connections). -### [](#r2dbc-core)4.2. Using the R2DBC Core Classes to Control Basic R2DBC Processing and Error Handling ### +### 4.2. Using the R2DBC Core Classes to Control Basic R2DBC Processing and Error Handling This section covers how to use the R2DBC core classes to control basic R2DBC processing, including error handling. It includes the following topics: @@ -6232,7 +6014,7 @@ including error handling. It includes the following topics: * [Retrieving Auto-generated Keys](#r2dbc-auto-generated-keys) -#### [](#r2dbc-DatabaseClient)4.2.1. Using `DatabaseClient` #### +#### 4.2.1. Using `DatabaseClient` `DatabaseClient` is the central class in the R2DBC core package. It handles the creation and release of resources, which helps to avoid common errors, such as @@ -6312,7 +6094,7 @@ The following sections provide some examples of `DatabaseClient` usage. These ex are not an exhaustive list of all of the functionality exposed by the `DatabaseClient`. See the attendant [javadoc](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/r2dbc/core/DatabaseClient.html) for that. -##### [](#r2dbc-DatabaseClient-examples-statement)Executing Statements ##### +##### Executing Statements `DatabaseClient` provides the basic functionality of running a statement. The following example shows what you need to include for minimal but fully functional @@ -6340,7 +6122,7 @@ multiple statements) completes. | |`execute(…)` accepts either the SQL query string or a query `Supplier`to defer the actual query creation until execution.| |---|---------------------------------------------------------------------------------------------------------------------------------| -##### [](#r2dbc-DatabaseClient-examples-query)Querying (`SELECT`) ##### +##### Querying (`SELECT`) SQL queries can return values through `Row` objects or the number of affected rows.`DatabaseClient` can return the number of updated rows or the rows themselves, depending on the issued query. @@ -6428,7 +6210,7 @@ That requirement mandates proper `null` handling in the extractor function. While you can obtain `null` values from a `Row`, you must not emit a `null`value. You must wrap any `null` values in an object (for example, `Optional`for singular values) to make sure a `null` value is never returned directly by your extractor function. -##### [](#r2dbc-DatabaseClient-examples-update)Updating (`INSERT`, `UPDATE`, and `DELETE`) with `DatabaseClient` ##### +##### Updating (`INSERT`, `UPDATE`, and `DELETE`) with `DatabaseClient` ##### The only difference of modifying statements is that these statements typically do not return tabular data so you use `rowsUpdated()` to consume results. @@ -6452,7 +6234,7 @@ val affectedRows = client.sql("UPDATE person SET first_name = :fn") .fetch().awaitRowsUpdated() ``` -##### [](#r2dbc-DatabaseClient-named-parameters)Binding Values to Queries ##### +##### Binding Values to Queries A typical application requires parameterized SQL statements to select or update rows according to some input. These are typically `SELECT` statements @@ -6555,7 +6337,7 @@ client.sql("SELECT id, name, state FROM table WHERE age IN (:ages)") | |R2DBC itself does not support Collection-like values. Nevertheless,
expanding a given `List` in the example above works for named parameters
in Spring’s R2DBC support, e.g. for use in `IN` clauses as shown above.
However, inserting or updating array-typed columns (e.g. in Postgres)
requires an array type that is supported by the underlying R2DBC driver:
typically a Java array, e.g. `String[]` to update a `text[]` column.
Do not pass `Collection` or the like as an array parameter.| |---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#r2dbc-DatabaseClient-filter)Statement Filters ##### +##### Statement Filters Sometimes it you need to fine-tune options on the actual `Statement`before it gets run. Register a `Statement` filter (`StatementFilterFunction`) through `DatabaseClient` to intercept and @@ -6603,7 +6385,7 @@ client.sql("SELECT id, name, state FROM table") `StatementFilterFunction` implementations allow filtering of the`Statement` and filtering of `Result` objects. -##### [](#r2dbc-DatabaseClient-idioms)`DatabaseClient` Best Practices ##### +##### `DatabaseClient` Best Practices Instances of the `DatabaseClient` class are thread-safe, once configured. This is important because it means that you can configure a single instance of a `DatabaseClient`and then safely inject this shared reference into multiple DAOs (or repositories). @@ -6689,7 +6471,7 @@ time you want to run SQL. Once configured, a `DatabaseClient` instance is thread If your application accesses multiple databases, you may want multiple `DatabaseClient` instances, which requires multiple`ConnectionFactory` and, subsequently, multiple differently configured `DatabaseClient`instances. -### [](#r2dbc-auto-generated-keys)4.3. Retrieving Auto-generated Keys ### +### 4.3. Retrieving Auto-generated Keys `INSERT` statements may generate keys when inserting rows into a table that defines an auto-increment or identity column. To get full control over @@ -6718,7 +6500,7 @@ val generatedId = client.sql("INSERT INTO table (name, state) VALUES(:name, :sta // generatedId emits the generated key once the INSERT statement has finished ``` -### [](#r2dbc-connections)4.4. Controlling Database Connections ### +### 4.4. Controlling Database Connections This section covers: @@ -6732,7 +6514,7 @@ This section covers: * [Using `R2dbcTransactionManager`](#r2dbc-R2dbcTransactionManager) -#### [](#r2dbc-ConnectionFactory)4.4.1. Using `ConnectionFactory` #### +#### 4.4.1. Using `ConnectionFactory` Spring obtains an R2DBC connection to the database through a `ConnectionFactory`. A `ConnectionFactory` is part of the R2DBC specification and is a common entry-point @@ -6769,14 +6551,14 @@ Kotlin val factory = ConnectionFactories.get("r2dbc:h2:mem:///test?options=DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE"); ``` -#### [](#r2dbc-ConnectionFactoryUtils)4.4.2. Using `ConnectionFactoryUtils` #### +#### 4.4.2. Using `ConnectionFactoryUtils` The `ConnectionFactoryUtils` class is a convenient and powerful helper class that provides `static` methods to obtain connections from `ConnectionFactory`and close connections (if necessary). It supports subscriber `Context`-bound connections with, for example`R2dbcTransactionManager`. -#### [](#r2dbc-SingleConnectionFactory)4.4.3. Using `SingleConnectionFactory` #### +#### 4.4.3. Using `SingleConnectionFactory` The `SingleConnectionFactory` class is an implementation of `DelegatingConnectionFactory`interface that wraps a single `Connection` that is not closed after each use. @@ -6790,7 +6572,7 @@ such as pipelining if your R2DBC driver permits for such use. In contrast to a pooled `ConnectionFactory`, it reuses the same connection all the time, avoiding excessive creation of physical connections. -#### [](#r2dbc-TransactionAwareConnectionFactoryProxy)4.4.4. Using `TransactionAwareConnectionFactoryProxy` #### +#### 4.4.4. Using `TransactionAwareConnectionFactoryProxy` `TransactionAwareConnectionFactoryProxy` is a proxy for a target `ConnectionFactory`. The proxy wraps that target `ConnectionFactory` to add awareness of Spring-managed transactions. @@ -6800,7 +6582,7 @@ The proxy wraps that target `ConnectionFactory` to add awareness of Spring-manag See the [`TransactionAwareConnectionFactoryProxy`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/r2dbc/connection/TransactionAwareConnectionFactoryProxy.html)javadoc for more details. -#### [](#r2dbc-R2dbcTransactionManager)4.4.5. Using `R2dbcTransactionManager` #### +#### 4.4.5. Using `R2dbcTransactionManager` The `R2dbcTransactionManager` class is a `ReactiveTransactionManager` implementation for single R2DBC datasources. It binds an R2DBC connection from the specified connection factory @@ -6815,12 +6597,11 @@ Thus, it can be used in any case. The `R2dbcTransactionManager` class supports custom isolation levels that get applied to the connection. -[](#orm)5. Object Relational Mapping (ORM) Data Access ----------- +## 5. Object Relational Mapping (ORM) Data Access This section covers data access when you use Object Relational Mapping (ORM). -### [](#orm-introduction)5.1. Introduction to ORM with Spring ### +### 5.1. Introduction to ORM with Spring The Spring Framework supports integration with the Java Persistence API (JPA) and supports native Hibernate for resource management, data access object (DAO) implementations, @@ -6879,7 +6660,7 @@ The benefits of using the Spring Framework to create your ORM DAOs include: | |For more comprehensive ORM support, including support for alternative database
technologies such as MongoDB, you might want to check out the[Spring Data](https://projects.spring.io/spring-data/) suite of projects. If you are
a JPA user, the [Getting Started Accessing
Data with JPA](https://spring.io/guides/gs/accessing-data-jpa/) guide from [https://spring.io](https://spring.io) provides a great introduction.| |---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -### [](#orm-general)5.2. General ORM Integration Considerations ### +### 5.2. General ORM Integration Considerations This section highlights considerations that apply to all ORM technologies. The [Hibernate](#orm-hibernate) section provides more details and also show these features and @@ -6898,7 +6679,7 @@ many important objects are JavaBeans: data access templates, data access objects transaction managers, business services that use the data access objects and transaction managers, web view resolvers, web controllers that use the business services, and so on. -#### [](#orm-resource-mngmnt)5.2.1. Resource and Transaction Management #### +#### 5.2.1. Resource and Transaction Management Typical business applications are cluttered with repetitive resource management code. Many projects try to invent their own solutions, sometimes sacrificing proper handling @@ -6919,7 +6700,7 @@ Spring transaction managers. For the supported ORM technologies, Spring offers H and JPA support through the Hibernate and JPA transaction managers as well as JTA support. For details on transaction support, see the [Transaction Management](#transaction) chapter. -#### [](#orm-exception-translation)5.2.2. Exception Translation #### +#### 5.2.2. Exception Translation When you use Hibernate or JPA in a DAO, you must decide how to handle the persistence technology’s native exception classes. The DAO throws a subclass of a `HibernateException`or `PersistenceException`, depending on the technology. These exceptions are all runtime @@ -6974,7 +6755,7 @@ annotations while still benefiting from Spring-managed transactions, dependency injection, and transparent exception conversion (if desired) to Spring’s custom exception hierarchies. -### [](#orm-hibernate)5.3. Hibernate ### +### 5.3. Hibernate We start with a coverage of [Hibernate 5](https://hibernate.org/) in a Spring environment, using it to demonstrate the approach that Spring takes towards integrating OR mappers. @@ -6986,7 +6767,7 @@ cover the other ORM technologies and show brief examples. | |As of Spring Framework 5.3, Spring requires Hibernate ORM 5.2+ for Spring’s`HibernateJpaVendorAdapter` as well as for a native Hibernate `SessionFactory` setup.
It is strongly recommended to go with Hibernate ORM 5.4 for a newly started application.
For use with `HibernateJpaVendorAdapter`, Hibernate Search needs to be upgraded to 5.11.6.| |---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#orm-session-factory-setup)5.3.1. `SessionFactory` Setup in a Spring Container #### +#### 5.3.1. `SessionFactory` Setup in a Spring Container To avoid tying application objects to hard-coded resource lookups, you can define resources (such as a JDBC `DataSource` or a Hibernate `SessionFactory`) as beans in the @@ -7039,7 +6820,7 @@ However, that is typically not common outside of an EJB context. | |Spring also provides a `LocalSessionFactoryBuilder` variant, seamlessly integrating
with `@Bean` style configuration and programmatic setup (no `FactoryBean` involved).

Both `LocalSessionFactoryBean` and `LocalSessionFactoryBuilder` support background
bootstrapping, with Hibernate initialization running in parallel to the application
bootstrap thread on a given bootstrap executor (such as a `SimpleAsyncTaskExecutor`).
On `LocalSessionFactoryBean`, this is available through the `bootstrapExecutor`property. On the programmatic `LocalSessionFactoryBuilder`, there is an overloaded`buildSessionFactory` method that takes a bootstrap executor argument.

As of Spring Framework 5.1, such a native Hibernate setup can also expose a JPA`EntityManagerFactory` for standard JPA interaction next to native Hibernate access.
See [Native Hibernate Setup for JPA](#orm-jpa-hibernate) for details.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#orm-hibernate-straight)5.3.2. Implementing DAOs Based on the Plain Hibernate API #### +#### 5.3.2. Implementing DAOs Based on the Plain Hibernate API Hibernate has a feature called contextual sessions, wherein Hibernate itself manages one current `Session` per transaction. This is roughly equivalent to Spring’s @@ -7121,7 +6902,7 @@ This behavior applies regardless of whether you use Spring’s`JtaTransactionMan In summary, you can implement DAOs based on the plain Hibernate API, while still being able to participate in Spring-managed transactions. -#### [](#orm-hibernate-tx-declarative)5.3.3. Declarative Transaction Demarcation #### +#### 5.3.3. Declarative Transaction Demarcation We recommend that you use Spring’s declarative transaction support, which lets you replace explicit transaction demarcation API calls in your Java code with an AOP @@ -7210,7 +6991,7 @@ In the container, you need to set up the `PlatformTransactionManager` implementa ``` -#### [](#orm-hibernate-tx-programmatic)5.3.4. Programmatic Transaction Demarcation #### +#### 5.3.4. Programmatic Transaction Demarcation You can demarcate transactions in a higher level of the application, on top of lower-level data access services that span any number of operations. Nor do restrictions @@ -7284,7 +7065,7 @@ exceptions within the callback. `TransactionTemplate` triggers a rollback in cas an unchecked application exception or if the transaction is marked rollback-only by the application (by setting `TransactionStatus`). By default, `TransactionInterceptor`behaves the same way but allows configurable rollback policies per method. -#### [](#orm-hibernate-tx-strategies)5.3.5. Transaction Management Strategies #### +#### 5.3.5. Transaction Management Strategies Both `TransactionTemplate` and `TransactionInterceptor` delegate the actual transaction handling to a `PlatformTransactionManager` instance (which can be a`HibernateTransactionManager` (for a single Hibernate `SessionFactory`) by using a`ThreadLocal` `Session` under the hood) or a `JtaTransactionManager` (delegating to the @@ -7310,7 +7091,7 @@ transaction demarcation with mixed Hibernate and JDBC data access completely wit JTA, provided you access only one database. `HibernateTransactionManager` automatically exposes the Hibernate transaction as a JDBC transaction if you have set up the passed-in`SessionFactory` with a `DataSource` through the `dataSource` property of the`LocalSessionFactoryBean` class. Alternatively, you can specify explicitly the`DataSource` for which the transactions are supposed to be exposed through the`dataSource` property of the `HibernateTransactionManager` class. -#### [](#orm-hibernate-resources)5.3.6. Comparing Container-managed and Locally Defined Resources #### +#### 5.3.6. Comparing Container-managed and Locally Defined Resources You can switch between a container-managed JNDI `SessionFactory` and a locally defined one without having to change a single line of application code. Whether to keep @@ -7351,7 +7132,7 @@ transactions, without the inconvenience of container deployment. JNDI registrati Hibernate `SessionFactory` through the JCA connector adds value only when used in conjunction with EJBs. -#### [](#orm-hibernate-invalid-jdbc-access-error)5.3.7. Spurious Application Server Warnings with Hibernate #### +#### 5.3.7. Spurious Application Server Warnings with Hibernate In some JTA environments with very strict `XADataSource` implementations (currently some WebLogic Server and WebSphere versions), when Hibernate is configured without @@ -7420,14 +7201,14 @@ the following events occur when a JTA transaction commits: through an `afterCompletion` callback by the JTA transaction manager and can properly clear its cache. -### [](#orm-jpa)5.4. JPA ### +### 5.4. JPA The Spring JPA, available under the `org.springframework.orm.jpa` package, offers comprehensive support for the[Java Persistence API](https://www.oracle.com/technetwork/articles/javaee/jpa-137156.html) in a manner similar to the integration with Hibernate while being aware of the underlying implementation in order to provide additional features. -#### [](#orm-jpa-setup)5.4.1. Three Options for JPA Setup in a Spring Environment #### +#### 5.4.1. Three Options for JPA Setup in a Spring Environment The Spring JPA support offers three ways of setting up the JPA `EntityManagerFactory`that is used by the application to obtain an entity manager. @@ -7437,7 +7218,7 @@ The Spring JPA support offers three ways of setting up the JPA `EntityManagerFac * [Using `LocalContainerEntityManagerFactoryBean`](#orm-jpa-setup-lcemfb) -##### [](#orm-jpa-setup-lemfb)Using `LocalEntityManagerFactoryBean` ##### +##### Using `LocalEntityManagerFactoryBean` You can use this option only in simple deployment environments such as stand-alone applications and integration tests. @@ -7463,7 +7244,7 @@ provider-specific, often requiring a specific JVM agent to be specified on start option is sufficient only for stand-alone applications and test environments, for which the JPA specification is designed. -##### [](#orm-jpa-setup-jndi)Obtaining an EntityManagerFactory from JNDI ##### +##### Obtaining an EntityManagerFactory from JNDI You can use this option when deploying to a Java EE server. Check your server’s documentation on how to deploy a custom JPA provider into your server, allowing for a different @@ -7491,7 +7272,7 @@ If you use multiple persistence units in the same application, the bean names of JNDI-retrieved persistence units should match the persistence unit names that the application uses to refer to them (for example, in `@PersistenceUnit` and`@PersistenceContext` annotations). -##### [](#orm-jpa-setup-lcemfb)Using `LocalContainerEntityManagerFactoryBean` ##### +##### Using `LocalContainerEntityManagerFactoryBean` You can use this option for full JPA capabilities in a Spring-based application environment. This includes web containers such as Tomcat, stand-alone applications, and @@ -7596,7 +7377,7 @@ This is especially important when the hosting applications rely on different JPA implementations, because the JPA transformers are applied only at the class-loader level and are, thus, isolated from each other. -##### [](#orm-jpa-setup-multiple)Dealing with Multiple Persistence Units ##### +##### Dealing with Multiple Persistence Units For applications that rely on multiple persistence units locations (stored in various JARS in the classpath, for example), Spring offers the `PersistenceUnitManager` to act as @@ -7635,7 +7416,7 @@ The default implementation allows customization of the `PersistenceUnitInfo` ins (before they are fed to the JPA provider) either declaratively (through its properties, which affect all hosted units) or programmatically (through the`PersistenceUnitPostProcessor`, which allows persistence unit selection). If no`PersistenceUnitManager` is specified, one is created and used internally by`LocalContainerEntityManagerFactoryBean`. -##### [](#orm-jpa-setup-background)Background Bootstrapping ##### +##### Background Bootstrapping `LocalContainerEntityManagerFactoryBean` supports background bootstrapping through the `bootstrapExecutor` property, as the following example shows: @@ -7654,7 +7435,7 @@ is being accessed by other components (for example, calling `createEntityManager block until the background bootstrapping has completed. In particular, when you use Spring Data JPA, make sure to set up deferred bootstrapping for its repositories as well. -#### [](#orm-jpa-dao)5.4.2. Implementing DAOs Based on JPA: `EntityManagerFactory` and `EntityManager` #### +#### 5.4.2. Implementing DAOs Based on JPA: `EntityManagerFactory` and `EntityManager` | |Although `EntityManagerFactory` instances are thread-safe, `EntityManager` instances are
not. The injected JPA `EntityManager` behaves like an `EntityManager` fetched from an
application server’s JNDI environment, as defined by the JPA specification. It delegates
all calls to the current transactional `EntityManager`, if any. Otherwise, it falls back
to a newly created `EntityManager` per operation, in effect making its usage thread-safe.| |---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| @@ -7813,7 +7594,7 @@ No import of any Spring class is required. Moreover, as the JPA annotations are the injections are applied automatically by the Spring container. This is appealing from a non-invasiveness perspective and can feel more natural to JPA developers. -#### [](#orm-jpa-tx)5.4.3. Spring-driven JPA transactions #### +#### 5.4.3. Spring-driven JPA transactions | |We strongly encourage you to read [Declarative Transaction Management](#transaction-declarative), if you have not
already done so, to get more detailed coverage of Spring’s declarative transaction support.| |---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| @@ -7831,7 +7612,7 @@ See the [next section](#orm-jpa-dialect) for details on the `JpaDialect` mechani | |As an immediate alternative, Spring’s native `HibernateTransactionManager` is capable
of interacting with JPA access code, adapting to several Hibernate specifics and providing
JDBC interaction. This makes particular sense in combination with `LocalSessionFactoryBean`setup. See [Native Hibernate Setup for JPA Interaction](#orm-jpa-hibernate) for details.| |---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#orm-jpa-dialect)5.4.4. Understanding `JpaDialect` and `JpaVendorAdapter` #### +#### 5.4.4. Understanding `JpaDialect` and `JpaVendorAdapter` As an advanced feature, `JpaTransactionManager` and subclasses of`AbstractEntityManagerFactoryBean` allow a custom `JpaDialect` to be passed into the`jpaDialect` bean property. A `JpaDialect` implementation can enable the following advanced features supported by Spring, usually in a vendor-specific manner: @@ -7854,7 +7635,7 @@ to specify the appropriate dialect. See the [`JpaDialect`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/orm/jpa/JpaDialect.html) and[`JpaVendorAdapter`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/orm/jpa/JpaVendorAdapter.html) javadoc for more details of its operations and how they are used within Spring’s JPA support. -#### [](#orm-jpa-jta)5.4.5. Setting up JPA with JTA Transaction Management #### +#### 5.4.5. Setting up JPA with JTA Transaction Management As an alternative to `JpaTransactionManager`, Spring also allows for multi-resource transaction coordination through JTA, either in a Java EE environment or with a @@ -7881,7 +7662,7 @@ steps: server itself (that is, through a JNDI lookup instead of a locally declared`LocalContainerEntityManagerFactoryBean`). A server-provided `EntityManagerFactory`might require special definitions in your server configuration (making the deployment less portable) but is set up for the server’s JTA environment. -#### [](#orm-jpa-hibernate)5.4.6. Native Hibernate Setup and Native Hibernate Transactions for JPA Interaction #### +#### 5.4.6. Native Hibernate Setup and Native Hibernate Transactions for JPA Interaction A native `LocalSessionFactoryBean` setup in combination with `HibernateTransactionManager`allows for interaction with `@PersistenceContext` and other JPA access code. A Hibernate`SessionFactory` natively implements JPA’s `EntityManagerFactory` interface now and a Hibernate `Session` handle natively is a JPA `EntityManager`. @@ -7902,10 +7683,9 @@ seamlessly integrating with `@Bean` style configuration (no `FactoryBean` involv | |`LocalSessionFactoryBean` and `LocalSessionFactoryBuilder` support background
bootstrapping, just as the JPA `LocalContainerEntityManagerFactoryBean` does.
See [Background Bootstrapping](#orm-jpa-setup-background) for an introduction.

On `LocalSessionFactoryBean`, this is available through the `bootstrapExecutor`property. On the programmatic `LocalSessionFactoryBuilder`, an overloaded`buildSessionFactory` method takes a bootstrap executor argument.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -[](#oxm)6. Marshalling XML by Using Object-XML Mappers ----------- +## 6. Marshalling XML by Using Object-XML Mappers -### [](#oxm-introduction)6.1. Introduction ### +### 6.1. Introduction This chapter, describes Spring’s Object-XML Mapping support. Object-XML Mapping (O-X mapping for short) is the act of converting an XML document to and from @@ -7925,7 +7705,7 @@ Some of the benefits of using Spring for your O/X mapping needs are: * [Consistent Exception Hierarchy](#oxm-consistent-exception-hierarchy) -#### [](#oxm-ease-of-configuration)6.1.1. Ease of configuration #### +#### 6.1.1. Ease of configuration Spring’s bean factory makes it easy to configure marshallers, without needing to construct JAXB context, JiBX binding factories, and so on. You can configure the marshallers @@ -7933,7 +7713,7 @@ as you would any other bean in your application context. Additionally, XML names configuration is available for a number of marshallers, making the configuration even simpler. -#### [](#oxm-consistent-interfaces)6.1.2. Consistent Interfaces #### +#### 6.1.2. Consistent Interfaces Spring’s O-X mapping operates through two global interfaces: [`Marshaller`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/oxm/Marshaller.html) and[`Unmarshaller`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/oxm/Unmarshaller.html). These abstractions let you switch O-X mapping frameworks with relative ease, with little or no change required on the classes that do the @@ -7942,19 +7722,19 @@ marshalling with a mix-and-match approach (for example, some marshalling perform and some by XStream) in a non-intrusive fashion, letting you use the strength of each technology. -#### [](#oxm-consistent-exception-hierarchy)6.1.3. Consistent Exception Hierarchy #### +#### 6.1.3. Consistent Exception Hierarchy Spring provides a conversion from exceptions from the underlying O-X mapping tool to its own exception hierarchy with the `XmlMappingException` as the root exception. These runtime exceptions wrap the original exception so that no information is lost. -### [](#oxm-marshaller-unmarshaller)6.2. `Marshaller` and `Unmarshaller` ### +### 6.2. `Marshaller` and `Unmarshaller` As stated in the [introduction](#oxm-introduction), a marshaller serializes an object to XML, and an unmarshaller deserializes XML stream to an object. This section describes the two Spring interfaces used for this purpose. -#### [](#oxm-marshaller)6.2.1. Understanding `Marshaller` #### +#### 6.2.1. Understanding `Marshaller` Spring abstracts all marshalling operations behind the`org.springframework.oxm.Marshaller` interface, the main method of which follows: @@ -7982,7 +7762,7 @@ representations, as the following table indicates: | |Although the `marshal()` method accepts a plain object as its first parameter, most`Marshaller` implementations cannot handle arbitrary objects. Instead, an object class
must be mapped in a mapping file, be marked with an annotation, be registered with the
marshaller, or have a common base class. Refer to the later sections in this chapter
to determine how your O-X technology manages this.| |---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#oxm-unmarshaller)6.2.2. Understanding `Unmarshaller` #### +#### 6.2.2. Understanding `Unmarshaller` Similar to the `Marshaller`, we have the `org.springframework.oxm.Unmarshaller`interface, which the following listing shows: @@ -8010,7 +7790,7 @@ Even though there are two separate marshalling interfaces (`Marshaller` and`Unma This means that you can wire up one marshaller class and refer to it both as a marshaller and as an unmarshaller in your `applicationContext.xml`. -#### [](#oxm-xmlmappingexception)6.2.3. Understanding `XmlMappingException` #### +#### 6.2.3. Understanding `XmlMappingException` Spring converts exceptions from the underlying O-X mapping tool to its own exception hierarchy with the `XmlMappingException` as the root exception. @@ -8023,7 +7803,7 @@ The O-X Mapping exception hierarchy is shown in the following figure: ![oxm exceptions](images/oxm-exceptions.png) -### [](#oxm-usage)6.3. Using `Marshaller` and `Unmarshaller` ### +### 6.3. Using `Marshaller` and `Unmarshaller` You can use Spring’s OXM for a wide variety of situations. In the following example, we use it to marshal the settings of a Spring-managed application as an XML file. In the following example, we @@ -8161,7 +7941,7 @@ This sample application produces the following `settings.xml` file: ``` -### [](#oxm-schema-based-config)6.4. XML Configuration Namespace ### +### 6.4. XML Configuration Namespace You can configure marshallers more concisely by using tags from the OXM namespace. To make these tags available, you must first reference the appropriate schema in the @@ -8194,7 +7974,7 @@ the configuration of a JAXB2 marshaller might resemble the following: ``` -### [](#oxm-jaxb)6.5. JAXB ### +### 6.5. JAXB The JAXB binding compiler translates a W3C XML Schema into one or more Java classes, a`jaxb.properties` file, and possibly some resource files. JAXB also offers a way to generate a schema from annotated Java classes. @@ -8202,7 +7982,7 @@ generate a schema from annotated Java classes. Spring supports the JAXB 2.0 API as XML marshalling strategies, following the`Marshaller` and `Unmarshaller` interfaces described in [`Marshaller` and `Unmarshaller`](#oxm-marshaller-unmarshaller). The corresponding integration classes reside in the `org.springframework.oxm.jaxb`package. -#### [](#oxm-jaxb2)6.5.1. Using `Jaxb2Marshaller` #### +#### 6.5.1. Using `Jaxb2Marshaller` The `Jaxb2Marshaller` class implements both of Spring’s `Marshaller` and `Unmarshaller`interfaces. It requires a context path to operate. You can set the context path by setting the`contextPath` property. The context path is a list of colon-separated Java package names that contain schema derived classes. It also offers a `classesToBeBound` property, @@ -8226,7 +8006,7 @@ validation is performed by specifying one or more schema resources to the bean, ``` -##### [](#oxm-jaxb2-xsd)XML Configuration Namespace ##### +##### XML Configuration Namespace The `jaxb2-marshaller` element configures a `org.springframework.oxm.jaxb.Jaxb2Marshaller`, as the following example shows: @@ -8252,7 +8032,7 @@ The following table describes the available attributes: | `id` |The ID of the marshaller| No | |`contextPath`| The JAXB Context path | No | -### [](#oxm-jibx)6.6. JiBX ### +### 6.6. JiBX The JiBX framework offers a solution similar to that which Hibernate provides for ORM: A binding definition defines the rules for how your Java objects are converted to or from @@ -8263,7 +8043,7 @@ from or to XML. For more information on JiBX, see the [JiBX web site](http://jibx.sourceforge.net/). The Spring integration classes reside in the `org.springframework.oxm.jibx`package. -#### [](#oxm-jibx-marshaller)6.6.1. Using `JibxMarshaller` #### +#### 6.6.1. Using `JibxMarshaller` The `JibxMarshaller` class implements both the `Marshaller` and `Unmarshaller`interface. To operate, it requires the name of the class to marshal in, which you can set using the `targetClass` property. Optionally, you can set the binding name by setting the`bindingName` property. In the following example, we bind the `Flights` class: @@ -8280,7 +8060,7 @@ set using the `targetClass` property. Optionally, you can set the binding name b A `JibxMarshaller` is configured for a single class. If you want to marshal multiple classes, you have to configure multiple `JibxMarshaller` instances with different `targetClass`property values. -##### [](#oxm-jibx-xsd)XML Configuration Namespace ##### +##### XML Configuration Namespace The `jibx-marshaller` tag configures a `org.springframework.oxm.jibx.JibxMarshaller`, as the following example shows: @@ -8297,7 +8077,7 @@ The following table describes the available attributes: |`target-class`| The target class for this marshaller | Yes | |`bindingName` |The binding name used by this marshaller| No | -### [](#oxm-xstream)6.7. XStream ### +### 6.7. XStream XStream is a simple library to serialize objects to XML and back again. It does not require any mapping and generates clean XML. @@ -8305,7 +8085,7 @@ require any mapping and generates clean XML. For more information on XStream, see the [XStream web site](https://x-stream.github.io/). The Spring integration classes reside in the`org.springframework.oxm.xstream` package. -#### [](#oxm-xstream-marshaller)6.7.1. Using `XStreamMarshaller` #### +#### 6.7.1. Using `XStreamMarshaller` The `XStreamMarshaller` does not require any configuration and can be configured in an application context directly. To further customize the XML, you can set an alias map, @@ -8330,10 +8110,9 @@ which consists of string aliases mapped to classes, as the following example sho | |Note that XStream is an XML serialization library, not a data binding library.
Therefore, it has limited namespace support. As a result, it is rather unsuitable for usage
within Web Services.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -[](#appendix)7. Appendix ----------- +## 7. Appendix -### [](#xsd-schemas)7.1. XML Schemas ### +### 7.1. XML Schemas This part of the appendix lists XML schemas for data access, including the following: @@ -8341,7 +8120,7 @@ This part of the appendix lists XML schemas for data access, including the follo * [The `jdbc` Schema](#xsd-schemas-jdbc) -#### [](#xsd-schemas-tx)7.1.1. The `tx` Schema #### +#### 7.1.1. The `tx` Schema The `tx` tags deal with configuring all of those beans in Spring’s comprehensive support for transactions. These tags are covered in the chapter entitled[Transaction Management](#transaction). @@ -8377,7 +8156,7 @@ are available to you: | |Often, when you use the elements in the `tx` namespace, you are also using the
elements from the `aop` namespace (since the declarative transaction support in Spring is
implemented by using AOP). The preceding XML snippet contains the relevant lines needed
to reference the `aop` schema so that the elements in the `aop` namespace are available
to you.| |---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#xsd-schemas-jdbc)7.1.2. The `jdbc` Schema #### +#### 7.1.2. The `jdbc` Schema The `jdbc` elements let you quickly configure an embedded database or initialize an existing data source. These elements are documented in[Embedded Database Support](#jdbc-embedded-database-support) and[Initializing a DataSource](#jdbc-initializing-datasource), respectively. diff --git a/docs/en/spring-framework/integration.md b/docs/en/spring-framework/integration.md index d90b025..f394e20 100644 --- a/docs/en/spring-framework/integration.md +++ b/docs/en/spring-framework/integration.md @@ -1,222 +1,9 @@ -Integration -========== - -version 5.3.16 - -Table of Contents - -* [1. REST Endpoints](#rest-client-access) - * [1.1. `RestTemplate`](#rest-resttemplate) - * [1.1.1. Initialization](#rest-resttemplate-create) - * [URIs](#rest-resttemplate-uri) - * [Headers](#rest-template-headers) - - * [1.1.2. Body](#rest-template-body) - * [1.1.3. Message Conversion](#rest-message-conversion) - * [1.1.4. Jackson JSON Views](#rest-template-jsonview) - * [Multipart](#rest-template-multipart) - - * [1.2. Using `AsyncRestTemplate` (Deprecated)](#rest-async-resttemplate) - -* [2. Remoting and Web Services](#remoting) - * [2.1. AMQP](#remoting-amqp) - * [2.2. Considerations when Choosing a Technology](#remoting-considerations) - * [2.3. Java Web Services](#remoting-web-services) - * [2.3.1. Exposing Servlet-based Web Services by Using JAX-WS](#remoting-web-services-jaxws-export-servlet) - * [2.3.2. Exporting Standalone Web Services by Using JAX-WS](#remoting-web-services-jaxws-export-standalone) - * [2.3.3. Exporting Web Services by Using JAX-WS RI’s Spring Support](#remoting-web-services-jaxws-export-ri) - * [2.3.4. Accessing Web Services by Using JAX-WS](#remoting-web-services-jaxws-access) - - * [2.4. RMI (Deprecated)](#remoting-rmi) - * [2.4.1. Exporting the Service by Using `RmiServiceExporter`](#remoting-rmi-server) - * [2.4.2. Linking in the Service at the Client](#remoting-rmi-client) - - * [2.5. Using Hessian to Remotely Call Services through HTTP (Deprecated)](#remoting-caucho-protocols) - * [2.5.1. Hessian](#remoting-caucho-protocols-hessian) - * [2.5.2. Exposing Your Beans by Using `HessianServiceExporter`](#remoting-caucho-protocols-hessian-server) - * [2.5.3. Linking in the Service on the Client](#remoting-caucho-protocols-hessian-client) - * [2.5.4. Applying HTTP Basic Authentication to a Service Exposed through Hessian](#remoting-caucho-protocols-security) - - * [2.6. Spring HTTP Invoker (Deprecated)](#remoting-httpinvoker) - * [2.6.1. Exposing the Service Object](#remoting-httpinvoker-server) - * [2.6.2. Linking in the Service at the Client](#remoting-httpinvoker-client) - - * [2.7. JMS (Deprecated)](#remoting-jms) - * [2.7.1. Server-side Configuration](#remoting-jms-server) - * [2.7.2. Client-side Configuration](#remoting-jms-client) - -* [3. Enterprise JavaBeans (EJB) Integration](#ejb) - * [3.1. Accessing EJBs](#ejb-access) - * [3.1.1. Concepts](#ejb-access-concepts) - * [3.1.2. Accessing Local SLSBs](#ejb-access-local) - * [3.1.3. Accessing Remote SLSBs](#ejb-access-remote) - * [3.1.4. Accessing EJB 2.x SLSBs Versus EJB 3 SLSBs](#ejb-access-ejb2-ejb3) - -* [4. JMS (Java Message Service)](#jms) - * [4.1. Using Spring JMS](#jms-using) - * [4.1.1. Using `JmsTemplate`](#jms-jmstemplate) - * [4.1.2. Connections](#jms-connections) - * [Caching Messaging Resources](#jms-caching-resources) - * [Using `SingleConnectionFactory`](#jms-connection-factory) - * [Using `CachingConnectionFactory`](#jdbc-connection-factory-caching) - - * [4.1.3. Destination Management](#jms-destinations) - * [4.1.4. Message Listener Containers](#jms-mdp) - * [Using `SimpleMessageListenerContainer`](#jms-mdp-simple) - * [Using `DefaultMessageListenerContainer`](#jms-mdp-default) - - * [4.1.5. Transaction Management](#jms-tx) - - * [4.2. Sending a Message](#jms-sending) - * [4.2.1. Using Message Converters](#jms-msg-conversion) - * [4.2.2. Using `SessionCallback` and `ProducerCallback`](#jms-callbacks) - - * [4.3. Receiving a Message](#jms-receiving) - * [4.3.1. Synchronous Reception](#jms-receiving-sync) - * [4.3.2. Asynchronous reception: Message-Driven POJOs](#jms-receiving-async) - * [4.3.3. Using the `SessionAwareMessageListener` Interface](#jms-receiving-async-session-aware-message-listener) - * [4.3.4. Using `MessageListenerAdapter`](#jms-receiving-async-message-listener-adapter) - * [4.3.5. Processing Messages Within Transactions](#jms-tx-participation) - - * [4.4. Support for JCA Message Endpoints](#jms-jca-message-endpoint-manager) - * [4.5. Annotation-driven Listener Endpoints](#jms-annotated) - * [4.5.1. Enable Listener Endpoint Annotations](#jms-annotated-support) - * [4.5.2. Programmatic Endpoint Registration](#jms-annotated-programmatic-registration) - * [4.5.3. Annotated Endpoint Method Signature](#jms-annotated-method-signature) - * [4.5.4. Response Management](#jms-annotated-response) - - * [4.6. JMS Namespace Support](#jms-namespace) - -* [5. JMX](#jmx) - * [5.1. Exporting Your Beans to JMX](#jmx-exporting) - * [5.1.1. Creating an MBeanServer](#jmx-exporting-mbeanserver) - * [5.1.2. Reusing an Existing `MBeanServer`](#jmx-mbean-server) - * [5.1.3. Lazily Initialized MBeans](#jmx-exporting-lazy) - * [5.1.4. Automatic Registration of MBeans](#jmx-exporting-auto) - * [5.1.5. Controlling the Registration Behavior](#jmx-exporting-registration-behavior) - - * [5.2. Controlling the Management Interface of Your Beans](#jmx-interface) - * [5.2.1. Using the `MBeanInfoAssembler` Interface](#jmx-interface-assembler) - * [5.2.2. Using Source-level Metadata: Java Annotations](#jmx-interface-metadata) - * [5.2.3. Source-level Metadata Types](#jmx-interface-metadata-types) - * [5.2.4. Using the `AutodetectCapableMBeanInfoAssembler` Interface](#jmx-interface-autodetect) - * [5.2.5. Defining Management Interfaces by Using Java Interfaces](#jmx-interface-java) - * [5.2.6. Using `MethodNameBasedMBeanInfoAssembler`](#jmx-interface-methodnames) - - * [5.3. Controlling `ObjectName` Instances for Your Beans](#jmx-naming) - * [5.3.1. Reading `ObjectName` Instances from Properties](#jmx-naming-properties) - * [5.3.2. Using `MetadataNamingStrategy`](#jmx-naming-metadata) - * [5.3.3. Configuring Annotation-based MBean Export](#jmx-context-mbeanexport) - - * [5.4. Using JSR-160 Connectors](#jmx-jsr160) - * [5.4.1. Server-side Connectors](#jmx-jsr160-server) - * [5.4.2. Client-side Connectors](#jmx-jsr160-client) - * [5.4.3. JMX over Hessian or SOAP](#jmx-jsr160-protocols) - - * [5.5. Accessing MBeans through Proxies](#jmx-proxy) - * [5.6. Notifications](#jmx-notifications) - * [5.6.1. Registering Listeners for Notifications](#jmx-notifications-listeners) - * [5.6.2. Publishing Notifications](#jmx-notifications-publishing) - - * [5.7. Further Resources](#jmx-resources) - -* [6. Email](#mail) - * [6.1. Usage](#mail-usage) - * [6.1.1. Basic `MailSender` and `SimpleMailMessage` Usage](#mail-usage-simple) - * [6.1.2. Using `JavaMailSender` and `MimeMessagePreparator`](#mail-usage-mime) - - * [6.2. Using the JavaMail `MimeMessageHelper`](#mail-javamail-mime) - * [6.2.1. Sending Attachments and Inline Resources](#mail-javamail-mime-attachments) - * [Attachments](#mail-javamail-mime-attachments-attachment) - * [Inline Resources](#mail-javamail-mime-attachments-inline) - - * [6.2.2. Creating Email Content by Using a Templating Library](#mail-templates) - -* [7. Task Execution and Scheduling](#scheduling) - * [7.1. The Spring `TaskExecutor` Abstraction](#scheduling-task-executor) - * [7.1.1. `TaskExecutor` Types](#scheduling-task-executor-types) - * [7.1.2. Using a `TaskExecutor`](#scheduling-task-executor-usage) - - * [7.2. The Spring `TaskScheduler` Abstraction](#scheduling-task-scheduler) - * [7.2.1. `Trigger` Interface](#scheduling-trigger-interface) - * [7.2.2. `Trigger` Implementations](#scheduling-trigger-implementations) - * [7.2.3. `TaskScheduler` implementations](#scheduling-task-scheduler-implementations) - - * [7.3. Annotation Support for Scheduling and Asynchronous Execution](#scheduling-annotation-support) - * [7.3.1. Enable Scheduling Annotations](#scheduling-enable-annotation-support) - * [7.3.2. The `@Scheduled` annotation](#scheduling-annotation-support-scheduled) - * [7.3.3. The `@Async` annotation](#scheduling-annotation-support-async) - * [7.3.4. Executor Qualification with `@Async`](#scheduling-annotation-support-qualification) - * [7.3.5. Exception Management with `@Async`](#scheduling-annotation-support-exception) - - * [7.4. The `task` Namespace](#scheduling-task-namespace) - * [7.4.1. The 'scheduler' Element](#scheduling-task-namespace-scheduler) - * [7.4.2. The `executor` Element](#scheduling-task-namespace-executor) - * [7.4.3. The 'scheduled-tasks' Element](#scheduling-task-namespace-scheduled-tasks) - - * [7.5. Cron Expressions](#scheduling-cron-expression) - * [7.5.1. Macros](#macros) - - * [7.6. Using the Quartz Scheduler](#scheduling-quartz) - * [7.6.1. Using the `JobDetailFactoryBean`](#scheduling-quartz-jobdetail) - * [7.6.2. Using the `MethodInvokingJobDetailFactoryBean`](#scheduling-quartz-method-invoking-job) - * [7.6.3. Wiring up Jobs by Using Triggers and `SchedulerFactoryBean`](#scheduling-quartz-cron) - -* [8. Cache Abstraction](#cache) - * [8.1. Understanding the Cache Abstraction](#cache-strategies) - * [8.2. Declarative Annotation-based Caching](#cache-annotations) - * [8.2.1. The `@Cacheable` Annotation](#cache-annotations-cacheable) - * [Default Key Generation](#cache-annotations-cacheable-default-key) - * [Custom Key Generation Declaration](#cache-annotations-cacheable-key) - * [Default Cache Resolution](#cache-annotations-cacheable-default-cache-resolver) - * [Custom Cache Resolution](#cache-annotations-cacheable-cache-resolver) - * [Synchronized Caching](#cache-annotations-cacheable-synchronized) - * [Conditional Caching](#cache-annotations-cacheable-condition) - * [Available Caching SpEL Evaluation Context](#cache-spel-context) - - * [8.2.2. The `@CachePut` Annotation](#cache-annotations-put) - * [8.2.3. The `@CacheEvict` annotation](#cache-annotations-evict) - * [8.2.4. The `@Caching` Annotation](#cache-annotations-caching) - * [8.2.5. The `@CacheConfig` annotation](#cache-annotations-config) - * [8.2.6. Enabling Caching Annotations](#cache-annotation-enable) - * [8.2.7. Using Custom Annotations](#cache-annotation-stereotype) - - * [8.3. JCache (JSR-107) Annotations](#cache-jsr-107) - * [8.3.1. Feature Summary](#cache-jsr-107-summary) - * [8.3.2. Enabling JSR-107 Support](#enabling-jsr-107-support) - - * [8.4. Declarative XML-based Caching](#cache-declarative-xml) - * [8.5. Configuring the Cache Storage](#cache-store-configuration) - * [8.5.1. JDK `ConcurrentMap`-based Cache](#cache-store-configuration-jdk) - * [8.5.2. Ehcache-based Cache](#cache-store-configuration-ehcache) - * [8.5.3. Caffeine Cache](#cache-store-configuration-caffeine) - * [8.5.4. GemFire-based Cache](#cache-store-configuration-gemfire) - * [8.5.5. JSR-107 Cache](#cache-store-configuration-jsr107) - * [8.5.6. Dealing with Caches without a Backing Store](#cache-store-configuration-noop) - - * [8.6. Plugging-in Different Back-end Caches](#cache-plug) - * [8.7. How can I Set the TTL/TTI/Eviction policy/XXX feature?](#cache-specific-config) - -* [9. Appendix](#appendix) - * [9.1. XML Schemas](#xsd-schemas) - * [9.1.1. The `jee` Schema](#xsd-schemas-jee) - * [\ (simple)](#xsd-schemas-jee-jndi-lookup) - * [`` (with Single JNDI Environment Setting)](#xsd-schemas-jee-jndi-lookup-environment-single) - * [`` (with Multiple JNDI Environment Settings)](#xsd-schemas-jee-jndi-lookup-evironment-multiple) - * [`` (Complex)](#xsd-schemas-jee-jndi-lookup-complex) - * [`` (Simple)](#xsd-schemas-jee-local-slsb) - * [`` (Complex)](#xsd-schemas-jee-local-slsb-complex) - * [\](#xsd-schemas-jee-remote-slsb) - - * [9.1.2. The `jms` Schema](#xsd-schemas-jms) - * [9.1.3. Using ``](#xsd-schemas-context-mbe) - * [9.1.4. The `cache` Schema](#xsd-schemas-cache) +# Integration This part of the reference documentation covers Spring Framework’s integration with a number of technologies. -[](#rest-client-access)1. REST Endpoints ----------- +## 1. REST Endpoints The Spring Framework provides two choices for making calls to REST endpoints: @@ -229,7 +16,7 @@ The Spring Framework provides two choices for making calls to REST endpoints: | |As of 5.0 the `RestTemplate` is in maintenance mode, with only minor requests for
changes and bugs to be accepted going forward. Please, consider using the[WebClient](web-reactive.html#webflux-client) which offers a more modern API and
supports sync, async, and streaming scenarios.| |---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -### [](#rest-resttemplate)1.1. `RestTemplate` ### +### 1.1. `RestTemplate` The `RestTemplate` provides a higher level API over HTTP client libraries. It makes it easy to invoke REST endpoints in a single line. It exposes the following groups of @@ -250,7 +37,7 @@ overloaded methods: | `exchange` |More generalized (and less opinionated) version of the preceding methods that provides extra
flexibility when needed. It accepts a `RequestEntity` (including HTTP method, URL, headers,
and body as input) and returns a `ResponseEntity`.

These methods allow the use of `ParameterizedTypeReference` instead of `Class` to specify
a response type with generics.| | `execute` | The most generalized way to perform a request, with full control over request
preparation and response extraction through callback interfaces. | -#### [](#rest-resttemplate-create)1.1.1. Initialization #### +#### 1.1.1. Initialization The default constructor uses `java.net.HttpURLConnection` to perform requests. You can switch to a different HTTP library with an implementation of `ClientHttpRequestFactory`. @@ -274,7 +61,7 @@ HTTP client library — for example, for credentials, connection pooling, an | |Note that the `java.net` implementation for HTTP requests can raise an exception when
accessing the status of a response that represents an error (such as 401). If this is an
issue, switch to another HTTP client library.| |---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#rest-resttemplate-uri)URIs ##### +##### URIs Many of the `RestTemplate` methods accept a URI template and URI template variables, either as a `String` variable argument, or as `Map`. @@ -309,7 +96,7 @@ the `RestTemplate` methods that accepts a `URI`. For more details on working with and encoding URIs, see [URI Links](web.html#mvc-uri-building). -##### [](#rest-template-headers)Headers ##### +##### Headers You can use the `exchange()` methods to specify request headers, as the following example shows: @@ -329,7 +116,7 @@ String body = response.getBody(); You can obtain response headers through many `RestTemplate` method variants that return`ResponseEntity`. -#### [](#rest-template-body)1.1.2. Body #### +#### 1.1.2. Body Objects passed into and returned from `RestTemplate` methods are converted to and from raw content with the help of an `HttpMessageConverter`. @@ -359,7 +146,7 @@ By default, `RestTemplate` registers all built-in[message converters](#rest-mess to determine what optional conversion libraries are present. You can also set the message converters to use explicitly. -#### [](#rest-message-conversion)1.1.3. Message Conversion #### +#### 1.1.3. Message Conversion [WebFlux](web-reactive.html#webflux-codecs) @@ -384,7 +171,7 @@ For all converters, a default media type is used, but you can override it by set | `SourceHttpMessageConverter` | An `HttpMessageConverter` implementation that can read and write`javax.xml.transform.Source` from the HTTP request and response. Only `DOMSource`,`SAXSource`, and `StreamSource` are supported. By default, this converter supports`text/xml` and `application/xml`. | | `BufferedImageHttpMessageConverter` | An `HttpMessageConverter` implementation that can read and write`java.awt.image.BufferedImage` from the HTTP request and response. This converter reads
and writes the media type supported by the Java I/O API. | -#### [](#rest-template-jsonview)1.1.4. Jackson JSON Views #### +#### 1.1.4. Jackson JSON Views You can specify a [Jackson JSON View](https://www.baeldung.com/jackson-json-view-annotation)to serialize only a subset of the object properties, as the following example shows: @@ -398,7 +185,7 @@ RequestEntity requestEntity = ResponseEntity response = template.exchange(requestEntity, String.class); ``` -##### [](#rest-template-multipart)Multipart ##### +##### Multipart To send multipart data, you need to provide a `MultiValueMap` whose values may be an `Object` for part content, a `Resource` for a file part, or an `HttpEntity` for @@ -432,12 +219,11 @@ If the `MultiValueMap` contains at least one non-`String` value, the `Content-Ty to `multipart/form-data` by the `FormHttpMessageConverter`. If the `MultiValueMap` has`String` values the `Content-Type` is defaulted to `application/x-www-form-urlencoded`. If necessary the `Content-Type` may also be set explicitly. -### [](#rest-async-resttemplate)1.2. Using `AsyncRestTemplate` (Deprecated) ### +### 1.2. Using `AsyncRestTemplate` (Deprecated) The `AsyncRestTemplate` is deprecated. For all use cases where you might consider using`AsyncRestTemplate`, use the [WebClient](web-reactive.html#webflux-client) instead. -[](#remoting)2. Remoting and Web Services ----------- +## 2. Remoting and Web Services Spring provides support for remoting with various technologies. The remoting support eases the development of remote-enabled services, implemented @@ -511,7 +297,7 @@ This section starts by exposing the service to a remote client by using RMI and about the drawbacks of using RMI. It then continues with an example that uses Hessian as the protocol. -### [](#remoting-amqp)2.1. AMQP ### +### 2.1. AMQP Remoting via AMQP as the underlying protocol is supported in the Spring AMQP project. For further details please visit the [Spring Remoting](https://docs.spring.io/spring-amqp/docs/current/reference/html/#remoting)section of the Spring AMQP reference. @@ -519,7 +305,7 @@ For further details please visit the [Spring Remoting](https://docs.spring.io/sp | |Auto-detection is not implemented for remote interfaces.

The main reason why auto-detection of implemented interfaces does not occur for remote
interfaces is to avoid opening too many doors to remote callers. The target object might
implement internal callback interfaces, such as `InitializingBean` or `DisposableBean`which one would not want to expose to callers.

Offering a proxy with all interfaces implemented by the target usually does not matter
in the local case. However, when you export a remote service, you should expose a specific
service interface, with specific operations intended for remote usage. Besides internal
callback interfaces, the target might implement multiple business interfaces, with only
one of them intended for remote exposure. For these reasons, we require such a
service interface to be specified.

This is a trade-off between configuration convenience and the risk of accidental
exposure of internal methods. Always specifying a service interface is not too much
effort and puts you on the safe side regarding controlled exposure of specific methods.| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -### [](#remoting-considerations)2.2. Considerations when Choosing a Technology ### +### 2.2. Considerations when Choosing a Technology Each and every technology presented here has its drawbacks. When choosing a technology, you should carefully consider your needs, the services you expose, and the objects you @@ -555,7 +341,7 @@ possible to get RMI invokers or HTTP invokers to support security context propag well, although this is not provided by core Spring. Spring offers only appropriate hooks for plugging in third-party or custom solutions. -### [](#remoting-web-services)2.3. Java Web Services ### +### 2.3. Java Web Services Spring provides full support for the standard Java web services APIs: @@ -568,7 +354,7 @@ features [Spring Web Services](https://projects.spring.io/spring-ws), which is a contract-first, document-driven web services — highly recommended for building modern, future-proof web services. -#### [](#remoting-web-services-jaxws-export-servlet)2.3.1. Exposing Servlet-based Web Services by Using JAX-WS #### +#### 2.3.1. Exposing Servlet-based Web Services by Using JAX-WS Spring provides a convenient base class for JAX-WS servlet endpoint implementations:`SpringBeanAutowiringSupport`. To expose our `AccountService`, we extend Spring’s`SpringBeanAutowiringSupport` class and implement our business logic here, usually delegating the call to the business layer. We use Spring’s `@Autowired`annotation to express such dependencies on Spring-managed beans. The following example @@ -617,7 +403,7 @@ context to allow for access to Spring’s facilities. This is the case by defaul EE environments, using the standard contract for JAX-WS servlet endpoint deployment. See the various Java EE web service tutorials for details. -#### [](#remoting-web-services-jaxws-export-standalone)2.3.2. Exporting Standalone Web Services by Using JAX-WS #### +#### 2.3.2. Exporting Standalone Web Services by Using JAX-WS The built-in JAX-WS provider that comes with Oracle’s JDK supports exposure of web services by using the built-in HTTP server that is also included in the JDK. Spring’s`SimpleJaxWsServiceExporter` detects all `@WebService`-annotated beans in the Spring @@ -666,7 +452,7 @@ public class AccountServiceEndpoint { } ``` -#### [](#remoting-web-services-jaxws-export-ri)2.3.3. Exporting Web Services by Using JAX-WS RI’s Spring Support #### +#### 2.3.3. Exporting Web Services by Using JAX-WS RI’s Spring Support #### Oracle’s JAX-WS RI, developed as part of the GlassFish project, ships Spring support as part of its JAX-WS Commons project. This allows for defining JAX-WS endpoints as @@ -683,7 +469,7 @@ typically delegating to Spring beans (through the use of `@Autowired`, as shown See [https://jax-ws-commons.java.net/spring/](https://jax-ws-commons.java.net/spring/)for details on setup and usage style. -#### [](#remoting-web-services-jaxws-access)2.3.4. Accessing Web Services by Using JAX-WS #### +#### 2.3.4. Accessing Web Services by Using JAX-WS Spring provides two factory beans to create JAX-WS web service proxies, namely`LocalJaxWsServiceFactoryBean` and `JaxWsPortProxyFactoryBean`. The former can return only a JAX-WS service class for us to work with. The latter is the full-fledged @@ -739,7 +525,7 @@ public class AccountClientImpl { | |The above is slightly simplified in that JAX-WS requires endpoint interfaces
and implementation classes to be annotated with `@WebService`, `@SOAPBinding`, etc.
annotations. This means that you cannot (easily) use plain Java interfaces and
implementation classes as JAX-WS endpoint artifacts; you need to annotate them
accordingly first. Check the JAX-WS documentation for details on those requirements.| |---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -### [](#remoting-rmi)2.4. RMI (Deprecated) ### +### 2.4. RMI (Deprecated) | |As of Spring Framework 5.3, RMI support is deprecated and will not be replaced.| |---|-------------------------------------------------------------------------------| @@ -751,7 +537,7 @@ context propagation or remote transaction propagation. Spring does provide hooks such additional invocation context when you use the RMI invoker, so you can, for example, plug in security frameworks or custom security credentials. -#### [](#remoting-rmi-server)2.4.1. Exporting the Service by Using `RmiServiceExporter` #### +#### 2.4.1. Exporting the Service by Using `RmiServiceExporter` Using the `RmiServiceExporter`, we can expose the interface of our AccountService object as RMI object. The interface can be accessed by using `RmiProxyFactoryBean`, or via @@ -790,7 +576,7 @@ the service at the client side. | |The `servicePort` property has been omitted (it defaults to 0). This means that an
anonymous port is used to communicate with the service.| |---|----------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#remoting-rmi-client)2.4.2. Linking in the Service at the Client #### +#### 2.4.2. Linking in the Service at the Client Our client is a simple object that uses the `AccountService` to manage accounts, as the following example shows: @@ -825,7 +611,7 @@ to contain the following simple object and the service linking configuration bit That is all we need to do to support the remote account service on the client. Spring transparently creates an invoker and remotely enables the account service through the`RmiServiceExporter`. At the client, we link it in by using the `RmiProxyFactoryBean`. -### [](#remoting-caucho-protocols)2.5. Using Hessian to Remotely Call Services through HTTP (Deprecated) ### +### 2.5. Using Hessian to Remotely Call Services through HTTP (Deprecated) | |As of Spring Framework 5.3, Hessian support is deprecated and will not be replaced.| |---|-----------------------------------------------------------------------------------| @@ -833,7 +619,7 @@ transparently creates an invoker and remotely enables the account service throug Hessian offers a binary HTTP-based remoting protocol. It is developed by Caucho, and you can find more information about Hessian itself at [https://www.caucho.com/](https://www.caucho.com/). -#### [](#remoting-caucho-protocols-hessian)2.5.1. Hessian #### +#### 2.5.1. Hessian Hessian communicates through HTTP and does so by using a custom servlet. By using Spring’s`DispatcherServlet` principles (see [webmvc.html](webmvc.html#mvc-servlet)), we can wire up such a servlet to expose your services. First, we have to create a new servlet in our application, @@ -862,7 +648,7 @@ default, in `WEB-INF/applicationContext.xml`), with individual servlet definitio pointing to specific exporter beans. In this case, each servlet name needs to match the bean name of its target exporter. -#### [](#remoting-caucho-protocols-hessian-server)2.5.2. Exposing Your Beans by Using `HessianServiceExporter` #### +#### 2.5.2. Exposing Your Beans by Using `HessianServiceExporter` In the newly created application context called `remoting-servlet.xml`, we create a`HessianServiceExporter` to export our services, as the following example shows: @@ -907,7 +693,7 @@ the target exporter. The following example shows how to do so: ``` -#### [](#remoting-caucho-protocols-hessian-client)2.5.3. Linking in the Service on the Client #### +#### 2.5.3. Linking in the Service on the Client By using the `HessianProxyFactoryBean`, we can link in the service at the client. The same principles apply as with the RMI example. We create a separate bean factory or @@ -925,7 +711,7 @@ the `AccountService` to manage accounts, as the following example shows:
``` -#### [](#remoting-caucho-protocols-security)2.5.4. Applying HTTP Basic Authentication to a Service Exposed through Hessian #### +#### 2.5.4. Applying HTTP Basic Authentication to a Service Exposed through Hessian #### One of the advantages of Hessian is that we can easily apply HTTP basic authentication, because both protocols are HTTP-based. Your normal HTTP server security mechanism can @@ -951,7 +737,7 @@ this application context. | |The preceding example does not show a flexible kind of security infrastructure. For
more options as far as security is concerned, have a look at the Spring Security project
at [https://projects.spring.io/spring-security/](https://projects.spring.io/spring-security/).| |---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -### [](#remoting-httpinvoker)2.6. Spring HTTP Invoker (Deprecated) ### +### 2.6. Spring HTTP Invoker (Deprecated) | |As of Spring Framework 5.3, HTTP Invoker support is deprecated and will not be replaced.| |---|----------------------------------------------------------------------------------------| @@ -970,7 +756,7 @@ advanced and easier-to-use functionality, use the latter. See[hc.apache.org/http | |Be aware of vulnerabilities due to unsafe Java deserialization:
Manipulated input streams can lead to unwanted code execution on the server
during the deserialization step. As a consequence, do not expose HTTP invoker
endpoints to untrusted clients. Rather, expose them only between your own services.
In general, we strongly recommend using any other message format (such as JSON) instead.

If you are concerned about security vulnerabilities due to Java serialization,
consider the general-purpose serialization filter mechanism at the core JVM level,
originally developed for JDK 9 but backported to JDK 8, 7 and 6 in the meantime. See[https://blogs.oracle.com/java-platform-group/entry/incoming\_filter\_serialization\_data\_a](https://blogs.oracle.com/java-platform-group/entry/incoming_filter_serialization_data_a)and [https://openjdk.java.net/jeps/290](https://openjdk.java.net/jeps/290).| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#remoting-httpinvoker-server)2.6.1. Exposing the Service Object #### +#### 2.6.1. Exposing the Service Object Setting up the HTTP invoker infrastructure for a service object closely resembles the way you would do the same by using Hessian. As Hessian support provides`HessianServiceExporter`, Spring’s HttpInvoker support provides`org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter`. @@ -1013,7 +799,7 @@ servlet name matching the bean name of the target exporter, as the following exa ``` -#### [](#remoting-httpinvoker-client)2.6.2. Linking in the Service at the Client #### +#### 2.6.2. Linking in the Service at the Client Again, linking in the service from the client much resembles the way you would do it when you use Hessian. By using a proxy, Spring can translate your calls to @@ -1036,7 +822,7 @@ The following example shows how to do so:
``` -### [](#remoting-jms)2.7. JMS (Deprecated) ### +### 2.7. JMS (Deprecated) | |As of Spring Framework 5.3, JMS remoting support is deprecated and will not be replaced.| |---|----------------------------------------------------------------------------------------| @@ -1093,7 +879,7 @@ on both the client and the server: ``` -#### [](#remoting-jms-server)2.7.1. Server-side Configuration #### +#### 2.7.1. Server-side Configuration On the server, you need to expose the service object that uses the`JmsInvokerServiceExporter`, as the following example shows: @@ -1135,7 +921,7 @@ public class Server { } ``` -#### [](#remoting-jms-client)2.7.2. Client-side Configuration #### +#### 2.7.2. Client-side Configuration The client merely needs to create a client-side proxy that implements the agreed-upon interface (`CheckingAccountService`). @@ -1176,8 +962,7 @@ public class Client { } ``` -[](#ejb)3. Enterprise JavaBeans (EJB) Integration ----------- +## 3. Enterprise JavaBeans (EJB) Integration As a lightweight container, Spring is often considered an EJB replacement. We do believe that for many, if not most, applications and use cases, Spring, as a container, combined @@ -1196,11 +981,11 @@ In this chapter, we look at how Spring can help you access and implement EJBs. S provides particular value when accessing stateless session beans (SLSBs), so we begin by discussing this topic. -### [](#ejb-access)3.1. Accessing EJBs ### +### 3.1. Accessing EJBs This section covers how to access EJBs. -#### [](#ejb-access-concepts)3.1.1. Concepts #### +#### 3.1.1. Concepts To invoke a method on a local or remote stateless session bean, client code must normally perform a JNDI lookup to obtain the (local or remote) EJB Home object and then use @@ -1228,7 +1013,7 @@ configured inside a Spring container), which act as codeless business delegates. not write another Service Locator, another JNDI lookup, or duplicate methods in a hand-coded Business Delegate unless you actually add real value in such code. -#### [](#ejb-access-local)3.1.2. Accessing Local SLSBs #### +#### 3.1.2. Accessing Local SLSBs Assume that we have a web controller that needs to use a local EJB. We follow best practice and use the EJB Business Methods Interface pattern, so that the EJB’s local @@ -1323,7 +1108,7 @@ by using the `lazy-init` attribute. Although not of interest to the majority of Spring users, those doing programmatic AOP work with EJBs may want to look at `LocalSlsbInvokerInterceptor`. -#### [](#ejb-access-remote)3.1.3. Accessing Remote SLSBs #### +#### 3.1.3. Accessing Remote SLSBs Accessing remote EJBs is essentially identical to accessing local EJBs, except that the`SimpleRemoteStatelessSessionProxyFactoryBean` or `` configuration element is used. Of course, with or without Spring, remote invocation semantics apply: A @@ -1350,7 +1135,7 @@ between a local EJB or remote EJB (or even plain Java object) implementation, wi the client code knowing or caring. Of course, this is optional: Nothing stops you from declaring `RemoteException` in your business interface. -#### [](#ejb-access-ejb2-ejb3)3.1.4. Accessing EJB 2.x SLSBs Versus EJB 3 SLSBs #### +#### 3.1.4. Accessing EJB 2.x SLSBs Versus EJB 3 SLSBs Accessing EJB 2.x Session Beans and EJB 3 Session Beans through Spring is largely transparent. Spring’s EJB accessors, including the `` and`` facilities, transparently adapt to the actual component at runtime. @@ -1360,8 +1145,7 @@ invocations if no home interface is available (EJB 3 style). Note: For EJB 3 Session Beans, you can effectively use a `JndiObjectFactoryBean` /`` as well, since fully usable component references are exposed for plain JNDI lookups there. Defining explicit `` or ``lookups provides consistent and more explicit EJB access configuration. -[](#jms)4. JMS (Java Message Service) ----------- +## 4. JMS (Java Message Service) Spring provides a JMS integration framework that simplifies the use of the JMS API in much the same way as Spring’s integration does for the JDBC API. @@ -1409,11 +1193,11 @@ resource into Spring’s transaction management mechanisms. | |As of Spring Framework 5, Spring’s JMS package fully supports JMS 2.0 and requires the
JMS 2.0 API to be present at runtime. We recommend the use of a JMS 2.0 compatible provider.

If you happen to use an older message broker in your system, you may try upgrading to a
JMS 2.0 compatible driver for your existing broker generation. Alternatively, you may also
try to run against a JMS 1.1 based driver, simply putting the JMS 2.0 API jar on the
classpath but only using JMS 1.1 compatible API against your driver. Spring’s JMS support
adheres to JMS 1.1 conventions by default, so with corresponding configuration it does
support such a scenario. However, please consider this for transition scenarios only.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -### [](#jms-using)4.1. Using Spring JMS ### +### 4.1. Using Spring JMS This section describes how to use Spring’s JMS components. -#### [](#jms-jmstemplate)4.1.1. Using `JmsTemplate` #### +#### 4.1.1. Using `JmsTemplate` The `JmsTemplate` class is the central class in the JMS core package. It simplifies the use of JMS, since it handles the creation and release of resources when sending or @@ -1448,7 +1232,7 @@ the operation. As of Spring Framework 4.1, `JmsMessagingTemplate` is built on top of `JmsTemplate`and provides an integration with the messaging abstraction — that is,`org.springframework.messaging.Message`. This lets you create the message to send in a generic manner. -#### [](#jms-connections)4.1.2. Connections #### +#### 4.1.2. Connections The `JmsTemplate` requires a reference to a `ConnectionFactory`. The `ConnectionFactory`is part of the JMS specification and serves as the entry point for working with JMS. It is used by the client application as a factory to create connections with the JMS @@ -1462,7 +1246,7 @@ typically require that you declare a JMS connection factory as a `resource-ref` the EJB or servlet deployment descriptors. To ensure the use of these features with the`JmsTemplate` inside an EJB, the client application should ensure that it references the managed implementation of the `ConnectionFactory`. -##### [](#jms-caching-resources)Caching Messaging Resources ##### +##### Caching Messaging Resources The standard API involves creating many intermediate objects. To send a message, the following 'API' walk is performed: @@ -1475,12 +1259,12 @@ Between the `ConnectionFactory` and the `Send` operation, three intermediate objects are created and destroyed. To optimize the resource usage and increase performance, Spring provides two implementations of `ConnectionFactory`. -##### [](#jms-connection-factory)Using `SingleConnectionFactory` ##### +##### Using `SingleConnectionFactory` Spring provides an implementation of the `ConnectionFactory` interface,`SingleConnectionFactory`, that returns the same `Connection` on all`createConnection()` calls and ignores calls to `close()`. This is useful for testing and standalone environments so that the same connection can be used for multiple`JmsTemplate` calls that may span any number of transactions. `SingleConnectionFactory`takes a reference to a standard `ConnectionFactory` that would typically come from JNDI. -##### [](#jdbc-connection-factory-caching)Using `CachingConnectionFactory` ##### +##### Using `CachingConnectionFactory` The `CachingConnectionFactory` extends the functionality of `SingleConnectionFactory`and adds the caching of `Session`, `MessageProducer`, and `MessageConsumer` instances. The initial cache size is set to `1`. You can use the `sessionCacheSize` property to increase the number of @@ -1493,7 +1277,7 @@ consumers when caching. MessageProducers are cached based on their destination. MessageConsumers are cached based on a key composed of the destination, selector, noLocal delivery flag, and the durable subscription name (if creating durable consumers). -#### [](#jms-destinations)4.1.3. Destination Management #### +#### 4.1.3. Destination Management Destinations, as `ConnectionFactory` instances, are JMS administered objects that you can store and retrieve in JNDI. When configuring a Spring application context, you can use the @@ -1532,7 +1316,7 @@ You can also configure the `JmsTemplate` with a default destination through the property `defaultDestination`. The default destination is with send and receive operations that do not refer to a specific destination. -#### [](#jms-mdp)4.1.4. Message Listener Containers #### +#### 4.1.4. Message Listener Containers One of the most common uses of JMS messages in the EJB world is to drive message-driven beans (MDBs). Spring offers a solution to create message-driven POJOs (MDPs) in a way @@ -1557,7 +1341,7 @@ its specialized feature set. * [`DefaultMessageListenerContainer`](#jms-mdp-default) -##### [](#jms-mdp-simple)Using `SimpleMessageListenerContainer` ##### +##### Using `SimpleMessageListenerContainer` This message listener container is the simpler of the two standard flavors. It creates a fixed number of JMS sessions and consumers at startup, registers the listener by using @@ -1573,7 +1357,7 @@ specification, but is generally not compatible with Java EE’s JMS restrictions | |The default `AUTO_ACKNOWLEDGE` mode does not provide proper reliability guarantees.
Messages can get lost when listener execution fails (since the provider automatically
acknowledges each message after listener invocation, with no exceptions to be propagated to
the provider) or when the listener container shuts down (you can configure this by setting
the `acceptMessagesWhileStopping` flag). Make sure to use transacted sessions in case of
reliability needs (for example, for reliable queue handling and durable topic subscriptions).| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#jms-mdp-default)Using `DefaultMessageListenerContainer` ##### +##### Using `DefaultMessageListenerContainer` This message listener container is used in most cases. In contrast to`SimpleMessageListenerContainer`, this container variant allows for dynamic adaptation to runtime demands and is able to participate in externally managed transactions. @@ -1597,7 +1381,7 @@ a custom `BackOff` implementation for more fine-grained recovery options. See[`E | |The default `AUTO_ACKNOWLEDGE` mode does not provide proper reliability guarantees.
Messages can get lost when listener execution fails (since the provider automatically
acknowledges each message after listener invocation, with no exceptions to be propagated to
the provider) or when the listener container shuts down (you can configure this by setting
the `acceptMessagesWhileStopping` flag). Make sure to use transacted sessions in case of
reliability needs (for example, for reliable queue handling and durable topic subscriptions).| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#jms-tx)4.1.5. Transaction Management #### +#### 4.1.5. Transaction Management Spring provides a `JmsTransactionManager` that manages transactions for a single JMS`ConnectionFactory`. This lets JMS applications leverage the managed-transaction features of Spring, as described in[Transaction Management section of the Data Access chapter](data-access.html#transaction). @@ -1624,7 +1408,7 @@ are ignored by the vendor’s wrapper to the JMS Connection. When you use the `J properties `sessionTransacted` and `sessionAcknowledgeMode`. When you use a`PlatformTransactionManager` with `JmsTemplate`, the template is always given a transactional JMS `Session`. -### [](#jms-sending)4.2. Sending a Message ### +### 4.2. Sending a Message The `JmsTemplate` contains many convenience methods to send a message. Send methods specify the destination by using a `javax.jms.Destination` object, and others @@ -1678,7 +1462,7 @@ you should set the `destinationResolver` property of the template to an instance If you created the `JmsTemplate` and specified a default destination, the`send(MessageCreator c)` sends a message to that destination. -#### [](#jms-msg-conversion)4.2.1. Using Message Converters #### +#### 4.2.1. Using Message Converters To facilitate the sending of domain model objects, the `JmsTemplate` has various send methods that take a Java object as an argument for a message’s data @@ -1731,17 +1515,17 @@ MapMessage={ } ``` -#### [](#jms-callbacks)4.2.2. Using `SessionCallback` and `ProducerCallback` #### +#### 4.2.2. Using `SessionCallback` and `ProducerCallback` While the send operations cover many common usage scenarios, you might sometimes want to perform multiple operations on a JMS `Session` or `MessageProducer`. The`SessionCallback` and `ProducerCallback` expose the JMS `Session` and `Session` /`MessageProducer` pair, respectively. The `execute()` methods on `JmsTemplate` run these callback methods. -### [](#jms-receiving)4.3. Receiving a Message ### +### 4.3. Receiving a Message This describes how to receive messages with JMS in Spring. -#### [](#jms-receiving-sync)4.3.1. Synchronous Reception #### +#### 4.3.1. Synchronous Reception While JMS is typically associated with asynchronous processing, you can consume messages synchronously. The overloaded `receive(..)` methods provide this @@ -1750,7 +1534,7 @@ becomes available. This can be a dangerous operation, since the calling thread c potentially be blocked indefinitely. The `receiveTimeout` property specifies how long the receiver should wait before giving up waiting for a message. -#### [](#jms-receiving-async)4.3.2. Asynchronous reception: Message-Driven POJOs #### +#### 4.3.2. Asynchronous reception: Message-Driven POJOs | |Spring also supports annotated-listener endpoints through the use of the `@JmsListener`annotation and provides an open infrastructure to register endpoints programmatically.
This is, by far, the most convenient way to setup an asynchronous receiver.
See [Enable Listener Endpoint Annotations](#jms-annotated-support) for more details.| |---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| @@ -1807,7 +1591,7 @@ containers that ships with Spring (in this case, `DefaultMessageListenerContaine See the Spring javadoc of the various message listener containers (all of which implement[MessageListenerContainer](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/jms/listener/MessageListenerContainer.html)) for a full description of the features supported by each implementation. -#### [](#jms-receiving-async-session-aware-message-listener)4.3.3. Using the `SessionAwareMessageListener` Interface #### +#### 4.3.3. Using the `SessionAwareMessageListener` Interface #### The `SessionAwareMessageListener` interface is a Spring-specific interface that provides a similar contract to the JMS `MessageListener` interface but also gives the message-handling @@ -1833,7 +1617,7 @@ as an application developer or architect. Note that the `onMessage(..)` method of the `SessionAwareMessageListener`interface throws `JMSException`. In contrast to the standard JMS `MessageListener`interface, when using the `SessionAwareMessageListener` interface, it is the responsibility of the client code to handle any thrown exceptions. -#### [](#jms-receiving-async-message-listener-adapter)4.3.4. Using `MessageListenerAdapter` #### +#### 4.3.4. Using `MessageListenerAdapter` The `MessageListenerAdapter` class is the final component in Spring’s asynchronous messaging support. In a nutshell, it lets you expose almost any class as an MDP @@ -1947,7 +1731,7 @@ If no `Destination` is found, an `InvalidDestinationException` is thrown (note that this exception is not swallowed and propagates up the call stack). -#### [](#jms-tx-participation)4.3.5. Processing Messages Within Transactions #### +#### 4.3.5. Processing Messages Within Transactions Invoking a message listener within a transaction requires only reconfiguration of the listener container. @@ -2005,7 +1789,7 @@ takes care of the rest. The following example shows how to do so: |**1**|Our transaction manager.| |-----|------------------------| -### [](#jms-jca-message-endpoint-manager)4.4. Support for JCA Message Endpoints ### +### 4.4. Support for JCA Message Endpoints Beginning with version 2.5, Spring also provides support for a JCA-based`MessageListener` container. The `JmsMessageEndpointManager` tries to automatically determine the `ActivationSpec` class name from the provider’s`ResourceAdapter` class name. Therefore, it is typically possible to provide @@ -2074,7 +1858,7 @@ find out about the actual capabilities of your connector, and see the[`GenericMe | |JCA-based message endpoint management is very analogous to EJB 2.1 Message-Driven Beans.
It uses the same underlying resource provider contract. As with EJB 2.1 MDBs, you can use any
message listener interface supported by your JCA provider in the Spring context as well.
Spring nevertheless provides explicit “convenience” support for JMS, because JMS is the
most common endpoint API used with the JCA endpoint management contract.| |---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -### [](#jms-annotated)4.5. Annotation-driven Listener Endpoints ### +### 4.5. Annotation-driven Listener Endpoints The easiest way to receive a message asynchronously is to use the annotated listener endpoint infrastructure. In a nutshell, it lets you expose a method of a managed @@ -2101,7 +1885,7 @@ located for management purposes by using the `JmsListenerEndpointRegistry` bean. | |`@JmsListener` is a repeatable annotation on Java 8, so you can associate
several JMS destinations with the same method by adding additional `@JmsListener`declarations to it.| |---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#jms-annotated-support)4.5.1. Enable Listener Endpoint Annotations #### +#### 4.5.1. Enable Listener Endpoint Annotations To enable support for `@JmsListener` annotations, you can add `@EnableJms` to one of your `@Configuration` classes, as the following example shows: @@ -2145,7 +1929,7 @@ If you prefer [XML configuration](#jms-namespace), you can use the ` ``` -#### [](#jms-annotated-programmatic-registration)4.5.2. Programmatic Endpoint Registration #### +#### 4.5.2. Programmatic Endpoint Registration `JmsListenerEndpoint` provides a model of a JMS endpoint and is responsible for configuring the container for that model. The infrastructure lets you programmatically configure endpoints @@ -2176,7 +1960,7 @@ to describe a custom invocation mechanism. Note that you could skip the use of `@JmsListener` altogether and programmatically register only your endpoints through `JmsListenerConfigurer`. -#### [](#jms-annotated-method-signature)4.5.3. Annotated Endpoint Method Signature #### +#### 4.5.3. Annotated Endpoint Method Signature So far, we have been injecting a simple `String` in our endpoint, but it can actually have a very flexible method signature. In the following example, we rewrite it to inject the `Order` with @@ -2249,7 +2033,7 @@ public class AppConfig implements JmsListenerConfigurer { } ``` -#### [](#jms-annotated-response)4.5.4. Response Management #### +#### 4.5.4. Response Management The existing support in [`MessageListenerAdapter`](#jms-receiving-async-message-listener-adapter)already lets your method have a non-`void` return type. When that is the case, the result of the invocation is encapsulated in a `javax.jms.Message`, sent either in the destination specified @@ -2324,7 +2108,7 @@ public class AppConfig { } ``` -### [](#jms-namespace)4.6. JMS Namespace Support ### +### 4.6. JMS Namespace Support Spring provides an XML namespace for simplifying JMS configuration. To use the JMS namespace elements, you need to reference the JMS schema, as the following example shows: @@ -2457,8 +2241,7 @@ The following table describes the available configuration options for the JCA va | `concurrency` |The number of concurrent sessions or consumers to start for each listener. It can either be
a simple number indicating the maximum number (for example `5`) or a range indicating the
lower as well as the upper limit (for example, `3-5`). Note that a specified minimum is only a
hint and is typically ignored at runtime when you use a JCA listener container.
The default is 1.| | `prefetch` | The maximum number of messages to load into a single session. Note that raising this
number might lead to starvation of concurrent consumers. | -[](#jmx)5. JMX ----------- +## 5. JMX The JMX (Java Management Extensions) support in Spring provides features that let you easily and transparently integrate your Spring application into a JMX infrastructure. @@ -2483,7 +2266,7 @@ either Spring or JMX interfaces and classes. Indeed, for the most part, your app classes need not be aware of either Spring or JMX in order to take advantage of the Spring JMX features. -### [](#jmx-exporting)5.1. Exporting Your Beans to JMX ### +### 5.1. Exporting Your Beans to JMX The core class in Spring’s JMX framework is the `MBeanExporter`. This class is responsible for taking your Spring beans and registering them with a JMX `MBeanServer`. @@ -2556,7 +2339,7 @@ are exposed as attributes and all `public` methods (except those inherited from | |`MBeanExporter` is a `Lifecycle` bean (see [Startup and Shutdown Callbacks](core.html#beans-factory-lifecycle-processor)). By default, MBeans are exported as late as possible during
the application lifecycle. You can configure the `phase` at which
the export happens or disable automatic registration by setting the `autoStartup` flag.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#jmx-exporting-mbeanserver)5.1.1. Creating an MBeanServer #### +#### 5.1.1. Creating an MBeanServer The configuration shown in the [preceding section](#jmx-exporting) assumes that the application is running in an environment that has one (and only one) `MBeanServer`already running. In this case, Spring tries to locate the running `MBeanServer` and @@ -2598,7 +2381,7 @@ In the preceding example, an instance of `MBeanServer` is created by the `MBeanS supplied to the `MBeanExporter` through the `server` property. When you supply your own`MBeanServer` instance, the `MBeanExporter` does not try to locate a running`MBeanServer` and uses the supplied `MBeanServer` instance. For this to work correctly, you must have a JMX implementation on your classpath. -#### [](#jmx-mbean-server)5.1.2. Reusing an Existing `MBeanServer` #### +#### 5.1.2. Reusing an Existing `MBeanServer` If no server is specified, the `MBeanExporter` tries to automatically detect a running`MBeanServer`. This works in most environments, where only one `MBeanServer` instance is used. However, when multiple instances exist, the exporter might pick the wrong server. @@ -2637,7 +2420,7 @@ as the following example shows: ``` -#### [](#jmx-exporting-lazy)5.1.3. Lazily Initialized MBeans #### +#### 5.1.3. Lazily Initialized MBeans If you configure a bean with an `MBeanExporter` that is also configured for lazy initialization, the `MBeanExporter` does not break this contract and avoids @@ -2645,7 +2428,7 @@ instantiating the bean. Instead, it registers a proxy with the `MBeanServer` and defers obtaining the bean from the container until the first invocation on the proxy occurs. -#### [](#jmx-exporting-auto)5.1.4. Automatic Registration of MBeans #### +#### 5.1.4. Automatic Registration of MBeans Any beans that are exported through the `MBeanExporter` and are already valid MBeans are registered as-is with the `MBeanServer` without further intervention from Spring. You can cause MBeans @@ -2664,7 +2447,7 @@ and is automatically registered by Spring. By default, a bean that is autodetect registration has its bean name used as the `ObjectName`. You can override this behavior, as detailed in [Controlling `ObjectName` Instances for Your Beans](#jmx-naming). -#### [](#jmx-exporting-registration-behavior)5.1.5. Controlling the Registration Behavior #### +#### 5.1.5. Controlling the Registration Behavior Consider the scenario where a Spring `MBeanExporter` attempts to register an `MBean`with an `MBeanServer` by using the `ObjectName` `bean:name=testBean1`. If an `MBean`instance has already been registered under that same `ObjectName`, the default behavior is to fail (and throw an `InstanceAlreadyExistsException`). @@ -2708,7 +2491,7 @@ behavior to the `REPLACE_EXISTING` behavior: ``` -### [](#jmx-interface)5.2. Controlling the Management Interface of Your Beans ### +### 5.2. Controlling the Management Interface of Your Beans In the example in the [preceding section](#jmx-exporting-registration-behavior), you had little control over the management interface of your bean. All of the `public`properties and methods of each exported bean were exposed as JMX attributes and @@ -2717,7 +2500,7 @@ properties and methods of your exported beans are actually exposed as JMX attrib and operations, Spring JMX provides a comprehensive and extensible mechanism for controlling the management interfaces of your beans. -#### [](#jmx-interface-assembler)5.2.1. Using the `MBeanInfoAssembler` Interface #### +#### 5.2.1. Using the `MBeanInfoAssembler` Interface Behind the scenes, the `MBeanExporter` delegates to an implementation of the`org.springframework.jmx.export.assembler.MBeanInfoAssembler` interface, which is responsible for defining the management interface of each bean that is exposed. @@ -2728,7 +2511,7 @@ additional implementations of the `MBeanInfoAssembler` interface that let you control the generated management interface by using either source-level metadata or any arbitrary interface. -#### [](#jmx-interface-metadata)5.2.2. Using Source-level Metadata: Java Annotations #### +#### 5.2.2. Using Source-level Metadata: Java Annotations By using the `MetadataMBeanInfoAssembler`, you can define the management interfaces for your beans by using source-level metadata. The reading of metadata is encapsulated @@ -2857,7 +2640,7 @@ In the preceding example, an `MetadataMBeanInfoAssembler` bean has been configur instance of the `AnnotationJmxAttributeSource` class and passed to the `MBeanExporter`through the assembler property. This is all that is required to take advantage of metadata-driven management interfaces for your Spring-exposed MBeans. -#### [](#jmx-interface-metadata-types)5.2.3. Source-level Metadata Types #### +#### 5.2.3. Source-level Metadata Types The following table describes the source-level metadata types that are available for use in Spring JMX: @@ -2886,7 +2669,7 @@ metadata types: | `name` | Sets the display name of an operation parameter. | `ManagedOperationParameter` | | `index` | Sets the index of an operation parameter. | `ManagedOperationParameter` | -#### [](#jmx-interface-autodetect)5.2.4. Using the `AutodetectCapableMBeanInfoAssembler` Interface #### +#### 5.2.4. Using the `AutodetectCapableMBeanInfoAssembler` Interface To simplify configuration even further, Spring includes the`AutodetectCapableMBeanInfoAssembler` interface, which extends the `MBeanInfoAssembler`interface to add support for autodetection of MBean resources. If you configure the`MBeanExporter` with an instance of `AutodetectCapableMBeanInfoAssembler`, it is allowed to “vote” on the inclusion of beans for exposure to JMX. @@ -2924,7 +2707,7 @@ However, the `JmxTestBean` is still registered, since it is marked with the `Man The only problem with this approach is that the name of the `JmxTestBean` now has business meaning. You can address this issue by changing the default behavior for `ObjectName`creation as defined in [Controlling `ObjectName` Instances for Your Beans](#jmx-naming). -#### [](#jmx-interface-java)5.2.5. Defining Management Interfaces by Using Java Interfaces #### +#### 5.2.5. Defining Management Interfaces by Using Java Interfaces In addition to the `MetadataMBeanInfoAssembler`, Spring also includes the`InterfaceBasedMBeanInfoAssembler`, which lets you constrain the methods and properties that are exposed based on the set of methods defined in a collection of @@ -2998,7 +2781,7 @@ If no management interface is specified through either the `managedInterfaces` o on the bean and uses all of the interfaces implemented by that bean to create the management interface. -#### [](#jmx-interface-methodnames)5.2.6. Using `MethodNameBasedMBeanInfoAssembler` #### +#### 5.2.6. Using `MethodNameBasedMBeanInfoAssembler` `MethodNameBasedMBeanInfoAssembler` lets you specify a list of method names that are exposed to JMX as attributes and operations. The following code shows a sample @@ -3028,14 +2811,14 @@ beans that are exposed to JMX. To control method exposure on a bean-by-bean basi the `methodMappings` property of `MethodNameMBeanInfoAssembler` to map bean names to lists of method names. -### [](#jmx-naming)5.3. Controlling `ObjectName` Instances for Your Beans ### +### 5.3. Controlling `ObjectName` Instances for Your Beans Behind the scenes, the `MBeanExporter` delegates to an implementation of the`ObjectNamingStrategy` to obtain an `ObjectName` instance for each of the beans it registers. By default, the default implementation, `KeyNamingStrategy` uses the key of the`beans` `Map` as the `ObjectName`. In addition, the `KeyNamingStrategy` can map the key of the `beans` `Map` to an entry in a `Properties` file (or files) to resolve the`ObjectName`. In addition to the `KeyNamingStrategy`, Spring provides two additional`ObjectNamingStrategy` implementations: the `IdentityNamingStrategy` (which builds an`ObjectName` based on the JVM identity of the bean) and the `MetadataNamingStrategy` (which uses source-level metadata to obtain the `ObjectName`). -#### [](#jmx-naming-properties)5.3.1. Reading `ObjectName` Instances from Properties #### +#### 5.3.1. Reading `ObjectName` Instances from Properties You can configure your own `KeyNamingStrategy` instance and configure it to read`ObjectName` instances from a `Properties` instance rather than use a bean key. The`KeyNamingStrategy` tries to locate an entry in the `Properties` with a key that corresponds to the bean key. If no entry is found or if the `Properties` instance is`null`, the bean key itself is used. @@ -3083,7 +2866,7 @@ bean key. If no entry in the `Properties` instance can be found, the bean key name is used as the `ObjectName`. -#### [](#jmx-naming-metadata)5.3.2. Using `MetadataNamingStrategy` #### +#### 5.3.2. Using `MetadataNamingStrategy` `MetadataNamingStrategy` uses the `objectName` property of the `ManagedResource`attribute on each bean to create the `ObjectName`. The following code shows the configuration for the `MetadataNamingStrategy`: @@ -3123,7 +2906,7 @@ example, the generated `ObjectName` for the following bean would be`com.example: ``` -#### [](#jmx-context-mbeanexport)5.3.3. Configuring Annotation-based MBean Export #### +#### 5.3.3. Configuring Annotation-based MBean Export If you prefer to use [the annotation-based approach](#jmx-interface-metadata) to define your management interfaces, a convenience subclass of `MBeanExporter` is available:`AnnotationMBeanExporter`. When defining an instance of this subclass, you no longer need the`namingStrategy`, `assembler`, and `attributeSource` configuration, @@ -3168,12 +2951,12 @@ The following example shows the XML equivalent of the preceding annotation-based | |Do not use interface-based AOP proxies in combination with autodetection of JMX
annotations in your bean classes. Interface-based proxies “hide” the target class, which
also hides the JMX-managed resource annotations. Hence, you should use target-class proxies in that
case (through setting the 'proxy-target-class' flag on ``,`` and so on). Otherwise, your JMX beans might be silently ignored at
startup.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -### [](#jmx-jsr160)5.4. Using JSR-160 Connectors ### +### 5.4. Using JSR-160 Connectors For remote access, Spring JMX module offers two `FactoryBean` implementations inside the`org.springframework.jmx.support` package for creating both server- and client-side connectors. -#### [](#jmx-jsr160-server)5.4.1. Server-side Connectors #### +#### 5.4.1. Server-side Connectors To have Spring JMX create, start, and expose a JSR-160 `JMXConnectorServer`, you can use the following configuration: @@ -3231,7 +3014,7 @@ snippet of configuration:
``` -#### [](#jmx-jsr160-client)5.4.2. Client-side Connectors #### +#### 5.4.2. Client-side Connectors To create an `MBeanServerConnection` to a remote JSR-160-enabled `MBeanServer`, you can use the`MBeanServerConnectionFactoryBean`, as the following example shows: @@ -3241,7 +3024,7 @@ To create an `MBeanServerConnection` to a remote JSR-160-enabled `MBeanServer`,
``` -#### [](#jmx-jsr160-protocols)5.4.3. JMX over Hessian or SOAP #### +#### 5.4.3. JMX over Hessian or SOAP JSR-160 permits extensions to the way in which communication is done between the client and the server. The examples shown in the preceding sections use the mandatory RMI-based implementation @@ -3260,7 +3043,7 @@ as the following example shows: In the preceding example, we used MX4J 3.0.0. See the official MX4J documentation for more information. -### [](#jmx-proxy)5.5. Accessing MBeans through Proxies ### +### 5.5. Accessing MBeans through Proxies Spring JMX lets you create proxies that re-route calls to MBeans that are registered in a local or remote `MBeanServer`. These proxies provide you with a standard Java interface, @@ -3300,11 +3083,11 @@ that uses the `MBeanServerConnectionFactoryBean`. This `MBeanServerConnection` i passed to the `MBeanProxyFactoryBean` through the `server` property. The proxy that is created forwards all invocations to the `MBeanServer` through this`MBeanServerConnection`. -### [](#jmx-notifications)5.6. Notifications ### +### 5.6. Notifications Spring’s JMX offering includes comprehensive support for JMX notifications. -#### [](#jmx-notifications-listeners)5.6.1. Registering Listeners for Notifications #### +#### 5.6.1. Registering Listeners for Notifications Spring’s JMX support makes it easy to register any number of`NotificationListeners` with any number of MBeans (this includes MBeans exported by Spring’s `MBeanExporter` and MBeans registered through some other mechanism). For @@ -3513,7 +3296,7 @@ we also want to filter out extraneous `Notifications` by supplying a`Notificatio indeed, what a `NotificationFilter` is, see the section of the JMX specification (1.2) entitled 'The JMX Notification Model'.) -#### [](#jmx-notifications-publishing)5.6.2. Publishing Notifications #### +#### 5.6.2. Publishing Notifications Spring provides support not only for registering to receive `Notifications` but also for publishing `Notifications`. @@ -3575,7 +3358,7 @@ coupling your classes to both Spring and JMX. As always, the advice here is to b pragmatic. If you need the functionality offered by the `NotificationPublisher` and you can accept the coupling to both Spring and JMX, then do so. -### [](#jmx-resources)5.7. Further Resources ### +### 5.7. Further Resources This section contains links to further resources about JMX: @@ -3591,8 +3374,7 @@ This section contains links to further resources about JMX: * The [MX4J homepage](http://mx4j.sourceforge.net/). (MX4J is an open-source implementation of various JMX specs.) -[](#mail)6. Email ----------- +## 6. Email This section describes how to send email with the Spring Framework. @@ -3620,7 +3402,7 @@ The `org.springframework.mail.javamail.JavaMailSender` interface adds specialize JavaMail features, such as MIME message support to the `MailSender` interface (from which it inherits). `JavaMailSender` also provides a callback interface called`org.springframework.mail.javamail.MimeMessagePreparator` for preparing a `MimeMessage`. -### [](#mail-usage)6.1. Usage ### +### 6.1. Usage Assume that we have a business interface called `OrderManager`, as the following example shows: @@ -3635,7 +3417,7 @@ public interface OrderManager { Further assume that we have a requirement stating that an email message with an order number needs to be generated and sent to a customer who placed the relevant order. -#### [](#mail-usage-simple)6.1.1. Basic `MailSender` and `SimpleMailMessage` Usage #### +#### 6.1.1. Basic `MailSender` and `SimpleMailMessage` Usage The following example shows how to use `MailSender` and `SimpleMailMessage` to send an email when someone places an order: @@ -3703,7 +3485,7 @@ The following example shows the bean definitions for the preceding code:
``` -#### [](#mail-usage-mime)6.1.2. Using `JavaMailSender` and `MimeMessagePreparator` #### +#### 6.1.2. Using `JavaMailSender` and `MimeMessagePreparator` This section describes another implementation of `OrderManager` that uses the `MimeMessagePreparator`callback interface. In the following example, the `mailSender` property is of type`JavaMailSender` so that we are able to use the JavaMail `MimeMessage` class: @@ -3759,7 +3541,7 @@ public class SimpleOrderManager implements OrderManager { The Spring Framework’s mail support ships with the standard JavaMail implementation. See the relevant javadoc for more information. -### [](#mail-javamail-mime)6.2. Using the JavaMail `MimeMessageHelper` ### +### 6.2. Using the JavaMail `MimeMessageHelper` A class that comes in pretty handy when dealing with JavaMail messages is`org.springframework.mail.javamail.MimeMessageHelper`, which shields you from having to use the verbose JavaMail API. Using the `MimeMessageHelper`, it is @@ -3778,13 +3560,13 @@ helper.setText("Thank you for ordering!"); sender.send(message); ``` -#### [](#mail-javamail-mime-attachments)6.2.1. Sending Attachments and Inline Resources #### +#### 6.2.1. Sending Attachments and Inline Resources Multipart email messages allow for both attachments and inline resources. Examples of inline resources include an image or a stylesheet that you want to use in your message but that you do not want displayed as an attachment. -##### [](#mail-javamail-mime-attachments-attachment)Attachments ##### +##### Attachments The following example shows you how to use the `MimeMessageHelper` to send an email with a single JPEG image attachment: @@ -3808,7 +3590,7 @@ helper.addAttachment("CoolImage.jpg", file); sender.send(message); ``` -##### [](#mail-javamail-mime-attachments-inline)Inline Resources ##### +##### Inline Resources The following example shows you how to use the `MimeMessageHelper` to send an email with an inline image: @@ -3836,7 +3618,7 @@ sender.send(message); | |Inline resources are added to the `MimeMessage` by using the specified `Content-ID`(`identifier1234` in the above example). The order in which you add the text
and the resource are very important. Be sure to first add the text and then
the resources. If you are doing it the other way around, it does not work.| |---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#mail-templates)6.2.2. Creating Email Content by Using a Templating Library #### +#### 6.2.2. Creating Email Content by Using a Templating Library The code in the examples shown in the previous sections explicitly created the content of the email message, by using methods calls such as `message.setText(..)`. This is fine for simple cases, and it @@ -3860,8 +3642,7 @@ sending the email. It is definitely a best practice when the content of your ema becomes even moderately complex, and, with the Spring Framework’s support classes for FreeMarker, it becomes quite easy to do. -[](#scheduling)7. Task Execution and Scheduling ----------- +## 7. Task Execution and Scheduling The Spring Framework provides abstractions for the asynchronous execution and scheduling of tasks with the `TaskExecutor` and `TaskScheduler` interfaces, respectively. Spring also @@ -3875,7 +3656,7 @@ You can set up both of those schedulers by using a `FactoryBean` with optional r the Quartz Scheduler and the `Timer` is available that lets you invoke a method of an existing target object (analogous to the normal `MethodInvokingFactoryBean`operation). -### [](#scheduling-task-executor)7.1. The Spring `TaskExecutor` Abstraction ### +### 7.1. The Spring `TaskExecutor` Abstraction Executors are the JDK name for the concept of thread pools. The “executor” naming is due to the fact that there is no guarantee that the underlying implementation is @@ -3892,7 +3673,7 @@ for thread pooling where needed. Components such as the `ApplicationEventMultica JMS’s `AbstractMessageListenerContainer`, and Quartz integration all use the`TaskExecutor` abstraction to pool threads. However, if your beans need thread pooling behavior, you can also use this abstraction for your own needs. -#### [](#scheduling-task-executor-types)7.1.1. `TaskExecutor` Types #### +#### 7.1.1. `TaskExecutor` Types Spring includes a number of pre-built implementations of `TaskExecutor`. In all likelihood, you should never need to implement your own. @@ -3930,7 +3711,7 @@ The variants that Spring provides are as follows: compatible runtime environment (such as a Java EE 7+ application server), replacing a CommonJ WorkManager for that purpose. -#### [](#scheduling-task-executor-usage)7.1.2. Using a `TaskExecutor` #### +#### 7.1.2. Using a `TaskExecutor` Spring’s `TaskExecutor` implementations are used as simple JavaBeans. In the following example, we define a bean that uses the `ThreadPoolTaskExecutor` to asynchronously print @@ -3986,7 +3767,7 @@ To configure the rules that the `TaskExecutor` uses, we expose simple bean prope ``` -### [](#scheduling-task-scheduler)7.2. The Spring `TaskScheduler` Abstraction ### +### 7.2. The Spring `TaskScheduler` Abstraction In addition to the `TaskExecutor` abstraction, Spring 3.0 introduced a `TaskScheduler`with a variety of methods for scheduling tasks to run at some point in the future. The following listing shows the `TaskScheduler` interface definition: @@ -4024,7 +3805,7 @@ are capable of scheduling tasks to run repeatedly. The fixed-rate and fixed-dela methods are for simple, periodic execution, but the method that accepts a `Trigger` is much more flexible. -#### [](#scheduling-trigger-interface)7.2.1. `Trigger` Interface #### +#### 7.2.1. `Trigger` Interface The `Trigger` interface is essentially inspired by JSR-236 which, as of Spring 3.0, was not yet officially implemented. The basic idea of the `Trigger` is that execution @@ -4055,7 +3836,7 @@ public interface TriggerContext { } ``` -#### [](#scheduling-trigger-implementations)7.2.2. `Trigger` Implementations #### +#### 7.2.2. `Trigger` Implementations Spring provides two implementations of the `Trigger` interface. The most interesting one is the `CronTrigger`. It enables the scheduling of tasks based on[cron expressions](#scheduling-cron-expression). @@ -4074,7 +3855,7 @@ the `Trigger` abstraction. For example, it may be convenient to allow periodic t cron-based triggers, and even custom trigger implementations to be used interchangeably. Such a component could take advantage of dependency injection so that you can configure such `Triggers`externally and, therefore, easily modify or extend them. -#### [](#scheduling-task-scheduler-implementations)7.2.3. `TaskScheduler` implementations #### +#### 7.2.3. `TaskScheduler` implementations As with Spring’s `TaskExecutor` abstraction, the primary benefit of the `TaskScheduler`arrangement is that an application’s scheduling needs are decoupled from the deployment environment. This abstraction level is particularly relevant when deploying to an @@ -4087,12 +3868,12 @@ through Spring’s `ConcurrentTaskScheduler`. As a convenience, Spring also prov These variants work perfectly fine for locally embedded thread pool setups in lenient application server environments, as well — in particular on Tomcat and Jetty. -### [](#scheduling-annotation-support)7.3. Annotation Support for Scheduling and Asynchronous Execution ### +### 7.3. Annotation Support for Scheduling and Asynchronous Execution Spring provides annotation support for both task scheduling and asynchronous method execution. -#### [](#scheduling-enable-annotation-support)7.3.1. Enable Scheduling Annotations #### +#### 7.3.1. Enable Scheduling Annotations To enable support for `@Scheduled` and `@Async` annotations, you can add `@EnableScheduling` and`@EnableAsync` to one of your `@Configuration` classes, as the following example shows: @@ -4124,7 +3905,7 @@ reference is provided for managing those methods annotated with `@Scheduled`. | |The default advice mode for processing `@Async` annotations is `proxy` which allows
for interception of calls through the proxy only. Local calls within the same class
cannot get intercepted that way. For a more advanced mode of interception, consider
switching to `aspectj` mode in combination with compile-time or load-time weaving.| |---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#scheduling-annotation-support-scheduled)7.3.2. The `@Scheduled` annotation #### +#### 7.3.2. The `@Scheduled` annotation You can add the `@Scheduled` annotation to a method, along with trigger metadata. For example, the following method is invoked every five seconds (5000 milliseconds) with a @@ -4182,7 +3963,7 @@ context, those would typically have been provided through dependency injection. | |As of Spring Framework 4.3, `@Scheduled` methods are supported on beans of any scope.

Make sure that you are not initializing multiple instances of the same `@Scheduled`annotation class at runtime, unless you do want to schedule callbacks to each such
instance. Related to this, make sure that you do not use `@Configurable` on bean
classes that are annotated with `@Scheduled` and registered as regular Spring beans
with the container. Otherwise, you would get double initialization (once through the
container and once through the `@Configurable` aspect), with the consequence of each`@Scheduled` method being invoked twice.| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#scheduling-annotation-support-async)7.3.3. The `@Async` annotation #### +#### 7.3.3. The `@Async` annotation You can provide the `@Async` annotation on a method so that invocation of that method occurs asynchronously. In other words, the caller returns immediately upon @@ -4257,7 +4038,7 @@ public class SampleBeanInitializer { | |There is no direct XML equivalent for `@Async`, since such methods should be designed
for asynchronous execution in the first place, not externally re-declared to be asynchronous.
However, you can manually set up Spring’s `AsyncExecutionInterceptor` with Spring AOP,
in combination with a custom pointcut.| |---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#scheduling-annotation-support-qualification)7.3.4. Executor Qualification with `@Async` #### +#### 7.3.4. Executor Qualification with `@Async` By default, when specifying `@Async` on a method, the executor that is used is the one [configured when enabling async support](#scheduling-enable-annotation-support), @@ -4275,7 +4056,7 @@ In this case, `"otherExecutor"` can be the name of any `Executor` bean in the Sp container, or it may be the name of a qualifier associated with any `Executor` (for example, as specified with the `` element or Spring’s `@Qualifier` annotation). -#### [](#scheduling-annotation-support-exception)7.3.5. Exception Management with `@Async` #### +#### 7.3.5. Exception Management with `@Async` When an `@Async` method has a `Future`-typed return value, it is easy to manage an exception that was thrown during the method execution, as this exception is @@ -4295,12 +4076,12 @@ public class MyAsyncUncaughtExceptionHandler implements AsyncUncaughtExceptionHa By default, the exception is merely logged. You can define a custom `AsyncUncaughtExceptionHandler`by using `AsyncConfigurer` or the `` XML element. -### [](#scheduling-task-namespace)7.4. The `task` Namespace ### +### 7.4. The `task` Namespace As of version 3.0, Spring includes an XML namespace for configuring `TaskExecutor` and`TaskScheduler` instances. It also provides a convenient way to configure tasks to be scheduled with a trigger. -#### [](#scheduling-task-namespace-scheduler)7.4.1. The 'scheduler' Element #### +#### 7.4.1. The 'scheduler' Element The following element creates a `ThreadPoolTaskScheduler` instance with the specified thread pool size: @@ -4314,7 +4095,7 @@ within the pool. The `scheduler` element is relatively straightforward. If you d provide a `pool-size` attribute, the default thread pool has only a single thread. There are no other configuration options for the scheduler. -#### [](#scheduling-task-namespace-executor)7.4.2. The `executor` Element #### +#### 7.4.2. The `executor` Element The following creates a `ThreadPoolTaskExecutor` instance: @@ -4399,7 +4180,7 @@ The following example sets the `keep-alive` value to two minutes: keep-alive="120"/> ``` -#### [](#scheduling-task-namespace-scheduled-tasks)7.4.3. The 'scheduled-tasks' Element #### +#### 7.4.3. The 'scheduled-tasks' Element The most powerful feature of Spring’s task namespace is the support for configuring tasks to be scheduled within a Spring Application Context. This follows an approach @@ -4436,7 +4217,7 @@ The following example shows these other options: ``` -### [](#scheduling-cron-expression)7.5. Cron Expressions ### +### 7.5. Cron Expressions All Spring cron expressions have to conform to the same format, whether you are using them in[`@Scheduled` annotations](#scheduling-annotation-support-scheduled),[`task:scheduled-tasks` elements](#scheduling-task-namespace-scheduled-tasks), or someplace else. @@ -4508,7 +4289,7 @@ Here are some examples: | `0 0 0 ? * 5#2` | the second Friday in the month at midnight | | `0 0 0 ? * MON#1` | the first Monday in the month at midnight | -#### [](#macros)7.5.1. Macros #### +#### 7.5.1. Macros Expressions such as `0 0 * * * *` are hard for humans to parse and are, therefore, hard to fix in case of bugs. To improve readability, Spring supports the following macros, which represent commonly used sequences. @@ -4522,13 +4303,13 @@ You can use these macros instead of the six-digit value, thus: `@Scheduled(cron |`@daily` (or `@midnight`) |once a day (`0 0 0 * * *`), or| | `@hourly` |once an hour, (`0 0 * * * *`) | -### [](#scheduling-quartz)7.6. Using the Quartz Scheduler ### +### 7.6. Using the Quartz Scheduler Quartz uses `Trigger`, `Job`, and `JobDetail` objects to realize scheduling of all kinds of jobs. For the basic concepts behind Quartz, see[https://www.quartz-scheduler.org/](https://www.quartz-scheduler.org/). For convenience purposes, Spring offers a couple of classes that simplify using Quartz within Spring-based applications. -#### [](#scheduling-quartz-jobdetail)7.6.1. Using the `JobDetailFactoryBean` #### +#### 7.6.1. Using the `JobDetailFactoryBean` Quartz `JobDetail` objects contain all the information needed to run a job. Spring provides a`JobDetailFactoryBean`, which provides bean-style properties for XML configuration purposes. Consider the following example: @@ -4575,7 +4356,7 @@ All additional properties from the job data map are available to you as well. | |By using the `name` and `group` properties, you can modify the name and the group
of the job, respectively. By default, the name of the job matches the bean name
of the `JobDetailFactoryBean` (`exampleJob` in the preceding example above).| |---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#scheduling-quartz-method-invoking-job)7.6.2. Using the `MethodInvokingJobDetailFactoryBean` #### +#### 7.6.2. Using the `MethodInvokingJobDetailFactoryBean` Often you merely need to invoke a method on a specific object. By using the`MethodInvokingJobDetailFactoryBean`, you can do exactly this, as the following example shows: @@ -4623,7 +4404,7 @@ job does not start before the first one has finished. To make jobs resulting fro | |By default, jobs will run in a concurrent fashion.| |---|--------------------------------------------------| -#### [](#scheduling-quartz-cron)7.6.3. Wiring up Jobs by Using Triggers and `SchedulerFactoryBean` #### +#### 7.6.3. Wiring up Jobs by Using Triggers and `SchedulerFactoryBean` We have created job details and jobs. We have also reviewed the convenience bean that lets you invoke a method on a specific object. Of course, we still need to schedule the @@ -4674,8 +4455,7 @@ the [`SchedulerFactoryBean`](https://docs.spring.io/spring-framework/docs/5.3.16 | |`SchedulerFactoryBean` also recognizes a `quartz.properties` file in the classpath,
based on Quartz property keys, as with regular Quartz configuration. Please note that many`SchedulerFactoryBean` settings interact with common Quartz settings in the properties file;
it is therefore not recommended to specify values at both levels. For example, do not set
an "org.quartz.jobStore.class" property if you mean to rely on a Spring-provided DataSource,
or specify an `org.springframework.scheduling.quartz.LocalDataSourceJobStore` variant which
is a full-fledged replacement for the standard `org.quartz.impl.jdbcjobstore.JobStoreTX`.| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -[](#cache)8. Cache Abstraction ----------- +## 8. Cache Abstraction Since version 3.1, the Spring Framework provides support for transparently adding caching to an existing Spring application. Similar to the [transaction](data-access.html#transaction)support, the caching abstraction allows consistent use of various caching solutions with @@ -4684,7 +4464,7 @@ minimal impact on the code. In Spring Framework 4.1, the cache abstraction was significantly extended with support for [JSR-107 annotations](#cache-jsr-107) and more customization options. -### [](#cache-strategies)8.1. Understanding the Cache Abstraction ### +### 8.1. Understanding the Cache Abstraction Cache vs Buffer @@ -4753,7 +4533,7 @@ To use the cache abstraction, you need to take care of two aspects: * Cache configuration: The backing cache where the data is stored and from which it is read. -### [](#cache-annotations)8.2. Declarative Annotation-based Caching ### +### 8.2. Declarative Annotation-based Caching For caching declaration, Spring’s caching abstraction provides a set of Java annotations: @@ -4767,7 +4547,7 @@ For caching declaration, Spring’s caching abstraction provides a set of Java a * `@CacheConfig`: Shares some common cache-related settings at class-level. -#### [](#cache-annotations-cacheable)8.2.1. The `@Cacheable` Annotation #### +#### 8.2.1. The `@Cacheable` Annotation As the name implies, you can use `@Cacheable` to demarcate methods that are cacheable — that is, methods for which the result is stored in the cache so that, on subsequent invocations (with the same arguments), the value in the cache is returned without @@ -4797,7 +4577,7 @@ The following example uses `@Cacheable` on the `findBook` method with multiple c public Book findBook(ISBN isbn) {...} ``` -##### [](#cache-annotations-cacheable-default-key)Default Key Generation ##### +##### Default Key Generation Since caches are essentially key-value stores, each invocation of a cached method needs to be translated into a suitable key for cache access. The caching abstraction @@ -4818,7 +4598,7 @@ To provide a different default key generator, you need to implement the`org.spri | |The default key generation strategy changed with the release of Spring 4.0. Earlier
versions of Spring used a key generation strategy that, for multiple key parameters,
considered only the `hashCode()` of parameters and not `equals()`. This could cause
unexpected key collisions (see [SPR-10237](https://jira.spring.io/browse/SPR-10237)for background). The new `SimpleKeyGenerator` uses a compound key for such scenarios.

If you want to keep using the previous key strategy, you can configure the deprecated`org.springframework.cache.interceptor.DefaultKeyGenerator` class or create a custom
hash-based `KeyGenerator` implementation.| |---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#cache-annotations-cacheable-key)Custom Key Generation Declaration ##### +##### Custom Key Generation Declaration Since caching is generic, the target methods are quite likely to have various signatures that cannot be readily mapped on top of the cache structure. This tends to become obvious @@ -4872,14 +4652,14 @@ public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed) | |The `key` and `keyGenerator` parameters are mutually exclusive and an operation
that specifies both results in an exception.| |---|--------------------------------------------------------------------------------------------------------------------------------| -##### [](#cache-annotations-cacheable-default-cache-resolver)Default Cache Resolution ##### +##### Default Cache Resolution The caching abstraction uses a simple `CacheResolver` that retrieves the caches defined at the operation level by using the configured`CacheManager`. To provide a different default cache resolver, you need to implement the`org.springframework.cache.interceptor.CacheResolver` interface. -##### [](#cache-annotations-cacheable-cache-resolver)Custom Cache Resolution ##### +##### Custom Cache Resolution The default cache resolution fits well for applications that work with a single `CacheManager` and have no complex cache resolution requirements. @@ -4911,7 +4691,7 @@ public Book findBook(ISBN isbn) {...} | |Since Spring 4.1, the `value` attribute of the cache annotations are no longer
mandatory, since this particular information can be provided by the `CacheResolver`regardless of the content of the annotation.

Similarly to `key` and `keyGenerator`, the `cacheManager` and `cacheResolver`parameters are mutually exclusive, and an operation specifying both
results in an exception, as a custom `CacheManager` is ignored by the`CacheResolver` implementation. This is probably not what you expect.| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#cache-annotations-cacheable-synchronized)Synchronized Caching ##### +##### Synchronized Caching In a multi-threaded environment, certain operations might be concurrently invoked for the same argument (typically on startup). By default, the cache abstraction does not @@ -4934,7 +4714,7 @@ public Foo executeExpensiveOperation(String id) {...} | |This is an optional feature, and your favorite cache library may not support it.
All `CacheManager` implementations provided by the core framework support it. See the
documentation of your cache provider for more details.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#cache-annotations-cacheable-condition)Conditional Caching ##### +##### Conditional Caching Sometimes, a method might not be suitable for caching all the time (for example, it might depend on the given arguments). The cache annotations support such use cases through the`condition` parameter, which takes a `SpEL` expression that is evaluated to either `true`or `false`. If `true`, the method is cached. If not, it behaves as if the method is not @@ -4976,7 +4756,7 @@ public Optional findBook(String name) Note that `#result` still refers to `Book` and not `Optional`. Since it might be`null`, we use SpEL’s [safe navigation operator](core.html#expressions-operator-safe-navigation). -##### [](#cache-spel-context)Available Caching SpEL Evaluation Context ##### +##### Available Caching SpEL Evaluation Context Each `SpEL` expression evaluates against a dedicated [`context`](core.html#expressions-language-ref). In addition to the built-in parameters, the framework provides dedicated caching-related @@ -4994,7 +4774,7 @@ available to the context so that you can use them for key and conditional comput |Argument name|Evaluation context| Name of any of the method arguments. If the names are not available
(perhaps due to having no debug information), the argument names are also available under the `#a<#arg>`where `#arg` stands for the argument index (starting from `0`). |`#iban` or `#a0` (you can also use `#p0` or `#p<#arg>` notation as an alias).| | `result` |Evaluation context|The result of the method call (the value to be cached). Only available in `unless`expressions, `cache put` expressions (to compute the `key`), or `cache evict`expressions (when `beforeInvocation` is `false`). For supported wrappers (such as`Optional`), `#result` refers to the actual object, not the wrapper.| `#result` | -#### [](#cache-annotations-put)8.2.2. The `@CachePut` Annotation #### +#### 8.2.2. The `@CachePut` Annotation When the cache needs to be updated without interfering with the method execution, you can use the `@CachePut` annotation. That is, the method is always invoked and its @@ -5010,7 +4790,7 @@ public Book updateBook(ISBN isbn, BookDescriptor descriptor) | |Using `@CachePut` and `@Cacheable` annotations on the same method is generally
strongly discouraged because they have different behaviors. While the latter causes the
method invocation to be skipped by using the cache, the former forces the invocation in
order to run a cache update. This leads to unexpected behavior and, with the exception
of specific corner-cases (such as annotations having conditions that exclude them from each
other), such declarations should be avoided. Note also that such conditions should not rely
on the result object (that is, the `#result` variable), as these are validated up-front to
confirm the exclusion.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#cache-annotations-evict)8.2.3. The `@CacheEvict` annotation #### +#### 8.2.3. The `@CacheEvict` annotation The cache abstraction allows not just population of a cache store but also eviction. This process is useful for removing stale or unused data from the cache. As opposed to`@Cacheable`, `@CacheEvict` demarcates methods that perform cache @@ -5050,7 +4830,7 @@ trigger, the return values are ignored (as they do not interact with the cache). not the case with `@Cacheable` which adds data to the cache or updates data in the cache and, thus, requires a result. -#### [](#cache-annotations-caching)8.2.4. The `@Caching` Annotation #### +#### 8.2.4. The `@Caching` Annotation Sometimes, multiple annotations of the same type (such as `@CacheEvict` or`@CachePut`) need to be specified — for example, because the condition or the key expression is different between different caches. `@Caching` lets multiple nested`@Cacheable`, `@CachePut`, and `@CacheEvict` annotations be used on the same method. @@ -5061,7 +4841,7 @@ The following example uses two `@CacheEvict` annotations: public Book importBooks(String deposit, Date date) ``` -#### [](#cache-annotations-config)8.2.5. The `@CacheConfig` annotation #### +#### 8.2.5. The `@CacheConfig` annotation So far, we have seen that caching operations offer many customization options and that you can set these options for each operation. However, some of the customization options @@ -5094,7 +4874,7 @@ Therefore, this gives three levels of customizations for each cache operation: * At the operation level. -#### [](#cache-annotation-enable)8.2.6. Enabling Caching Annotations #### +#### 8.2.6. Enabling Caching Annotations It is important to note that even though declaring the cache annotations does not automatically trigger their actions - like many things in Spring, the feature has to be @@ -5162,7 +4942,7 @@ if you need to annotate non-public methods, as it changes the bytecode itself. | |In proxy mode (the default), only external method calls coming in through the
proxy are intercepted. This means that self-invocation (in effect, a method within the
target object that calls another method of the target object) does not lead to actual
caching at runtime even if the invoked method is marked with `@Cacheable`. Consider
using the `aspectj` mode in this case. Also, the proxy must be fully initialized to
provide the expected behavior, so you should not rely on this feature in your
initialization code (that is, `@PostConstruct`).| |---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#cache-annotation-stereotype)8.2.7. Using Custom Annotations #### +#### 8.2.7. Using Custom Annotations Custom annotation and AspectJ @@ -5209,7 +4989,7 @@ public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed) Even though `@SlowService` is not a Spring annotation, the container automatically picks up its declaration at runtime and understands its meaning. Note that, as mentioned[earlier](#cache-annotation-enable), annotation-driven behavior needs to be enabled. -### [](#cache-jsr-107)8.3. JCache (JSR-107) Annotations ### +### Annotations Since version 4.1, Spring’s caching abstraction fully supports the JCache standard (JSR-107) annotations: `@CacheResult`, `@CachePut`, `@CacheRemove`, and `@CacheRemoveAll`as well as the `@CacheDefaults`, `@CacheKey`, and `@CacheValue` companions. @@ -5219,7 +4999,7 @@ specification. In other words, if you are already using Spring’s caching abstr you can switch to these standard annotations without changing your cache storage (or configuration, for that matter). -#### [](#cache-jsr-107-summary)8.3.1. Feature Summary #### +#### 8.3.1. Feature Summary For those who are familiar with Spring’s caching annotations, the following table describes the main differences between the Spring annotations and their JSR-107 @@ -5286,7 +5066,7 @@ invoking the method again: public Book findBook(ISBN isbn) ``` -#### [](#enabling-jsr-107-support)8.3.2. Enabling JSR-107 Support #### +#### 8.3.2. Enabling JSR-107 Support You do not need to do anything specific to enable the JSR-107 support alongside Spring’s declarative annotation support. Both `@EnableCaching` and the `cache:annotation-driven`XML element automatically enable the JCache support if both the JSR-107 API and the`spring-context-support` module are present in the classpath. @@ -5294,7 +5074,7 @@ declarative annotation support. Both `@EnableCaching` and the `cache:annotation- | |Depending on your use case, the choice is basically yours. You can even mix and
match services by using the JSR-107 API on some and using Spring’s own annotations on
others. However, if these services impact the same caches, you should use a consistent
and identical key generation implementation.| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -### [](#cache-declarative-xml)8.4. Declarative XML-based Caching ### +### 8.4. Declarative XML-based Caching If annotations are not an option (perhaps due to having no access to the sources or no external code), you can use XML for declarative caching. So, instead of @@ -5340,12 +5120,12 @@ However, through XML, it is easier to apply package or group or interface-wide c (again, due to the AspectJ pointcut) and to create template-like definitions (as we did in the preceding example by defining the target cache through the `cache:definitions``cache` attribute). -### [](#cache-store-configuration)8.5. Configuring the Cache Storage ### +### 8.5. Configuring the Cache Storage The cache abstraction provides several storage integration options. To use them, you need to declare an appropriate `CacheManager` (an entity that controls and manages `Cache`instances and that can be used to retrieve these for storage). -#### [](#cache-store-configuration-jdk)8.5.1. JDK `ConcurrentMap`-based Cache #### +#### 8.5.1. JDK `ConcurrentMap`-based Cache The JDK-based `Cache` implementation resides under`org.springframework.cache.concurrent` package. It lets you use `ConcurrentHashMap`as a backing `Cache` store. The following example shows how to configure two caches: @@ -5370,7 +5150,7 @@ suitable for basic use cases, tests, or simple applications. The cache scales we and is very fast, but it does not provide any management, persistence capabilities, or eviction contracts. -#### [](#cache-store-configuration-ehcache)8.5.2. Ehcache-based Cache #### +#### 8.5.2. Ehcache-based Cache | |Ehcache 3.x is fully JSR-107 compliant and no dedicated support is required for it.| |---|-----------------------------------------------------------------------------------| @@ -5390,7 +5170,7 @@ The following example shows how to do so: This setup bootstraps the ehcache library inside the Spring IoC (through the `ehcache`bean), which is then wired into the dedicated `CacheManager` implementation. Note that the entire Ehcache-specific configuration is read from `ehcache.xml`. -#### [](#cache-store-configuration-caffeine)8.5.3. Caffeine Cache #### +#### 8.5.3. Caffeine Cache Caffeine is a Java 8 rewrite of Guava’s cache, and its implementation is located in the`org.springframework.cache.caffeine` package and provides access to several features of Caffeine. @@ -5419,14 +5199,14 @@ are made available by the manager. The following example shows how to do so: The Caffeine `CacheManager` also supports custom `Caffeine` and `CacheLoader`. See the [Caffeine documentation](https://github.com/ben-manes/caffeine/wiki)for more information about those. -#### [](#cache-store-configuration-gemfire)8.5.4. GemFire-based Cache #### +#### 8.5.4. GemFire-based Cache GemFire is a memory-oriented, disk-backed, elastically scalable, continuously available, 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[Spring Data GemFire reference documentation](https://docs.spring.io/spring-gemfire/docs/current/reference/html/). -#### [](#cache-store-configuration-jsr107)8.5.5. JSR-107 Cache #### +#### 8.5.5. JSR-107 Cache Spring’s caching abstraction can also use JSR-107-compliant caches. The JCache implementation is located in the `org.springframework.cache.jcache` package. @@ -5443,7 +5223,7 @@ The following example shows how to do so: ``` -#### [](#cache-store-configuration-noop)8.5.6. Dealing with Caches without a Backing Store #### +#### 8.5.6. Dealing with Caches without a Backing Store Sometimes, when switching environments or doing testing, you might have cache declarations without having an actual backing cache configured. As this is an invalid @@ -5472,7 +5252,7 @@ either `jdkCache` or `gemfireCache` (configured earlier in the example) is handl the no-op cache, which does not store any information, causing the target method to be invoked every time. -### [](#cache-plug)8.6. Plugging-in Different Back-end Caches ### +### 8.6. Plugging-in Different Back-end Caches Clearly, there are plenty of caching products out there that you can use as a backing store. For those that do not support JSR-107 you need to provide a `CacheManager` and a`Cache` implementation. This may sound harder than it is, since, in practice, the classes @@ -5481,7 +5261,7 @@ caching abstraction framework on top of the storage API, as the `ehcache` classe Most `CacheManager` classes can use the classes in the`org.springframework.cache.support` package (such as `AbstractCacheManager` which takes care of the boiler-plate code, leaving only the actual mapping to be completed). -### [](#cache-specific-config)8.7. How can I Set the TTL/TTI/Eviction policy/XXX feature? ### +### 8.7. How can I Set the TTL/TTI/Eviction policy/XXX feature? Directly through your cache provider. The cache abstraction is an abstraction, not a cache implementation. The solution you use might support various data @@ -5490,14 +5270,13 @@ the JDK `ConcurrentHashMap` — exposing that in the cache abstraction would because there would no backing support). Such functionality should be controlled directly through the backing cache (when configuring it) or through its native API. -[](#appendix)9. Appendix ----------- +## 9. Appendix -### [](#xsd-schemas)9.1. XML Schemas ### +### 9.1. XML Schemas This part of the appendix lists XML schemas related to integration technologies. -#### [](#xsd-schemas-jee)9.1.1. The `jee` Schema #### +#### 9.1.1. The `jee` Schema The `jee` elements deal with issues related to Java EE (Java Enterprise Edition) configuration, such as looking up a JNDI object and defining EJB references. @@ -5520,7 +5299,7 @@ correct schema so that the elements in the `jee` namespace are available to you: ``` -##### [](#xsd-schemas-jee-jndi-lookup)\ (simple) ##### +##### \ (simple) The following example shows how to use JNDI to look up a data source without the `jee` schema: @@ -5545,7 +5324,7 @@ The following example shows how to use JNDI to look up a data source with the `j ``` -##### [](#xsd-schemas-jee-jndi-lookup-environment-single)`` (with Single JNDI Environment Setting) ##### +##### `` (with Single JNDI Environment Setting) The following example shows how to use JNDI to look up an environment variable without`jee`: @@ -5568,7 +5347,7 @@ The following example shows how to use JNDI to look up an environment variable w ``` -##### [](#xsd-schemas-jee-jndi-lookup-evironment-multiple)`` (with Multiple JNDI Environment Settings) ##### +##### `` (with Multiple JNDI Environment Settings) The following example shows how to use JNDI to look up multiple environment variables without `jee`: @@ -5597,7 +5376,7 @@ The following example shows how to use JNDI to look up multiple environment vari ``` -##### [](#xsd-schemas-jee-jndi-lookup-complex)`` (Complex) ##### +##### `` (Complex) The following example shows how to use JNDI to look up a data source and a number of different properties without `jee`: @@ -5626,7 +5405,7 @@ different properties with `jee`: proxy-interface="com.myapp.Thing"/> ``` -##### [](#xsd-schemas-jee-local-slsb)`` (Simple) ##### +##### `` (Simple) The `` element configures a reference to a local EJB Stateless Session Bean. @@ -5649,7 +5428,7 @@ with `jee`: business-interface="com.foo.service.RentalService"/> ``` -##### [](#xsd-schemas-jee-local-slsb-complex)`` (Complex) ##### +##### `` (Complex) The `` element configures a reference to a local EJB Stateless Session Bean. @@ -5679,7 +5458,7 @@ and a number of properties with `jee`: resource-ref="true"> ``` -##### [](#xsd-schemas-jee-remote-slsb)\ ##### +##### \ The `` element configures a reference to a `remote` EJB Stateless Session Bean. @@ -5713,7 +5492,7 @@ with `jee`: refresh-home-on-connect-failure="true"> ``` -#### [](#xsd-schemas-jms)9.1.2. The `jms` Schema #### +#### 9.1.2. The `jms` Schema The `jms` elements deal with configuring JMS-related beans, such as Spring’s[Message Listener Containers](#jms-mdp). These elements are detailed in the section of the [JMS chapter](#jms) entitled [JMS Namespace Support](#jms-namespace). See that chapter for full details on this support @@ -5738,11 +5517,11 @@ are available to you: ``` -#### [](#xsd-schemas-context-mbe)9.1.3. Using `` #### +#### 9.1.3. Using `` This element is detailed in[Configuring Annotation-based MBean Export](#jmx-context-mbeanexport). -#### [](#xsd-schemas-cache)9.1.4. The `cache` Schema #### +#### 9.1.4. The `cache` Schema You can use the `cache` elements to enable support for Spring’s `@CacheEvict`, `@CachePut`, and `@Caching` annotations. It it also supports declarative XML-based caching. See[Enabling Caching Annotations](#cache-annotation-enable) and[Declarative XML-based Caching](#cache-declarative-xml) for details. diff --git a/docs/en/spring-framework/languages.md b/docs/en/spring-framework/languages.md index 40b63da..b26bda7 100644 --- a/docs/en/spring-framework/languages.md +++ b/docs/en/spring-framework/languages.md @@ -1,79 +1,6 @@ -Language Support -========== - -version 5.3.16 - -Table of Contents - -* [1. Kotlin](#kotlin) - * [1.1. Requirements](#kotlin-requirements) - * [1.2. Extensions](#kotlin-extensions) - * [1.3. Null-safety](#kotlin-null-safety) - * [1.4. Classes and Interfaces](#kotlin-classes-interfaces) - * [1.5. Annotations](#kotlin-annotations) - * [1.6. Bean Definition DSL](#kotlin-bean-definition-dsl) - * [1.7. Web](#kotlin-web) - * [1.7.1. Router DSL](#router-dsl) - * [1.7.2. MockMvc DSL](#mockmvc-dsl) - * [1.7.3. Kotlin Script Templates](#kotlin-script-templates) - * [1.7.4. Kotlin multiplatform serialization](#kotlin-multiplatform-serialization) - - * [1.8. Coroutines](#coroutines) - * [1.8.1. Dependencies](#dependencies) - * [1.8.2. How Reactive translates to Coroutines?](#how-reactive-translates-to-coroutines) - * [1.8.3. Controllers](#controllers) - * [1.8.4. WebFlux.fn](#webflux-fn) - * [1.8.5. Transactions](#transactions) - - * [1.9. Spring Projects in Kotlin](#kotlin-spring-projects-in-kotlin) - * [1.9.1. Final by Default](#final-by-default) - * [1.9.2. Using Immutable Class Instances for Persistence](#using-immutable-class-instances-for-persistence) - * [1.9.3. Injecting Dependencies](#injecting-dependencies) - * [1.9.4. Injecting Configuration Properties](#injecting-configuration-properties) - * [1.9.5. Checked Exceptions](#checked-exceptions) - * [1.9.6. Annotation Array Attributes](#annotation-array-attributes) - * [1.9.7. Testing](#testing) - * [Constructor injection](#constructor-injection) - * [`PER_CLASS` Lifecycle](#per_class-lifecycle) - * [Specification-like Tests](#specification-like-tests) - * [`WebTestClient` Type Inference Issue in Kotlin](#kotlin-webtestclient-issue) - - * [1.10. Getting Started](#kotlin-getting-started) - * [1.10.1. `start.spring.io`](#start-spring-io) - * [1.10.2. Choosing the Web Flavor](#choosing-the-web-flavor) - - * [1.11. Resources](#kotlin-resources) - * [1.11.1. Examples](#examples) - * [1.11.2. Issues](#issues) - -* [2. Apache Groovy](#groovy) -* [3. Dynamic Language Support](#dynamic-language) - * [3.1. A First Example](#dynamic-language-a-first-example) - * [3.2. Defining Beans that Are Backed by Dynamic Languages](#dynamic-language-beans) - * [3.2.1. Common Concepts](#dynamic-language-beans-concepts) - * [The \ element](#dynamic-language-beans-concepts-xml-language-element) - * [Refreshable Beans](#dynamic-language-refreshable-beans) - * [Inline Dynamic Language Source Files](#dynamic-language-beans-inline) - * [Understanding Constructor Injection in the Context of Dynamic-language-backed Beans](#dynamic-language-beans-ctor-injection) - - * [3.2.2. Groovy Beans](#dynamic-language-beans-groovy) - * [Customizing Groovy Objects by Using a Callback](#dynamic-language-beans-groovy-customizer) - - * [3.2.3. BeanShell Beans](#dynamic-language-beans-bsh) - - * [3.3. Scenarios](#dynamic-language-scenarios) - * [3.3.1. Scripted Spring MVC Controllers](#dynamic-language-scenarios-controllers) - * [3.3.2. Scripted Validators](#dynamic-language-scenarios-validators) - - * [3.4. Additional Details](#dynamic-language-final-notes) - * [3.4.1. AOP — Advising Scripted Beans](#dynamic-language-final-notes-aop) - * [3.4.2. Scoping](#dynamic-language-final-notes-scopes) - * [3.4.3. The `lang` XML schema](#xsd-schemas-lang) - - * [3.5. Further Resources](#dynamic-language-resources) - -[](#kotlin)1. Kotlin ----------- +# Language Support + +## 1. Kotlin [Kotlin](https://kotlinlang.org) is a statically typed language that targets the JVM (and other platforms) which allows writing concise and elegant code while providing @@ -89,7 +16,7 @@ its [dedicated Kotlin support](https://docs.spring.io/spring-boot/docs/current/r Feel free to join the #spring channel of [Kotlin Slack](https://slack.kotlinlang.org/)or ask a question with `spring` and `kotlin` as tags on[Stackoverflow](https://stackoverflow.com/questions/tagged/spring+kotlin) if you need support. -### [](#kotlin-requirements)1.1. Requirements ### +### 1.1. Requirements Spring Framework supports Kotlin 1.3+ and requires[`kotlin-stdlib`](https://search.maven.org/artifact/org.jetbrains.kotlin/kotlin-stdlib)(or one of its variants, such as [`kotlin-stdlib-jdk8`](https://search.maven.org/artifact/org.jetbrains.kotlin/kotlin-stdlib-jdk8)) and [`kotlin-reflect`](https://search.maven.org/artifact/org.jetbrains.kotlin/kotlin-reflect)to be present on the classpath. They are provided by default if you bootstrap a Kotlin project on[start.spring.io](https://start.spring.io/#!language=kotlin&type=gradle-project). @@ -97,7 +24,7 @@ and [`kotlin-reflect`](https://search.maven.org/artifact/org.jetbrains.kotlin/ko | |The [Jackson Kotlin module](https://github.com/FasterXML/jackson-module-kotlin) is required
for serializing or deserializing JSON data for Kotlin classes with Jackson, so make sure to add the`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)1.2. Extensions ### +### 1.2. Extensions Kotlin [extensions](https://kotlinlang.org/docs/reference/extensions.html) provide the ability to extend existing classes with additional functionality. The Spring Framework Kotlin APIs @@ -134,7 +61,7 @@ val users : Flux = client.get().retrieve().bodyToFlux() As in Java, `users` in Kotlin is strongly typed, but Kotlin’s clever type inference allows for shorter syntax. -### [](#kotlin-null-safety)1.3. Null-safety ### +### 1.3. Null-safety One of Kotlin’s key features is [null-safety](https://kotlinlang.org/docs/reference/null-safety.html), which cleanly deals with `null` values at compile time rather than bumping into the famous`NullPointerException` at runtime. This makes applications safer through nullability @@ -162,7 +89,7 @@ be added in the future. | |Generic type arguments, varargs, and array elements nullability are not supported yet,
but should be in an upcoming release. See [this discussion](https://github.com/Kotlin/KEEP/issues/79)for up-to-date information.| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -### [](#kotlin-classes-interfaces)1.4. Classes and Interfaces ### +### 1.4. Classes and Interfaces The Spring Framework supports various Kotlin constructs, such as instantiating Kotlin classes through primary constructors, immutable classes data binding, and function optional parameters @@ -174,7 +101,7 @@ which allows finding interface method parameter names without requiring the Java You can declare configuration classes as[top level or nested but not inner](https://kotlinlang.org/docs/reference/nested-classes.html), since the later requires a reference to the outer class. -### [](#kotlin-annotations)1.5. Annotations ### +### 1.5. Annotations The Spring Framework also takes advantage of [Kotlin null-safety](https://kotlinlang.org/docs/reference/null-safety.html)to determine if an HTTP parameter is required without having to explicitly define the `required` attribute. That means `@RequestParam name: String?` is treated @@ -194,7 +121,7 @@ type `Car` may or may not exist. The same behavior applies to autowired construc | |If you use bean validation on classes with properties or a primary constructor
parameters, you may need to use[annotation use-site targets](https://kotlinlang.org/docs/reference/annotations.html#annotation-use-site-targets),
such as `@field:NotNull` or `@get:Size(min=5, max=15)`, as described in[this Stack Overflow response](https://stackoverflow.com/a/35853200/1092077).| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -### [](#kotlin-bean-definition-dsl)1.6. Bean Definition DSL ### +### 1.6. Bean Definition DSL Spring Framework supports registering beans in a functional way by using lambdas as an alternative to XML or Java configuration (`@Configuration` and `@Bean`). In a nutshell, @@ -298,9 +225,9 @@ val context = GenericApplicationContext().apply { | |Spring Boot is based on JavaConfig and[does not yet provide specific support for functional bean definition](https://github.com/spring-projects/spring-boot/issues/8115),
but you can experimentally use functional bean definitions through Spring Boot’s `ApplicationContextInitializer` support.
See [this Stack Overflow answer](https://stackoverflow.com/questions/45935931/how-to-use-functional-bean-definition-kotlin-dsl-with-spring-boot-and-spring-w/46033685#46033685)for more details and up-to-date information. See also the experimental Kofu DSL developed in [Spring Fu incubator](https://github.com/spring-projects/spring-fu).| |---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -### [](#kotlin-web)1.7. Web ### +### 1.7. Web -#### [](#router-dsl)1.7.1. Router DSL #### +#### 1.7.1. Router DSL Spring Framework comes with a Kotlin router DSL available in 3 flavors: @@ -341,7 +268,7 @@ class RouterRouterConfiguration { See [MiXiT project](https://github.com/mixitconf/mixit/) for a concrete example. -#### [](#mockmvc-dsl)1.7.2. MockMvc DSL #### +#### 1.7.2. MockMvc DSL A Kotlin DSL is provided via `MockMvc` Kotlin extensions in order to provide a more idiomatic Kotlin API and to allow better discoverability (no usage of static methods). @@ -365,7 +292,7 @@ mockMvc.get("/person/{name}", "Lee") { } ``` -#### [](#kotlin-script-templates)1.7.3. Kotlin Script Templates #### +#### 1.7.3. Kotlin Script Templates Spring Framework provides a[`ScriptTemplateView`](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/view/script/ScriptTemplateView.html)which supports [JSR-223](https://www.jcp.org/en/jsr/detail?id=223) to render templates by using script engines. @@ -407,7 +334,7 @@ class KotlinScriptConfiguration { See the [kotlin-script-templating](https://github.com/sdeleuze/kotlin-script-templating) example project for more details. -#### [](#kotlin-multiplatform-serialization)1.7.4. Kotlin multiplatform serialization #### +#### 1.7.4. Kotlin multiplatform serialization As of Spring Framework 5.3, [Kotlin multiplatform serialization](https://github.com/Kotlin/kotlinx.serialization) is supported in Spring MVC, Spring WebFlux and Spring Messaging (RSocket). The builtin support currently only targets JSON format. @@ -418,7 +345,7 @@ 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)1.8. Coroutines ### +### 1.8. Coroutines Kotlin [Coroutines](https://kotlinlang.org/docs/reference/coroutines-overview.html) are Kotlin lightweight threads allowing to write non-blocking code in an imperative way. On language side, @@ -438,7 +365,7 @@ Spring Framework provides support for Coroutines on the following scope: * Extensions for [`RSocketRequester`](https://docs.spring.io/spring-framework/docs/5.3.16/kdoc-api/spring-framework/org.springframework.messaging.rsocket/index.html) -#### [](#dependencies)1.8.1. Dependencies #### +#### 1.8.1. Dependencies Coroutines support is enabled when `kotlinx-coroutines-core` and `kotlinx-coroutines-reactor`dependencies are in the classpath: @@ -454,7 +381,7 @@ dependencies { Version `1.4.0` and above are supported. -#### [](#how-reactive-translates-to-coroutines)1.8.2. How Reactive translates to Coroutines? #### +#### 1.8.2. How Reactive translates to Coroutines? For return values, the translation from Reactive to Coroutines APIs is the following: @@ -488,7 +415,7 @@ For input parameters: Read this blog post about [Going Reactive with Spring, Coroutines and Kotlin Flow](https://spring.io/blog/2019/04/12/going-reactive-with-spring-coroutines-and-kotlin-flow)for more details, including how to run code concurrently with Coroutines. -#### [](#controllers)1.8.3. Controllers #### +#### 1.8.3. Controllers Here is an example of a Coroutines `@RestController`. @@ -582,7 +509,7 @@ class CoroutinesViewController(banner: Banner) { } ``` -#### [](#webflux-fn)1.8.4. WebFlux.fn #### +#### 1.8.4. WebFlux.fn Here is an example of Coroutines router defined via the [coRouter { }](https://docs.spring.io/spring-framework/docs/5.3.16/kdoc-api/spring-framework/org.springframework.web.reactive.function.server/co-router.html) DSL and related handlers. @@ -613,7 +540,7 @@ class UserHandler(builder: WebClient.Builder) { } ``` -#### [](#transactions)1.8.5. Transactions #### +#### 1.8.5. Transactions Transactions on Coroutines are supported via the programmatic variant of the Reactive transaction management provided as of Spring Framework 5.2. @@ -659,12 +586,12 @@ class PersonRepository(private val operator: TransactionalOperator) { } ``` -### [](#kotlin-spring-projects-in-kotlin)1.9. Spring Projects in Kotlin ### +### 1.9. Spring Projects in Kotlin This section provides some specific hints and recommendations worth for developing Spring projects in Kotlin. -#### [](#final-by-default)1.9.1. Final by Default #### +#### 1.9.1. Final by Default By default, [all classes in Kotlin are `final`](https://discuss.kotlinlang.org/t/classes-final-by-default/166). The `open` modifier on a class is the opposite of Java’s `final`: It allows others to inherit from this @@ -702,7 +629,7 @@ without any additional `open` keyword, as in Java. | |The Kotlin code samples in Spring Framework documentation do not explicitly specify`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)1.9.2. Using Immutable Class Instances for Persistence #### +#### 1.9.2. Using Immutable Class Instances for Persistence In Kotlin, it is convenient and considered to be a best practice to declare read-only properties within the primary constructor, as in the following example: @@ -741,7 +668,7 @@ the [`kotlin-noarg`](https://kotlinlang.org/docs/reference/compiler-plugins.html | |As of the Kay release train, Spring Data supports Kotlin immutable class instances and
does not require the `kotlin-noarg` plugin if the module uses Spring Data object mappings
(such as MongoDB, Redis, Cassandra, and others).| |---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#injecting-dependencies)1.9.3. Injecting Dependencies #### +#### 1.9.3. Injecting Dependencies Our recommendation is to try to favor constructor injection with `val` read-only (and non-nullable when possible) [properties](https://kotlinlang.org/docs/reference/properties.html), @@ -773,7 +700,7 @@ class YourBean { } ``` -#### [](#injecting-configuration-properties)1.9.4. Injecting Configuration Properties #### +#### 1.9.4. Injecting Configuration Properties In Java, you can inject configuration properties by using annotations (such as `@Value("${property}")`). However, in Kotlin, `$` is a reserved character that is used for[string interpolation](https://kotlinlang.org/docs/reference/idioms.html#string-interpolation). @@ -807,7 +734,7 @@ fun kotlinPropertyConfigurer() = PropertySourcesPlaceholderConfigurer().apply { fun defaultPropertyConfigurer() = PropertySourcesPlaceholderConfigurer() ``` -#### [](#checked-exceptions)1.9.5. Checked Exceptions #### +#### 1.9.5. Checked Exceptions Java and [Kotlin exception handling](https://kotlinlang.org/docs/reference/exceptions.html)are pretty close, with the main difference being that Kotlin treats all exceptions as unchecked exceptions. However, when using proxied objects (for example classes or methods @@ -816,7 +743,7 @@ an `UndeclaredThrowableException`. To get the original exception thrown like in Java, methods should be annotated with[`@Throws`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/-throws/index.html)to specify explicitly the checked exceptions thrown (for example `@Throws(IOException::class)`). -#### [](#annotation-array-attributes)1.9.6. Annotation Array Attributes #### +#### 1.9.6. Annotation Array Attributes Kotlin annotations are mostly similar to Java annotations, but array attributes (which are extensively used in Spring) behave differently. As explained in the[Kotlin documentation](https://kotlinlang.org/docs/reference/annotations.html) you can omit @@ -855,7 +782,7 @@ use a shortcut annotation, such as `@GetMapping`, `@PostMapping`, and others. | |If the `@RequestMapping` `method` attribute is not specified, all HTTP methods will
be matched, not only the `GET` method.| |---|------------------------------------------------------------------------------------------------------------------------------| -#### [](#testing)1.9.7. Testing #### +#### 1.9.7. Testing This section addresses testing with the combination of Kotlin and Spring Framework. The recommended testing framework is [JUnit 5](https://junit.org/junit5/) along with[Mockk](https://mockk.io/) for mocking. @@ -863,7 +790,7 @@ The recommended testing framework is [JUnit 5](https://junit.org/junit5/) along | |If you are using Spring Boot, see[this related documentation](https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-kotlin-testing).| |---|------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#constructor-injection)Constructor injection ##### +##### Constructor injection As described in the [dedicated section](testing.html#testcontext-junit-jupiter-di#spring-web-reactive), JUnit 5 allows constructor injection of beans which is pretty useful with Kotlin @@ -879,7 +806,7 @@ class OrderServiceIntegrationTests(val orderService: OrderService, } ``` -##### [](#per_class-lifecycle)`PER_CLASS` Lifecycle ##### +##### `PER_CLASS` Lifecycle Kotlin lets you specify meaningful test function names between backticks (```). As of JUnit 5, Kotlin test classes can use the `@TestInstance(TestInstance.Lifecycle.PER_CLASS)`annotation to enable single instantiation of test classes, which allows the use of `@BeforeAll`and `@AfterAll` annotations on non-static methods, which is a good fit for Kotlin. @@ -918,7 +845,7 @@ class IntegrationTests { } ``` -##### [](#specification-like-tests)Specification-like Tests ##### +##### Specification-like Tests You can create specification-like tests with JUnit 5 and Kotlin. The following example shows how to do so: @@ -946,7 +873,7 @@ class SpecificationLikeTests { } ``` -##### [](#kotlin-webtestclient-issue)`WebTestClient` Type Inference Issue in Kotlin ##### +##### `WebTestClient` Type Inference Issue in Kotlin Due to a [type inference issue](https://youtrack.jetbrains.com/issue/KT-5464), you must use the Kotlin `expectBody` extension (such as `.expectBody().isEqualTo("toys")`), @@ -954,16 +881,16 @@ since it provides a workaround for the Kotlin issue with the Java API. See also the related [SPR-16057](https://jira.spring.io/browse/SPR-16057) issue. -### [](#kotlin-getting-started)1.10. Getting Started ### +### 1.10. Getting Started The easiest way to learn how to build a Spring application with Kotlin is to follow[the dedicated tutorial](https://spring.io/guides/tutorials/spring-boot-kotlin/). -#### [](#start-spring-io)1.10.1. `start.spring.io` #### +#### 1.10.1. `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 [start.spring.io](https://start.spring.io/#!language=kotlin&type=gradle-project). -#### [](#choosing-the-web-flavor)1.10.2. Choosing the Web Flavor #### +#### 1.10.2. Choosing the Web Flavor Spring Framework now comes with two different web stacks: [Spring MVC](web.html#mvc) and[Spring WebFlux](web-reactive.html#spring-web-reactive). @@ -974,7 +901,7 @@ 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)1.11. Resources ### +### 1.11. Resources We recommend the following resources for people learning how to build applications with Kotlin and the Spring Framework: @@ -991,7 +918,7 @@ Kotlin and the Spring Framework: * [Awesome Kotlin](https://kotlin.link/) -#### [](#examples)1.11.1. Examples #### +#### 1.11.1. Examples The following Github projects offer examples that you can learn from and possibly even extend: @@ -1009,7 +936,7 @@ The following Github projects offer examples that you can learn from and possibl * [spring-cloud-gcp-kotlin-app-sample](https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-kotlin-samples/spring-cloud-gcp-kotlin-app-sample): Spring Boot with Google Cloud Platform Integrations -#### [](#issues)1.11.2. Issues #### +#### 1.11.2. Issues The following list categorizes the pending issues related to Spring and Kotlin support: @@ -1033,8 +960,7 @@ The following list categorizes the pending issues related to Spring and Kotlin s * [Kotlin properties do not override Java-style getters and setters](https://youtrack.jetbrains.com/issue/KT-6653) -[](#groovy)2. Apache Groovy ----------- +## 2. Apache Groovy Groovy is a powerful, optionally typed, and dynamic language, with static-typing and static compilation capabilities. It offers a concise syntax and integrates smoothly with any @@ -1046,8 +972,7 @@ Bean Definition DSL. For more details, see[The Groovy Bean Definition DSL](core. Further support for Groovy, including beans written in Groovy, refreshable script beans, and more is available in [Dynamic Language Support](#dynamic-language). -[](#dynamic-language)3. Dynamic Language Support ----------- +## 3. Dynamic Language Support Spring provides comprehensive support for using classes and objects that have been defined by using a dynamic language (such as Groovy) with Spring. This support lets @@ -1063,7 +988,7 @@ e.g. JRuby. You can find fully working examples of where this dynamic language support can be immediately useful in [Scenarios](#dynamic-language-scenarios). -### [](#dynamic-language-a-first-example)3.1. A First Example ### +### 3.1. A First Example The bulk of this chapter is concerned with describing the dynamic language support in detail. Before diving into all of the ins and outs of the dynamic language support, @@ -1155,7 +1080,7 @@ plain Groovy. Hopefully, the preceding XML snippet is self-explanatory, but do not worry unduly if it is not. Keep reading for the in-depth detail on the whys and wherefores of the preceding configuration. -### [](#dynamic-language-beans)3.2. Defining Beans that Are Backed by Dynamic Languages ### +### 3.2. Defining Beans that Are Backed by Dynamic Languages This section describes exactly how you define Spring-managed beans in any of the supported dynamic languages. @@ -1166,7 +1091,7 @@ in your application, we assume that you already know Groovy. If you need further about the dynamic languages themselves, see [Further Resources](#dynamic-language-resources) at the end of this chapter. -#### [](#dynamic-language-beans-concepts)3.2.1. Common Concepts #### +#### 3.2.1. Common Concepts The steps involved in using dynamic-language-backed beans are as follows: @@ -1187,7 +1112,7 @@ source files. You first want to read the rest of this chapter, though, as Spring’s dynamic language support does make some (small) assumptions about the contents of your dynamic language source files. -##### [](#dynamic-language-beans-concepts-xml-language-element)The \ element ##### +##### The \ element The final step in the list in the [preceding section](#dynamic-language-beans-concepts)involves defining dynamic-language-backed bean definitions, one for each bean that you want to configure (this is no different from normal JavaBean configuration). However, @@ -1206,7 +1131,7 @@ The exact attributes and child elements that are available for configuration dep exactly which language the bean has been defined in (the language-specific sections later in this chapter detail this). -##### [](#dynamic-language-refreshable-beans)Refreshable Beans ##### +##### Refreshable Beans One of the (and perhaps the single) most compelling value adds of the dynamic language support in Spring is the “refreshable bean” feature. @@ -1327,7 +1252,7 @@ changes to the underlying source file can actually be detected (for example, by that checks the last modified date of a dynamic language source file that exists on the file system). -##### [](#dynamic-language-beans-inline)Inline Dynamic Language Source Files ##### +##### Inline Dynamic Language Source Files The dynamic language support can also cater to dynamic language source files that are embedded directly in Spring bean definitions. More specifically, the`` element lets you define dynamic language source immediately @@ -1357,7 +1282,7 @@ Spring `Validator` implementation to a Spring MVC `Controller`. This is but a mo work using inline source. (See [Scripted Validators](#dynamic-language-scenarios-validators) for such an example.) -##### [](#dynamic-language-beans-ctor-injection)Understanding Constructor Injection in the Context of Dynamic-language-backed Beans ##### +##### Understanding Constructor Injection in the Context of Dynamic-language-backed Beans There is one very important thing to be aware of with regard to Spring’s dynamic language support. Namely, you can not (currently) supply constructor arguments @@ -1406,7 +1331,7 @@ In practice this limitation is not as significant as it first appears, since set injection is the injection style favored by the overwhelming majority of developers (we leave the discussion as to whether that is a good thing to another day). -#### [](#dynamic-language-beans-groovy)3.2.2. Groovy Beans #### +#### 3.2.2. Groovy Beans This section describes how to use beans defined in Groovy in Spring. @@ -1478,7 +1403,7 @@ legal in Groovy, it is (arguably) a bad practice. In the interests of a consiste approach, you should (in the opinion of the Spring team) respect the standard Java conventions of one (public) class per source file. -##### [](#dynamic-language-beans-groovy-customizer)Customizing Groovy Objects by Using a Callback ##### +##### Customizing Groovy Objects by Using a Callback The `GroovyObjectCustomizer` interface is a callback that lets you hook additional creation logic into the process of creating a Groovy-backed bean. For example, @@ -1548,7 +1473,7 @@ If you do not use the Spring namespace support, you can still use the`GroovyObje | |You may also specify a Groovy `CompilationCustomizer` (such as an `ImportCustomizer`)
or even a full Groovy `CompilerConfiguration` object in the same place as Spring’s`GroovyObjectCustomizer`. Furthermore, you may set a common `GroovyClassLoader` with custom
configuration for your beans at the `ConfigurableApplicationContext.setClassLoader` level;
this also leads to shared `GroovyClassLoader` usage and is therefore recommendable in case of
a large number of scripted beans (avoiding an isolated `GroovyClassLoader` instance per bean).| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#dynamic-language-beans-bsh)3.2.3. BeanShell Beans #### +#### 3.2.3. BeanShell Beans This section describes how to use BeanShell beans in Spring. @@ -1612,13 +1537,13 @@ The following example shows the Spring XML that defines an “instance” of the See [Scenarios](#dynamic-language-scenarios) for some scenarios where you might want to use BeanShell-based beans. -### [](#dynamic-language-scenarios)3.3. Scenarios ### +### 3.3. Scenarios The possible scenarios where defining Spring managed beans in a scripting language would be beneficial are many and varied. This section describes two possible use cases for the dynamic language support in Spring. -#### [](#dynamic-language-scenarios-controllers)3.3.1. Scripted Spring MVC Controllers #### +#### 3.3.1. Scripted Spring MVC Controllers One group of classes that can benefit from using dynamic-language-backed beans is that of Spring MVC controllers. In pure Spring MVC applications, the navigational flow @@ -1674,7 +1599,7 @@ class FortuneController implements Controller { ``` -#### [](#dynamic-language-scenarios-validators)3.3.2. Scripted Validators #### +#### 3.3.2. Scripted Validators Another area of application development with Spring that may benefit from the flexibility afforded by dynamic-language-backed beans is that of validation. It can @@ -1711,11 +1636,11 @@ class TestBeanValidator implements Validator { } ``` -### [](#dynamic-language-final-notes)3.4. Additional Details ### +### 3.4. Additional Details This last section contains some additional details related to the dynamic language support. -#### [](#dynamic-language-final-notes-aop)3.4.1. AOP — Advising Scripted Beans #### +#### 3.4.1. AOP — Advising Scripted Beans You can use the Spring AOP framework to advise scripted beans. The Spring AOP framework actually is unaware that a bean that is being advised might be a scripted @@ -1727,7 +1652,7 @@ You are not limited to advising scripted beans. You can also write aspects thems in a supported dynamic language and use such beans to advise other Spring beans. This really would be an advanced use of the dynamic language support though. -#### [](#dynamic-language-final-notes-scopes)3.4.2. Scoping #### +#### 3.4.2. Scoping In case it is not immediately obvious, scripted beans can be scoped in the same way as any other bean. The `scope` attribute on the various `` elements lets @@ -1759,7 +1684,7 @@ a [prototype](core.html#beans-factory-scopes-prototype): See [Bean Scopes](core.html#beans-factory-scopes) in [The IoC Container](core.html#beans)for a full discussion of the scoping support in the Spring Framework. -#### [](#xsd-schemas-lang)3.4.3. The `lang` XML schema #### +#### 3.4.3. The `lang` XML schema The `lang` elements in Spring XML configuration deal with exposing objects that have been written in a dynamic language (such as Groovy or BeanShell) as beans in the Spring container. @@ -1785,7 +1710,7 @@ the correct schema so that the tags in the `lang` namespace are available to you ``` -### [](#dynamic-language-resources)3.5. Further Resources ### +### 3.5. Further Resources The following links go to further resources about the various dynamic languages referenced in this chapter: diff --git a/docs/en/spring-framework/overview.md b/docs/en/spring-framework/overview.md index e09d46f..55a15b9 100644 --- a/docs/en/spring-framework/overview.md +++ b/docs/en/spring-framework/overview.md @@ -1,15 +1,4 @@ -Spring Framework Overview -========== - -version 5.3.16 - -Table of Contents - -* [1. What We Mean by "Spring"](#overview-spring) -* [2. History of Spring and the Spring Framework](#overview-history) -* [3. Design Philosophy](#overview-philosophy) -* [4. Feedback and Contributions](#overview-feedback) -* [5. Getting Started](#overview-getting-started) +# Spring Framework Overview 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 @@ -29,8 +18,7 @@ Spring is open source. It has a large and active community that provides continu based on a diverse range of real-world use cases. This has helped Spring to successfully evolve over a very long time. -[](#overview-spring)1. What We Mean by "Spring" ----------- +## 1. What We Mean by "Spring" The term "Spring" means different things in different contexts. It can be used to refer to the Spring Framework project itself, which is where it all started. Over time, other Spring @@ -52,8 +40,7 @@ A note about modules: Spring’s framework jars allow for deployment to JDK 9’ the same naming pattern with "-" instead of ".", e.g. "spring-core" and "spring-context"). Of course, Spring’s framework jars keep working fine on the classpath on both JDK 8 and 9+. -[](#overview-history)2. History of Spring and the Spring Framework ----------- +## 2. History of Spring and the Spring Framework Spring came into being in 2003 as a response to the complexity of the early[J2EE](https://en.wikipedia.org/wiki/Java_Platform,_Enterprise_Edition) specifications. While some consider Java EE and Spring to be in competition, Spring is, in fact, complementary @@ -99,8 +86,7 @@ among others. It’s important to remember that each project has its own source issue tracker, and release cadence. See [spring.io/projects](https://spring.io/projects) for the complete list of Spring projects. -[](#overview-philosophy)3. Design Philosophy ----------- +## 3. Design Philosophy When you learn about a framework, it’s important to know not only what it does but what principles it follows. Here are the guiding principles of the Spring Framework: @@ -126,8 +112,7 @@ principles it follows. Here are the guiding principles of the Spring Framework: meaningful, current, and accurate javadoc. It is one of very few projects that can claim clean code structure with no circular dependencies between packages. -[](#overview-feedback)4. Feedback and Contributions ----------- +## 4. Feedback and Contributions For how-to questions or diagnosing or debugging issues, we suggest using Stack Overflow. Click[here](https://stackoverflow.com/questions/tagged/spring+or+spring-mvc+or+spring-aop+or+spring-jdbc+or+spring-r2dbc+or+spring-transactions+or+spring-annotations+or+spring-jms+or+spring-el+or+spring-test+or+spring+or+spring-remoting+or+spring-orm+or+spring-jmx+or+spring-cache+or+spring-webflux+or+spring-rsocket?tab=Newest)for a list of the suggested tags to use on Stack Overflow. If you’re fairly certain that there is a problem in the Spring Framework or would like to suggest a feature, please use @@ -140,8 +125,7 @@ tracker, where discussions take place and leave a record for future reference. For more details see the guidelines at the [CONTRIBUTING](https://github.com/spring-projects/spring-framework/tree/main/CONTRIBUTING.md), top-level project page. -[](#overview-getting-started)5. Getting Started ----------- +## 5. Getting Started If you are just getting started with Spring, you may want to begin using the Spring Framework by creating a [Spring Boot](https://projects.spring.io/spring-boot/)-based diff --git a/docs/en/spring-framework/testing.md b/docs/en/spring-framework/testing.md index b761d95..e8aafba 100644 --- a/docs/en/spring-framework/testing.md +++ b/docs/en/spring-framework/testing.md @@ -1,165 +1,4 @@ -Testing -========== - -version 5.3.16 - -Table of Contents - -* [1. Introduction to Spring Testing](#testing-introduction) -* [2. Unit Testing](#unit-testing) - * [2.1. Mock Objects](#mock-objects) - * [2.1.1. Environment](#mock-objects-env) - * [2.1.2. JNDI](#mock-objects-jndi) - * [2.1.3. Servlet API](#mock-objects-servlet) - * [2.1.4. Spring Web Reactive](#mock-objects-web-reactive) - - * [2.2. Unit Testing Support Classes](#unit-testing-support-classes) - * [2.2.1. General Testing Utilities](#unit-testing-utilities) - * [2.2.2. Spring MVC Testing Utilities](#unit-testing-spring-mvc) - -* [3. Integration Testing](#integration-testing) - * [3.1. Overview](#integration-testing-overview) - * [3.2. Goals of Integration Testing](#integration-testing-goals) - * [3.2.1. Context Management and Caching](#testing-ctx-management) - * [3.2.2. Dependency Injection of Test Fixtures](#testing-fixture-di) - * [3.2.3. Transaction Management](#testing-tx) - * [3.2.4. Support Classes for Integration Testing](#testing-support-classes) - - * [3.3. JDBC Testing Support](#integration-testing-support-jdbc) - * [3.4. Annotations](#integration-testing-annotations) - * [3.4.1. Spring Testing Annotations](#integration-testing-annotations-spring) - * [`@BootstrapWith`](#spring-testing-annotation-bootstrapwith) - * [`@ContextConfiguration`](#spring-testing-annotation-contextconfiguration) - * [`@WebAppConfiguration`](#spring-testing-annotation-webappconfiguration) - * [`@ContextHierarchy`](#spring-testing-annotation-contexthierarchy) - * [`@ActiveProfiles`](#spring-testing-annotation-activeprofiles) - * [`@TestPropertySource`](#spring-testing-annotation-testpropertysource) - * [`@DynamicPropertySource`](#spring-testing-annotation-dynamicpropertysource) - * [`@DirtiesContext`](#spring-testing-annotation-dirtiescontext) - * [`@TestExecutionListeners`](#spring-testing-annotation-testexecutionlisteners) - * [`@RecordApplicationEvents`](#spring-testing-annotation-recordapplicationevents) - * [`@Commit`](#spring-testing-annotation-commit) - * [`@Rollback`](#spring-testing-annotation-rollback) - * [`@BeforeTransaction`](#spring-testing-annotation-beforetransaction) - * [`@AfterTransaction`](#spring-testing-annotation-aftertransaction) - * [`@Sql`](#spring-testing-annotation-sql) - * [`@SqlConfig`](#spring-testing-annotation-sqlconfig) - * [`@SqlMergeMode`](#spring-testing-annotation-sqlmergemode) - * [`@SqlGroup`](#spring-testing-annotation-sqlgroup) - - * [3.4.2. Standard Annotation Support](#integration-testing-annotations-standard) - * [3.4.3. Spring JUnit 4 Testing Annotations](#integration-testing-annotations-junit4) - * [`@IfProfileValue`](#integration-testing-annotations-junit4-ifprofilevalue) - * [`@ProfileValueSourceConfiguration`](#integration-testing-annotations-junit4-profilevaluesourceconfiguration) - * [`@Timed`](#integration-testing-annotations-junit4-timed) - * [`@Repeat`](#integration-testing-annotations-junit4-repeat) - - * [3.4.4. Spring JUnit Jupiter Testing Annotations](#integration-testing-annotations-junit-jupiter) - * [`@SpringJUnitConfig`](#integration-testing-annotations-junit-jupiter-springjunitconfig) - * [`@SpringJUnitWebConfig`](#integration-testing-annotations-junit-jupiter-springjunitwebconfig) - * [`@TestConstructor`](#integration-testing-annotations-testconstructor) - * [`@NestedTestConfiguration`](#integration-testing-annotations-nestedtestconfiguration) - * [`@EnabledIf`](#integration-testing-annotations-junit-jupiter-enabledif) - * [`@DisabledIf`](#integration-testing-annotations-junit-jupiter-disabledif) - - * [3.4.5. Meta-Annotation Support for Testing](#integration-testing-annotations-meta) - - * [3.5. Spring TestContext Framework](#testcontext-framework) - * [3.5.1. Key Abstractions](#testcontext-key-abstractions) - * [`TestContext`](#testcontext) - * [`TestContextManager`](#testcontextmanager) - * [`TestExecutionListener`](#testexecutionlistener) - * [Context Loaders](#context-loaders) - - * [3.5.2. Bootstrapping the TestContext Framework](#testcontext-bootstrapping) - * [3.5.3. `TestExecutionListener` Configuration](#testcontext-tel-config) - * [Registering `TestExecutionListener` Implementations](#testcontext-tel-config-registering-tels) - * [Automatic Discovery of Default `TestExecutionListener` Implementations](#testcontext-tel-config-automatic-discovery) - * [Ordering `TestExecutionListener` Implementations](#testcontext-tel-config-ordering) - * [Merging `TestExecutionListener` Implementations](#testcontext-tel-config-merging) - - * [3.5.4. Application Events](#testcontext-application-events) - * [3.5.5. Test Execution Events](#testcontext-test-execution-events) - * [Exception Handling](#testcontext-test-execution-events-exception-handling) - * [Asynchronous Listeners](#testcontext-test-execution-events-async) - - * [3.5.6. Context Management](#testcontext-ctx-management) - * [Context Configuration with XML resources](#testcontext-ctx-management-xml) - * [Context Configuration with Groovy Scripts](#testcontext-ctx-management-groovy) - * [Context Configuration with Component Classes](#testcontext-ctx-management-javaconfig) - * [Mixing XML, Groovy Scripts, and Component Classes](#testcontext-ctx-management-mixed-config) - * [Context Configuration with Context Initializers](#testcontext-ctx-management-initializers) - * [Context Configuration Inheritance](#testcontext-ctx-management-inheritance) - * [Context Configuration with Environment Profiles](#testcontext-ctx-management-env-profiles) - * [Context Configuration with Test Property Sources](#testcontext-ctx-management-property-sources) - * [Context Configuration with Dynamic Property Sources](#testcontext-ctx-management-dynamic-property-sources) - * [Loading a `WebApplicationContext`](#testcontext-ctx-management-web) - * [Context Caching](#testcontext-ctx-management-caching) - * [Context Hierarchies](#testcontext-ctx-management-ctx-hierarchies) - - * [3.5.7. Dependency Injection of Test Fixtures](#testcontext-fixture-di) - * [3.5.8. Testing Request- and Session-scoped Beans](#testcontext-web-scoped-beans) - * [3.5.9. Transaction Management](#testcontext-tx) - * [Test-managed Transactions](#testcontext-tx-test-managed-transactions) - * [Enabling and Disabling Transactions](#testcontext-tx-enabling-transactions) - * [Transaction Rollback and Commit Behavior](#testcontext-tx-rollback-and-commit-behavior) - * [Programmatic Transaction Management](#testcontext-tx-programmatic-tx-mgt) - * [Running Code Outside of a Transaction](#testcontext-tx-before-and-after-tx) - * [Configuring a Transaction Manager](#testcontext-tx-mgr-config) - * [Demonstration of All Transaction-related Annotations](#testcontext-tx-annotation-demo) - - * [3.5.10. Executing SQL Scripts](#testcontext-executing-sql) - * [Executing SQL scripts programmatically](#testcontext-executing-sql-programmatically) - * [Executing SQL scripts declaratively with @Sql](#testcontext-executing-sql-declaratively) - - * [3.5.11. Parallel Test Execution](#testcontext-parallel-test-execution) - * [3.5.12. TestContext Framework Support Classes](#testcontext-support-classes) - * [Spring JUnit 4 Runner](#testcontext-junit4-runner) - * [Spring JUnit 4 Rules](#testcontext-junit4-rules) - * [JUnit 4 Support Classes](#testcontext-support-classes-junit4) - * [SpringExtension for JUnit Jupiter](#testcontext-junit-jupiter-extension) - * [Dependency Injection with `SpringExtension`](#testcontext-junit-jupiter-di) - * [`@Nested` test class configuration](#testcontext-junit-jupiter-nested-test-configuration) - * [TestNG Support Classes](#testcontext-support-classes-testng) - - * [3.6. WebTestClient](#webtestclient) - * [3.6.1. Setup](#webtestclient-setup) - * [Bind to Controller](#webtestclient-controller-config) - * [Bind to `ApplicationContext`](#webtestclient-context-config) - * [Bind to Router Function](#webtestclient-fn-config) - * [Bind to Server](#webtestclient-server-config) - * [Client Config](#webtestclient-client-config) - - * [3.6.2. Writing Tests](#webtestclient-tests) - * [No Content](#webtestclient-no-content) - * [JSON Content](#webtestclient-json) - * [Streaming Responses](#webtestclient-stream) - * [MockMvc Assertions](#webtestclient-mockmvc) - - * [3.7. MockMvc](#spring-mvc-test-framework) - * [3.7.1. Overview](#spring-mvc-test-server) - * [Static Imports](#spring-mvc-test-server-static-imports) - * [Setup Choices](#spring-mvc-test-server-setup-options) - * [Setup Features](#spring-mvc-test-server-setup-steps) - * [Performing Requests](#spring-mvc-test-server-performing-requests) - * [Defining Expectations](#spring-mvc-test-server-defining-expectations) - * [Async Requests](#spring-mvc-test-async-requests) - * [Streaming Responses](#spring-mvc-test-vs-streaming-response) - * [Filter Registrations](#spring-mvc-test-server-filters) - * [MockMvc vs End-to-End Tests](#spring-mvc-test-vs-end-to-end-integration-tests) - * [Further Examples](#spring-mvc-test-server-resources) - - * [3.7.2. HtmlUnit Integration](#spring-mvc-test-server-htmlunit) - * [Why HtmlUnit Integration?](#spring-mvc-test-server-htmlunit-why) - * [MockMvc and HtmlUnit](#spring-mvc-test-server-htmlunit-mah) - * [MockMvc and WebDriver](#spring-mvc-test-server-htmlunit-webdriver) - * [MockMvc and Geb](#spring-mvc-test-server-htmlunit-geb) - - * [3.8. Testing Client Applications](#spring-mvc-test-client) - * [3.8.1. Static Imports](#spring-mvc-test-client-static-imports) - * [3.8.2. Further Examples of Client-side REST Tests](#spring-mvc-test-client-resources) - -* [4. Further Resources](#testing-resources) +# Testing This chapter covers Spring’s support for integration testing and best practices for unit testing. The Spring team advocates test-driven development (TDD). The Spring team has @@ -168,8 +7,7 @@ and integration testing easier (in that the presence of setter methods and appro constructors on classes makes them easier to wire together in a test without having to set up service locator registries and similar structures). -[](#testing-introduction)1. Introduction to Spring Testing ----------- +## 1. 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 @@ -177,8 +15,7 @@ of the Spring Framework’s support for [integration testing](#integration-testi thorough treatment of testing in the enterprise is beyond the scope of this reference manual.) -[](#unit-testing)2. Unit Testing ----------- +## 2. Unit Testing Dependency injection should make your code less dependent on the container than it would be with traditional Java EE development. The POJOs that make up your application should @@ -195,7 +32,7 @@ effective unit tests for your IoC-based applications. For certain unit testing s however, the Spring Framework provides mock objects and testing support classes, which are described in this chapter. -### [](#mock-objects)2.1. Mock Objects ### +### 2.1. Mock Objects Spring includes a number of packages dedicated to mocking: @@ -207,12 +44,12 @@ Spring includes a number of packages dedicated to mocking: * [Spring Web Reactive](#mock-objects-web-reactive) -#### [](#mock-objects-env)2.1.1. Environment #### +#### 2.1.1. Environment The `org.springframework.mock.env` package contains mock implementations of the`Environment` and `PropertySource` abstractions (see[Bean Definition Profiles](core.html#beans-definition-profiles)and [`PropertySource` Abstraction](core.html#beans-property-source-abstraction)).`MockEnvironment` and `MockPropertySource` are useful for developing out-of-container tests for code that depends on environment-specific properties. -#### [](#mock-objects-jndi)2.1.2. JNDI #### +#### 2.1.2. 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 @@ -223,7 +60,7 @@ and configuration in testing scenarios without modification. | |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 [Simple-JNDI](https://github.com/h-thurow/Simple-JNDI).| |---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#mock-objects-servlet)2.1.3. Servlet API #### +#### 2.1.3. 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 @@ -237,7 +74,7 @@ or alternative Servlet API mock objects (such as [MockObjects](http://www.mockob The Spring MVC Test framework builds on the mock Servlet API objects to provide an integration testing framework for Spring MVC. See [MockMvc](#spring-mvc-test-framework). -#### [](#mock-objects-web-reactive)2.1.4. Spring Web Reactive #### +#### 2.1.4. 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 @@ -256,7 +93,7 @@ The [WebTestClient](#webtestclient) builds on the mock request and response to p 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)2.2. Unit Testing Support Classes ### +### 2.2. Unit Testing Support Classes Spring includes a number of classes that can help with unit testing. They fall into two categories: @@ -265,7 +102,7 @@ categories: * [Spring MVC Testing Utilities](#unit-testing-spring-mvc) -#### [](#unit-testing-utilities)2.2.1. General Testing Utilities #### +#### 2.2.1. General Testing Utilities The `org.springframework.test.util` package contains several general purpose utilities for use in unit and integration testing. @@ -293,7 +130,7 @@ and the mock is wrapped in a Spring proxy, you may need direct access to the und mock to configure expectations on it and perform verifications. For Spring’s core AOP utilities, see [`AopUtils`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/aop/support/AopUtils.html) and[`AopProxyUtils`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/aop/framework/AopProxyUtils.html). -#### [](#unit-testing-spring-mvc)2.2.2. Spring MVC Testing Utilities #### +#### 2.2.2. Spring MVC Testing Utilities The `org.springframework.test.web` package contains[`ModelAndViewAssert`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/test/web/ModelAndViewAssert.html), which you can use in combination with JUnit, TestNG, or any other testing framework for unit tests @@ -302,8 +139,7 @@ that deal with Spring MVC `ModelAndView` objects. | |Unit testing Spring MVC Controllers

To unit test your Spring MVC `Controller` classes as POJOs, use `ModelAndViewAssert`combined with `MockHttpServletRequest`, `MockHttpSession`, and so on from Spring’s[Servlet API mocks](#mock-objects-servlet). 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.| |---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -[](#integration-testing)3. Integration Testing ----------- +## 3. Integration Testing This section (most of the rest of this chapter) covers integration testing for Spring applications. It includes the following topics: @@ -320,7 +156,7 @@ applications. It includes the following topics: * [MockMvc](#spring-mvc-test-framework) -### [](#integration-testing-overview)3.1. Overview ### +### 3.1. Overview It is important to be able to perform some integration testing without requiring deployment to your application server or connecting to other enterprise infrastructure. @@ -343,7 +179,7 @@ Unit and integration testing support is provided in the form of the annotation-d agnostic of the actual testing framework in use, which allows instrumentation of tests in various environments, including JUnit, TestNG, and others. -### [](#integration-testing-goals)3.2. Goals of Integration Testing ### +### 3.2. Goals of Integration Testing Spring’s integration testing support has the following primary goals: @@ -359,7 +195,7 @@ Spring’s integration testing support has the following primary goals: The next few sections describe each goal and provide links to implementation and configuration details. -#### [](#testing-ctx-management)3.2.1. Context Management and Caching #### +#### 3.2.1. 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 @@ -387,7 +223,7 @@ rebuild the application context before executing the next test. See [Context Management](#testcontext-ctx-management) and [Context Caching](#testcontext-ctx-management-caching) with the TestContext framework. -#### [](#testing-fixture-di)3.2.2. Dependency Injection of Test Fixtures #### +#### 3.2.2. 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 @@ -411,7 +247,7 @@ integration tests that test the following areas: See dependency injection of test fixtures with the[TestContext framework](#testcontext-fixture-di). -#### [](#testing-tx)3.2.3. Transaction Management #### +#### 3.2.3. 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 @@ -433,7 +269,7 @@ framework to cause the transaction to commit instead of roll back by using the[` See transaction management with the [TestContext framework](#testcontext-tx). -#### [](#testing-support-classes)3.2.4. Support Classes for Integration Testing #### +#### 3.2.4. 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 @@ -454,7 +290,7 @@ instance variables and methods specific to your project. See support classes for the [TestContext framework](#testcontext-support-classes). -### [](#integration-testing-support-jdbc)3.3. JDBC Testing Support ### +### 3.3. JDBC Testing Support The `org.springframework.test.jdbc` package contains `JdbcTestUtils`, which is a collection of JDBC-related utility functions intended to simplify standard database @@ -475,7 +311,7 @@ methods. | |[`AbstractTransactionalJUnit4SpringContextTests`](#testcontext-support-classes-junit4)and [`AbstractTransactionalTestNGSpringContextTests`](#testcontext-support-classes-testng)provide convenience methods that delegate to the aforementioned methods in`JdbcTestUtils`.

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 [Embedded Database
Support](data-access.html#jdbc-embedded-database-support) and [Testing Data Access
Logic with an Embedded Database](data-access.html#jdbc-embedded-database-dao-testing).| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -### [](#integration-testing-annotations)3.4. Annotations ### +### 3.4. Annotations This section covers annotations that you can use when you test Spring applications. It includes the following topics: @@ -490,7 +326,7 @@ It includes the following topics: * [Meta-Annotation Support for Testing](#integration-testing-annotations-meta) -#### [](#integration-testing-annotations-spring)3.4.1. Spring Testing Annotations #### +#### 3.4.1. Spring Testing Annotations The Spring Framework provides the following set of Spring-specific annotations that you can use in your unit and integration tests in conjunction with the TestContext framework. @@ -535,13 +371,13 @@ Spring’s testing annotations include the following: * [`@SqlGroup`](#spring-testing-annotation-sqlgroup) -##### [](#spring-testing-annotation-bootstrapwith)`@BootstrapWith` ##### +##### `@BootstrapWith` `@BootstrapWith` is a class-level annotation that you can use to configure how the Spring TestContext Framework is bootstrapped. Specifically, you can use `@BootstrapWith` to specify a custom `TestContextBootstrapper`. See the section on[bootstrapping the TestContext framework](#testcontext-bootstrapping) for further details. -##### [](#spring-testing-annotation-contextconfiguration)`@ContextConfiguration` ##### +##### `@ContextConfiguration` `@ContextConfiguration` defines class-level metadata that is used to determine how to load and configure an `ApplicationContext` for integration tests. Specifically,`@ContextConfiguration` declares the application context resource `locations` or the @@ -669,7 +505,7 @@ class CustomLoaderXmlApplicationContextTests { See [Context Management](#testcontext-ctx-management),[`@Nested` test class configuration](#testcontext-junit-jupiter-nested-test-configuration), and the `@ContextConfiguration`javadocs for further details. -##### [](#spring-testing-annotation-webappconfiguration)`@WebAppConfiguration` ##### +##### `@WebAppConfiguration` `@WebAppConfiguration` is a class-level annotation that you can use to declare that the`ApplicationContext` loaded for an integration test should be a `WebApplicationContext`. The mere presence of `@WebAppConfiguration` on a test class ensures that a`WebApplicationContext` is loaded for the test, using the default value of`"file:src/main/webapp"` for the path to the root of the web application (that is, the @@ -734,7 +570,7 @@ class WebAppTests { Note that `@WebAppConfiguration` must be used in conjunction with`@ContextConfiguration`, either within a single test class or within a test class hierarchy. See the[`@WebAppConfiguration`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/test/context/web/WebAppConfiguration.html)javadoc for further details. -##### [](#spring-testing-annotation-contexthierarchy)`@ContextHierarchy` ##### +##### `@ContextHierarchy` `@ContextHierarchy` is a class-level annotation that is used to define a hierarchy of`ApplicationContext` instances for integration tests. `@ContextHierarchy` should be declared with a list of one or more `@ContextConfiguration` instances, each of which @@ -795,7 +631,7 @@ the same value to the `name` attribute in `@ContextConfiguration` at each corres level in the class hierarchy. See [Context Hierarchies](#testcontext-ctx-management-ctx-hierarchies) and the[`@ContextHierarchy`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/test/context/ContextHierarchy.html) javadoc for further examples. -##### [](#spring-testing-annotation-activeprofiles)`@ActiveProfiles` ##### +##### `@ActiveProfiles` `@ActiveProfiles` is a class-level annotation that is used to declare which bean definition profiles should be active when loading an `ApplicationContext` for an @@ -864,7 +700,7 @@ class DeveloperIntegrationTests { See [Context Configuration with Environment Profiles](#testcontext-ctx-management-env-profiles),[`@Nested` test class configuration](#testcontext-junit-jupiter-nested-test-configuration), and the[`@ActiveProfiles`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/test/context/ActiveProfiles.html) javadoc for examples and further details. -##### [](#spring-testing-annotation-testpropertysource)`@TestPropertySource` ##### +##### `@TestPropertySource` `@TestPropertySource` is a class-level annotation that you can use to configure the locations of properties files and inlined properties to be added to the set of`PropertySources` in the `Environment` for an `ApplicationContext` loaded for an @@ -928,7 +764,7 @@ class MyIntegrationTests { See [Context Configuration with Test Property Sources](#testcontext-ctx-management-property-sources) for examples and further details. -##### [](#spring-testing-annotation-dynamicpropertysource)`@DynamicPropertySource` ##### +##### `@DynamicPropertySource` `@DynamicPropertySource` is a method-level annotation that you can use to register*dynamic* properties to be added to the set of `PropertySources` in the `Environment` for an `ApplicationContext` loaded for an integration test. Dynamic properties are useful @@ -988,7 +824,7 @@ class MyIntegrationTests { See [Context Configuration with Dynamic Property Sources](#testcontext-ctx-management-dynamic-property-sources) for further details. -##### [](#spring-testing-annotation-dirtiescontext)`@DirtiesContext` ##### +##### `@DirtiesContext` `@DirtiesContext` indicates that the underlying Spring `ApplicationContext` has been dirtied during the execution of a test (that is, the test modified or corrupted it in @@ -1226,7 +1062,7 @@ class ExtendedTests : BaseTests() { For further details regarding the `EXHAUSTIVE` and `CURRENT_LEVEL` algorithms, see the[`DirtiesContext.HierarchyMode`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/test/annotation/DirtiesContext.HierarchyMode.html)javadoc. -##### [](#spring-testing-annotation-testexecutionlisteners)`@TestExecutionListeners` ##### +##### `@TestExecutionListeners` `@TestExecutionListeners` defines class-level metadata for configuring the`TestExecutionListener` implementations that should be registered with the`TestContextManager`. Typically, `@TestExecutionListeners` is used in conjunction with`@ContextConfiguration`. @@ -1261,7 +1097,7 @@ class CustomTestExecutionListenerTests { By default, `@TestExecutionListeners` provides support for inheriting listeners from superclasses or enclosing classes. See[`@Nested` test class configuration](#testcontext-junit-jupiter-nested-test-configuration) and the[`@TestExecutionListeners`javadoc](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/test/context/TestExecutionListeners.html) for an example and further details. -##### [](#spring-testing-annotation-recordapplicationevents)`@RecordApplicationEvents` ##### +##### `@RecordApplicationEvents` `@RecordApplicationEvents` is a class-level annotation that is used to instruct the*Spring TestContext Framework* to record all application events that are published in the`ApplicationContext` during the execution of a single test. @@ -1269,7 +1105,7 @@ The recorded events can be accessed via the `ApplicationEvents` API within tests See [Application Events](#testcontext-application-events) and the[`@RecordApplicationEvents`javadoc](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/test/context/event/RecordApplicationEvents.html) for an example and further details. -##### [](#spring-testing-annotation-commit)`@Commit` ##### +##### `@Commit` `@Commit` indicates that the transaction for a transactional test method should be committed after the test method has completed. You can use `@Commit` as a direct @@ -1305,7 +1141,7 @@ fun testProcessWithoutRollback() { |**1**|Commit the result of the test to the database.| |-----|----------------------------------------------| -##### [](#spring-testing-annotation-rollback)`@Rollback` ##### +##### `@Rollback` `@Rollback` indicates whether the transaction for a transactional test method should be rolled back after the test method has completed. If `true`, the transaction is rolled @@ -1346,7 +1182,7 @@ fun testProcessWithoutRollback() { |**1**|Do not roll back the result.| |-----|----------------------------| -##### [](#spring-testing-annotation-beforetransaction)`@BeforeTransaction` ##### +##### `@BeforeTransaction` `@BeforeTransaction` indicates that the annotated `void` method should be run before a transaction is started, for test methods that have been configured to run within a @@ -1380,7 +1216,7 @@ fun beforeTransaction() { |**1**|Run this method before a transaction.| |-----|-------------------------------------| -##### [](#spring-testing-annotation-aftertransaction)`@AfterTransaction` ##### +##### `@AfterTransaction` `@AfterTransaction` indicates that the annotated `void` method should be run after a transaction is ended, for test methods that have been configured to run within a @@ -1412,7 +1248,7 @@ fun afterTransaction() { |**1**|Run this method after a transaction.| |-----|------------------------------------| -##### [](#spring-testing-annotation-sql)`@Sql` ##### +##### `@Sql` `@Sql` is used to annotate a test class or test method to configure SQL scripts to be run against a given database during integration tests. The following example shows how to use @@ -1446,7 +1282,7 @@ fun userTest() { See [Executing SQL scripts declaratively with @Sql](#testcontext-executing-sql-declaratively) for further details. -##### [](#spring-testing-annotation-sqlconfig)`@SqlConfig` ##### +##### `@SqlConfig` `@SqlConfig` defines metadata that is used to determine how to parse and run SQL scripts configured with the `@Sql` annotation. The following example shows how to use it: @@ -1480,7 +1316,7 @@ fun userTest() { |**1**|Set the comment prefix and the separator in SQL scripts.| |-----|--------------------------------------------------------| -##### [](#spring-testing-annotation-sqlmergemode)`@SqlMergeMode` ##### +##### `@SqlMergeMode` `@SqlMergeMode` is used to annotate a test class or test method to configure whether method-level `@Sql` declarations are merged with class-level `@Sql` declarations. If`@SqlMergeMode` is not declared on a test class or test method, the `OVERRIDE` merge mode @@ -1569,7 +1405,7 @@ class UserTests { |**1**|Set the `@Sql` merge mode to `MERGE` for a specific test method.| |-----|----------------------------------------------------------------| -##### [](#spring-testing-annotation-sqlgroup)`@SqlGroup` ##### +##### `@SqlGroup` `@SqlGroup` is a container annotation that aggregates several `@Sql` annotations. You can use `@SqlGroup` natively to declare several nested `@Sql` annotations, or you can use it @@ -1608,7 +1444,7 @@ fun userTest() { |**1**|Declare a group of SQL scripts.| |-----|-------------------------------| -#### [](#integration-testing-annotations-standard)3.4.2. Standard Annotation Support #### +#### 3.4.2. Standard Annotation Support The following annotations are supported with standard semantics for all configurations of the Spring TestContext Framework. Note that these annotations are not specific to tests @@ -1639,7 +1475,7 @@ and can be used anywhere in the Spring Framework. | |JSR-250 Lifecycle Annotations

In the Spring TestContext Framework, you can use `@PostConstruct` and `@PreDestroy` with
standard semantics on any application components configured in the `ApplicationContext`.
However, these lifecycle annotations have limited usage within an actual test class.

If a method within a test class is annotated with `@PostConstruct`, that method runs
before any before methods of the underlying test framework (for example, methods
annotated with JUnit Jupiter’s `@BeforeEach`), and that applies for every test method in
the test class. On the other hand, if a method within a test class is annotated with`@PreDestroy`, that method never runs. Therefore, within a test class, we recommend that
you use test lifecycle callbacks from the underlying test framework instead of`@PostConstruct` and `@PreDestroy`.| |---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#integration-testing-annotations-junit4)3.4.3. Spring JUnit 4 Testing Annotations #### +#### 3.4.3. Spring JUnit 4 Testing Annotations The following annotations are supported only when used in conjunction with the[SpringRunner](#testcontext-junit4-runner), [Spring’s JUnit 4 rules](#testcontext-junit4-rules), or [Spring’s JUnit 4 support classes](#testcontext-support-classes-junit4): @@ -1652,7 +1488,7 @@ rules](#testcontext-junit4-rules), or [Spring’s JUnit 4 support classes](#test * [`@Repeat`](#integration-testing-annotations-junit4-repeat) -##### [](#integration-testing-annotations-junit4-ifprofilevalue)`@IfProfileValue` ##### +##### `@IfProfileValue` `@IfProfileValue` indicates that the annotated test is enabled for a specific testing environment. If the configured `ProfileValueSource` returns a matching `value` for the @@ -1721,7 +1557,7 @@ fun testProcessWhichRunsForUnitOrIntegrationTestGroups() { |**1**|Run this test for unit tests and integration tests.| |-----|---------------------------------------------------| -##### [](#integration-testing-annotations-junit4-profilevaluesourceconfiguration)`@ProfileValueSourceConfiguration` ##### +##### `@ProfileValueSourceConfiguration` `@ProfileValueSourceConfiguration` is a class-level annotation that specifies what type of `ProfileValueSource` to use when retrieving profile values configured through the`@IfProfileValue` annotation. If `@ProfileValueSourceConfiguration` is not declared for a @@ -1752,7 +1588,7 @@ class CustomProfileValueSourceTests { |**1**|Use a custom profile value source.| |-----|----------------------------------| -##### [](#integration-testing-annotations-junit4-timed)`@Timed` ##### +##### `@Timed` `@Timed` indicates that the annotated test method must finish execution in a specified time period (in milliseconds). If the text execution time exceeds the specified time @@ -1790,7 +1626,7 @@ Spring’s `@Timed` annotation has different semantics than JUnit 4’s `@Test(t hand, does not preemptively fail the test but rather waits for the test to complete before failing. -##### [](#integration-testing-annotations-junit4-repeat)`@Repeat` ##### +##### `@Repeat` `@Repeat` indicates that the annotated test method must be run repeatedly. The number of times that the test method is to be run is specified in the annotation. @@ -1826,7 +1662,7 @@ fun testProcessRepeatedly() { |**1**|Repeat this test ten times.| |-----|---------------------------| -#### [](#integration-testing-annotations-junit-jupiter)3.4.4. Spring JUnit Jupiter Testing Annotations #### +#### 3.4.4. Spring JUnit Jupiter Testing Annotations The following annotations are supported when used in conjunction with the[`SpringExtension`](#testcontext-junit-jupiter-extension) and JUnit Jupiter (that is, the programming model in JUnit 5): @@ -1843,7 +1679,7 @@ The following annotations are supported when used in conjunction with the[`Sprin * [`@DisabledIf`](#integration-testing-annotations-junit-jupiter-disabledif) -##### [](#integration-testing-annotations-junit-jupiter-springjunitconfig)`@SpringJUnitConfig` ##### +##### `@SpringJUnitConfig` `@SpringJUnitConfig` is a composed annotation that combines`@ExtendWith(SpringExtension.class)` from JUnit Jupiter with `@ContextConfiguration` from the Spring TestContext Framework. It can be used at the class level as a drop-in @@ -1907,7 +1743,7 @@ class XmlJUnitJupiterSpringTests { See [Context Management](#testcontext-ctx-management) as well as the javadoc for[`@SpringJUnitConfig`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/test/context/junit/jupiter/SpringJUnitConfig.html)and `@ContextConfiguration` for further details. -##### [](#integration-testing-annotations-junit-jupiter-springjunitwebconfig)`@SpringJUnitWebConfig` ##### +##### `@SpringJUnitWebConfig` `@SpringJUnitWebConfig` is a composed annotation that combines`@ExtendWith(SpringExtension.class)` from JUnit Jupiter with `@ContextConfiguration` and`@WebAppConfiguration` from the Spring TestContext Framework. You can use it at the class level as a drop-in replacement for `@ContextConfiguration` and `@WebAppConfiguration`. @@ -1969,7 +1805,7 @@ class XmlJUnitJupiterSpringWebTests { See [Context Management](#testcontext-ctx-management) as well as the javadoc for[`@SpringJUnitWebConfig`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/test/context/junit/jupiter/web/SpringJUnitWebConfig.html),[`@ContextConfiguration`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/test/context/ContextConfiguration.html), and[`@WebAppConfiguration`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/test/context/web/WebAppConfiguration.html)for further details. -##### [](#integration-testing-annotations-testconstructor)`@TestConstructor` ##### +##### `@TestConstructor` `@TestConstructor` is a type-level annotation that is used to configure how the parameters of a test class constructor are autowired from components in the test’s`ApplicationContext`. @@ -1985,7 +1821,7 @@ constructor takes precedence over both `@TestConstructor` and the default mode. | |As of Spring Framework 5.2, `@TestConstructor` is only supported in conjunction
with the `SpringExtension` for use with JUnit Jupiter. Note that the `SpringExtension` is
often automatically registered for you – for example, when using annotations such as`@SpringJUnitConfig` and `@SpringJUnitWebConfig` or various test-related annotations from
Spring Boot Test.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#integration-testing-annotations-nestedtestconfiguration)`@NestedTestConfiguration` ##### +##### `@NestedTestConfiguration` `@NestedTestConfiguration` is a type-level annotation that is used to configure how Spring test configuration annotations are processed within enclosing class hierarchies @@ -2042,7 +1878,7 @@ following annotations. See [`@Nested` test class configuration](#testcontext-junit-jupiter-nested-test-configuration) for an example and further details. -##### [](#integration-testing-annotations-junit-jupiter-enabledif)`@EnabledIf` ##### +##### `@EnabledIf` `@EnabledIf` is used to signal that the annotated JUnit Jupiter test class or test method is enabled and should be run if the supplied `expression` evaluates to `true`. @@ -2089,7 +1925,7 @@ Kotlin annotation class EnabledOnMac {} ``` -##### [](#integration-testing-annotations-junit-jupiter-disabledif)`@DisabledIf` ##### +##### `@DisabledIf` `@DisabledIf` is used to signal that the annotated JUnit Jupiter test class or test method is disabled and should not be run if the supplied `expression` evaluates to`true`. Specifically, if the expression evaluates to `Boolean.TRUE` or a `String` equal @@ -2136,7 +1972,7 @@ Kotlin annotation class DisabledOnMac {} ``` -#### [](#integration-testing-annotations-meta)3.4.5. Meta-Annotation Support for Testing #### +#### 3.4.5. Meta-Annotation Support for Testing You can use most test-related annotations as[meta-annotations](core.html#beans-meta-annotations) to create custom composed annotations and reduce configuration duplication across a test suite. @@ -2425,7 +2261,7 @@ fun deleteOrder() { } For further details, see the[Spring Annotation Programming Model](https://github.com/spring-projects/spring-framework/wiki/Spring-Annotation-Programming-Model)wiki page. -### [](#testcontext-framework)3.5. Spring TestContext Framework ### +### 3.5. Spring TestContext Framework The Spring TestContext Framework (located in the `org.springframework.test.context`package) provides generic, annotation-driven unit and integration testing support that is agnostic of the testing framework in use. The TestContext framework also places a great @@ -2445,7 +2281,7 @@ with your own custom listeners or custom loaders, feel free to go directly to th configuration ([context management](#testcontext-ctx-management),[dependency injection](#testcontext-fixture-di), [transaction management](#testcontext-tx)), [support classes](#testcontext-support-classes), and[annotation support](#integration-testing-annotations) sections. -#### [](#testcontext-key-abstractions)3.5.1. Key Abstractions #### +#### 3.5.1. Key Abstractions The core of the framework consists of the `TestContextManager` class and the`TestContext`, `TestExecutionListener`, and `SmartContextLoader` interfaces. A`TestContextManager` is created for each test class (for example, for the execution of all test methods within a single test class in JUnit Jupiter). The `TestContextManager`, @@ -2455,13 +2291,13 @@ test execution by providing dependency injection, managing transactions, and so class. See the [javadoc](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/test/context/package-summary.html) and the Spring test suite for further information and examples of various implementations. -##### [](#testcontext)`TestContext` ##### +##### `TestContext` `TestContext` encapsulates the context in which a test is run (agnostic of the actual testing framework in use) and provides context management and caching support for the test instance for which it is responsible. The `TestContext` also delegates to a`SmartContextLoader` to load an `ApplicationContext` if requested. -##### [](#testcontextmanager)`TestContextManager` ##### +##### `TestContextManager` `TestContextManager` is the main entry point into the Spring TestContext Framework and is responsible for managing a single `TestContext` and signaling events to each registered`TestExecutionListener` at well-defined test execution points: @@ -2480,12 +2316,12 @@ responsible for managing a single `TestContext` and signaling events to each reg * After any “after class” or “after all” methods of a particular testing framework. -##### [](#testexecutionlistener)`TestExecutionListener` ##### +##### `TestExecutionListener` `TestExecutionListener` defines the API for reacting to test-execution events published by the `TestContextManager` with which the listener is registered. See [`TestExecutionListener` Configuration](#testcontext-tel-config). -##### [](#context-loaders)Context Loaders ##### +##### Context Loaders `ContextLoader` is a strategy interface for loading an `ApplicationContext` for an integration test managed by the Spring TestContext Framework. You should implement`SmartContextLoader` instead of this interface to provide support for component classes, @@ -2527,7 +2363,7 @@ Spring provides the following implementations: * `GenericXmlWebContextLoader`: Loads a `WebApplicationContext` from XML resource locations. -#### [](#testcontext-bootstrapping)3.5.2. Bootstrapping the TestContext Framework #### +#### 3.5.2. Bootstrapping the TestContext Framework The default configuration for the internals of the Spring TestContext Framework is sufficient for all common use cases. However, there are times when a development team or @@ -2545,7 +2381,7 @@ new requirements), we strongly encourage implementers not to implement this inte directly but rather to extend `AbstractTestContextBootstrapper` or one of its concrete subclasses instead. -#### [](#testcontext-tel-config)3.5.3. `TestExecutionListener` Configuration #### +#### 3.5.3. `TestExecutionListener` Configuration Spring provides the following `TestExecutionListener` implementations that are registered by default, exactly in the following order: @@ -2569,12 +2405,12 @@ by default, exactly in the following order: * `EventPublishingTestExecutionListener`: Publishes test execution events to the test’s`ApplicationContext` (see [Test Execution Events](#testcontext-test-execution-events)). -##### [](#testcontext-tel-config-registering-tels)Registering `TestExecutionListener` Implementations ##### +##### Registering `TestExecutionListener` Implementations You can register `TestExecutionListener` implementations for a test class and its subclasses by using the `@TestExecutionListeners` annotation. See[annotation support](#integration-testing-annotations) and the javadoc for[`@TestExecutionListeners`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/test/context/TestExecutionListeners.html)for details and examples. -##### [](#testcontext-tel-config-automatic-discovery)Automatic Discovery of Default `TestExecutionListener` Implementations ##### +##### Automatic Discovery of Default `TestExecutionListener` Implementations Registering `TestExecutionListener` implementations by using `@TestExecutionListeners` is suitable for custom listeners that are used in limited testing scenarios. However, it can @@ -2587,7 +2423,7 @@ can contribute their own `TestExecutionListener` implementations to the list of listeners in the same manner through their own `META-INF/spring.factories` properties file. -##### [](#testcontext-tel-config-ordering)Ordering `TestExecutionListener` Implementations ##### +##### Ordering `TestExecutionListener` Implementations When the TestContext framework discovers default `TestExecutionListener` implementations through the [aforementioned](#testcontext-tel-config-automatic-discovery)`SpringFactoriesLoader` mechanism, the instantiated listeners are sorted by using @@ -2597,7 +2433,7 @@ their default `TestExecutionListener` implementations are registered in the prop by implementing `Ordered` or declaring `@Order`. See the javadoc for the `getOrder()`methods of the core default `TestExecutionListener` implementations for details on what values are assigned to each core listener. -##### [](#testcontext-tel-config-merging)Merging `TestExecutionListener` Implementations ##### +##### Merging `TestExecutionListener` Implementations If a custom `TestExecutionListener` is registered via `@TestExecutionListeners`, the default listeners are not registered. In most common testing scenarios, this effectively @@ -2685,7 +2521,7 @@ class MyTest { } ``` -#### [](#testcontext-application-events)3.5.4. Application Events #### +#### 3.5.4. Application Events Since Spring Framework 5.3.3, the TestContext framework provides support for recording[application events](core.html#context-functionality-events) published in the`ApplicationContext` so that assertions can be performed against those events within tests. All events published during the execution of a single test are made available via @@ -2768,7 +2604,7 @@ class OrderServiceTests { See the[`ApplicationEvents`javadoc](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/test/context/event/ApplicationEvents.html) for further details regarding the `ApplicationEvents` API. -#### [](#testcontext-test-execution-events)3.5.5. Test Execution Events #### +#### 3.5.5. Test Execution Events The `EventPublishingTestExecutionListener` introduced in Spring Framework 5.2 offers an alternative approach to implementing a custom `TestExecutionListener`. Components in the @@ -2818,7 +2654,7 @@ These annotations reside in the `org.springframework.test.context.event.annotati * `@AfterTestClass` -##### [](#testcontext-test-execution-events-exception-handling)Exception Handling ##### +##### Exception Handling By default, if a test execution event listener throws an exception while consuming an event, that exception will propagate to the underlying testing framework in use (such as @@ -2828,12 +2664,12 @@ contrast, if an asynchronous test execution event listener throws an exception, exception will not propagate to the underlying testing framework. For further details on asynchronous exception handling, consult the class-level javadoc for `@EventListener`. -##### [](#testcontext-test-execution-events-async)Asynchronous Listeners ##### +##### Asynchronous Listeners If you want a particular test execution event listener to process events asynchronously, you can use Spring’s [regular`@Async` support](integration.html#scheduling-annotation-support-async). For further details, consult the class-level javadoc for`@EventListener`. -#### [](#testcontext-ctx-management)3.5.6. Context Management #### +#### 3.5.6. Context Management Each `TestContext` provides context management and caching support for the test instance for which it is responsible. Test instances do not automatically receive access to the @@ -2889,7 +2725,7 @@ advanced use cases. * [Context Hierarchies](#testcontext-ctx-management-ctx-hierarchies) -##### [](#testcontext-ctx-management-xml)Context Configuration with XML resources ##### +##### Context Configuration with XML resources To load an `ApplicationContext` for your tests by using XML configuration files, annotate your test class with `@ContextConfiguration` and configure the `locations` attribute with @@ -2996,7 +2832,7 @@ class MyTest { |**1**|Loading configuration from the default location.| |-----|------------------------------------------------| -##### [](#testcontext-ctx-management-groovy)Context Configuration with Groovy Scripts ##### +##### Context Configuration with Groovy Scripts To load an `ApplicationContext` for your tests by using Groovy scripts that use the[Groovy Bean Definition DSL](core.html#groovy-bean-definition-dsl), you can annotate your test class with `@ContextConfiguration` and configure the `locations` or `value`attribute with an array that contains the resource locations of Groovy scripts. Resource @@ -3071,7 +2907,7 @@ class MyTest { | |Declaring XML configuration and Groovy scripts simultaneously

You can declare both XML configuration files and Groovy scripts simultaneously by using
the `locations` or `value` attribute of `@ContextConfiguration`. If the path to a
configured resource location ends with `.xml`, it is loaded by using an`XmlBeanDefinitionReader`. Otherwise, it is loaded by using a`GroovyBeanDefinitionReader`.

The following listing shows how to combine both in an integration test:

Java

```
@ExtendWith(SpringExtension.class)
// ApplicationContext will be loaded from
// "/app-config.xml" and "/TestConfig.groovy"
@ContextConfiguration({ "/app-config.xml", "/TestConfig.groovy" })
class MyTest {
// class body...
}
```

Kotlin

```
@ExtendWith(SpringExtension::class)
// ApplicationContext will be loaded from
// "/app-config.xml" and "/TestConfig.groovy"
@ContextConfiguration("/app-config.xml", "/TestConfig.groovy")
class MyTest {
// class body...
}
```| |---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#testcontext-ctx-management-javaconfig)Context Configuration with Component Classes ##### +##### Context Configuration with Component Classes To load an `ApplicationContext` for your tests by using component classes (see[Java-based container configuration](core.html#beans-java)), you can annotate your test class with `@ContextConfiguration` and configure the `classes` attribute with an array @@ -3183,7 +3019,7 @@ class OrderServiceTest { |**1**|Loading configuration information from the nested `Config` class.| |-----|-----------------------------------------------------------------| -##### [](#testcontext-ctx-management-mixed-config)Mixing XML, Groovy Scripts, and Component Classes ##### +##### Mixing XML, Groovy Scripts, and Component Classes It may sometimes be desirable to mix XML configuration files, Groovy scripts, and component classes (typically `@Configuration` classes) to configure an`ApplicationContext` for your tests. For example, if you use XML configuration in @@ -3209,7 +3045,7 @@ to how you configure your application in production: In production configuration define either a set of XML or Groovy resource locations or a set of `@Configuration`classes from which your production `ApplicationContext` is loaded, but you still have the freedom to include or import the other type of configuration. -##### [](#testcontext-ctx-management-initializers)Context Configuration with Context Initializers ##### +##### Context Configuration with Context Initializers To configure an `ApplicationContext` for your tests by using context initializers, annotate your test class with `@ContextConfiguration` and configure the `initializers`attribute with an array that contains references to classes that implement`ApplicationContextInitializer`. The declared context initializers are then used to @@ -3287,7 +3123,7 @@ class MyTest { |**1**|Specifying configuration by using only an initializer.| |-----|------------------------------------------------------| -##### [](#testcontext-ctx-management-inheritance)Context Configuration Inheritance ##### +##### Context Configuration Inheritance `@ContextConfiguration` supports boolean `inheritLocations` and `inheritInitializers`attributes that denote whether resource locations or component classes and context initializers declared by superclasses should be inherited. The default value for both @@ -3450,7 +3286,7 @@ class ExtendedTest : BaseTest() { |-----|--------------------------------------| |**2**| Initializer defined in the subclass. | -##### [](#testcontext-ctx-management-env-profiles)Context Configuration with Environment Profiles ##### +##### Context Configuration with Environment Profiles The Spring Framework has first-class support for the notion of environments and profiles (AKA "bean definition profiles"), and integration tests can be configured to activate @@ -3931,7 +3767,7 @@ class OperatingSystemActiveProfilesResolver : ActiveProfilesResolver { } ``` -##### [](#testcontext-ctx-management-property-sources)Context Configuration with Test Property Sources ##### +##### Context Configuration with Test Property Sources The Spring Framework has first-class support for the notion of an environment with a hierarchy of property sources, and you can configure integration tests with test-specific @@ -3942,7 +3778,7 @@ These test property sources are added to the set of `PropertySources` in the`Env | |You can use `@TestPropertySource` with any implementation of the `SmartContextLoader`SPI, but `@TestPropertySource` is not supported with implementations of the older`ContextLoader` SPI.

Implementations of `SmartContextLoader` gain access to merged test property source values
through the `getPropertySourceLocations()` and `getPropertySourceProperties()` methods in`MergedContextConfiguration`.| |---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -###### [](#declaring-test-property-sources)Declaring Test Property Sources ###### +###### Declaring Test Property Sources You can configure test properties files by using the `locations` or `value` attribute of`@TestPropertySource`. @@ -4025,7 +3861,7 @@ class MyIntegrationTests { | |As of Spring Framework 5.2, `@TestPropertySource` can be used as *repeatable annotation*.
That means that you can have multiple declarations of `@TestPropertySource` on a single
test class, with the `locations` and `properties` from later `@TestPropertySource`annotations overriding those from previous `@TestPropertySource` annotations.

In addition, you may declare multiple composed annotations on a test class that are each
meta-annotated with `@TestPropertySource`, and all of those `@TestPropertySource`declarations will contribute to your test property sources.

Directly present `@TestPropertySource` annotations always take precedence over
meta-present `@TestPropertySource` annotations. In other words, `locations` and`properties` from a directly present `@TestPropertySource` annotation will override the`locations` and `properties` from a `@TestPropertySource` annotation used as a
meta-annotation.| |---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -###### [](#default-properties-file-detection)Default Properties File Detection ###### +###### Default Properties File Detection If `@TestPropertySource` is declared as an empty annotation (that is, without explicit values for the `locations` or `properties` attributes), an attempt is made to detect a @@ -4033,7 +3869,7 @@ default properties file relative to the class that declared the annotation. For if the annotated test class is `com.example.MyTest`, the corresponding default properties file is `classpath:com/example/MyTest.properties`. If the default cannot be detected, an`IllegalStateException` is thrown. -###### [](#precedence)Precedence ###### +###### Precedence Test properties have higher precedence than those defined in the operating system’s environment, Java system properties, or property sources added by the application @@ -4074,7 +3910,7 @@ class MyIntegrationTests { } ``` -###### [](#inheriting-and-overriding-test-property-sources)Inheriting and Overriding Test Property Sources ###### +###### Inheriting and Overriding Test Property Sources `@TestPropertySource` supports boolean `inheritLocations` and `inheritProperties`attributes that denote whether resource locations for properties files and inlined properties declared by superclasses should be inherited. The default value for both flags @@ -4165,7 +4001,7 @@ class ExtendedTest : BaseTest() { } ``` -##### [](#testcontext-ctx-management-dynamic-property-sources)Context Configuration with Dynamic Property Sources ##### +##### Context Configuration with Dynamic Property Sources As of Spring Framework 5.2.5, the TestContext framework provides support for *dynamic*properties via the `@DynamicPropertySource` annotation. This annotation can be used in integration tests that need to add properties with dynamic values to the set of`PropertySources` in the `Environment` for the `ApplicationContext` loaded for the @@ -4232,14 +4068,14 @@ class ExampleIntegrationTests { } ``` -###### [](#precedence-2)Precedence ###### +###### Precedence Dynamic properties have higher precedence than those loaded from `@TestPropertySource`, the operating system’s environment, Java system properties, or property sources added by the application declaratively by using `@PropertySource` or programmatically. Thus, dynamic properties can be used to selectively override properties loaded via`@TestPropertySource`, system property sources, and application property sources. -##### [](#testcontext-ctx-management-web)Loading a `WebApplicationContext` ##### +##### Loading a `WebApplicationContext` To instruct the TestContext framework to load a `WebApplicationContext` instead of a standard `ApplicationContext`, you can annotate the respective test class with`@WebAppConfiguration`. @@ -4441,7 +4277,7 @@ class WacTests { } ``` -##### [](#testcontext-ctx-management-caching)Context Caching ##### +##### Context Caching Once the TestContext framework loads an `ApplicationContext` (or `WebApplicationContext`) for a test, that context is cached and reused for all subsequent tests that declare the @@ -4506,7 +4342,7 @@ context. Note that support for the `@DirtiesContext` annotation is provided by t | |ApplicationContext lifecycle and console logging

When you need to debug a test executed with the Spring TestContext Framework, it can be
useful to analyze the console output (that is, output to the `SYSOUT` and `SYSERR`streams). Some build tools and IDEs are able to associate console output with a given
test; however, some console output cannot be easily associated with a given test.

With regard to console logging triggered by the Spring Framework itself or by components
registered in the `ApplicationContext`, it is important to understand the lifecycle of an`ApplicationContext` that has been loaded by the Spring TestContext Framework within a
test suite.

The `ApplicationContext` for a test is typically loaded when an instance of the test
class is being prepared — for example, to perform dependency injection into `@Autowired`fields of the test instance. This means that any console logging triggered during the
initialization of the `ApplicationContext` typically cannot be associated with an
individual test method. However, if the context is closed immediately before the
execution of a test method according to [`@DirtiesContext`](#spring-testing-annotation-dirtiescontext)semantics, a new instance of the context will be loaded just prior to execution of the
test method. In the latter scenario, an IDE or build tool may potentially associate
console logging with the individual test method.

The `ApplicationContext` for a test can be closed via one of the following scenarios.

* The context is closed according to `@DirtiesContext` semantics.

* The context is closed because it has been automatically evicted from the cache
according to the LRU eviction policy.

* The context is closed via a JVM shutdown hook when the JVM for the test suite
terminates.

If the context is closed according to `@DirtiesContext` semantics after a particular test
method, an IDE or build tool may potentially associate console logging with the
individual test method. If the context is closed according to `@DirtiesContext` semantics
after a test class, any console logging triggered during the shutdown of the`ApplicationContext` cannot be associated with an individual test method. Similarly, any
console logging triggered during the shutdown phase via a JVM shutdown hook cannot be
associated with an individual test method.

When a Spring `ApplicationContext` is closed via a JVM shutdown hook, callbacks executed
during the shutdown phase are executed on a thread named `SpringContextShutdownHook`. So,
if you wish to disable console logging triggered when the `ApplicationContext` is closed
via a JVM shutdown hook, you may be able to register a custom filter with your logging
framework that allows you to ignore any logging initiated by that thread.| |---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#testcontext-ctx-management-ctx-hierarchies)Context Hierarchies ##### +##### Context Hierarchies When writing integration tests that rely on a loaded Spring `ApplicationContext`, it is often sufficient to test against a single context. However, there are times when it is @@ -4704,7 +4540,7 @@ class ExtendedTests : BaseTests() {} | |Dirtying a context within a context hierarchy

If you use `@DirtiesContext` in a test whose context is configured as part of a
context hierarchy, you can use the `hierarchyMode` flag to control how the context cache
is cleared. For further details, see the discussion of `@DirtiesContext` in[Spring Testing Annotations](#spring-testing-annotation-dirtiescontext) and the[`@DirtiesContext`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/test/annotation/DirtiesContext.html) javadoc.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#testcontext-fixture-di)3.5.7. Dependency Injection of Test Fixtures #### +#### 3.5.7. Dependency Injection of Test Fixtures When you use the `DependencyInjectionTestExecutionListener` (which is configured by default), the dependencies of your test instances are injected from beans in the @@ -4857,7 +4693,7 @@ shows this configuration: | |If you are extending from a Spring-provided test base class that happens to use`@Autowired` on one of its setter methods, you might have multiple beans of the affected
type defined in your application context (for example, multiple `DataSource` beans). In
such a case, you can override the setter method and use the `@Qualifier` annotation to
indicate a specific target bean, as follows (but make sure to delegate to the overridden
method in the superclass as well):

Java

```
// ...

@Autowired
@Override
public void setDataSource(@Qualifier("myDataSource") DataSource dataSource) {
super.setDataSource(dataSource);
}

// ...
```

Kotlin

```
// ...

@Autowired
override fun setDataSource(@Qualifier("myDataSource") dataSource: DataSource) {
super.setDataSource(dataSource)
}

// ...
```

The specified qualifier value indicates the specific `DataSource` bean to inject,
narrowing the set of type matches to a specific bean. Its value is matched against`` declarations within the corresponding `` definitions. The bean name
is used as a fallback qualifier value, so you can effectively also point to a specific
bean by name there (as shown earlier, assuming that `myDataSource` is the bean `id`).| |---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#testcontext-web-scoped-beans)3.5.8. Testing Request- and Session-scoped Beans #### +#### 3.5.8. Testing Request- and Session-scoped Beans Spring has supported [Request- and session-scoped beans](core.html#beans-factory-scopes-other) since the early years, and you can test your request-scoped and session-scoped @@ -5009,14 +4845,14 @@ class SessionScopedBeanTests { } ``` -#### [](#testcontext-tx)3.5.9. Transaction Management #### +#### 3.5.9. Transaction Management In the TestContext framework, transactions are managed by the`TransactionalTestExecutionListener`, which is configured by default, even if you do not explicitly declare `@TestExecutionListeners` on your test class. To enable support for transactions, however, you must configure a `PlatformTransactionManager` bean in the`ApplicationContext` that is loaded with `@ContextConfiguration` semantics (further details are provided later). In addition, you must declare Spring’s `@Transactional`annotation either at the class or the method level for your tests. -##### [](#testcontext-tx-test-managed-transactions)Test-managed Transactions ##### +##### Test-managed Transactions Test-managed transactions are transactions that are managed declaratively by using the`TransactionalTestExecutionListener` or programmatically by using `TestTransaction`(described later). You should not confuse such transactions with Spring-managed transactions (those managed directly by Spring within the `ApplicationContext` loaded for @@ -5029,7 +4865,7 @@ propagation type other than `REQUIRED` or `SUPPORTS` (see the discussion on[tran | |Preemptive timeouts and test-managed transactions

Caution must be taken when using any form of preemptive timeouts from a testing framework
in conjunction with Spring’s test-managed transactions.

Specifically, Spring’s testing support binds transaction state to the current thread (via
a `java.lang.ThreadLocal` variable) *before* the current test method is invoked. If a
testing framework invokes the current test method in a new thread in order to support a
preemptive timeout, any actions performed within the current test method will *not* be
invoked within the test-managed transaction. Consequently, the result of any such actions
will not be rolled back with the test-managed transaction. On the contrary, such actions
will be committed to the persistent store — for example, a relational database — even
though the test-managed transaction is properly rolled back by Spring.

Situations in which this can occur include but are not limited to the following.

* JUnit 4’s `@Test(timeout = …​)` support and `TimeOut` rule

* JUnit Jupiter’s `assertTimeoutPreemptively(…​)` methods in the`org.junit.jupiter.api.Assertions` class

* TestNG’s `@Test(timeOut = …​)` support| |---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#testcontext-tx-enabling-transactions)Enabling and Disabling Transactions ##### +##### Enabling and Disabling Transactions Annotating a test method with `@Transactional` causes the test to be run within a transaction that is, by default, automatically rolled back after completion of the test. @@ -5147,13 +4983,13 @@ As explained in [Transaction Rollback and Commit Behavior](#testcontext-tx-rollb clean up the database after the `createUser()` method runs, since any changes made to the database are automatically rolled back by the `TransactionalTestExecutionListener`. -##### [](#testcontext-tx-rollback-and-commit-behavior)Transaction Rollback and Commit Behavior ##### +##### Transaction Rollback and Commit Behavior By default, test transactions will be automatically rolled back after completion of the test; however, transactional commit and rollback behavior can be configured declaratively via the `@Commit` and `@Rollback` annotations. See the corresponding entries in the[annotation support](#integration-testing-annotations) section for further details. -##### [](#testcontext-tx-programmatic-tx-mgt)Programmatic Transaction Management ##### +##### Programmatic Transaction Management You can interact with test-managed transactions programmatically by using the static methods in `TestTransaction`. For example, you can use `TestTransaction` within test @@ -5225,7 +5061,7 @@ class ProgrammaticTransactionManagementTests : AbstractTransactionalJUnit4Spring } ``` -##### [](#testcontext-tx-before-and-after-tx)Running Code Outside of a Transaction ##### +##### Running Code Outside of a Transaction Occasionally, you may need to run certain code before or after a transactional test method but outside the transactional context — for example, to verify the initial @@ -5237,7 +5073,7 @@ transaction method or after transaction method runs at the appropriate time. | |Any before methods (such as methods annotated with JUnit Jupiter’s `@BeforeEach`)
and any after methods (such as methods annotated with JUnit Jupiter’s `@AfterEach`) are
run within a transaction. In addition, methods annotated with `@BeforeTransaction` or`@AfterTransaction` are not run for test methods that are not configured to run within a
transaction.| |---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#testcontext-tx-mgr-config)Configuring a Transaction Manager ##### +##### Configuring a Transaction Manager `TransactionalTestExecutionListener` expects a `PlatformTransactionManager` bean to be defined in the Spring `ApplicationContext` for the test. If there are multiple instances @@ -5247,7 +5083,7 @@ qualifier by using `@Transactional("myTxMgr")` or `@Transactional(transactionMan for `TestContextTransactionUtils.retrieveTransactionManager()`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/test/context/transaction/TestContextTransactionUtils.html#retrieveTransactionManager-org.springframework.test.context.TestContext-java.lang.String-) for details on the algorithm used to look up a transaction manager in the test’s `ApplicationContext`. -##### [](#testcontext-tx-annotation-demo)Demonstration of All Transaction-related Annotations ##### +##### Demonstration of All Transaction-related Annotations The following JUnit Jupiter based example displays a fictitious integration testing scenario that highlights all transaction-related annotations. The example is not intended @@ -5336,7 +5172,7 @@ class FictitiousTransactionalTest { | |Avoid false positives when testing ORM code

When you test application code that manipulates the state of a Hibernate session or JPA
persistence context, make sure to flush the underlying unit of work within test methods
that run that code. Failing to flush the underlying unit of work can produce false
positives: Your test passes, but the same code throws an exception in a live, production
environment. Note that this applies to any ORM framework that maintains an in-memory unit
of work. In the following Hibernate-based example test case, one method demonstrates a
false positive, and the other method correctly exposes the results of flushing the
session:

Java

```
// ...

@Autowired
SessionFactory sessionFactory;

@Transactional
@Test // no expected exception!
public void falsePositive() {
updateEntityInHibernateSession();
// False positive: an exception will be thrown once the Hibernate
// Session is finally flushed (i.e., in production code)
}

@Transactional
@Test(expected = ...)
public void updateWithSessionFlush() {
updateEntityInHibernateSession();
// Manual flush is required to avoid false positive in test
sessionFactory.getCurrentSession().flush();
}

// ...
```

Kotlin

```
// ...

@Autowired
lateinit var sessionFactory: SessionFactory

@Transactional
@Test // no expected exception!
fun falsePositive() {
updateEntityInHibernateSession()
// False positive: an exception will be thrown once the Hibernate
// Session is finally flushed (i.e., in production code)
}

@Transactional
@Test(expected = ...)
fun updateWithSessionFlush() {
updateEntityInHibernateSession()
// Manual flush is required to avoid false positive in test
sessionFactory.getCurrentSession().flush()
}

// ...
```

The following example shows matching methods for JPA:

Java

```
// ...

@PersistenceContext
EntityManager entityManager;

@Transactional
@Test // no expected exception!
public void falsePositive() {
updateEntityInJpaPersistenceContext();
// False positive: an exception will be thrown once the JPA
// EntityManager is finally flushed (i.e., in production code)
}

@Transactional
@Test(expected = ...)
public void updateWithEntityManagerFlush() {
updateEntityInJpaPersistenceContext();
// Manual flush is required to avoid false positive in test
entityManager.flush();
}

// ...
```

Kotlin

```
// ...

@PersistenceContext
lateinit var entityManager:EntityManager

@Transactional
@Test // no expected exception!
fun falsePositive() {
updateEntityInJpaPersistenceContext()
// False positive: an exception will be thrown once the JPA
// EntityManager is finally flushed (i.e., in production code)
}

@Transactional
@Test(expected = ...)
void updateWithEntityManagerFlush() {
updateEntityInJpaPersistenceContext()
// Manual flush is required to avoid false positive in test
entityManager.flush()
}

// ...
```| |---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#testcontext-executing-sql)3.5.10. Executing SQL Scripts #### +#### 3.5.10. Executing SQL Scripts When writing integration tests against a relational database, it is often beneficial to run SQL scripts to modify the database schema or insert test data into tables. The`spring-jdbc` module provides support for *initializing* an embedded or existing database @@ -5347,7 +5183,7 @@ Although it is very useful to initialize a database for testing *once* when the` database *during* integration tests. The following sections explain how to run SQL scripts programmatically and declaratively during integration tests. -##### [](#testcontext-executing-sql-programmatically)Executing SQL scripts programmatically ##### +##### Executing SQL scripts programmatically Spring provides the following options for executing SQL scripts programmatically within integration test methods. @@ -5411,7 +5247,7 @@ Note that `ResourceDatabasePopulator` internally delegates to `ScriptUtils` for and running SQL scripts. Similarly, the `executeSqlScript(..)` methods in[`AbstractTransactionalJUnit4SpringContextTests`](#testcontext-support-classes-junit4)and [`AbstractTransactionalTestNGSpringContextTests`](#testcontext-support-classes-testng)internally use a `ResourceDatabasePopulator` to run SQL scripts. See the Javadoc for the various `executeSqlScript(..)` methods for further details. -##### [](#testcontext-executing-sql-declaratively)Executing SQL scripts declaratively with @Sql ##### +##### Executing SQL scripts declaratively with @Sql In addition to the aforementioned mechanisms for running SQL scripts programmatically, you can declaratively configure SQL scripts in the Spring TestContext Framework. @@ -5422,7 +5258,7 @@ run against a given database before or after an integration test method. Support | |Method-level `@Sql` declarations override class-level declarations by default. As
of Spring Framework 5.2, however, this behavior may be configured per test class or per
test method via `@SqlMergeMode`. See[Merging and Overriding Configuration with `@SqlMergeMode`](#testcontext-executing-sql-declaratively-script-merging) for further details.| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -###### [](#testcontext-executing-sql-declaratively-script-resources)Path Resource Semantics ###### +###### Path Resource Semantics Each path is interpreted as a Spring `Resource`. A plain path (for example,`"schema.sql"`) is treated as a classpath resource that is relative to the package in which the test class is defined. A path starting with a slash is treated as an absolute @@ -5473,7 +5309,7 @@ class DatabaseTests { } ``` -###### [](#testcontext-executing-sql-declaratively-script-detection)Default Script Detection ###### +###### Default Script Detection If no SQL scripts or statements are specified, an attempt is made to detect a `default`script, depending on where `@Sql` is declared. If a default cannot be detected, an`IllegalStateException` is thrown. @@ -5483,7 +5319,7 @@ If no SQL scripts or statements are specified, an attempt is made to detect a `d * Method-level declaration: If the annotated test method is named `testMethod()` and is defined in the class `com.example.MyTest`, the corresponding default script is`classpath:com/example/MyTest.testMethod.sql`. -###### [](#testcontext-executing-sql-declaratively-multiple-annotations)Declaring Multiple `@Sql` Sets ###### +###### Declaring Multiple `@Sql` Sets If you need to configure multiple sets of SQL scripts for a given test class or test method but with different syntax configuration, different error handling rules, or @@ -5540,7 +5376,7 @@ fun userTest() { } ``` -###### [](#testcontext-executing-sql-declaratively-script-execution-phases)Script Execution Phases ###### +###### Script Execution Phases By default, SQL scripts are run before the corresponding test method. However, if you need to run a particular set of scripts after the test method (for example, to clean @@ -5584,7 +5420,7 @@ fun userTest() { Note that `ISOLATED` and `AFTER_TEST_METHOD` are statically imported from`Sql.TransactionMode` and `Sql.ExecutionPhase`, respectively. -###### [](#testcontext-executing-sql-declaratively-script-configuration)Script Configuration with `@SqlConfig` ###### +###### Script Configuration with `@SqlConfig` You can configure script parsing and error handling by using the `@SqlConfig` annotation. When declared as a class-level annotation on an integration test class, `@SqlConfig`serves as global configuration for all SQL scripts within the test class hierarchy. When @@ -5686,7 +5522,7 @@ Note that there is no need to clean up the database after the `usersTest()` meth run, since any changes made to the database (either within the test method or within the`/test-data.sql` script) are automatically rolled back by the`TransactionalTestExecutionListener` (see [transaction management](#testcontext-tx) for details). -###### [](#testcontext-executing-sql-declaratively-script-merging)Merging and Overriding Configuration with `@SqlMergeMode` ###### +###### Merging and Overriding Configuration with `@SqlMergeMode` As of Spring Framework 5.2, it is possible to merge method-level `@Sql` declarations with class-level declarations. For example, this allows you to provide the configuration for a @@ -5696,7 +5532,7 @@ your test class or test method with `@SqlMergeMode(MERGE)`. To disable merging f specific test method (or specific test subclass), you can switch back to the default mode via `@SqlMergeMode(OVERRIDE)`. Consult the [`@SqlMergeMode` annotation documentation section](#spring-testing-annotation-sqlmergemode) for examples and further details. -#### [](#testcontext-parallel-test-execution)3.5.11. Parallel Test Execution #### +#### 3.5.11. Parallel Test Execution Spring Framework 5.0 introduced basic support for executing tests in parallel within a single JVM when using the Spring TestContext Framework. In general, this means that most @@ -5730,11 +5566,11 @@ Do not run tests in parallel if the tests: | |Parallel test execution in the Spring TestContext Framework is only possible if
the underlying `TestContext` implementation provides a copy constructor, as explained in
the javadoc for [`TestContext`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/test/context/TestContext.html). The`DefaultTestContext` used in Spring provides such a constructor. However, if you use a
third-party library that provides a custom `TestContext` implementation, you need to
verify that it is suitable for parallel test execution.| |---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#testcontext-support-classes)3.5.12. TestContext Framework Support Classes #### +#### 3.5.12. TestContext Framework Support Classes This section describes the various classes that support the Spring TestContext Framework. -##### [](#testcontext-junit4-runner)Spring JUnit 4 Runner ##### +##### Spring JUnit 4 Runner The Spring TestContext Framework offers full integration with JUnit 4 through a custom runner (supported on JUnit 4.12 or higher). By annotating test classes with`@RunWith(SpringJUnit4ClassRunner.class)` or the shorter `@RunWith(SpringRunner.class)`variant, developers can implement standard JUnit 4-based unit and integration tests and @@ -5779,7 +5615,7 @@ In the preceding example, `@TestExecutionListeners` is configured with an empty disable the default listeners, which otherwise would require an `ApplicationContext` to be configured through `@ContextConfiguration`. -##### [](#testcontext-junit4-rules)Spring JUnit 4 Rules ##### +##### Spring JUnit 4 Rules The `org.springframework.test.context.junit4.rules` package provides the following JUnit 4 rules (supported on JUnit 4.12 or higher): @@ -5842,7 +5678,7 @@ class IntegrationTest { } ``` -##### [](#testcontext-support-classes-junit4)JUnit 4 Support Classes ##### +##### JUnit 4 Support Classes The `org.springframework.test.context.junit4` package provides the following support classes for JUnit 4-based test cases (supported on JUnit 4.12 or higher): @@ -5870,7 +5706,7 @@ Furthermore, `AbstractTransactionalJUnit4SpringContextTests` provides an`execute | |These classes are a convenience for extension. If you do not want your test classes
to be tied to a Spring-specific class hierarchy, you can configure your own custom test
classes by using `@RunWith(SpringRunner.class)` or [Spring’s
JUnit rules](#testcontext-junit4-rules).| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#testcontext-junit-jupiter-extension)SpringExtension for JUnit Jupiter ##### +##### SpringExtension for JUnit Jupiter The Spring TestContext Framework offers full integration with the JUnit Jupiter testing framework, introduced in JUnit 5. By annotating test classes with`@ExtendWith(SpringExtension.class)`, you can implement standard JUnit Jupiter-based unit @@ -5996,14 +5832,14 @@ class SimpleWebTests { See the documentation for `@SpringJUnitConfig` and `@SpringJUnitWebConfig` in[Spring JUnit Jupiter Testing Annotations](#integration-testing-annotations-junit-jupiter) for further details. -##### [](#testcontext-junit-jupiter-di)Dependency Injection with `SpringExtension` ##### +##### Dependency Injection with `SpringExtension` `SpringExtension` implements the[`ParameterResolver`](https://junit.org/junit5/docs/current/user-guide/#extensions-parameter-resolution)extension API from JUnit Jupiter, which lets Spring provide dependency injection for test constructors, test methods, and test lifecycle callback methods. Specifically, `SpringExtension` can inject dependencies from the test’s`ApplicationContext` into test constructors and methods that are annotated with`@BeforeAll`, `@AfterAll`, `@BeforeEach`, `@AfterEach`, `@Test`, `@RepeatedTest`,`@ParameterizedTest`, and others. -###### [](#testcontext-junit-jupiter-di-constructor)Constructor Injection ###### +###### Constructor Injection If a specific parameter in a constructor for a JUnit Jupiter test class is of type`ApplicationContext` (or a sub-type thereof) or is annotated or meta-annotated with`@Autowired`, `@Qualifier`, or `@Value`, Spring injects the value for that specific parameter with the corresponding bean or value from the test’s `ApplicationContext`. @@ -6083,7 +5919,7 @@ class OrderServiceIntegrationTests(val orderService:OrderService) { } ``` -###### [](#testcontext-junit-jupiter-di-method)Method Injection ###### +###### Method Injection If a parameter in a JUnit Jupiter test method or test lifecycle callback method is of type `ApplicationContext` (or a sub-type thereof) or is annotated or meta-annotated with`@Autowired`, `@Qualifier`, or `@Value`, Spring injects the value for that specific @@ -6158,7 +5994,7 @@ class OrderServiceIntegrationTests { Note that the use of `@RepeatedTest` from JUnit Jupiter lets the test method gain access to the `RepetitionInfo`. -##### [](#testcontext-junit-jupiter-nested-test-configuration)`@Nested` test class configuration ##### +##### `@Nested` test class configuration The *Spring TestContext Framework* has supported the use of test-related annotations on`@Nested` test classes in JUnit Jupiter since Spring Framework 5.0; however, until Spring Framework 5.3 class-level test configuration annotations were not *inherited* from @@ -6241,7 +6077,7 @@ class GreetingServiceTests { } ``` -##### [](#testcontext-support-classes-testng)TestNG Support Classes ##### +##### TestNG Support Classes The `org.springframework.test.context.testng` package provides the following support classes for TestNG based test cases: @@ -6269,7 +6105,7 @@ Furthermore, `AbstractTransactionalTestNGSpringContextTests` provides an`execute | |These classes are a convenience for extension. If you do not want your test classes
to be tied to a Spring-specific class hierarchy, you can configure your own custom test
classes by using `@ContextConfiguration`, `@TestExecutionListeners`, and so on and by
manually instrumenting your test class with a `TestContextManager`. See the source code
of `AbstractTestNGSpringContextTests` for an example of how to instrument your test class.| |---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -### [](#webtestclient)3.6. WebTestClient ### +### 3.6. WebTestClient `WebTestClient` is an HTTP client designed for testing server applications. It wraps Spring’s [WebClient](web-reactive.html#webflux-client) and uses it to perform requests @@ -6280,12 +6116,12 @@ applications without a running server via mock server request and response objec | |Kotlin users: See [this section](languages.html#kotlin-webtestclient-issue)related to use of the `WebTestClient`.| |---|-----------------------------------------------------------------------------------------------------------------| -#### [](#webtestclient-setup)3.6.1. Setup #### +#### 3.6.1. Setup To set up a `WebTestClient` you need to choose a server setup to bind to. This can be one of several mock server setup choices or a connection to a live server. -##### [](#webtestclient-controller-config)Bind to Controller ##### +##### Bind to Controller This setup allows you to test specific controller(s) via mock request and response objects, without a running server. @@ -6322,7 +6158,7 @@ Kotlin val client = MockMvcWebTestClient.bindToController(TestController()).build() ``` -##### [](#webtestclient-context-config)Bind to `ApplicationContext` ##### +##### Bind to `ApplicationContext` This setup allows you to load Spring configuration with Spring MVC or Spring WebFlux infrastructure and controller declarations and use it to handle requests via mock request @@ -6430,7 +6266,7 @@ class MyTests { |**2**| Inject the configuration | |**3**| Create the `WebTestClient` | -##### [](#webtestclient-fn-config)Bind to Router Function ##### +##### Bind to Router Function This setup allows you to test [functional endpoints](web-reactive.html#webflux-fn) via mock request and response objects, without a running server. @@ -6454,7 +6290,7 @@ val client = WebTestClient.bindToRouterFunction(route).build() For Spring MVC there are currently no options to test[WebMvc functional endpoints](web.html#webmvc-fn). -##### [](#webtestclient-server-config)Bind to Server ##### +##### Bind to Server This setup connects to a running server to perform full, end-to-end HTTP tests: @@ -6470,7 +6306,7 @@ Kotlin client = WebTestClient.bindToServer().baseUrl("http://localhost:8080").build() ``` -##### [](#webtestclient-client-config)Client Config ##### +##### Client Config In addition to the server setup options described earlier, you can also configure client options, including base URL, default headers, client filters, and others. These options @@ -6496,7 +6332,7 @@ client = WebTestClient.bindToController(TestController()) .build() ``` -#### [](#webtestclient-tests)3.6.2. Writing Tests #### +#### 3.6.2. Writing Tests `WebTestClient` provides an API identical to [WebClient](web-reactive.html#webflux-client)up to the point of performing a request by using `exchange()`. See the[WebClient](web-reactive.html#webflux-client-body) documentation for examples on how to prepare a request with any content including form data, multipart data, and more. @@ -6629,7 +6465,7 @@ val result = client.get().uri("/persons/1") | |When you need to decode to a target type with generics, look for the overloaded methods
that accept[`ParameterizedTypeReference`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/core/ParameterizedTypeReference.html)instead of `Class`.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#webtestclient-no-content)No Content ##### +##### No Content If the response is not expected to have content, you can assert that as follows: @@ -6674,7 +6510,7 @@ client.get().uri("/persons/123") .expectBody() ``` -##### [](#webtestclient-json)JSON Content ##### +##### JSON Content You can use `expectBody()` without a target type to perform assertions on the raw content rather than through higher level Object(s). @@ -6725,7 +6561,7 @@ client.get().uri("/persons") .jsonPath("$[1].name").isEqualTo("Jason") ``` -##### [](#webtestclient-stream)Streaming Responses ##### +##### Streaming Responses To test potentially infinite streams such as `"text/event-stream"` or`"application/x-ndjson"`, start by verifying the response status and headers, and then obtain a `FluxExchangeResult`: @@ -6780,7 +6616,7 @@ StepVerifier.create(eventFlux) .verify() ``` -##### [](#webtestclient-mockmvc)MockMvc Assertions ##### +##### MockMvc Assertions `WebTestClient` is an HTTP client and as such it can only verify what is in the client response including status, headers, and body. @@ -6839,7 +6675,7 @@ MockMvcWebTestClient.resultActionsFor(result) .andExpect(model().attribute("string", "a string value")); ``` -### [](#spring-mvc-test-framework)3.7. MockMvc ### +### 3.7. MockMvc The Spring MVC Test framework, also known as MockMvc, provides support for testing Spring MVC applications. It performs full Spring MVC request handling but via mock request and @@ -6851,7 +6687,7 @@ requests with. The advantage of `WebTestClient` is the option to work with highe objects instead of raw data as well as the ability to switch to full, end-to-end HTTP tests against a live server and use the same test API. -#### [](#spring-mvc-test-server)3.7.1. Overview #### +#### 3.7.1. Overview You can write plain unit tests for Spring MVC by instantiating a controller, injecting it with dependencies, and calling its methods. However such tests do not verify request @@ -6869,7 +6705,7 @@ its own to perform requests and to verify responses, or you can also use it thro the [WebTestClient](#webtestclient) API with MockMvc plugged in as the server to handle requests with. -##### [](#spring-mvc-test-server-static-imports)Static Imports ##### +##### Static Imports When using MockMvc directly to perform requests, you’ll need static imports for: @@ -6887,7 +6723,7 @@ add the above as “favorite static members” in the Eclipse preferences. When using MockMvc through the [WebTestClient](#webtestclient) you do not need static imports. The `WebTestClient` provides a fluent API without static imports. -##### [](#spring-mvc-test-server-setup-options)Setup Choices ##### +##### Setup Choices MockMvc can be setup in one of two ways. One is to point directly to the controllers you want to test and programmatically configure Spring MVC infrastructure. The second is to @@ -7045,7 +6881,7 @@ answer. However, using the `standaloneSetup` does imply the need for additional` Alternatively, you can write all your tests with `webAppContextSetup`, in order to always test against your actual Spring MVC configuration. -##### [](#spring-mvc-test-server-setup-steps)Setup Features ##### +##### Setup Features No matter which MockMvc builder you use, all `MockMvcBuilder` implementations provide some common and very useful features. For example, you can declare an `Accept` header for @@ -7095,7 +6931,7 @@ Kotlin See the javadoc for[`ConfigurableMockMvcBuilder`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/test/web/servlet/setup/ConfigurableMockMvcBuilder.html)for a list of all MockMvc builder features or use the IDE to explore the available options. -##### [](#spring-mvc-test-server-performing-requests)Performing Requests ##### +##### Performing Requests This section shows how to use MockMvc on its own to perform requests and verify responses. If using MockMvc through the `WebTestClient` please see the corresponding section on[Writing Tests](#webtestclient-tests) instead. @@ -7230,7 +7066,7 @@ If the same property is also specified on a given request, it overrides the defa value. That is why the HTTP method and URI in the default request do not matter, since they must be specified on every request. -##### [](#spring-mvc-test-server-defining-expectations)Defining Expectations ##### +##### Defining Expectations You can define expectations by appending one or more `andExpect(..)` calls after performing a request, as the following example shows. As soon as one expectation fails, @@ -7423,7 +7259,7 @@ mockMvc.get("/handle") { } ``` -##### [](#spring-mvc-test-async-requests)Async Requests ##### +##### Async Requests This section shows how to use MockMvc on its own to test asynchronous request handling. If using MockMvc through the [WebTestClient](#webtestclient), there is nothing special to do to make @@ -7492,7 +7328,7 @@ fun test() { |**4**|Manually perform an ASYNC dispatch (as there is no running container)| |**5**| Verify the final response | -##### [](#spring-mvc-test-vs-streaming-response)Streaming Responses ##### +##### Streaming Responses The best way to test streaming responses such as Server-Sent Events is through the[WebTestClient](#webtestclient) which can be used as a test client to connect to a `MockMvc` instance to perform tests on Spring MVC controllers without a running server. For example: @@ -7522,7 +7358,7 @@ StepVerifier.create(exchangeResult.getResponseBody()) `WebTestClient` can also connect to a live server and perform full end-to-end integration tests. This is also supported in Spring Boot where you can[test a running server](https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-testing-spring-boot-applications-testing-with-running-server). -##### [](#spring-mvc-test-server-filters)Filter Registrations ##### +##### Filter Registrations When setting up a `MockMvc` instance, you can register one or more Servlet `Filter`instances, as the following example shows: @@ -7541,7 +7377,7 @@ Kotlin Registered filters are invoked through the `MockFilterChain` from `spring-test`, and the last filter delegates to the `DispatcherServlet`. -##### [](#spring-mvc-test-vs-end-to-end-integration-tests)MockMvc vs End-to-End Tests ##### +##### MockMvc vs End-to-End Tests MockMVc is built on Servlet API mock implementations from the`spring-test` module and does not rely on a running container. Therefore, there are some differences when compared to full end-to-end integration tests with an actual @@ -7584,11 +7420,11 @@ same time, it is important not to lose sight of the fact that the response is th important thing to check. In short, there is room here for multiple styles and strategies of testing even within the same project. -##### [](#spring-mvc-test-server-resources)Further Examples ##### +##### Further Examples The framework’s own tests include[many sample tests](https://github.com/spring-projects/spring-framework/tree/main/spring-test/src/test/java/org/springframework/test/web/servlet/samples) intended to show how to use MockMvc on its own or through the[WebTestClient](https://github.com/spring-projects/spring-framework/tree/main/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client). Browse these examples for further ideas. -#### [](#spring-mvc-test-server-htmlunit)3.7.2. HtmlUnit Integration #### +#### 3.7.2. HtmlUnit Integration Spring provides integration between [MockMvc](#spring-mvc-test-server) and[HtmlUnit](http://htmlunit.sourceforge.net/). This simplifies performing end-to-end testing when using HTML-based views. This integration lets you: @@ -7605,7 +7441,7 @@ when using HTML-based views. This integration lets you: | |MockMvc works with templating technologies that do not rely on a Servlet Container
(for example, Thymeleaf, FreeMarker, and others), but it does not work with JSPs, since
they rely on the Servlet container.| |---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#spring-mvc-test-server-htmlunit-why)Why HtmlUnit Integration? ##### +##### Why HtmlUnit Integration? The most obvious question that comes to mind is “Why do I need this?” The answer is best found by exploring a very basic sample application. Assume you have a Spring MVC web @@ -7741,7 +7577,7 @@ the input to a user for creating a message. In addition, our form view can poten use additional resources that impact the behavior of the page, such as JavaScript validation. -###### [](#spring-mvc-test-server-htmlunit-why-integration)Integration Testing to the Rescue? ###### +###### Integration Testing to the Rescue? To resolve the issues mentioned earlier, we could perform end-to-end integration testing, but this has some drawbacks. Consider testing the view that lets us page through the @@ -7775,13 +7611,13 @@ and without side effects. We can then implement a small number of true end-to-en integration tests that validate simple workflows to ensure that everything works together properly. -###### [](#spring-mvc-test-server-htmlunit-why-mockmvc)Enter HtmlUnit Integration ###### +###### Enter HtmlUnit Integration So how can we achieve a balance between testing the interactions of our pages and still retain good performance within our test suite? The answer is: “By integrating MockMvc with HtmlUnit.” -###### [](#spring-mvc-test-server-htmlunit-options)HtmlUnit Integration Options ###### +###### HtmlUnit Integration Options You have a number of options when you want to integrate MockMvc with HtmlUnit: @@ -7795,12 +7631,12 @@ You have a number of options when you want to integrate MockMvc with HtmlUnit: use Groovy for testing, ease development, and reuse code between integration and end-to-end testing. -##### [](#spring-mvc-test-server-htmlunit-mah)MockMvc and HtmlUnit ##### +##### MockMvc and HtmlUnit This section describes how to integrate MockMvc and HtmlUnit. Use this option if you want to use the raw HtmlUnit libraries. -###### [](#spring-mvc-test-server-htmlunit-mah-setup)MockMvc and HtmlUnit Setup ###### +###### MockMvc and HtmlUnit Setup First, make sure that you have included a test dependency on`net.sourceforge.htmlunit:htmlunit`. In order to use HtmlUnit with Apache HttpComponents 4.5+, you need to use HtmlUnit 2.18 or higher. @@ -7840,7 +7676,7 @@ This ensures that any URL that references `localhost` as the server is directed requested by using a network connection, as normal. This lets us easily test the use of CDNs. -###### [](#spring-mvc-test-server-htmlunit-mah-usage)MockMvc and HtmlUnit Usage ###### +###### MockMvc and HtmlUnit Usage Now we can use HtmlUnit as we normally would but without the need to deploy our application to a Servlet container. For example, we can request the view to create a @@ -7927,7 +7763,7 @@ the behavior of JavaScript within our pages. See the [HtmlUnit documentation](http://htmlunit.sourceforge.net/gettingStarted.html) for additional information about using HtmlUnit. -###### [](#spring-mvc-test-server-htmlunit-mah-advanced-builder)Advanced `MockMvcWebClientBuilder` ###### +###### Advanced `MockMvcWebClientBuilder` In the examples so far, we have used `MockMvcWebClientBuilder` in the simplest way possible, by building a `WebClient` based on the `WebApplicationContext` loaded for us by @@ -8031,12 +7867,12 @@ the full power of MockMvc at our fingertips. | |For additional information on creating a `MockMvc` instance, see[Setup Choices](#spring-mvc-test-server-setup-options).| |---|-----------------------------------------------------------------------------------------------------------------------| -##### [](#spring-mvc-test-server-htmlunit-webdriver)MockMvc and WebDriver ##### +##### MockMvc and WebDriver In the previous sections, we have seen how to use MockMvc in conjunction with the raw HtmlUnit APIs. In this section, we use additional abstractions within the Selenium[WebDriver](https://docs.seleniumhq.org/projects/webdriver/) to make things even easier. -###### [](#spring-mvc-test-server-htmlunit-webdriver-why)Why WebDriver and MockMvc? ###### +###### Why WebDriver and MockMvc? We can already use HtmlUnit and MockMvc, so why would we want to use WebDriver? The Selenium WebDriver provides a very elegant API that lets us easily organize our code. To @@ -8176,7 +8012,7 @@ Formerly, this pattern was known as the[Page Object Pattern](https://github.com/ can certainly do this with HtmlUnit, WebDriver provides some tools that we explore in the following sections to make this pattern much easier to implement. -###### [](#spring-mvc-test-server-htmlunit-webdriver-setup)MockMvc and WebDriver Setup ###### +###### MockMvc and WebDriver Setup To use Selenium WebDriver with the Spring MVC Test framework, make sure that your project includes a test dependency on `org.seleniumhq.selenium:selenium-htmlunit-driver`. @@ -8217,7 +8053,7 @@ directed to our `MockMvc` instance without the need for a real HTTP connection. URL is requested by using a network connection, as normal. This lets us easily test the use of CDNs. -###### [](#spring-mvc-test-server-htmlunit-webdriver-usage)MockMvc and WebDriver Usage ###### +###### MockMvc and WebDriver Usage Now we can use WebDriver as we normally would but without the need to deploy our application to a Servlet container. For example, we can request the view to create a @@ -8392,7 +8228,7 @@ fun destroy() { For additional information on using WebDriver, see the Selenium[WebDriver documentation](https://github.com/SeleniumHQ/selenium/wiki/Getting-Started). -###### [](#spring-mvc-test-server-htmlunit-webdriver-advanced-builder)Advanced `MockMvcHtmlUnitDriverBuilder` ###### +###### Advanced `MockMvcHtmlUnitDriverBuilder` In the examples so far, we have used `MockMvcHtmlUnitDriverBuilder` in the simplest way possible, by building a `WebDriver` based on the `WebApplicationContext` loaded for us by @@ -8496,18 +8332,18 @@ the full power of MockMvc at our fingertips. | |For additional information on creating a `MockMvc` instance, see[Setup Choices](#spring-mvc-test-server-setup-options).| |---|-----------------------------------------------------------------------------------------------------------------------| -##### [](#spring-mvc-test-server-htmlunit-geb)MockMvc and Geb ##### +##### MockMvc and Geb In the previous section, we saw how to use MockMvc with WebDriver. In this section, we use [Geb](http://www.gebish.org/) to make our tests even Groovy-er. -###### [](#spring-mvc-test-server-htmlunit-geb-why)Why Geb and MockMvc? ###### +###### Why Geb and MockMvc? Geb is backed by WebDriver, so it offers many of the[same benefits](#spring-mvc-test-server-htmlunit-webdriver-why) that we get from WebDriver. However, Geb makes things even easier by taking care of some of the boilerplate code for us. -###### [](#spring-mvc-test-server-htmlunit-geb-setup)MockMvc and Geb Setup ###### +###### MockMvc and Geb Setup We can easily initialize a Geb `Browser` with a Selenium WebDriver that uses MockMvc, as follows: @@ -8527,7 +8363,7 @@ This ensures that any URL referencing `localhost` as the server is directed to o requested by using a network connection as normal. This lets us easily test the use of CDNs. -###### [](#spring-mvc-test-server-htmlunit-geb-usage)MockMvc and Geb Usage ###### +###### MockMvc and Geb Usage Now we can use Geb as we normally would but without the need to deploy our application to a Servlet container. For example, we can request the view to create a message with the @@ -8605,7 +8441,7 @@ message == expectedMessage For further details on how to get the most out of Geb, see[The Book of Geb](http://www.gebish.org/manual/current/) user’s manual. -### [](#spring-mvc-test-client)3.8. Testing Client Applications ### +### 3.8. 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 @@ -8723,7 +8559,7 @@ restTemplate = RestTemplate(MockMvcClientHttpRequestFactory(mockMvc)) // Test code that uses the above RestTemplate ... ``` -#### [](#spring-mvc-test-client-static-imports)3.8.1. Static Imports #### +#### 3.8.1. 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.*` and `MockRestResponseCreators.*` as @@ -8732,13 +8568,12 @@ Assist → Favorites. That allows using content assist after typing the first ch 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)3.8.2. Further Examples of Client-side REST Tests #### +#### 3.8.2. Further Examples of Client-side REST Tests Spring MVC Test’s own tests include[example tests](https://github.com/spring-projects/spring-framework/tree/main/spring-test/src/test/java/org/springframework/test/web/client/samples) of client-side REST tests. -[](#testing-resources)4. Further Resources ----------- +## 4. Further Resources See the following resources for more information about testing: diff --git a/docs/en/spring-framework/web-reactive.md b/docs/en/spring-framework/web-reactive.md index d9c3d95..75ff8f3 100644 --- a/docs/en/spring-framework/web-reactive.md +++ b/docs/en/spring-framework/web-reactive.md @@ -1,219 +1,4 @@ -Web on Reactive Stack -========== - -version 5.3.16 - -Table of Contents - -* [1. Spring WebFlux](#webflux) - * [1.1. Overview](#webflux-new-framework) - * [1.1.1. Define “Reactive”](#webflux-why-reactive) - * [1.1.2. Reactive API](#webflux-reactive-api) - * [1.1.3. Programming Models](#webflux-programming-models) - * [1.1.4. Applicability](#webflux-framework-choice) - * [1.1.5. Servers](#webflux-server-choice) - * [1.1.6. Performance](#webflux-performance) - * [1.1.7. Concurrency Model](#webflux-concurrency-model) - - * [1.2. Reactive Core](#webflux-reactive-spring-web) - * [1.2.1. `HttpHandler`](#webflux-httphandler) - * [1.2.2. `WebHandler` API](#webflux-web-handler-api) - * [Special bean types](#webflux-web-handler-api-special-beans) - * [Form Data](#webflux-form-data) - * [Multipart Data](#webflux-multipart) - * [Forwarded Headers](#webflux-forwarded-headers) - - * [1.2.3. Filters](#webflux-filters) - * [CORS](#webflux-filters-cors) - - * [1.2.4. Exceptions](#webflux-exception-handler) - * [1.2.5. Codecs](#webflux-codecs) - * [Jackson JSON](#webflux-codecs-jackson) - * [Form Data](#webflux-codecs-forms) - * [Multipart](#webflux-codecs-multipart) - * [Limits](#webflux-codecs-limits) - * [Streaming](#webflux-codecs-streaming) - * [`DataBuffer`](#webflux-codecs-buffers) - - * [1.2.6. Logging](#webflux-logging) - * [Log Id](#webflux-logging-id) - * [Sensitive Data](#webflux-logging-sensitive-data) - * [Appenders](#webflux-logging-appenders) - * [Custom codecs](#webflux-codecs-custom) - - * [1.3. `DispatcherHandler`](#webflux-dispatcher-handler) - * [1.3.1. Special Bean Types](#webflux-special-bean-types) - * [1.3.2. WebFlux Config](#webflux-framework-config) - * [1.3.3. Processing](#webflux-dispatcher-handler-sequence) - * [1.3.4. Result Handling](#webflux-resulthandling) - * [1.3.5. Exceptions](#webflux-dispatcher-exceptions) - * [1.3.6. View Resolution](#webflux-viewresolution) - * [Handling](#webflux-viewresolution-handling) - * [Redirecting](#webflux-redirecting-redirect-prefix) - * [Content Negotiation](#webflux-multiple-representations) - - * [1.4. Annotated Controllers](#webflux-controller) - * [1.4.1. `@Controller`](#webflux-ann-controller) - * [1.4.2. Request Mapping](#webflux-ann-requestmapping) - * [URI Patterns](#webflux-ann-requestmapping-uri-templates) - * [Pattern Comparison](#webflux-ann-requestmapping-pattern-comparison) - * [Consumable Media Types](#webflux-ann-requestmapping-consumes) - * [Producible Media Types](#webflux-ann-requestmapping-produces) - * [Parameters and Headers](#webflux-ann-requestmapping-params-and-headers) - * [HTTP HEAD, OPTIONS](#webflux-ann-requestmapping-head-options) - * [Custom Annotations](#webflux-ann-requestmapping-composed) - * [Explicit Registrations](#webflux-ann-requestmapping-registration) - - * [1.4.3. Handler Methods](#webflux-ann-methods) - * [Method Arguments](#webflux-ann-arguments) - * [Return Values](#webflux-ann-return-types) - * [Type Conversion](#webflux-ann-typeconversion) - * [Matrix Variables](#webflux-ann-matrix-variables) - * [`@RequestParam`](#webflux-ann-requestparam) - * [`@RequestHeader`](#webflux-ann-requestheader) - * [`@CookieValue`](#webflux-ann-cookievalue) - * [`@ModelAttribute`](#webflux-ann-modelattrib-method-args) - * [`@SessionAttributes`](#webflux-ann-sessionattributes) - * [`@SessionAttribute`](#webflux-ann-sessionattribute) - * [`@RequestAttribute`](#webflux-ann-requestattrib) - * [Multipart Content](#webflux-multipart-forms) - * [`@RequestBody`](#webflux-ann-requestbody) - * [`HttpEntity`](#webflux-ann-httpentity) - * [`@ResponseBody`](#webflux-ann-responsebody) - * [`ResponseEntity`](#webflux-ann-responseentity) - * [Jackson JSON](#webflux-ann-jackson) - - * [1.4.4. `Model`](#webflux-ann-modelattrib-methods) - * [1.4.5. `DataBinder`](#webflux-ann-initbinder) - * [1.4.6. Managing Exceptions](#webflux-ann-controller-exceptions) - * [REST API exceptions](#webflux-ann-rest-exceptions) - - * [1.4.7. Controller Advice](#webflux-ann-controller-advice) - - * [1.5. Functional Endpoints](#webflux-fn) - * [1.5.1. Overview](#webflux-fn-overview) - * [1.5.2. HandlerFunction](#webflux-fn-handler-functions) - * [ServerRequest](#webflux-fn-request) - * [ServerResponse](#webflux-fn-response) - * [Handler Classes](#webflux-fn-handler-classes) - * [Validation](#webflux-fn-handler-validation) - - * [1.5.3. `RouterFunction`](#webflux-fn-router-functions) - * [Predicates](#webflux-fn-predicates) - * [Routes](#webflux-fn-routes) - * [Nested Routes](#nested-routes) - - * [1.5.4. Running a Server](#webflux-fn-running) - * [1.5.5. Filtering Handler Functions](#webflux-fn-handler-filter-function) - - * [1.6. URI Links](#webflux-uri-building) - * [1.6.1. UriComponents](#web-uricomponents) - * [1.6.2. UriBuilder](#web-uribuilder) - * [1.6.3. URI Encoding](#web-uri-encoding) - - * [1.7. CORS](#webflux-cors) - * [1.7.1. Introduction](#webflux-cors-intro) - * [1.7.2. Processing](#webflux-cors-processing) - * [1.7.3. `@CrossOrigin`](#webflux-cors-controller) - * [1.7.4. Global Configuration](#webflux-cors-global) - * [1.7.5. CORS `WebFilter`](#webflux-cors-webfilter) - - * [1.8. Web Security](#webflux-web-security) - * [1.9. View Technologies](#webflux-view) - * [1.9.1. Thymeleaf](#webflux-view-thymeleaf) - * [1.9.2. FreeMarker](#webflux-view-freemarker) - * [View Configuration](#webflux-view-freemarker-contextconfig) - * [FreeMarker Configuration](#webflux-views-freemarker) - * [Form Handling](#webflux-view-freemarker-forms) - - * [1.9.3. Script Views](#webflux-view-script) - * [Requirements](#webflux-view-script-dependencies) - * [Script Templates](#webflux-view-script-integrate) - - * [1.9.4. JSON and XML](#webflux-view-httpmessagewriter) - - * [1.10. HTTP Caching](#webflux-caching) - * [1.10.1. `CacheControl`](#webflux-caching-cachecontrol) - * [1.10.2. Controllers](#webflux-caching-etag-lastmodified) - * [1.10.3. Static Resources](#webflux-caching-static-resources) - - * [1.11. WebFlux Config](#webflux-config) - * [1.11.1. Enabling WebFlux Config](#webflux-config-enable) - * [1.11.2. WebFlux config API](#webflux-config-customize) - * [1.11.3. Conversion, formatting](#webflux-config-conversion) - * [1.11.4. Validation](#webflux-config-validation) - * [1.11.5. Content Type Resolvers](#webflux-config-content-negotiation) - * [1.11.6. HTTP message codecs](#webflux-config-message-codecs) - * [1.11.7. View Resolvers](#webflux-config-view-resolvers) - * [1.11.8. Static Resources](#webflux-config-static-resources) - * [1.11.9. Path Matching](#webflux-config-path-matching) - * [1.11.10. WebSocketService](#webflux-config-websocket-service) - * [1.11.11. Advanced Configuration Mode](#webflux-config-advanced-java) - - * [1.12. HTTP/2](#webflux-http2) - -* [2. WebClient](#webflux-client) - * [2.1. Configuration](#webflux-client-builder) - * [2.1.1. MaxInMemorySize](#webflux-client-builder-maxinmemorysize) - * [2.1.2. Reactor Netty](#webflux-client-builder-reactor) - * [Resources](#webflux-client-builder-reactor-resources) - * [Timeouts](#webflux-client-builder-reactor-timeout) - - * [2.1.3. Jetty](#webflux-client-builder-jetty) - * [2.1.4. HttpComponents](#webflux-client-builder-http-components) - - * [2.2. `retrieve()`](#webflux-client-retrieve) - * [2.3. Exchange](#webflux-client-exchange) - * [2.4. Request Body](#webflux-client-body) - * [2.4.1. Form Data](#webflux-client-body-form) - * [2.4.2. Multipart Data](#webflux-client-body-multipart) - - * [2.5. Filters](#webflux-client-filter) - * [2.6. Attributes](#webflux-client-attributes) - * [2.7. Context](#webflux-client-context) - * [2.8. Synchronous Use](#webflux-client-synchronous) - * [2.9. Testing](#webflux-client-testing) - -* [3. WebSockets](#webflux-websocket) - * [3.1. Introduction to WebSocket](#websocket-intro) - * [3.1.1. HTTP Versus WebSocket](#websocket-intro-architecture) - * [3.1.2. When to Use WebSockets](#websocket-intro-when-to-use) - - * [3.2. WebSocket API](#webflux-websocket-server) - * [3.2.1. Server](#webflux-websocket-server-handler) - * [3.2.2. `WebSocketHandler`](#webflux-websockethandler) - * [3.2.3. `DataBuffer`](#webflux-websocket-databuffer) - * [3.2.4. Handshake](#webflux-websocket-server-handshake) - * [3.2.5. Server Configation](#webflux-websocket-server-config) - * [3.2.6. CORS](#webflux-websocket-server-cors) - * [3.2.7. Client](#webflux-websocket-client) - -* [4. Testing](#webflux-test) -* [5. RSocket](#rsocket) - * [5.1. Overview](#rsocket-overview) - * [5.1.1. The Protocol](#rsocket-protocol) - * [5.1.2. Java Implementation](#rsocket-java) - * [5.1.3. Spring Support](#rsocket-spring) - - * [5.2. RSocketRequester](#rsocket-requester) - * [5.2.1. Client Requester](#rsocket-requester-client) - * [Connection Setup](#rsocket-requester-client-setup) - * [Strategies](#rsocket-requester-client-strategies) - * [Client Responders](#rsocket-requester-client-responder) - * [Advanced](#rsocket-requester-client-advanced) - - * [5.2.2. Server Requester](#rsocket-requester-server) - * [5.2.3. Requests](#rsocket-requester-requests) - - * [5.3. Annotated Responders](#rsocket-annot-responders) - * [5.3.1. Server Responders](#rsocket-annot-responders-server) - * [5.3.2. Client Responders](#rsocket-annot-responders-client) - * [5.3.3. @MessageMapping](#rsocket-annot-messagemapping) - * [5.3.4. @ConnectMapping](#rsocket-annot-connectmapping) - - * [5.4. MetadataExtractor](#rsocket-metadata-extractor) - -* [6. Reactive Libraries](#webflux-reactive-libraries) +# Web on Reactive Stack This part of the documentation covers support for reactive-stack web applications built on a [Reactive Streams](https://www.reactive-streams.org/) API to run on non-blocking @@ -223,8 +8,7 @@ the reactive [`WebClient`](#webflux-client), support for [testing](#webflux-test and [reactive libraries](#webflux-reactive-libraries). For Servlet-stack web applications, see [Web on Servlet Stack](web.html#spring-web). -[](#webflux)1. Spring WebFlux ----------- +## 1. Spring WebFlux 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, @@ -236,7 +20,7 @@ Both web frameworks mirror the names of their source modules Spring Framework. Each module is optional. Applications can use one or the other module or, in some cases, both — for example, Spring MVC controllers with the reactive `WebClient`. -### [](#webflux-new-framework)1.1. Overview ### +### 1.1. Overview Why was Spring WebFlux created? @@ -255,7 +39,7 @@ by `CompletableFuture` and [ReactiveX](http://reactivex.io/)) that allow declara composition of asynchronous logic. At the programming-model level, Java 8 enabled Spring WebFlux to offer functional web endpoints alongside annotated controllers. -#### [](#webflux-why-reactive)1.1.1. Define “Reactive” #### +#### 1.1.1. Define “Reactive” We touched on “non-blocking” and “functional” but what does reactive mean? @@ -279,7 +63,7 @@ subscriber control how quickly or how slowly the publisher produces data. | |**Common question: what if a publisher cannot slow down?**
The purpose of Reactive Streams is only to establish the mechanism and a boundary.
If a publisher cannot slow down, it has to decide whether to buffer, drop, or fail.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#webflux-reactive-api)1.1.2. Reactive API #### +#### 1.1.2. Reactive API Reactive Streams plays an important role for interoperability. It is of interest to libraries and infrastructure components but less useful as an application API, because it is too @@ -304,7 +88,7 @@ of RxJava or another reactive library. See [Reactive Libraries](#webflux-reactiv | |In addition to Reactive APIs, WebFlux can also be used with[Coroutines](languages.html#coroutines) APIs in Kotlin which provides a more imperative style of programming.
The following Kotlin code samples will be provided with Coroutines APIs.| |---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#webflux-programming-models)1.1.3. Programming Models #### +#### 1.1.3. Programming Models The `spring-web` module contains the reactive foundation that underlies Spring WebFlux, including HTTP abstractions, Reactive Streams [adapters](#webflux-httphandler) for supported @@ -324,7 +108,7 @@ On that foundation, Spring WebFlux provides a choice of two programming models: is in charge of request handling from start to finish versus declaring intent through annotations and being called back. -#### [](#webflux-framework-choice)1.1.4. Applicability #### +#### 1.1.4. Applicability Spring MVC or WebFlux? @@ -377,7 +161,7 @@ We suggest that you consider the following specific points: unsure what benefits to look for, start by learning about how non-blocking I/O works (for example, concurrency on single-threaded Node.js) and its effects. -#### [](#webflux-server-choice)1.1.5. Servers #### +#### 1.1.5. Servers Spring WebFlux is supported on Tomcat, Jetty, Servlet 3.1+ containers, as well as on non-Servlet runtimes such as Netty and Undertow. All servers are adapted to a low-level,[common API](#webflux-httphandler) so that higher-level[programming models](#webflux-programming-models) can be supported across servers. @@ -399,7 +183,7 @@ adapter. It is not exposed for direct use. For Undertow, Spring WebFlux uses Undertow APIs directly without the Servlet API. -#### [](#webflux-performance)1.1.6. Performance #### +#### 1.1.6. Performance Performance has many characteristics and meanings. Reactive and non-blocking generally do not make applications run faster. They can, in some cases, (for example, if using the`WebClient` to run remote calls in parallel). On the whole, it requires more work to do @@ -412,7 +196,7 @@ need to have some latency (including a mix of slow and unpredictable network I/O That is where the reactive stack begins to show its strengths, and the differences can be dramatic. -#### [](#webflux-concurrency-model)1.1.7. Concurrency Model #### +#### 1.1.7. Concurrency Model Both Spring MVC and Spring WebFlux support annotated controllers, but there is a key difference in the concurrency model and the default assumptions for blocking and threads. @@ -472,7 +256,7 @@ you need to use server-specific configuration APIs, or, if you use Spring Boot, check the Spring Boot configuration options for each server. You can[configure](#webflux-client-builder) the `WebClient` directly. For all other libraries, see their respective documentation. -### [](#webflux-reactive-spring-web)1.2. Reactive Core ### +### 1.2. Reactive Core The `spring-web` module contains the following foundational support for reactive web applications: @@ -495,7 +279,7 @@ applications: * For client and server, [codecs](#webflux-codecs) for serialization and deserialization of HTTP request and response content. -#### [](#webflux-httphandler)1.2.1. `HttpHandler` #### +#### 1.2.1. `HttpHandler` [HttpHandler](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/http/server/reactive/HttpHandler.html)is a simple contract with a single method to handle a request and a response. It is intentionally minimal, and its main and only purpose is to be a minimal abstraction @@ -637,7 +421,7 @@ server.start() To deploy as a WAR to any Servlet 3.1+ container, you can extend and include[`AbstractReactiveWebInitializer`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/web/server/adapter/AbstractReactiveWebInitializer.html)in the WAR. That class wraps an `HttpHandler` with `ServletHttpHandlerAdapter` and registers that as a `Servlet`. -#### [](#webflux-web-handler-api)1.2.2. `WebHandler` API #### +#### 1.2.2. `WebHandler` API The `org.springframework.web.server` package builds on the [`HttpHandler`](#webflux-httphandler) contract to provide a general-purpose web API for processing requests through a chain of multiple[`WebExceptionHandler`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/web/server/WebExceptionHandler.html), multiple[`WebFilter`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/web/server/WebFilter.html), and a single[`WebHandler`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/web/server/WebHandler.html) component. The chain can @@ -659,7 +443,7 @@ such as: * and more.. -##### [](#webflux-web-handler-api-special-beans)Special bean types ##### +##### Special bean types The table below lists the components that `WebHttpHandlerBuilder` can auto-detect in a Spring ApplicationContext, or that can be registered directly with it: @@ -674,7 +458,7 @@ Spring ApplicationContext, or that can be registered directly with it: | `localeContextResolver` | `LocaleContextResolver` |0..1 | The resolver for `LocaleContext` exposed through a method on `ServerWebExchange`.`AcceptHeaderLocaleContextResolver` by default. | |`forwardedHeaderTransformer`|`ForwardedHeaderTransformer`|0..1 | For processing forwarded type headers, either by extracting and removing them or by removing them only.
Not used by default. | -##### [](#webflux-form-data)Form Data ##### +##### Form Data `ServerWebExchange` exposes the following method for accessing form data: @@ -694,7 +478,7 @@ The `DefaultServerWebExchange` uses the configured `HttpMessageReader` to parse (`application/x-www-form-urlencoded`) into a `MultiValueMap`. By default,`FormHttpMessageReader` is configured for use by the `ServerCodecConfigurer` bean (see the [Web Handler API](#webflux-web-handler-api)). -##### [](#webflux-multipart)Multipart Data ##### +##### Multipart Data [Web MVC](web.html#mvc-multipart) @@ -724,7 +508,7 @@ To parse multipart data in streaming fashion, you can use the `Flux` retur parsing multipart data in full. By contrast, you can use `@RequestBody` to decode the content to `Flux` without collecting to a `MultiValueMap`. -##### [](#webflux-forwarded-headers)Forwarded Headers ##### +##### Forwarded Headers [Web MVC](web.html#filters-forwarded-headers) @@ -748,7 +532,7 @@ from the outside. You can also configure the `ForwardedHeaderTransformer` with`r | |In 5.1 `ForwardedHeaderFilter` was deprecated and superceded by`ForwardedHeaderTransformer` so forwarded headers can be processed earlier, before the
exchange is created. If the filter is configured anyway, it is taken out of the list of
filters, and `ForwardedHeaderTransformer` is used instead.| |---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#webflux-filters)1.2.3. Filters #### +#### 1.2.3. Filters [Web MVC](web.html#filters) @@ -757,7 +541,7 @@ logic before and after the rest of the processing chain of filters and the targe as declaring it as a Spring bean and (optionally) expressing precedence by using `@Order` on the bean declaration or by implementing `Ordered`. -##### [](#webflux-filters-cors)CORS ##### +##### CORS [Web MVC](web.html#filters-cors) @@ -766,7 +550,7 @@ controllers. However, when you use it with Spring Security, we advise relying on See the section on [CORS](#webflux-cors) and the [webflux-cors.html](webflux-cors.html#webflux-cors-webfilter) for more details. -#### [](#webflux-exception-handler)1.2.4. Exceptions #### +#### 1.2.4. Exceptions [Web MVC](web.html#mvc-ann-customer-servlet-container-error-page) @@ -782,7 +566,7 @@ The following table describes the available `WebExceptionHandler` implementation | `ResponseStatusExceptionHandler` |Provides handling for exceptions of type[`ResponseStatusException`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/web/server/ResponseStatusException.html)by setting the response to the HTTP status code of the exception.| |`WebFluxResponseStatusExceptionHandler`| Extension of `ResponseStatusExceptionHandler` that can also determine the HTTP status
code of a `@ResponseStatus` annotation on any exception.

This handler is declared in the [WebFlux Config](#webflux-config). | -#### [](#webflux-codecs)1.2.5. Codecs #### +#### 1.2.5. Codecs [Web MVC](integration.html#rest-message-conversion) @@ -812,7 +596,7 @@ server-sent events, and others. `ClientCodecConfigurer` and `ServerCodecConfigurer` are typically used to configure and customize the codecs to use in an application. See the section on configuring[HTTP message codecs](#webflux-config-message-codecs). -##### [](#webflux-codecs-jackson)Jackson JSON ##### +##### Jackson JSON JSON and binary JSON ([Smile](https://github.com/FasterXML/smile-format-specification)) are both supported when the Jackson library is present. @@ -847,7 +631,7 @@ The `Jackson2Encoder` works as follows: | |By default both `Jackson2Encoder` and `Jackson2Decoder` do not support elements of type`String`. Instead the default assumption is that a string or a sequence of strings
represent serialized JSON content, to be rendered by the `CharSequenceEncoder`. If what
you need is to render a JSON array from `Flux`, use `Flux#collectToList()` and
encode a `Mono>`.| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#webflux-codecs-forms)Form Data ##### +##### Form Data `FormHttpMessageReader` and `FormHttpMessageWriter` support decoding and encoding`application/x-www-form-urlencoded` content. @@ -858,7 +642,7 @@ See [Form Data](#webflux-form-data) in the [`WebHandler` API](#webflux-web-handl Once `getFormData()` is used, the original raw content can no longer be read from the request body. For this reason, applications are expected to go through `ServerWebExchange`consistently for access to the cached form data versus reading from the raw request body. -##### [](#webflux-codecs-multipart)Multipart ##### +##### Multipart `MultipartHttpMessageReader` and `MultipartHttpMessageWriter` support decoding and encoding "multipart/form-data" content. In turn `MultipartHttpMessageReader` delegates to @@ -875,7 +659,7 @@ See [Multipart Data](#webflux-multipart) in the [`WebHandler` API](#webflux-web- Once `getMultipartData()` is used, the original raw content can no longer be read from the request body. For this reason applications have to consistently use `getMultipartData()`for repeated, map-like access to parts, or otherwise rely on the`SynchronossPartHttpMessageReader` for a one-time access to `Flux`. -##### [](#webflux-codecs-limits)Limits ##### +##### Limits `Decoder` and `HttpMessageReader` implementations that buffer some or all of the input stream can be configured with a limit on the maximum number of bytes to buffer in memory. @@ -896,7 +680,7 @@ is written to disk. For file parts written to disk, there is an additional`maxDi a `maxParts` property to limit the overall number of parts in a multipart request. To configure all three in WebFlux, you’ll need to supply a pre-configured instance of`MultipartHttpMessageReader` to `ServerCodecConfigurer`. -##### [](#webflux-codecs-streaming)Streaming ##### +##### Streaming [Web MVC](web.html#mvc-ann-async-http-streaming) @@ -905,7 +689,7 @@ reliably detect a disconnected client sooner rather than later. Such a send coul comment-only, empty SSE event or any other "no-op" data that would effectively serve as a heartbeat. -##### [](#webflux-codecs-buffers)`DataBuffer` ##### +##### `DataBuffer` `DataBuffer` is the representation for a byte buffer in WebFlux. The Spring Core part of this reference has more on that in the section on[Data Buffers and Codecs](core.html#databuffers). The key point to understand is that on some @@ -918,7 +702,7 @@ and from higher level objects, or unless they choose to create custom codecs. Fo cases please review the information in [Data Buffers and Codecs](core.html#databuffers), especially the section on [Using DataBuffer](core.html#databuffers-using). -#### [](#webflux-logging)1.2.6. Logging #### +#### 1.2.6. Logging [Web MVC](web.html#mvc-logging) @@ -933,7 +717,7 @@ messages may show a different level of detail at `TRACE` vs `DEBUG`. Good logging comes from the experience of using the logs. If you spot anything that does not meet the stated goals, please let us know. -##### [](#webflux-logging-id)Log Id ##### +##### Log Id In WebFlux, a single request can be run over multiple threads and the thread ID is not useful for correlating log messages that belong to a specific request. This is why @@ -945,7 +729,7 @@ while a fully formatted prefix based on that ID is available from`ServerWebExcha ([`LOG_ID_ATTRIBUTE`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/web/reactive/function/client/ClientRequest.html#LOG_ID_ATTRIBUTE)) ,while a fully formatted prefix is available from `ClientRequest#logPrefix()`. -##### [](#webflux-logging-sensitive-data)Sensitive Data ##### +##### Sensitive Data [Web MVC](web.html#mvc-logging-sensitive-data) @@ -1004,14 +788,14 @@ val webClient = WebClient.builder() .build() ``` -##### [](#webflux-logging-appenders)Appenders ##### +##### Appenders Logging libraries such as SLF4J and Log4J 2 provide asynchronous loggers that avoid blocking. While those have their own drawbacks such as potentially dropping messages that could not be queued for logging, they are the best available options currently for use in a reactive, non-blocking application. -##### [](#webflux-codecs-custom)Custom codecs ##### +##### Custom codecs Applications can register custom codecs for supporting additional media types, or specific behaviors that are not supported by the default codecs. @@ -1044,7 +828,7 @@ val webClient = WebClient.builder() .build() ``` -### [](#webflux-dispatcher-handler)1.3. `DispatcherHandler` ### +### 1.3. `DispatcherHandler` [Web MVC](web.html#mvc-servlet) @@ -1087,7 +871,7 @@ val handler = WebHttpHandlerBuilder.applicationContext(context).build() The resulting `HttpHandler` is ready for use with a [server adapter](#webflux-httphandler). -#### [](#webflux-special-bean-types)1.3.1. Special Bean Types #### +#### 1.3.1. Special Bean Types [Web MVC](web.html#mvc-servlet-special-bean-types) @@ -1105,7 +889,7 @@ there are also some other beans detected at a lower level (see[Special bean type | `HandlerAdapter` | Help the `DispatcherHandler` to invoke a handler mapped to a request regardless of
how the handler is actually invoked. For example, invoking an annotated controller
requires resolving annotations. The main purpose of a `HandlerAdapter` is to shield the`DispatcherHandler` from such details. | |`HandlerResultHandler`| Process the result from the handler invocation and finalize the response.
See [Result Handling](#webflux-resulthandling). | -#### [](#webflux-framework-config)1.3.2. WebFlux Config #### +#### 1.3.2. WebFlux Config [Web MVC](web.html#mvc-servlet-config) @@ -1116,7 +900,7 @@ required beans and provides a higher-level configuration callback API to customi | |Spring Boot relies on the WebFlux config to configure Spring WebFlux and also provides
many extra convenient options.| |---|-------------------------------------------------------------------------------------------------------------------------| -#### [](#webflux-dispatcher-handler-sequence)1.3.3. Processing #### +#### 1.3.3. Processing [Web MVC](web.html#mvc-servlet-sequence) @@ -1130,7 +914,7 @@ required beans and provides a higher-level configuration callback API to customi * The `HandlerResult` is given to an appropriate `HandlerResultHandler` to complete processing by writing to the response directly or by using a view to render. -#### [](#webflux-resulthandling)1.3.4. Result Handling #### +#### 1.3.4. Result Handling The return value from the invocation of a handler, through a `HandlerAdapter`, is wrapped as a `HandlerResult`, along with some additional context, and passed to the first`HandlerResultHandler` that claims support for it. The following table shows the available`HandlerResultHandler` implementations, all of which are declared in the [WebFlux Config](#webflux-config): @@ -1142,7 +926,7 @@ as a `HandlerResult`, along with some additional context, and passed to the firs | `ResponseBodyResultHandler` | Handle return values from `@ResponseBody` methods or `@RestController` classes. | 100 | |`ViewResolutionResultHandler`|`CharSequence`, [`View`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/web/reactive/result/view/View.html),[Model](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/ui/Model.html), `Map`,[Rendering](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/web/reactive/result/view/Rendering.html),
or any other `Object` is treated as a model attribute.

See also [View Resolution](#webflux-viewresolution).|`Integer.MAX_VALUE`| -#### [](#webflux-dispatcher-exceptions)1.3.5. Exceptions #### +#### 1.3.5. Exceptions [Web MVC](web.html#mvc-exceptionhandlers) @@ -1162,7 +946,7 @@ This generally should not matter. However, keep in mind that, in WebFlux, you ca See also [Managing Exceptions](#webflux-ann-controller-exceptions) in the “Annotated Controller” section or[Exceptions](#webflux-exception-handler) in the WebHandler API section. -#### [](#webflux-viewresolution)1.3.6. View Resolution #### +#### 1.3.6. View Resolution [Web MVC](web.html#mvc-viewresolver) @@ -1170,7 +954,7 @@ View resolution enables rendering to a browser with an HTML template and a model tying you to a specific view technology. In Spring WebFlux, view resolution is supported through a dedicated [HandlerResultHandler](#webflux-resulthandling) that uses`ViewResolver` instances to map a String (representing a logical view name) to a `View`instance. The `View` is then used to render the response. -##### [](#webflux-viewresolution-handling)Handling ##### +##### Handling [Web MVC](web.html#mvc-handling) @@ -1208,7 +992,7 @@ dedicated configuration API for view resolution. See [View Technologies](#webflux-view) for more on the view technologies integrated with Spring WebFlux. -##### [](#webflux-redirecting-redirect-prefix)Redirecting ##### +##### Redirecting [Web MVC](web.html#mvc-redirecting-redirect-prefix) @@ -1218,7 +1002,7 @@ redirect is needed. The rest of the view name is the redirect URL. The net effect is the same as if the controller had returned a `RedirectView` or`Rendering.redirectTo("abc").build()`, but now the controller itself can operate in terms of logical view names. A view name such as`redirect:/some/resource` is relative to the current application, while a view name such as`redirect:https://example.com/arbitrary/path` redirects to an absolute URL. -##### [](#webflux-multiple-representations)Content Negotiation ##### +##### Content Negotiation [Web MVC](web.html#mvc-multiple-representations) @@ -1229,7 +1013,7 @@ In order to support media types such as JSON and XML, Spring WebFlux provides`Ht views through the [WebFlux Configuration](#webflux-config-view-resolvers). Default views are always selected and used if they match the requested media type. -### [](#webflux-controller)1.4. Annotated Controllers ### +### 1.4. Annotated Controllers [Web MVC](web.html#mvc-controller) @@ -1265,7 +1049,7 @@ class HelloController { In the preceding example, the method returns a `String` to be written to the response body. -#### [](#webflux-ann-controller)1.4.1. `@Controller` #### +#### 1.4.1. `@Controller` [Web MVC](web.html#mvc-ann-controller) @@ -1311,7 +1095,7 @@ itself meta-annotated with `@Controller` and `@ResponseBody`, indicating a contr every method inherits the type-level `@ResponseBody` annotation and, therefore, writes directly to the response body versus view resolution and rendering with an HTML template. -#### [](#webflux-ann-requestmapping)1.4.2. Request Mapping #### +#### 1.4.2. Request Mapping [Web MVC](web.html#mvc-ann-requestmapping) @@ -1378,7 +1162,7 @@ class PersonController { } ``` -##### [](#webflux-ann-requestmapping-uri-templates)URI Patterns ##### +##### URI Patterns [Web MVC](web.html#mvc-ann-requestmapping-uri-templates) @@ -1497,7 +1281,7 @@ mapping such as `/person` also matches to `/person.*`. For URL-based content negotiation, if needed, we recommend using a query parameter, which is simpler, more explicit, and less vulnerable to URL path based exploits. -##### [](#webflux-ann-requestmapping-pattern-comparison)Pattern Comparison ##### +##### Pattern Comparison [Web MVC](web.html#mvc-ann-requestmapping-pattern-comparison) @@ -1511,7 +1295,7 @@ wins. If two patterns have the same score, the longer is chosen. Catch-all patterns (for example, `**`, `{*varName}`) are excluded from the scoring and are always sorted last instead. If two patterns are both catch-all, the longer is chosen. -##### [](#webflux-ann-requestmapping-consumes)Consumable Media Types ##### +##### Consumable Media Types [Web MVC](web.html#mvc-ann-requestmapping-consumes) @@ -1546,7 +1330,7 @@ overrides rather than extends the class-level declaration. | |`MediaType` provides constants for commonly used media types — for example,`APPLICATION_JSON_VALUE` and `APPLICATION_XML_VALUE`.| |---|--------------------------------------------------------------------------------------------------------------------------------| -##### [](#webflux-ann-requestmapping-produces)Producible Media Types ##### +##### Producible Media Types [Web MVC](web.html#mvc-ann-requestmapping-produces) @@ -1582,7 +1366,7 @@ overrides rather than extend the class level declaration. | |`MediaType` provides constants for commonly used media types — e.g.`APPLICATION_JSON_VALUE`, `APPLICATION_XML_VALUE`.| |---|---------------------------------------------------------------------------------------------------------------------| -##### [](#webflux-ann-requestmapping-params-and-headers)Parameters and Headers ##### +##### Parameters and Headers [Web MVC](web.html#mvc-ann-requestmapping-params-and-headers) @@ -1640,7 +1424,7 @@ fun findPet(@PathVariable petId: String) { |**1**|Check that `myHeader` equals `myValue`.| |-----|---------------------------------------| -##### [](#webflux-ann-requestmapping-head-options)HTTP HEAD, OPTIONS ##### +##### HTTP HEAD, OPTIONS [Web MVC](web.html#mvc-ann-requestmapping-head-options) @@ -1657,7 +1441,7 @@ supported HTTP methods (for example, by using the HTTP method specific variants You can explicitly map a `@RequestMapping` method to HTTP HEAD and HTTP OPTIONS, but that is not necessary in the common case. -##### [](#webflux-ann-requestmapping-composed)Custom Annotations ##### +##### Custom Annotations [Web MVC](web.html#mvc-ann-requestmapping-composed) @@ -1673,7 +1457,7 @@ Spring WebFlux also supports custom request mapping attributes with custom reque logic. This is a more advanced option that requires sub-classing`RequestMappingHandlerMapping` and overriding the `getCustomMethodCondition` method, where you can check the custom attribute and return your own `RequestCondition`. -##### [](#webflux-ann-requestmapping-registration)Explicit Registrations ##### +##### Explicit Registrations [Web MVC](web.html#mvc-ann-requestmapping-registration) @@ -1732,14 +1516,14 @@ class MyConfig { |**3**| Get the handler method. | |**4**| Add the registration. | -#### [](#webflux-ann-methods)1.4.3. Handler Methods #### +#### 1.4.3. Handler Methods [Web MVC](web.html#mvc-ann-methods) `@RequestMapping` handler methods have a flexible signature and can choose from a range of supported controller method arguments and return values. -##### [](#webflux-ann-arguments)Method Arguments ##### +##### Method Arguments [Web MVC](web.html#mvc-ann-arguments) @@ -1780,7 +1564,7 @@ and others) and is equivalent to `required=false`. | `@RequestAttribute` | For access to request attributes. See [`@RequestAttribute`](#webflux-ann-requestattrib) for more details. | | Any other argument | If a method argument is not matched to any of the above, it is, by default, resolved as
a `@RequestParam` if it is a simple type, as determined by[BeanUtils#isSimpleProperty](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-),
or as a `@ModelAttribute`, otherwise. | -##### [](#webflux-ann-return-types)Return Values ##### +##### Return Values [Web MVC](web.html#mvc-ann-return-types) @@ -1802,7 +1586,7 @@ generally supported for all return values. |`Flux`, `Observable`, or other reactive type| Emit server-sent events. The `ServerSentEvent` wrapper can be omitted when only data needs
to be written (however, `text/event-stream` must be requested or declared in the mapping
through the `produces` attribute). | | Any other return value | If a return value is not matched to any of the above, it is, by default, treated as a view
name, if it is `String` or `void` (default view name selection applies), or as a model
attribute to be added to the model, unless it is a simple type, as determined by[BeanUtils#isSimpleProperty](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-),
in which case it remains unresolved. | -##### [](#webflux-ann-typeconversion)Type Conversion ##### +##### Type Conversion [Web MVC](web.html#mvc-ann-typeconversion) @@ -1818,7 +1602,7 @@ Such a value is treated as missing if it becomes `null` as a result of type conv This can be the case for `Long`, `UUID`, and other target types. If you want to allow `null`to be injected, either use the `required` flag on the argument annotation, or declare the argument as `@Nullable`. -##### [](#webflux-ann-matrix-variables)Matrix Variables ##### +##### Matrix Variables [Web MVC](web.html#mvc-ann-matrix-variables) @@ -1953,7 +1737,7 @@ fun findPet( } ``` -##### [](#webflux-ann-requestparam)`@RequestParam` ##### +##### `@RequestParam` [Web MVC](web.html#mvc-ann-requestparam) @@ -2023,7 +1807,7 @@ default, any argument that is a simple value type (as determined by[BeanUtils#is and is not resolved by any other argument resolver is treated as if it were annotated with `@RequestParam`. -##### [](#webflux-ann-requestheader)`@RequestHeader` ##### +##### `@RequestHeader` [Web MVC](web.html#mvc-ann-requestheader) @@ -2081,7 +1865,7 @@ with all header values. | |Built-in support is available for converting a comma-separated string into an
array or collection of strings or other types known to the type conversion system. For
example, a method parameter annotated with `@RequestHeader("Accept")` may be of type`String` but also of `String[]` or `List`.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#webflux-ann-cookievalue)`@CookieValue` ##### +##### `@CookieValue` [Web MVC](web.html#mvc-ann-cookievalue) @@ -2122,7 +1906,7 @@ fun handle(@CookieValue("JSESSIONID") cookie: String) { (1) Type conversion is applied automatically if the target method parameter type is not`String`. See [Type Conversion](#webflux-ann-typeconversion). -##### [](#webflux-ann-modelattrib-method-args)`@ModelAttribute` ##### +##### `@ModelAttribute` [Web MVC](web.html#mvc-ann-modelattrib-method-args) @@ -2274,7 +2058,7 @@ By default, any argument that is not a simple value type( as determined by[BeanU and is not resolved by any other argument resolver is treated as if it were annotated with `@ModelAttribute`. -##### [](#webflux-ann-sessionattributes)`@SessionAttributes` ##### +##### `@SessionAttributes` [Web MVC](web.html#mvc-ann-sessionattributes) @@ -2366,7 +2150,7 @@ class EditPetForm { |-----|------------------------------------------| |**2**| Using a `SessionStatus` variable. | -##### [](#webflux-ann-sessionattribute)`@SessionAttribute` ##### +##### `@SessionAttribute` [Web MVC](web.html#mvc-ann-sessionattribute) @@ -2403,7 +2187,7 @@ For use cases that require adding or removing session attributes, consider injec For temporary storage of model attributes in the session as part of a controller workflow, consider using `SessionAttributes`, as described in[`@SessionAttributes`](#webflux-ann-sessionattributes). -##### [](#webflux-ann-requestattrib)`@RequestAttribute` ##### +##### `@RequestAttribute` [Web MVC](web.html#mvc-ann-requestattrib) @@ -2435,7 +2219,7 @@ fun handle(@RequestAttribute client: Client): String { (1) |**1**|Using `@RequestAttribute`.| |-----|--------------------------| -##### [](#webflux-multipart-forms)Multipart Content ##### +##### Multipart Content [Web MVC](web.html#mvc-multipart-forms) @@ -2642,7 +2426,7 @@ fun handle(@RequestBody parts: Flow): String { (1) |**1**|Using `@RequestBody`.| |-----|---------------------| -##### [](#webflux-ann-requestbody)`@RequestBody` ##### +##### `@RequestBody` [Web MVC](web.html#mvc-ann-requestbody) @@ -2715,7 +2499,7 @@ fun handle(@Valid @RequestBody account: Mono) { } ``` -##### [](#webflux-ann-httpentity)`HttpEntity` ##### +##### `HttpEntity` [Web MVC](web.html#mvc-ann-httpentity) @@ -2740,7 +2524,7 @@ fun handle(entity: HttpEntity) { } ``` -##### [](#webflux-ann-responsebody)`@ResponseBody` ##### +##### `@ResponseBody` [Web MVC](web.html#mvc-ann-responsebody) @@ -2782,7 +2566,7 @@ See [Jackson JSON](#webflux-ann-jackson) for details. You can use the [HTTP message codecs](#webflux-config-message-codecs) option of the [WebFlux Config](#webflux-config) to configure or customize message writing. -##### [](#webflux-ann-responseentity)`ResponseEntity` ##### +##### `ResponseEntity` [Web MVC](web.html#mvc-ann-responseentity) @@ -2826,11 +2610,11 @@ for the body. This allows a variety of async responses with `ResponseEntity` as possible, albeit less common alternative. They provide the response status and headers asynchronously first and then the response body, also asynchronously, second. -##### [](#webflux-ann-jackson)Jackson JSON ##### +##### Jackson JSON Spring offers support for the Jackson JSON library. -###### [](#webflux-ann-jsonview)JSON Views ###### +##### JSON Views# [Web MVC](web.html#mvc-ann-jackson) @@ -2903,7 +2687,7 @@ class User( | |`@JsonView` allows an array of view classes but you can only specify only one per
controller method. Use a composite interface if you need to activate multiple views.| |---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#webflux-ann-modelattrib-methods)1.4.4. `Model` #### +#### 1.4.4. `Model` [Web MVC](web.html#mvc-ann-modelattrib-methods) @@ -3039,7 +2823,7 @@ fun handle(): Account { } ``` -#### [](#webflux-ann-initbinder)1.4.5. `DataBinder` #### +#### 1.4.5. `DataBinder` [Web MVC](web.html#mvc-ann-initbinder) @@ -3137,7 +2921,7 @@ class FormController { |**1**|Adding a custom formatter (a `DateFormatter`, in this case).| |-----|------------------------------------------------------------| -#### [](#webflux-ann-controller-exceptions)1.4.6. Managing Exceptions #### +#### 1.4.6. Managing Exceptions [Web MVC](web.html#mvc-ann-exceptionhandler) @@ -3194,7 +2978,7 @@ See [the MVC section](web.html#mvc-ann-exceptionhandler) for details. Support for `@ExceptionHandler` methods in Spring WebFlux is provided by the`HandlerAdapter` for `@RequestMapping` methods. See [`DispatcherHandler`](#webflux-dispatcher-handler)for more detail. -##### [](#webflux-ann-rest-exceptions)REST API exceptions ##### +##### REST API exceptions [Web MVC](web.html#mvc-ann-rest-exceptions) @@ -3207,7 +2991,7 @@ in `@ControllerAdvice` classes to apply them globally. | |Note that Spring WebFlux does not have an equivalent for the Spring MVC`ResponseEntityExceptionHandler`, because WebFlux raises only `ResponseStatusException`(or subclasses thereof), and those do not need to be translated to
an HTTP status code.| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#webflux-ann-controller-advice)1.4.7. Controller Advice #### +#### 1.4.7. Controller Advice [Web MVC](web.html#mvc-ann-controller-advice) @@ -3264,7 +3048,7 @@ public class ExampleAdvice3 {} The selectors in the preceding example are evaluated at runtime and may negatively impact performance if used extensively. See the[`@ControllerAdvice`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/web/bind/annotation/ControllerAdvice.html)javadoc for more details. -### [](#webflux-fn)1.5. Functional Endpoints ### +### 1.5. Functional Endpoints [Web MVC](web.html#webmvc-fn) @@ -3273,7 +3057,7 @@ are used to route and handle requests and contracts are designed for immutabilit It is an alternative to the annotation-based programming model but otherwise runs on the same [Reactive Core](#webflux-reactive-spring-web) foundation. -#### [](#webflux-fn-overview)1.5.1. Overview #### +#### 1.5.1. Overview [Web MVC](web.html#webmvc-fn-overview) @@ -3368,7 +3152,7 @@ through one of the built-in [server adapters](#webflux-httphandler): Most applications can run through the WebFlux Java configuration, see [Running a Server](#webflux-fn-running). -#### [](#webflux-fn-handler-functions)1.5.2. HandlerFunction #### +#### 1.5.2. HandlerFunction [Web MVC](web.html#webmvc-fn-handler-functions) @@ -3380,7 +3164,7 @@ The request body is represented with a Reactor `Flux` or `Mono`. The response body is represented with any Reactive Streams `Publisher`, including `Flux` and `Mono`. For more on that, see [Reactive Libraries](#webflux-reactive-libraries). -##### [](#webflux-fn-request)ServerRequest ##### +##### ServerRequest `ServerRequest` provides access to the HTTP method, URI, headers, and query parameters, while access to the body is provided through the `body` methods. @@ -3474,7 +3258,7 @@ Kotlin val parts = request.body(BodyExtractors.toParts()).asFlow() ``` -##### [](#webflux-fn-response)ServerResponse ##### +##### ServerResponse `ServerResponse` provides access to the HTTP response and, since it is immutable, you can use a `build` method to create it. You can use the builder to set the response status, to add response @@ -3526,7 +3310,7 @@ Kotlin ServerResponse.ok().hint(Jackson2CodecSupport.JSON_VIEW_HINT, MyJacksonView::class.java).body(...) ``` -##### [](#webflux-fn-handler-classes)Handler Classes ##### +##### Handler Classes We can write a handler function as a lambda, as the following example shows: @@ -3617,7 +3401,7 @@ class PersonHandler(private val repository: PersonRepository) { |**2**| `createPerson` is a handler function that stores a new `Person` contained in the request body.
Note that `PersonRepository.savePerson(Person)` is a suspending function with no return type. | |**3**|`getPerson` is a handler function that returns a single person, identified by the `id` path
variable. We retrieve that `Person` from the repository and create a JSON response, if it is
found. If it is not found, we return a 404 Not Found response.| -##### [](#webflux-fn-handler-validation)Validation ##### +##### Validation A functional endpoint can use Spring’s [validation facilities](core.html#validation) to apply validation to the request body. For example, given a custom Spring[Validator](core.html#validation) implementation for a `Person`: @@ -3686,7 +3470,7 @@ Handlers can also use the standard bean validation API (JSR-303) by creating and a global `Validator` instance based on `LocalValidatorFactoryBean`. See [Spring Validation](core.html#validation-beanvalidation). -#### [](#webflux-fn-router-functions)1.5.3. `RouterFunction` #### +#### 1.5.3. `RouterFunction` [Web MVC](web.html#webmvc-fn-router-functions) @@ -3705,7 +3489,7 @@ predicates when mapping to requests. For each HTTP method there is an overloaded variant that takes a `RequestPredicate` as a parameter, though which additional constraints can be expressed. -##### [](#webflux-fn-predicates)Predicates ##### +##### Predicates You can write your own `RequestPredicate`, but the `RequestPredicates` utility class offers commonly used implementations, based on the request path, HTTP method, content-type, @@ -3740,7 +3524,7 @@ Many of the predicates from `RequestPredicates` are composed. For example, `RequestPredicates.GET(String)` is composed from `RequestPredicates.method(HttpMethod)`and `RequestPredicates.path(String)`. The example shown above also uses two request predicates, as the builder uses`RequestPredicates.GET` internally, and composes that with the `accept` predicate. -##### [](#webflux-fn-routes)Routes ##### +##### Routes Router functions are evaluated in order: if the first route does not match, the second is evaluated, and so on. @@ -3809,7 +3593,7 @@ val route = coRouter { |**3**| `POST /person` with no additional predicates is mapped to`PersonHandler.createPerson`, and | |**4**| `otherRoute` is a router function that is created elsewhere, and added to the route built. | -##### [](#nested-routes)Nested Routes ##### +##### Nested Routes It is common for a group of router functions to have a shared predicate, for instance a shared path. In the example above, the shared predicate would be a path predicate that @@ -3875,7 +3659,7 @@ val route = coRouter { } ``` -#### [](#webflux-fn-running)1.5.4. Running a Server #### +#### 1.5.4. Running a Server [Web MVC](web.html#webmvc-fn-running) @@ -3976,7 +3760,7 @@ class WebConfig : WebFluxConfigurer { } ``` -#### [](#webflux-fn-handler-filter-function)1.5.5. Filtering Handler Functions #### +#### 1.5.5. Filtering Handler Functions [Web MVC](web.html#webmvc-fn-handler-filter-function) @@ -4093,13 +3877,13 @@ filter to an existing router function via `RouterFunction.filter(HandlerFilterFu | |CORS support for functional endpoints is provided through a dedicated[`CorsWebFilter`](webflux-cors.html#webflux-cors-webfilter).| |---|---------------------------------------------------------------------------------------------------------------------------------| -### [](#webflux-uri-building)1.6. URI Links ### +### 1.6. URI Links [Web MVC](web.html#mvc-uri-building) This section describes various options available in the Spring Framework to prepare URIs. -#### [](#web-uricomponents)1.6.1. UriComponents #### +#### 1.6.1. UriComponents Spring MVC and Spring WebFlux @@ -4207,7 +3991,7 @@ val uri = UriComponentsBuilder .build("Westin", "123") ``` -#### [](#web-uribuilder)1.6.2. UriBuilder #### +#### 1.6.2. UriBuilder Spring MVC and Spring WebFlux @@ -4297,7 +4081,7 @@ val uri = uriBuilderFactory.uriString("/hotels/{hotel}") .build("Westin", "123") ``` -#### [](#web-uri-encoding)1.6.3. URI Encoding #### +#### 1.6.3. URI Encoding Spring MVC and Spring WebFlux @@ -4440,14 +4224,14 @@ reasons and for backwards compatibility. The `WebClient` relies on the default v in `DefaultUriBuilderFactory`, which was changed from `EncodingMode.URI_COMPONENT` in 5.0.x to `EncodingMode.TEMPLATE_AND_VALUES` in 5.1. -### [](#webflux-cors)1.7. CORS ### +### 1.7. CORS [Web MVC](web.html#mvc-cors) Spring WebFlux lets you handle CORS (Cross-Origin Resource Sharing). This section describes how to do so. -#### [](#webflux-cors-intro)1.7.1. Introduction #### +#### 1.7.1. Introduction [Web MVC](web.html#mvc-cors-intro) @@ -4460,7 +4244,7 @@ Cross-Origin Resource Sharing (CORS) is a [W3C specification](https://www.w3.org what kind of cross-domain requests are authorized, rather than using less secure and less powerful workarounds based on IFRAME or JSONP. -#### [](#webflux-cors-processing)1.7.2. Processing #### +#### 1.7.2. Processing [Web MVC](web.html#mvc-cors-processing) @@ -4495,7 +4279,7 @@ accepted, such as `allowCredentials` and `maxAge`, the local overrides the globa | |To learn more from the source or to make advanced customizations, see:

* `CorsConfiguration`

* `CorsProcessor` and `DefaultCorsProcessor`

* `AbstractHandlerMapping`| |---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#webflux-cors-controller)1.7.3. `@CrossOrigin` #### +#### 1.7.3. `@CrossOrigin` [Web MVC](web.html#mvc-cors-controller) @@ -4654,7 +4438,7 @@ class AccountController { |-----|-----------------------------------------| |**2**|Using `@CrossOrigin` at the method level.| -#### [](#webflux-cors-global)1.7.4. Global Configuration #### +#### 1.7.4. Global Configuration [Web MVC](web.html#mvc-cors-global) @@ -4724,7 +4508,7 @@ class WebConfig : WebFluxConfigurer { } ``` -#### [](#webflux-cors-webfilter)1.7.5. CORS `WebFilter` #### +#### 1.7.5. CORS `WebFilter` [Web MVC](web.html#mvc-cors-filter) @@ -4782,7 +4566,7 @@ fun corsFilter(): CorsWebFilter { } ``` -### [](#webflux-web-security)1.8. Web Security ### +### 1.8. Web Security [Web MVC](web.html#mvc-web-security) @@ -4798,7 +4582,7 @@ reference documentation, including: * [Security Response Headers](https://docs.spring.io/spring-security/site/docs/current/reference/html5/#headers) -### [](#webflux-view)1.9. View Technologies ### +### 1.9. View Technologies [Web MVC](web.html#mvc-view) @@ -4807,7 +4591,7 @@ use Thymeleaf, FreeMarker, or some other view technology is primarily a matter o configuration change. This chapter covers the view technologies integrated with Spring WebFlux. We assume you are already familiar with [View Resolution](#webflux-viewresolution). -#### [](#webflux-view-thymeleaf)1.9.1. Thymeleaf #### +#### 1.9.1. Thymeleaf [Web MVC](web.html#mvc-view-thymeleaf) @@ -4820,7 +4604,7 @@ and maintained. For a more complete introduction, see the[Thymeleaf](https://www The Thymeleaf integration with Spring WebFlux is managed by the Thymeleaf project. The configuration involves a few bean declarations, such as`SpringResourceTemplateResolver`, `SpringWebFluxTemplateEngine`, and`ThymeleafReactiveViewResolver`. For more details, see[Thymeleaf+Spring](https://www.thymeleaf.org/documentation.html) and the WebFlux integration[announcement](http://forum.thymeleaf.org/Thymeleaf-3-0-8-JUST-PUBLISHED-td4030687.html). -#### [](#webflux-view-freemarker)1.9.2. FreeMarker #### +#### 1.9.2. FreeMarker [Web MVC](web.html#mvc-view-freemarker) @@ -4828,7 +4612,7 @@ configuration involves a few bean declarations, such as`SpringResourceTemplateRe kind of text output from HTML to email and others. The Spring Framework has built-in integration for using Spring WebFlux with FreeMarker templates. -##### [](#webflux-view-freemarker-contextconfig)View Configuration ##### +##### View Configuration [Web MVC](web.html#mvc-view-freemarker-contextconfig) @@ -4881,7 +4665,7 @@ Your templates need to be stored in the directory specified by the `FreeMarkerCo shown in the preceding example. Given the preceding configuration, if your controller returns the view name, `welcome`, the resolver looks for the`classpath:/templates/freemarker/welcome.ftl` template. -##### [](#webflux-views-freemarker)FreeMarker Configuration ##### +##### FreeMarker Configuration [Web MVC](web.html#mvc-views-freemarker) @@ -4931,7 +4715,7 @@ class WebConfig : WebFluxConfigurer { See the FreeMarker documentation for details of settings and variables as they apply to the `Configuration` object. -##### [](#webflux-view-freemarker-forms)Form Handling ##### +##### Form Handling [Web MVC](web.html#mvc-view-freemarker-forms) @@ -4940,7 +4724,7 @@ form-backing objects and show the results of failed validations from a `Validato web or business tier. Spring also has support for the same functionality in FreeMarker, with additional convenience macros for generating form input elements themselves. -###### [](#webflux-view-bind-macros)The Bind Macros ###### +##### The Bind Macros# [Web MVC](web.html#mvc-view-bind-macros) @@ -4956,7 +4740,7 @@ directly, the file is called `spring.ftl` and is in the`org.springframework.web. For additional details on binding support, see [Simple Binding](web.html#mvc-view-simple-binding) for Spring MVC. -###### [](#webflux-views-form-macros)Form Macros ###### +##### Form Macros# For details on Spring’s form macro support for FreeMarker templates, consult the following sections of the Spring MVC documentation. @@ -4969,7 +4753,7 @@ sections of the Spring MVC documentation. * [HTML Escaping](web.html#mvc-views-form-macros-html-escaping) -#### [](#webflux-view-script)1.9.3. Script Views #### +#### 1.9.3. Script Views [Web MVC](web.html#mvc-view-script) @@ -4990,7 +4774,7 @@ The following table shows the templating libraries that we have tested on differ | |The basic rule for integrating any other script engine is that it must implement the`ScriptEngine` and `Invocable` interfaces.| |---|------------------------------------------------------------------------------------------------------------------------------| -##### [](#webflux-view-script-dependencies)Requirements ##### +##### Requirements [Web MVC](web.html#mvc-view-script-dependencies) @@ -5008,7 +4792,7 @@ You need to have the script engine on your classpath, the details of which vary You need to have the script templating library. One way to do that for JavaScript is through [WebJars](https://www.webjars.org/). -##### [](#webflux-view-script-integrate)Script Templates ##### +##### Script Templates [Web MVC](web.html#mvc-view-script-integrate) @@ -5148,7 +4932,7 @@ function render(template, model) { Check out the Spring Framework unit tests,[Java](https://github.com/spring-projects/spring-framework/tree/main/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/script), and[resources](https://github.com/spring-projects/spring-framework/tree/main/spring-webflux/src/test/resources/org/springframework/web/reactive/result/view/script), for more configuration examples. -#### [](#webflux-view-httpmessagewriter)1.9.4. JSON and XML #### +#### 1.9.4. JSON and XML [Web MVC](web.html#mvc-view-jackson) @@ -5166,7 +4950,7 @@ In most cases, a model contains multiple attributes. To determine which one to s you can configure `HttpMessageWriterView` with the name of the model attribute to use for rendering. If the model contains only one attribute, that one is used. -### [](#webflux-caching)1.10. HTTP Caching ### +### 1.10. HTTP Caching [Web MVC](web.html#mvc-caching) @@ -5180,7 +4964,7 @@ the `Last-Modified` header. This section describes the HTTP caching related options available in Spring WebFlux. -#### [](#webflux-caching-cachecontrol)1.10.1. `CacheControl` #### +#### 1.10.1. `CacheControl` [Web MVC](web.html#mvc-caching-cachecontrol) @@ -5226,7 +5010,7 @@ val ccNoStore = CacheControl.noStore() val ccCustom = CacheControl.maxAge(10, TimeUnit.DAYS).noTransform().cachePublic() ``` -#### [](#webflux-caching-etag-lastmodified)1.10.2. Controllers #### +#### 1.10.2. Controllers [Web MVC](web.html#mvc-caching-etag-lastmodified) @@ -5321,14 +5105,14 @@ There are three variants for checking conditional requests against `eTag` values 304 (NOT\_MODIFIED). For conditional `POST`, `PUT`, and `DELETE`, you can instead set the response to 412 (PRECONDITION\_FAILED) to prevent concurrent modification. -#### [](#webflux-caching-static-resources)1.10.3. Static Resources #### +#### 1.10.3. Static Resources [Web MVC](web.html#mvc-caching-static-resources) You should serve static resources with a `Cache-Control` and conditional response headers for optimal performance. See the section on configuring [Static Resources](#webflux-config-static-resources). -### [](#webflux-config)1.11. WebFlux Config ### +### 1.11. WebFlux Config [Web MVC](web.html#mvc-config) @@ -5342,7 +5126,7 @@ in [Special Bean Types](#webflux-special-bean-types). For more advanced customizations, not available in the configuration API, you can gain full control over the configuration through the[Advanced Configuration Mode](#webflux-config-advanced-java). -#### [](#webflux-config-enable)1.11.1. Enabling WebFlux Config #### +#### 1.11.1. Enabling WebFlux Config [Web MVC](web.html#mvc-config-enable) @@ -5368,7 +5152,7 @@ class WebConfig The preceding example registers a number of Spring WebFlux[infrastructure beans](#webflux-special-bean-types) and adapts to dependencies available on the classpath — for JSON, XML, and others. -#### [](#webflux-config-customize)1.11.2. WebFlux config API #### +#### 1.11.2. WebFlux config API [Web MVC](web.html#mvc-config-customize) @@ -5397,7 +5181,7 @@ class WebConfig : WebFluxConfigurer { } ``` -#### [](#webflux-config-conversion)1.11.3. Conversion, formatting #### +#### 1.11.3. Conversion, formatting [Web MVC](web.html#mvc-config-conversion) @@ -5473,7 +5257,7 @@ class WebConfig : WebFluxConfigurer { | |See [`FormatterRegistrar` SPI](core.html#format-FormatterRegistrar-SPI)and the `FormattingConversionServiceFactoryBean` for more information on when to
use `FormatterRegistrar` implementations.| |---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#webflux-config-validation)1.11.4. Validation #### +#### 1.11.4. Validation [Web MVC](web.html#mvc-config-validation) @@ -5545,7 +5329,7 @@ class MyController { | |If you need to have a `LocalValidatorFactoryBean` injected somewhere, create a bean and
mark it with `@Primary` in order to avoid conflict with the one declared in the MVC config.| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#webflux-config-content-negotiation)1.11.5. Content Type Resolvers #### +#### 1.11.5. Content Type Resolvers [Web MVC](web.html#mvc-config-content-negotiation) @@ -5581,7 +5365,7 @@ class WebConfig : WebFluxConfigurer { } ``` -#### [](#webflux-config-message-codecs)1.11.6. HTTP message codecs #### +#### 1.11.6. HTTP message codecs [Web MVC](web.html#mvc-config-message-converters) @@ -5634,7 +5418,7 @@ It also automatically registers the following well-known modules if they are det * [`jackson-module-kotlin`](https://github.com/FasterXML/jackson-module-kotlin): Support for Kotlin classes and data classes. -#### [](#webflux-config-view-resolvers)1.11.7. View Resolvers #### +#### 1.11.7. View Resolvers [Web MVC](web.html#mvc-config-view-resolvers) @@ -5788,7 +5572,7 @@ class WebConfig : WebFluxConfigurer { See [View Technologies](#webflux-view) for more on the view technologies that are integrated with Spring WebFlux. -#### [](#webflux-config-static-resources)1.11.8. Static Resources #### +#### 1.11.8. Static Resources [Web MVC](web.html#mvc-config-static-resources) @@ -5894,7 +5678,7 @@ without versions — for example, from `/jquery/jquery.min.js` to`/jquery/1. | |The Java configuration based on `ResourceHandlerRegistry` provides further options
for fine-grained control, e.g. last-modified behavior and optimized resource resolution.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#webflux-config-path-matching)1.11.9. Path Matching #### +#### 1.11.9. Path Matching [Web MVC](web.html#mvc-config-path-matching) @@ -5940,7 +5724,7 @@ class WebConfig : WebFluxConfigurer { | |Spring WebFlux relies on a parsed representation of the request path called`RequestPath` for access to decoded path segment values, with semicolon content removed
(that is, path or matrix variables). That means, unlike in Spring MVC, you need not indicate
whether to decode the request path nor whether to remove semicolon content for
path matching purposes.

Spring WebFlux also does not support suffix pattern matching, unlike in Spring MVC, where we
are also [recommend](web.html#mvc-ann-requestmapping-suffix-pattern-match) moving away from
reliance on it.| |---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#webflux-config-websocket-service)1.11.10. WebSocketService #### +#### 1.11.10. WebSocketService The WebFlux Java config declares of a `WebSocketHandlerAdapter` bean which provides support for the invocation of WebSocket handlers. That means all that remains to do in @@ -5984,7 +5768,7 @@ class WebConfig : WebFluxConfigurer { } ``` -#### [](#webflux-config-advanced-java)1.11.11. Advanced Configuration Mode #### +#### 1.11.11. Advanced Configuration Mode [Web MVC](web.html#mvc-config-advanced-java) @@ -6021,15 +5805,14 @@ You can keep existing methods in `WebConfig`, but you can now also override bean from the base class and still have any number of other `WebMvcConfigurer` implementations on the classpath. -### [](#webflux-http2)1.12. HTTP/2 ### +### 1.12. HTTP/2 [Web MVC](web.html#mvc-http2) HTTP/2 is supported with Reactor Netty, Tomcat, Jetty, and Undertow. However, there are considerations related to server configuration. For more details, see the[HTTP/2 wiki page](https://github.com/spring-projects/spring-framework/wiki/HTTP-2-support). -[](#webflux-client)2. WebClient ----------- +## 2. WebClient Spring WebFlux includes a client to perform HTTP requests with. `WebClient` has a functional, fluent API based on Reactor, see [Reactive Libraries](#webflux-reactive-libraries), @@ -6049,7 +5832,7 @@ support for the following: * Others can be plugged via `ClientHttpConnector`. -### [](#webflux-client-builder)2.1. Configuration ### +### 2.1. Configuration The simplest way to create a `WebClient` is through one of the static factory methods: @@ -6124,7 +5907,7 @@ val client2 = client1.mutate() // client2 has filterA, filterB, filterC, filterD ``` -#### [](#webflux-client-builder-maxinmemorysize)2.1.1. MaxInMemorySize #### +#### 2.1.1. MaxInMemorySize Codecs have [limits](#webflux-codecs-limits) for buffering data in memory to avoid application memory issues. By default those are set to 256KB. @@ -6152,7 +5935,7 @@ val webClient = WebClient.builder() .build() ``` -#### [](#webflux-client-builder-reactor)2.1.2. Reactor Netty #### +#### 2.1.2. Reactor Netty To customize Reactor Netty settings, provide a pre-configured `HttpClient`: @@ -6176,7 +5959,7 @@ val webClient = WebClient.builder() .build() ``` -##### [](#webflux-client-builder-reactor-resources)Resources ##### +##### Resources By default, `HttpClient` participates in the global Reactor Netty resources held in`reactor.netty.http.HttpResources`, including event loop threads and a connection pool. This is the recommended mode, since fixed, shared resources are preferred for event loop @@ -6263,7 +6046,7 @@ fun webClient(): WebClient { |**2**|Use the `ReactorClientHttpConnector` constructor with resource factory.| |**3**| Plug the connector into the `WebClient.Builder`. | -##### [](#webflux-client-builder-reactor-timeout)Timeouts ##### +##### Timeouts To configure a connection timeout: @@ -6372,7 +6155,7 @@ WebClient.create().get() .bodyToMono(String::class.java) ``` -#### [](#webflux-client-builder-jetty)2.1.3. Jetty #### +#### 2.1.3. Jetty The following example shows how to customize Jetty `HttpClient` settings: @@ -6453,7 +6236,7 @@ fun webClient(): WebClient { |-----|---------------------------------------------------------------------| |**2**| Plug the connector into the `WebClient.Builder`. | -#### [](#webflux-client-builder-http-components)2.1.4. HttpComponents #### +#### 2.1.4. HttpComponents The following example shows how to customize Apache HttpComponents `HttpClient` settings: @@ -6478,7 +6261,7 @@ val connector = HttpComponentsClientHttpConnector(client) val webClient = WebClient.builder().clientConnector(connector).build() ``` -### [](#webflux-client-retrieve)2.2. `retrieve()` ### +### 2.2. `retrieve()` The `retrieve()` method can be used to declare how to extract the response. For example: @@ -6574,7 +6357,7 @@ val result = client.get() .awaitBody() ``` -### [](#webflux-client-exchange)2.3. Exchange ### +### 2.3. Exchange The `exchangeToMono()` and `exchangeToFlux()` methods (or `awaitExchange { }` and `exchangeToFlow { }` in Kotlin) are useful for more advanced cases that require more control, such as to decode the response differently @@ -6618,7 +6401,7 @@ is checked and if not consumed it is released to prevent memory and connection l Therefore the response cannot be decoded further downstream. It is up to the provided function to declare how to decode the response if needed. -### [](#webflux-client-body)2.4. Request Body ### +### 2.4. Request Body The request body can be encoded from any asynchronous type handled by `ReactiveAdapterRegistry`, like `Mono` or Kotlin Coroutines `Deferred` as the following example shows: @@ -6706,7 +6489,7 @@ client.post() .awaitBody() ``` -#### [](#webflux-client-body-form)2.4.1. Form Data #### +#### 2.4.1. Form Data To send form data, you can provide a `MultiValueMap` as the body. Note that the content is automatically set to `application/x-www-form-urlencoded` by the`FormHttpMessageWriter`. The following example shows how to use `MultiValueMap`: @@ -6761,7 +6544,7 @@ client.post() .awaitBody() ``` -#### [](#webflux-client-body-multipart)2.4.2. Multipart Data #### +#### 2.4.2. Multipart Data To send multipart data, you need to provide a `MultiValueMap` whose values are either `Object` instances that represent part content or `HttpEntity` instances that represent the content and @@ -6857,7 +6640,7 @@ client.post() .awaitBody() ``` -### [](#webflux-client-filter)2.5. Filters ### +### 2.5. Filters You can register a client filter (`ExchangeFilterFunction`) through the `WebClient.Builder`in order to intercept and modify requests, as the following example shows: @@ -6984,7 +6767,7 @@ fun renewTokenFilter(): ExchangeFilterFunction? { } ``` -### [](#webflux-client-attributes)2.6. Attributes ### +### 2.6. Attributes You can add attributes to a request. This is convenient if you want to pass information through the filter chain and influence the behavior of filters for a given request. @@ -7028,7 +6811,7 @@ Note that you can configure a `defaultRequest` callback globally at the`WebClien which could be used for example in a Spring MVC application to populate request attributes based on `ThreadLocal` data. -### [](#webflux-client-context)2.7. Context ### +### 2.7. Context [Attributes](#webflux-client-attributes) provide a convenient way to pass information to the filter chain but they only influence the current request. If you want to pass information that @@ -7058,7 +6841,7 @@ client.get().uri("https://example.org/") .contextWrite(context -> context.put("foo", ...)); ``` -### [](#webflux-client-synchronous)2.8. Synchronous Use ### +### 2.8. Synchronous Use `WebClient` can be used in synchronous style by blocking at the end for the result: @@ -7136,20 +6919,19 @@ inter-dependent, without ever blocking until the end. | |With `Flux` or `Mono`, you should never have to block in a Spring MVC or Spring WebFlux controller.
Simply return the resulting reactive type from the controller method. The same principle apply to
Kotlin Coroutines and Spring WebFlux, just use suspending function or return `Flow` in your
controller method .| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -### [](#webflux-client-testing)2.9. Testing ### +### 2.9. Testing To test code that uses the `WebClient`, you can use a mock web server, such as the[OkHttp MockWebServer](https://github.com/square/okhttp#mockwebserver). To see an example of its use, check out[`WebClientIntegrationTests`](https://github.com/spring-projects/spring-framework/tree/main/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java)in the Spring Framework test suite or the[`static-server`](https://github.com/square/okhttp/tree/master/samples/static-server)sample in the OkHttp repository. -[](#webflux-websocket)3. WebSockets ----------- +## 3. WebSockets [Same as in the Servlet stack](web.html#websocket) This part of the reference documentation covers support for reactive-stack WebSocket messaging. -### [](#websocket-intro)3.1. Introduction to WebSocket ### +### 3.1. Introduction to WebSocket The WebSocket protocol, [RFC 6455](https://tools.ietf.org/html/rfc6455), provides a standardized way to establish a full-duplex, two-way communication channel between client and server @@ -7201,7 +6983,7 @@ likely need to configure it to pass WebSocket upgrade requests on to the WebSock server. Likewise, if the application runs in a cloud environment, check the instructions of the cloud provider related to WebSocket support. -#### [](#websocket-intro-architecture)3.1.1. HTTP Versus WebSocket #### +#### 3.1.1. HTTP Versus WebSocket Even though WebSocket is designed to be HTTP-compatible and starts with an HTTP request, it is important to understand that the two protocols lead to very different @@ -7223,7 +7005,7 @@ WebSocket clients and servers can negotiate the use of a higher-level, messaging (for example, STOMP), through the `Sec-WebSocket-Protocol` header on the HTTP handshake request. In the absence of that, they need to come up with their own conventions. -#### [](#websocket-intro-when-to-use)3.1.2. When to Use WebSockets #### +#### 3.1.2. When to Use WebSockets WebSockets can make a web page be dynamic and interactive. However, in many cases, a combination of Ajax and HTTP streaming or long polling can provide a simple and @@ -7243,14 +7025,14 @@ may preclude WebSocket interactions, either because they are not configured to p means that the use of WebSocket for internal applications within the firewall is a more straightforward decision than it is for public facing applications. -### [](#webflux-websocket-server)3.2. WebSocket API ### +### 3.2. WebSocket API [Same as in the Servlet stack](web.html#websocket-server) The Spring Framework provides a WebSocket API that you can use to write client- and server-side applications that handle WebSocket messages. -#### [](#webflux-websocket-server-handler)3.2.1. Server #### +#### 3.2.1. Server [Same as in the Servlet stack](web.html#websocket-server-handler) @@ -7352,7 +7134,7 @@ class WebConfig { } ``` -#### [](#webflux-websockethandler)3.2.2. `WebSocketHandler` #### +#### 3.2.2. `WebSocketHandler` The `handle` method of `WebSocketHandler` takes `WebSocketSession` and returns `Mono`to indicate when application handling of the session is complete. The session is handled through two streams, one for inbound and one for outbound messages. The following table @@ -7550,7 +7332,7 @@ class ExampleHandler : WebSocketHandler { |**2**| Send outgoing messages. | |**3**|Join the streams and return a `Mono` that completes when either stream ends.| -#### [](#webflux-websocket-databuffer)3.2.3. `DataBuffer` #### +#### 3.2.3. `DataBuffer` `DataBuffer` is the representation for a byte buffer in WebFlux. The Spring Core part of the reference has more on that in the section on[Data Buffers and Codecs](core.html#databuffers). The key point to understand is that on some @@ -7561,7 +7343,7 @@ When running on Netty, applications must use `DataBufferUtils.retain(dataBuffer) wish to hold on input data buffers in order to ensure they are not released, and subsequently use `DataBufferUtils.release(dataBuffer)` when the buffers are consumed. -#### [](#webflux-websocket-server-handshake)3.2.4. Handshake #### +#### 3.2.4. Handshake [Same as in the Servlet stack](web.html#websocket-server-handshake) @@ -7574,7 +7356,7 @@ support for Reactor Netty, Tomcat, Jetty, and Undertow. setting a `Predicate` to extract attributes from the `WebSession` and insert them into the attributes of the `WebSocketSession`. -#### [](#webflux-websocket-server-config)3.2.5. Server Configation #### +#### 3.2.5. Server Configation [Same as in the Servlet stack](web.html#websocket-server-runtime-configuration) @@ -7626,7 +7408,7 @@ class WebConfig { Check the upgrade strategy for your server to see what options are available. Currently, only Tomcat and Jetty expose such options. -#### [](#webflux-websocket-server-cors)3.2.6. CORS #### +#### 3.2.6. CORS [Same as in the Servlet stack](web.html#websocket-server-allowed-origins) @@ -7635,7 +7417,7 @@ have your `WebSocketHandler` implement `CorsConfigurationSource` and return a`Co that, you can also set the `corsConfigurations` property on the `SimpleUrlHandler` to specify CORS settings by URL pattern. If both are specified, they are combined by using the`combine` method on `CorsConfiguration`. -#### [](#webflux-websocket-client)3.2.7. Client #### +#### 3.2.7. Client Spring WebFlux provides a `WebSocketClient` abstraction with implementations for Reactor Netty, Tomcat, Jetty, Undertow, and standard Java (that is, JSR-356). @@ -7674,8 +7456,7 @@ Some clients, such as Jetty, implement `Lifecycle` and need to be stopped and st before you can use them. All clients have constructor options related to configuration of the underlying WebSocket client. -[](#webflux-test)4. Testing ----------- +## 4. Testing [Same in Spring MVC](web.html#testing) @@ -7687,12 +7468,11 @@ discussion of mock objects. response objects to provide support for testing WebFlux applications without an HTTP server. You can use the `WebTestClient` for end-to-end integration tests, too. -[](#rsocket)5. RSocket ----------- +## 5. RSocket This section describes Spring Framework’s support for the RSocket protocol. -### [](#rsocket-overview)5.1. Overview ### +### 5.1. Overview RSocket is an application protocol for multiplexed, duplex communication over TCP, WebSocket, and other byte stream transports, using one of the following interaction @@ -7736,7 +7516,7 @@ and [Reactor Netty](https://github.com/reactor/reactor-netty) for the transport. signals from Reactive Streams Publishers in your application propagate transparently through RSocket across the network. -#### [](#rsocket-protocol)5.1.1. The Protocol #### +#### 5.1.1. The Protocol One of the benefits of RSocket is that it has well defined behavior on the wire and an easy to read [specification](https://rsocket.io/docs/Protocol) along with some protocol[extensions](https://github.com/rsocket/rsocket/tree/master/Extensions). Therefore it is @@ -7786,7 +7566,7 @@ Protocol extensions define common metadata formats for use in applications: * [Routing](https://github.com/rsocket/rsocket/blob/master/Extensions/Routing.md) — the route for a request. -#### [](#rsocket-java)5.1.2. Java Implementation #### +#### 5.1.2. Java Implementation The [Java implementation](https://github.com/rsocket/rsocket-java) for RSocket is built on[Project Reactor](https://projectreactor.io/). The transports for TCP and WebSocket are built on [Reactor Netty](https://github.com/reactor/reactor-netty). As a Reactive Streams @@ -7809,7 +7589,7 @@ will not have to use its API directly. However it may be important to see or exp with RSocket independent of Spring. The RSocket Java repository contains a number of[sample apps](https://github.com/rsocket/rsocket-java/tree/master/rsocket-examples) that demonstrate its API and protocol features. -#### [](#rsocket-spring)5.1.3. Spring Support #### +#### 5.1.3. Spring Support The `spring-messaging` module contains the following: @@ -7833,13 +7613,13 @@ clients and servers. See the Spring Integration Reference Manual for more detail Spring Cloud Gateway supports RSocket connections. -### [](#rsocket-requester)5.2. RSocketRequester ### +### 5.2. RSocketRequester `RSocketRequester` provides a fluent API to perform RSocket requests, accepting and returning objects for data and metadata instead of low level data buffers. It can be used symmetrically, to make requests from clients and to make requests from servers. -#### [](#rsocket-requester-client)5.2.1. Client Requester #### +#### 5.2.1. Client Requester To obtain an `RSocketRequester` on the client side is to connect to a server which involves sending an RSocket `SETUP` frame with connection settings. `RSocketRequester` provides a @@ -7869,7 +7649,7 @@ val requester = RSocketRequester.builder().webSocket(url) The above does not connect immediately. When requests are made, a shared connection is established transparently and used. -##### [](#rsocket-requester-client-setup)Connection Setup ##### +##### Connection Setup `RSocketRequester.Builder` provides the following to customize the initial `SETUP` frame: @@ -7891,7 +7671,7 @@ Data and metadata in the `SETUP` frame is optional. On the server side,[@Connect connection and the content of the `SETUP` frame. Metadata may be used for connection level security. -##### [](#rsocket-requester-client-strategies)Strategies ##### +##### Strategies `RSocketRequester.Builder` accepts `RSocketStrategies` to configure the requester. You’ll need to use this to provide encoders and decoders for (de)-serialization of data and @@ -7927,7 +7707,7 @@ val requester = RSocketRequester.builder() `RSocketStrategies` is designed for re-use. In some scenarios, e.g. client and server in the same application, it may be preferable to declare it in Spring configuration. -##### [](#rsocket-requester-client-responder)Client Responders ##### +##### Client Responders `RSocketRequester.Builder` can be used to configure responders to requests from the server. @@ -8011,7 +7791,7 @@ application. See also [Annotated Responders](#rsocket-annot-responders), for more on the programming model. -##### [](#rsocket-requester-client-advanced)Advanced ##### +##### Advanced `RSocketRequesterBuilder` provides a callback to expose the underlying`io.rsocket.core.RSocketConnector` for further configuration options for keepalive intervals, session resumption, interceptors, and more. You can configure options @@ -8037,7 +7817,7 @@ val requester = RSocketRequester.builder() .tcp("localhost", 7000) ``` -#### [](#rsocket-requester-server)5.2.2. Server Requester #### +#### 5.2.2. Server Requester To make requests from a server to connected clients is a matter of obtaining the requester for the connected client from the server. @@ -8083,7 +7863,7 @@ suspend fun handle(requester: RSocketRequester) { |-----|------------------------------------------------------------| |**2**| Perform handling in the suspending function. | -#### [](#rsocket-requester-requests)5.2.3. Requests #### +#### 5.2.3. Requests Once you have a [client](#rsocket-requester-client) or[server](#rsocket-requester-server) requester, you can make requests as follows: @@ -8187,13 +7967,13 @@ For `Fire-and-Forget` use the `send()` method that returns `Mono`. Note th For `Metadata-Push` use the `sendMetadata()` method with a `Mono` return value. -### [](#rsocket-annot-responders)5.3. Annotated Responders ### +### 5.3. Annotated Responders RSocket responders can be implemented as `@MessageMapping` and `@ConnectMapping` methods.`@MessageMapping` methods handle individual requests while `@ConnectMapping` methods handle connection-level events (setup and metadata push). Annotated responders are supported symmetrically, for responding from the server side and for responding from the client side. -#### [](#rsocket-annot-responders-server)5.3.1. Server Responders #### +#### 5.3.1. Server Responders To use annotated responders on the server side, add `RSocketMessageHandler` to your Spring configuration to detect `@Controller` beans with `@MessageMapping` and `@ConnectMapping`methods: @@ -8312,11 +8092,11 @@ class ServerConfig { } ``` -#### [](#rsocket-annot-responders-client)5.3.2. Client Responders #### +#### 5.3.2. Client Responders Annotated responders on the client side need to be configured in the`RSocketRequester.Builder`. For details, see[Client Responders](#rsocket-requester-client-responder). -#### [](#rsocket-annot-messagemapping)5.3.3. @MessageMapping #### +#### 5.3.3. @MessageMapping Once [server](#rsocket-annot-responders-server) or[client](#rsocket-annot-responders-client) responder configuration is in place,`@MessageMapping` methods can be used as follows: @@ -8382,7 +8162,7 @@ interaction type(s): | 0, 1 | Many | Request-Stream | | Many | 0, 1, Many | Request-Channel | -#### [](#rsocket-annot-connectmapping)5.3.4. @ConnectMapping #### +#### 5.3.4. @ConnectMapping `@ConnectMapping` handles the `SETUP` frame at the start of an RSocket connection, and any subsequent metadata push notifications through the `METADATA_PUSH` frame, i.e.`metadataPush(Payload)` in `io.rsocket.RSocket`. @@ -8395,7 +8175,7 @@ then all connections match. connection then the connection is rejected. Handling must not be held up to make requests to the `RSocketRequester` for the connection. See[Server Requester](#rsocket-requester-server) for details. -### [](#rsocket-metadata-extractor)5.4. MetadataExtractor ### +### 5.4. MetadataExtractor Responders must interpret metadata.[Composite metadata](https://github.com/rsocket/rsocket/blob/master/Extensions/CompositeMetadata.md) allows independently formatted metadata values (e.g. for routing, security, tracing) each with its own mime @@ -8479,8 +8259,7 @@ val strategies = RSocketStrategies.builder() .build() ``` -[](#webflux-reactive-libraries)6. Reactive Libraries ----------- +## 6. Reactive Libraries `spring-webflux` depends on `reactor-core` and uses it internally to compose asynchronous logic and to provide Reactive Streams support. Generally, WebFlux APIs return `Flux` or`Mono` (since those are used internally) and leniently accept any Reactive Streams`Publisher` implementation as input. The use of `Flux` versus `Mono` is important, because diff --git a/docs/en/spring-framework/web-servlet.md b/docs/en/spring-framework/web-servlet.md index e2b1c3f..af5bb2d 100644 --- a/docs/en/spring-framework/web-servlet.md +++ b/docs/en/spring-framework/web-servlet.md @@ -1,289 +1,10 @@ -Web on Servlet Stack -========== - -version 5.3.16 - -Table of Contents - -* [1. Spring Web MVC](#mvc) - * [1.1. DispatcherServlet](#mvc-servlet) - * [1.1.1. Context Hierarchy](#mvc-servlet-context-hierarchy) - * [1.1.2. Special Bean Types](#mvc-servlet-special-bean-types) - * [1.1.3. Web MVC Config](#mvc-servlet-config) - * [1.1.4. Servlet Config](#mvc-container-config) - * [1.1.5. Processing](#mvc-servlet-sequence) - * [1.1.6. Path Matching](#mvc-handlermapping-path) - * [1.1.7. Interception](#mvc-handlermapping-interceptor) - * [1.1.8. Exceptions](#mvc-exceptionhandlers) - * [Chain of Resolvers](#mvc-excetionhandlers-handling) - * [Container Error Page](#mvc-ann-customer-servlet-container-error-page) - - * [1.1.9. View Resolution](#mvc-viewresolver) - * [Handling](#mvc-viewresolver-handling) - * [Redirecting](#mvc-redirecting-redirect-prefix) - * [Forwarding](#mvc-redirecting-forward-prefix) - * [Content Negotiation](#mvc-multiple-representations) - - * [1.1.10. Locale](#mvc-localeresolver) - * [Time Zone](#mvc-timezone) - * [Header Resolver](#mvc-localeresolver-acceptheader) - * [Cookie Resolver](#mvc-localeresolver-cookie) - * [Session Resolver](#mvc-localeresolver-session) - * [Locale Interceptor](#mvc-localeresolver-interceptor) - - * [1.1.11. Themes](#mvc-themeresolver) - * [Defining a theme](#mvc-themeresolver-defining) - * [Resolving Themes](#mvc-themeresolver-resolving) - - * [1.1.12. Multipart Resolver](#mvc-multipart) - * [Apache Commons `FileUpload`](#mvc-multipart-resolver-commons) - * [Servlet 3.0](#mvc-multipart-resolver-standard) - - * [1.1.13. Logging](#mvc-logging) - * [Sensitive Data](#mvc-logging-sensitive-data) - - * [1.2. Filters](#filters) - * [1.2.1. Form Data](#filters-http-put) - * [1.2.2. Forwarded Headers](#filters-forwarded-headers) - * [1.2.3. Shallow ETag](#filters-shallow-etag) - * [1.2.4. CORS](#filters-cors) - - * [1.3. Annotated Controllers](#mvc-controller) - * [1.3.1. Declaration](#mvc-ann-controller) - * [AOP Proxies](#mvc-ann-requestmapping-proxying) - - * [1.3.2. Request Mapping](#mvc-ann-requestmapping) - * [URI patterns](#mvc-ann-requestmapping-uri-templates) - * [Pattern Comparison](#mvc-ann-requestmapping-pattern-comparison) - * [Suffix Match](#mvc-ann-requestmapping-suffix-pattern-match) - * [Suffix Match and RFD](#mvc-ann-requestmapping-rfd) - * [Consumable Media Types](#mvc-ann-requestmapping-consumes) - * [Producible Media Types](#mvc-ann-requestmapping-produces) - * [Parameters, headers](#mvc-ann-requestmapping-params-and-headers) - * [HTTP HEAD, OPTIONS](#mvc-ann-requestmapping-head-options) - * [Custom Annotations](#mvc-ann-requestmapping-composed) - * [Explicit Registrations](#mvc-ann-requestmapping-registration) - - * [1.3.3. Handler Methods](#mvc-ann-methods) - * [Method Arguments](#mvc-ann-arguments) - * [Return Values](#mvc-ann-return-types) - * [Type Conversion](#mvc-ann-typeconversion) - * [Matrix Variables](#mvc-ann-matrix-variables) - * [`@RequestParam`](#mvc-ann-requestparam) - * [`@RequestHeader`](#mvc-ann-requestheader) - * [`@CookieValue`](#mvc-ann-cookievalue) - * [`@ModelAttribute`](#mvc-ann-modelattrib-method-args) - * [`@SessionAttributes`](#mvc-ann-sessionattributes) - * [`@SessionAttribute`](#mvc-ann-sessionattribute) - * [`@RequestAttribute`](#mvc-ann-requestattrib) - * [Redirect Attributes](#mvc-redirecting-passing-data) - * [Flash Attributes](#mvc-flash-attributes) - * [Multipart](#mvc-multipart-forms) - * [`@RequestBody`](#mvc-ann-requestbody) - * [HttpEntity](#mvc-ann-httpentity) - * [`@ResponseBody`](#mvc-ann-responsebody) - * [ResponseEntity](#mvc-ann-responseentity) - * [Jackson JSON](#mvc-ann-jackson) - - * [1.3.4. Model](#mvc-ann-modelattrib-methods) - * [1.3.5. `DataBinder`](#mvc-ann-initbinder) - * [1.3.6. Exceptions](#mvc-ann-exceptionhandler) - * [Method Arguments](#mvc-ann-exceptionhandler-args) - * [Return Values](#mvc-ann-exceptionhandler-return-values) - * [REST API exceptions](#mvc-ann-rest-exceptions) - - * [1.3.7. Controller Advice](#mvc-ann-controller-advice) - - * [1.4. Functional Endpoints](#webmvc-fn) - * [1.4.1. Overview](#webmvc-fn-overview) - * [1.4.2. HandlerFunction](#webmvc-fn-handler-functions) - * [ServerRequest](#webmvc-fn-request) - * [ServerResponse](#webmvc-fn-response) - * [Handler Classes](#webmvc-fn-handler-classes) - * [Validation](#webmvc-fn-handler-validation) - - * [1.4.3. `RouterFunction`](#webmvc-fn-router-functions) - * [Predicates](#webmvc-fn-predicates) - * [Routes](#webmvc-fn-routes) - * [Nested Routes](#nested-routes) - - * [1.4.4. Running a Server](#webmvc-fn-running) - * [1.4.5. Filtering Handler Functions](#webmvc-fn-handler-filter-function) - - * [1.5. URI Links](#mvc-uri-building) - * [1.5.1. UriComponents](#web-uricomponents) - * [1.5.2. UriBuilder](#web-uribuilder) - * [1.5.3. URI Encoding](#web-uri-encoding) - * [1.5.4. Relative Servlet Requests](#mvc-servleturicomponentsbuilder) - * [1.5.5. Links to Controllers](#mvc-links-to-controllers) - * [1.5.6. Links in Views](#mvc-links-to-controllers-from-views) - - * [1.6. Asynchronous Requests](#mvc-ann-async) - * [1.6.1. `DeferredResult`](#mvc-ann-async-deferredresult) - * [1.6.2. `Callable`](#mvc-ann-async-callable) - * [1.6.3. Processing](#mvc-ann-async-processing) - * [Exception Handling](#mvc-ann-async-exceptions) - * [Interception](#mvc-ann-async-interception) - * [Compared to WebFlux](#mvc-ann-async-vs-webflux) - - * [1.6.4. HTTP Streaming](#mvc-ann-async-http-streaming) - * [Objects](#mvc-ann-async-objects) - * [SSE](#mvc-ann-async-sse) - * [Raw Data](#mvc-ann-async-output-stream) - - * [1.6.5. Reactive Types](#mvc-ann-async-reactive-types) - * [1.6.6. Disconnects](#mvc-ann-async-disconnects) - * [1.6.7. Configuration](#mvc-ann-async-configuration) - * [Servlet Container](#mvc-ann-async-configuration-servlet3) - * [Spring MVC](#mvc-ann-async-configuration-spring-mvc) - - * [1.7. CORS](#mvc-cors) - * [1.7.1. Introduction](#mvc-cors-intro) - * [1.7.2. Processing](#mvc-cors-processing) - * [1.7.3. `@CrossOrigin`](#mvc-cors-controller) - * [1.7.4. Global Configuration](#mvc-cors-global) - * [Java Configuration](#mvc-cors-global-java) - * [XML Configuration](#mvc-cors-global-xml) - - * [1.7.5. CORS Filter](#mvc-cors-filter) - - * [1.8. Web Security](#mvc-web-security) - * [1.9. HTTP Caching](#mvc-caching) - * [1.9.1. `CacheControl`](#mvc-caching-cachecontrol) - * [1.9.2. Controllers](#mvc-caching-etag-lastmodified) - * [1.9.3. Static Resources](#mvc-caching-static-resources) - * [1.9.4. `ETag` Filter](#mvc-httpcaching-shallowetag) - - * [1.10. View Technologies](#mvc-view) - * [1.10.1. Thymeleaf](#mvc-view-thymeleaf) - * [1.10.2. FreeMarker](#mvc-view-freemarker) - * [View Configuration](#mvc-view-freemarker-contextconfig) - * [FreeMarker Configuration](#mvc-views-freemarker) - * [Form Handling](#mvc-view-freemarker-forms) - - * [1.10.3. Groovy Markup](#mvc-view-groovymarkup) - * [Configuration](#mvc-view-groovymarkup-configuration) - * [Example](#mvc-view-groovymarkup-example) - - * [1.10.4. Script Views](#mvc-view-script) - * [Requirements](#mvc-view-script-dependencies) - * [Script Templates](#mvc-view-script-integrate) - - * [1.10.5. JSP and JSTL](#mvc-view-jsp) - * [View Resolvers](#mvc-view-jsp-resolver) - * [JSPs versus JSTL](#mvc-view-jsp-jstl) - * [Spring’s JSP Tag Library](#mvc-view-jsp-tags) - * [Spring’s form tag library](#mvc-view-jsp-formtaglib) - - * [1.10.6. Tiles](#mvc-view-tiles) - * [Dependencies](#mvc-view-tiles-dependencies) - * [Configuration](#mvc-view-tiles-integrate) - - * [1.10.7. RSS and Atom](#mvc-view-feeds) - * [1.10.8. PDF and Excel](#mvc-view-document) - * [Introduction to Document Views](#mvc-view-document-intro) - * [PDF Views](#mvc-view-document-pdf) - * [Excel Views](#mvc-view-document-excel) - - * [1.10.9. Jackson](#mvc-view-jackson) - * [Jackson-based JSON MVC Views](#mvc-view-json-mapping) - * [Jackson-based XML Views](#mvc-view-xml-mapping) - - * [1.10.10. XML Marshalling](#mvc-view-xml-marshalling) - * [1.10.11. XSLT Views](#mvc-view-xslt) - * [Beans](#mvc-view-xslt-beandefs) - * [Controller](#mvc-view-xslt-controllercode) - * [Transformation](#mvc-view-xslt-transforming) - - * [1.11. MVC Config](#mvc-config) - * [1.11.1. Enable MVC Configuration](#mvc-config-enable) - * [1.11.2. MVC Config API](#mvc-config-customize) - * [1.11.3. Type Conversion](#mvc-config-conversion) - * [1.11.4. Validation](#mvc-config-validation) - * [1.11.5. Interceptors](#mvc-config-interceptors) - * [1.11.6. Content Types](#mvc-config-content-negotiation) - * [1.11.7. Message Converters](#mvc-config-message-converters) - * [1.11.8. View Controllers](#mvc-config-view-controller) - * [1.11.9. View Resolvers](#mvc-config-view-resolvers) - * [1.11.10. Static Resources](#mvc-config-static-resources) - * [1.11.11. Default Servlet](#mvc-default-servlet-handler) - * [1.11.12. Path Matching](#mvc-config-path-matching) - * [1.11.13. Advanced Java Config](#mvc-config-advanced-java) - * [1.11.14. Advanced XML Config](#mvc-config-advanced-xml) - - * [1.12. HTTP/2](#mvc-http2) - -* [2. REST Clients](#webmvc-client) - * [2.1. `RestTemplate`](#webmvc-resttemplate) - * [2.2. `WebClient`](#webmvc-webclient) - -* [3. Testing](#testing) -* [4. WebSockets](#websocket) - * [4.1. Introduction to WebSocket](#websocket-intro) - * [4.1.1. HTTP Versus WebSocket](#websocket-intro-architecture) - * [4.1.2. When to Use WebSockets](#websocket-intro-when-to-use) - - * [4.2. WebSocket API](#websocket-server) - * [4.2.1. `WebSocketHandler`](#websocket-server-handler) - * [4.2.2. WebSocket Handshake](#websocket-server-handshake) - * [4.2.3. Deployment](#websocket-server-deployment) - * [4.2.4. Server Configuration](#websocket-server-runtime-configuration) - * [4.2.5. Allowed Origins](#websocket-server-allowed-origins) - - * [4.3. SockJS Fallback](#websocket-fallback) - * [4.3.1. Overview](#websocket-fallback-sockjs-overview) - * [4.3.2. Enabling SockJS](#websocket-fallback-sockjs-enable) - * [4.3.3. IE 8 and 9](#websocket-fallback-xhr-vs-iframe) - * [4.3.4. Heartbeats](#websocket-fallback-sockjs-heartbeat) - * [4.3.5. Client Disconnects](#websocket-fallback-sockjs-servlet3-async) - * [4.3.6. SockJS and CORS](#websocket-fallback-cors) - * [4.3.7. `SockJsClient`](#websocket-fallback-sockjs-client) - - * [4.4. STOMP](#websocket-stomp) - * [4.4.1. Overview](#websocket-stomp-overview) - * [4.4.2. Benefits](#websocket-stomp-benefits) - * [4.4.3. Enable STOMP](#websocket-stomp-enable) - * [4.4.4. WebSocket Server](#websocket-stomp-server-config) - * [4.4.5. Flow of Messages](#websocket-stomp-message-flow) - * [4.4.6. Annotated Controllers](#websocket-stomp-handle-annotations) - * [`@MessageMapping`](#websocket-stomp-message-mapping) - * [`@SubscribeMapping`](#websocket-stomp-subscribe-mapping) - * [`@MessageExceptionHandler`](#websocket-stomp-exception-handler) - - * [4.4.7. Sending Messages](#websocket-stomp-handle-send) - * [4.4.8. Simple Broker](#websocket-stomp-handle-simple-broker) - * [4.4.9. External Broker](#websocket-stomp-handle-broker-relay) - * [4.4.10. Connecting to a Broker](#websocket-stomp-handle-broker-relay-configure) - * [4.4.11. Dots as Separators](#websocket-stomp-destination-separator) - * [4.4.12. Authentication](#websocket-stomp-authentication) - * [4.4.13. Token Authentication](#websocket-stomp-authentication-token-based) - * [4.4.14. Authorization](#websocket-stomp-authorization) - * [4.4.15. User Destinations](#websocket-stomp-user-destination) - * [4.4.16. Order of Messages](#websocket-stomp-ordered-messages) - * [4.4.17. Events](#websocket-stomp-appplication-context-events) - * [4.4.18. Interception](#websocket-stomp-interceptors) - * [4.4.19. STOMP Client](#websocket-stomp-client) - * [4.4.20. WebSocket Scope](#websocket-stomp-websocket-scope) - * [4.4.21. Performance](#websocket-stomp-configuration-performance) - * [4.4.22. Monitoring](#websocket-stomp-stats) - * [4.4.23. Testing](#websocket-stomp-testing) - -* [5. Other Web Frameworks](#web-integration) - * [5.1. Common Configuration](#web-integration-common) - * [5.2. JSF](#jsf) - * [5.2.1. Spring Bean Resolver](#jsf-springbeanfaceselresolver) - * [5.2.2. Using `FacesContextUtils`](#jsf-facescontextutils) - - * [5.3. Apache Struts 2.x](#struts) - * [5.4. Apache Tapestry 5.x](#tapestry) - * [5.5. Further Resources](#web-integration-resources) +# Web on Servlet Stack 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 [Spring MVC](#mvc),[View Technologies](#mvc-view), [CORS Support](#mvc-cors), and [WebSocket Support](#websocket). For reactive-stack web applications, see [Web on Reactive Stack](web-reactive.html#spring-web-reactive). -[](#mvc)1. Spring Web MVC ----------- +## 1. Spring Web MVC 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,” @@ -299,7 +20,7 @@ This section covers Spring Web MVC. The [next section](web-reactive.html#spring- For baseline information and compatibility with Servlet container and Java EE version ranges, see the Spring Framework[Wiki](https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-Versions). -### [](#mvc-servlet)1.1. DispatcherServlet ### +### 1.1. DispatcherServlet [WebFlux](web-reactive.html#webflux-dispatcher-handler) @@ -400,7 +121,7 @@ The following example of `web.xml` configuration registers and initializes the ` | |Spring Boot follows a different initialization sequence. Rather than hooking into
the lifecycle of the Servlet container, Spring Boot uses Spring configuration to
bootstrap itself and the embedded Servlet container. `Filter` and `Servlet` declarations
are detected in Spring configuration and registered with the Servlet container.
For more details, see the[Spring Boot documentation](https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-embedded-container).| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#mvc-servlet-context-hierarchy)1.1.1. Context Hierarchy #### +#### 1.1.1. Context Hierarchy `DispatcherServlet` expects a `WebApplicationContext` (an extension of a plain`ApplicationContext`) for its own configuration. `WebApplicationContext` has a link to the`ServletContext` and the `Servlet` with which it is associated. It is also bound to the `ServletContext`such that applications can use static methods on `RequestContextUtils` to look up the`WebApplicationContext` if they need access to it. @@ -498,7 +219,7 @@ The following example shows the `web.xml` equivalent: | |If an application context hierarchy is not required, applications may configure a
“root” context only and leave the `contextConfigLocation` Servlet parameter empty.| |---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#mvc-servlet-special-bean-types)1.1.2. Special Bean Types #### +#### 1.1.2. Special Bean Types [WebFlux](web-reactive.html#webflux-special-bean-types) @@ -520,7 +241,7 @@ The following table lists the special beans detected by the `DispatcherServlet`: | [`MultipartResolver`](#mvc-multipart) | Abstraction for parsing a multi-part request (for example, browser form file upload) with
the help of some multipart parsing library. See [Multipart Resolver](#mvc-multipart). | | [`FlashMapManager`](#mvc-flash-attributes) | Store and retrieve the “input” and the “output” `FlashMap` that can be used to pass
attributes from one request to another, usually across a redirect.
See [Flash Attributes](#mvc-flash-attributes). | -#### [](#mvc-servlet-config)1.1.3. Web MVC Config #### +#### 1.1.3. Web MVC Config [WebFlux](web-reactive.html#webflux-framework-config) @@ -534,7 +255,7 @@ customize it. | |Spring Boot relies on the MVC Java configuration to configure Spring MVC and
provides many extra convenient options.| |---|------------------------------------------------------------------------------------------------------------------------| -#### [](#mvc-container-config)1.1.4. Servlet Config #### +#### 1.1.4. Servlet Config In a Servlet 3.0+ environment, you have the option of configuring the Servlet container programmatically as an alternative or in combination with a `web.xml` file. The following @@ -713,7 +434,7 @@ filters mapped to it. By default, this flag is set to `true`. Finally, if you need to further customize the `DispatcherServlet` itself, you can override the `createDispatcherServlet` method. -#### [](#mvc-servlet-sequence)1.1.5. Processing #### +#### 1.1.5. Processing [WebFlux](web-reactive.html#webflux-dispatcher-handler-sequence) @@ -762,7 +483,7 @@ initialization parameters (`init-param` elements) to the Servlet declaration in | `namespace` | Namespace of the `WebApplicationContext`. Defaults to `[servlet-name]-servlet`. | |`throwExceptionIfNoHandlerFound`|Whether to throw a `NoHandlerFoundException` when no handler was found for a request.
The exception can then be caught with a `HandlerExceptionResolver` (for example, by using an`@ExceptionHandler` controller method) and handled as any others.

By default, this is set to `false`, in which case the `DispatcherServlet` sets the
response status to 404 (NOT\_FOUND) without raising an exception.

Note that, if [default servlet handling](#mvc-default-servlet-handler) is
also configured, unresolved requests are always forwarded to the default servlet
and a 404 is never raised.| -#### [](#mvc-handlermapping-path)1.1.6. Path Matching #### +#### 1.1.6. Path Matching The Servlet API exposes the full request path as `requestURI` and further sub-divides it into `contextPath`, `servletPath`, and `pathInfo` whose values vary depending on how a @@ -803,7 +524,7 @@ the risk of altering the structure of the path. Parsed `PathPattern` also suppor the use of `servletPath` prefix mapping as long as the prefix is kept simple and does not have any characters that need to be encoded. -#### [](#mvc-handlermapping-interceptor)1.1.7. Interception #### +#### 1.1.7. Interception All `HandlerMapping` implementations support handler interceptors that are useful when you want to apply specific functionality to certain requests — for example, checking for @@ -830,7 +551,7 @@ which the response is written and committed within the `HandlerAdapter` and befo an extra header. For such scenarios, you can implement `ResponseBodyAdvice` and either declare it as an [Controller Advice](#mvc-ann-controller-advice) bean or configure it directly on`RequestMappingHandlerAdapter`. -#### [](#mvc-exceptionhandlers)1.1.8. Exceptions #### +#### 1.1.8. Exceptions [WebFlux](web-reactive.html#webflux-dispatcher-exceptions) @@ -847,7 +568,7 @@ The following table lists the available `HandlerExceptionResolver` implementatio | `ResponseStatusExceptionResolver` | Resolves exceptions with the `@ResponseStatus` annotation and maps them to HTTP status
codes based on the value in the annotation. | | `ExceptionHandlerExceptionResolver` | Resolves exceptions by invoking an `@ExceptionHandler` method in a `@Controller` or a`@ControllerAdvice` class. See [@ExceptionHandler methods](#mvc-ann-exceptionhandler). | -##### [](#mvc-excetionhandlers-handling)Chain of Resolvers ##### +##### Chain of Resolvers You can form an exception resolver chain by declaring multiple `HandlerExceptionResolver`beans in your Spring configuration and setting their `order` properties as needed. The higher the order property, the later the exception resolver is positioned. @@ -864,7 +585,7 @@ The contract of `HandlerExceptionResolver` specifies that it can return: The [MVC Config](#mvc-config) automatically declares built-in resolvers for default Spring MVC exceptions, for `@ResponseStatus` annotated exceptions, and for support of`@ExceptionHandler` methods. You can customize that list or replace it. -##### [](#mvc-ann-customer-servlet-container-error-page)Container Error Page ##### +##### Container Error Page If an exception remains unresolved by any `HandlerExceptionResolver` and is, therefore, left to propagate or if the response status is set to an error status (that is, 4xx, 5xx), @@ -919,7 +640,7 @@ class ErrorController { | |The Servlet API does not provide a way to create error page mappings in Java. You can,
however, use both a `WebApplicationInitializer` and a minimal `web.xml`.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#mvc-viewresolver)1.1.9. View Resolution #### +#### 1.1.9. View Resolution [WebFlux](web-reactive.html#webflux-viewresolution) @@ -938,7 +659,7 @@ The following table provides more details on the `ViewResolver` hierarchy: |`ContentNegotiatingViewResolver`| Implementation of the `ViewResolver` interface that resolves a view based on the
request file name or `Accept` header. See [Content Negotiation](#mvc-multiple-representations). | | `BeanNameViewResolver` | Implementation of the `ViewResolver` interface that interprets a view name as a
bean name in the current application context. This is a very flexible variant which
allows for mixing and matching different view types based on distinct view names.
Each such `View` can be defined as a bean e.g. in XML or in configuration classes. | -##### [](#mvc-viewresolver-handling)Handling ##### +##### Handling [WebFlux](web-reactive.html#webflux-viewresolution-handling) @@ -954,7 +675,7 @@ Configuring view resolution is as simple as adding `ViewResolver` beans to your configuration. The [MVC Config](#mvc-config) provides a dedicated configuration API for[View Resolvers](#mvc-config-view-resolvers) and for adding logic-less[View Controllers](#mvc-config-view-controller) which are useful for HTML template rendering without controller logic. -##### [](#mvc-redirecting-redirect-prefix)Redirecting ##### +##### Redirecting [WebFlux](web-reactive.html#webflux-redirecting-redirect-prefix) @@ -969,7 +690,7 @@ Servlet context, while a name such as `redirect:https://myhost.com/some/arbitrar Note that, if a controller method is annotated with the `@ResponseStatus`, the annotation value takes precedence over the response status set by `RedirectView`. -##### [](#mvc-redirecting-forward-prefix)Forwarding ##### +##### Forwarding You can also use a special `forward:` prefix for view names that are ultimately resolved by `UrlBasedViewResolver` and subclasses. This creates an`InternalResourceView`, which does a `RequestDispatcher.forward()`. @@ -977,7 +698,7 @@ Therefore, this prefix is not useful with `InternalResourceViewResolver` and`Int technology but still want to force a forward of a resource to be handled by the Servlet/JSP engine. Note that you may also chain multiple view resolvers, instead. -##### [](#mvc-multiple-representations)Content Negotiation ##### +##### Content Negotiation [WebFlux](web-reactive.html#webflux-multiple-representations) @@ -996,7 +717,7 @@ representation of the current resource regardless of the logical view name. The See [View Resolvers](#mvc-config-view-resolvers) under [MVC Config](#mvc-config) for configuration details. -#### [](#mvc-localeresolver)1.1.10. Locale #### +#### 1.1.10. Locale Most parts of Spring’s architecture support internationalization, as the Spring web MVC framework does. `DispatcherServlet` lets you automatically resolve messages @@ -1024,7 +745,7 @@ Spring. * [Locale Interceptor](#mvc-localeresolver-interceptor) -##### [](#mvc-timezone)Time Zone ##### +##### Time Zone In addition to obtaining the client’s locale, it is often useful to know its time zone. The `LocaleContextResolver` interface offers an extension to `LocaleResolver` that lets @@ -1033,14 +754,14 @@ resolvers provide a richer `LocaleContext`, which may include time zone informat When available, the user’s `TimeZone` can be obtained by using the`RequestContext.getTimeZone()` method. Time zone information is automatically used by any Date/Time `Converter` and `Formatter` objects that are registered with Spring’s`ConversionService`. -##### [](#mvc-localeresolver-acceptheader)Header Resolver ##### +##### Header Resolver This locale resolver inspects the `accept-language` header in the request that was sent by the client (for example, a web browser). Usually, this header field contains the locale of the client’s operating system. Note that this resolver does not support time zone information. -##### [](#mvc-localeresolver-cookie)Cookie Resolver ##### +##### Cookie Resolver This locale resolver inspects a `Cookie` that might exist on the client to see if a`Locale` or `TimeZone` is specified. If so, it uses the specified details. By using the properties of this locale resolver, you can specify the name of the cookie as well as the @@ -1065,7 +786,7 @@ The following table describes the properties `CookieLocaleResolver`: |`cookieMaxAge`|Servlet container default|The maximum time a cookie persists on the client. If `-1` is specified, the
cookie will not be persisted. It is available only until the client shuts down
the browser.| | `cookiePath` | / | Limits the visibility of the cookie to a certain part of your site. When `cookiePath` is
specified, the cookie is visible only to that path and the paths below it. | -##### [](#mvc-localeresolver-session)Session Resolver ##### +##### Session Resolver The `SessionLocaleResolver` lets you retrieve `Locale` and `TimeZone` from the session that might be associated with the user’s request. In contrast to`CookieLocaleResolver`, this strategy stores locally chosen locale settings in the @@ -1076,7 +797,7 @@ Note that there is no direct relationship with external session management mecha such as the Spring Session project. This `SessionLocaleResolver` evaluates and modifies the corresponding `HttpSession` attributes against the current `HttpServletRequest`. -##### [](#mvc-localeresolver-interceptor)Locale Interceptor ##### +##### Locale Interceptor You can enable changing of locales by adding the `LocaleChangeInterceptor` to one of the`HandlerMapping` definitions. It detects a parameter in the request and changes the locale accordingly, calling the `setLocale` method on the `LocaleResolver` in the dispatcher’s @@ -1107,14 +828,14 @@ language to Dutch. The following example shows how to intercept the locale:
``` -#### [](#mvc-themeresolver)1.1.11. Themes #### +#### 1.1.11. Themes You can apply Spring Web MVC framework themes to set the overall look-and-feel of your application, thereby enhancing user experience. A theme is a collection of static resources, typically style sheets and images, that affect the visual style of the application. -##### [](#mvc-themeresolver-defining)Defining a theme ##### +##### Defining a theme To use themes in your web application, you must set up an implementation of the`org.springframework.ui.context.ThemeSource` interface. The `WebApplicationContext`interface extends `ThemeSource` but delegates its responsibilities to a dedicated implementation. By default, the delegate is an`org.springframework.ui.context.support.ResourceBundleThemeSource` implementation that @@ -1154,7 +875,7 @@ resource bundle loading mechanism, allowing for full internationalization of the example, we could have a `/WEB-INF/classes/cool_nl.properties` that references a special background image with Dutch text on it. -##### [](#mvc-themeresolver-resolving)Resolving Themes ##### +##### Resolving Themes After you define themes, as described in the [preceding section](#mvc-themeresolver-defining), you decide which theme to use. The `DispatcherServlet` looks for a bean named `themeResolver`to find out which `ThemeResolver` implementation to use. A theme resolver works in much the same @@ -1170,7 +891,7 @@ alter the request’s theme. The following table describes the theme resolvers p Spring also provides a `ThemeChangeInterceptor` that lets theme changes on every request with a simple request parameter. -#### [](#mvc-multipart)1.1.12. Multipart Resolver #### +#### 1.1.12. Multipart Resolver [WebFlux](web-reactive.html#webflux-multipart) @@ -1185,7 +906,7 @@ with a content type of `multipart/form-data` is received, the resolver parses th content wraps the current `HttpServletRequest` as a `MultipartHttpServletRequest` to provide access to resolved files in addition to exposing parts as request parameters. -##### [](#mvc-multipart-resolver-commons)Apache Commons `FileUpload` ##### +##### 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. @@ -1197,7 +918,7 @@ Servlet multipart resolution through the container’s own parser as discussed b | |Commons FileUpload traditionally applies to POST requests only but accepts any`multipart/` content type. See the[`CommonsMultipartResolver`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/web/multipart/commons/CommonsMultipartResolver.html)javadoc for details and configuration options.| |---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#mvc-multipart-resolver-standard)Servlet 3.0 ##### +##### Servlet 3.0 Servlet 3.0 multipart parsing needs to be enabled through Servlet container configuration. To do so: @@ -1246,7 +967,7 @@ Once the Servlet 3.0 configuration is in place, you can add a bean of type`Stand | |This resolver variant uses your Servlet container’s multipart parser as-is,
potentially exposing the application to container implementation differences.
By default, it will try to parse any `multipart/` content type with any HTTP
method but this may not be supported across all Servlet containers. See the[`StandardServletMultipartResolver`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/web/multipart/support/StandardServletMultipartResolver.html)javadoc for details and configuration options.| |---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#mvc-logging)1.1.13. Logging #### +#### 1.1.13. Logging [WebFlux](web-reactive.html#webflux-logging) @@ -1261,7 +982,7 @@ messages may show a different level of detail at TRACE versus DEBUG. Good logging comes from the experience of using the logs. If you spot anything that does not meet the stated goals, please let us know. -##### [](#mvc-logging-sensitive-data)Sensitive Data ##### +##### Sensitive Data [WebFlux](web-reactive.html#webflux-logging-sensitive-data) @@ -1323,7 +1044,7 @@ class MyInitializer : AbstractAnnotationConfigDispatcherServletInitializer() { } ``` -### [](#filters)1.2. Filters ### +### 1.2. Filters [WebFlux](web-reactive.html#webflux-filters) @@ -1337,7 +1058,7 @@ The `spring-web` module provides some useful filters: * [CORS](#filters-cors) -#### [](#filters-http-put)1.2.1. Form Data #### +#### 1.2.1. Form Data Browsers can submit form data only through HTTP GET or HTTP POST but non-browser clients can also use HTTP PUT, PATCH, and DELETE. The Servlet API requires `ServletRequest.getParameter*()`methods to support form field access only for HTTP POST. @@ -1347,7 +1068,7 @@ requests with a content type of `application/x-www-form-urlencoded`, read the fo the body of the request, and wrap the `ServletRequest` to make the form data available through the `ServletRequest.getParameter*()` family of methods. -#### [](#filters-forwarded-headers)1.2.2. Forwarded Headers #### +#### 1.2.2. Forwarded Headers [WebFlux](web-reactive.html#webflux-forwarded-headers) @@ -1374,7 +1095,7 @@ filter should be mapped with `DispatcherType.ASYNC` and also `DispatcherType.ERR If using Spring Framework’s `AbstractAnnotationConfigDispatcherServletInitializer`(see [Servlet Config](#mvc-container-config)) all filters are automatically registered for all dispatch types. However if registering the filter via `web.xml` or in Spring Boot via a`FilterRegistrationBean` be sure to include `DispatcherType.ASYNC` and`DispatcherType.ERROR` in addition to `DispatcherType.REQUEST`. -#### [](#filters-shallow-etag)1.2.3. Shallow ETag #### +#### 1.2.3. Shallow ETag The `ShallowEtagHeaderFilter` filter creates a “shallow” ETag by caching the content written to the response and computing an MD5 hash from it. The next time a client sends, @@ -1393,7 +1114,7 @@ ETag to the end of the last async dispatch. If using Spring Framework’s`Abstra all filters are automatically registered for all dispatch types. However if registering the filter via `web.xml` or in Spring Boot via a `FilterRegistrationBean` be sure to include`DispatcherType.ASYNC`. -#### [](#filters-cors)1.2.4. CORS #### +#### 1.2.4. CORS [WebFlux](web-reactive.html#webflux-filters-cors) @@ -1402,7 +1123,7 @@ controllers. However, when used with Spring Security, we advise relying on the b See the sections on [CORS](#mvc-cors) and the [CORS Filter](#mvc-cors-filter) for more details. -### [](#mvc-controller)1.3. Annotated Controllers ### +### 1.3. Annotated Controllers [WebFlux](web-reactive.html#webflux-controller) @@ -1447,7 +1168,7 @@ but many other options exist and are explained later in this chapter. | |Guides and tutorials on [spring.io](https://spring.io/guides) use the annotation-based
programming model described in this section.| |---|---------------------------------------------------------------------------------------------------------------------------------------| -#### [](#mvc-ann-controller)1.3.1. Declaration #### +#### 1.3.1. Declaration [WebFlux](web-reactive.html#webflux-ann-controller) @@ -1508,7 +1229,7 @@ itself meta-annotated with `@Controller` and `@ResponseBody` to indicate a contr every method inherits the type-level `@ResponseBody` annotation and, therefore, writes directly to the response body versus view resolution and rendering with an HTML template. -##### [](#mvc-ann-requestmapping-proxying)AOP Proxies ##### +##### AOP Proxies In some cases, you may need to decorate a controller with an AOP proxy at runtime. One example is if you choose to have `@Transactional` annotations directly on the @@ -1519,7 +1240,7 @@ callback (such as `InitializingBean`, `*Aware`, and others), you may need to exp configure class-based proxying. For example, with `` you can change to ``, and with`@EnableTransactionManagement` you can change to`@EnableTransactionManagement(proxyTargetClass = true)`. -#### [](#mvc-ann-requestmapping)1.3.2. Request Mapping #### +#### 1.3.2. Request Mapping [WebFlux](web-reactive.html#webflux-ann-requestmapping) @@ -1587,7 +1308,7 @@ class PersonController { } ``` -##### [](#mvc-ann-requestmapping-uri-templates)URI patterns ##### +##### URI patterns [WebFlux](web-reactive.html#webflux-ann-requestmapping-uri-templates) @@ -1709,7 +1430,7 @@ by using `PropertyPlaceHolderConfigurer` against local, system, environment, and sources. You can use this, for example, to parameterize a base URL based on some external configuration. -##### [](#mvc-ann-requestmapping-pattern-comparison)Pattern Comparison ##### +##### Pattern Comparison [WebFlux](web-reactive.html#webflux-ann-requestmapping-pattern-comparison) @@ -1732,7 +1453,7 @@ specific than other pattern that do not have double wildcards. For the full details, follow the above links to the pattern Comparators. -##### [](#mvc-ann-requestmapping-suffix-pattern-match)Suffix Match ##### +##### Suffix Match Starting in 5.3, by default Spring MVC no longer performs `.*` suffix pattern matching where a controller mapped to `/person` is also implicitly mapped to`/person.*`. As a consequence path extensions are no longer used to interpret @@ -1759,7 +1480,7 @@ be useful, e.g. when typing a URL in a browser. A safe alternative to path exten to use the query parameter strategy. If you must use file extensions, consider restricting them to a list of explicitly registered extensions through the `mediaTypes` property of[ContentNegotiationConfigurer](#mvc-config-content-negotiation). -##### [](#mvc-ann-requestmapping-rfd)Suffix Match and RFD ##### +##### Suffix Match and RFD A reflected file download (RFD) attack is similar to XSS in that it relies on request input (for example, a query parameter and a URI variable) being reflected in the response. However, instead of @@ -1783,7 +1504,7 @@ See [Content Types](#mvc-config-content-negotiation). See [CVE-2015-5211](https://pivotal.io/security/cve-2015-5211) for additional recommendations related to RFD. -##### [](#mvc-ann-requestmapping-consumes)Consumable Media Types ##### +##### Consumable Media Types [WebFlux](web-reactive.html#webflux-ann-requestmapping-consumes) @@ -1824,7 +1545,7 @@ overrides rather than extends the class-level declaration. | |`MediaType` provides constants for commonly used media types, such as`APPLICATION_JSON_VALUE` and `APPLICATION_XML_VALUE`.| |---|--------------------------------------------------------------------------------------------------------------------------| -##### [](#mvc-ann-requestmapping-produces)Producible Media Types ##### +##### Producible Media Types [WebFlux](web-reactive.html#webflux-ann-requestmapping-produces) @@ -1866,7 +1587,7 @@ overrides rather than extends the class-level declaration. | |`MediaType` provides constants for commonly used media types, such as`APPLICATION_JSON_VALUE` and `APPLICATION_XML_VALUE`.| |---|--------------------------------------------------------------------------------------------------------------------------| -##### [](#mvc-ann-requestmapping-params-and-headers)Parameters, headers ##### +##### Parameters, headers [WebFlux](web-reactive.html#webflux-ann-requestmapping-params-and-headers) @@ -1924,7 +1645,7 @@ fun findPet(@PathVariable petId: String) { | |You can match `Content-Type` and `Accept` with the headers condition, but it is better to use[consumes](#mvc-ann-requestmapping-consumes) and [produces](#mvc-ann-requestmapping-produces)instead.| |---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#mvc-ann-requestmapping-head-options)HTTP HEAD, OPTIONS ##### +##### HTTP HEAD, OPTIONS [WebFlux](web-reactive.html#webflux-ann-requestmapping-head-options) @@ -1945,7 +1666,7 @@ supported HTTP methods (for example, by using the HTTP method specific variants: You can explicitly map the `@RequestMapping` method to HTTP HEAD and HTTP OPTIONS, but that is not necessary in the common case. -##### [](#mvc-ann-requestmapping-composed)Custom Annotations ##### +##### Custom Annotations [WebFlux](web-reactive.html#mvc-ann-requestmapping-head-options) @@ -1961,7 +1682,7 @@ Spring MVC also supports custom request-mapping attributes with custom request-m logic. This is a more advanced option that requires subclassing`RequestMappingHandlerMapping` and overriding the `getCustomMethodCondition` method, where you can check the custom attribute and return your own `RequestCondition`. -##### [](#mvc-ann-requestmapping-registration)Explicit Registrations ##### +##### Explicit Registrations [WebFlux](web-reactive.html#webflux-ann-requestmapping-registration) @@ -2016,14 +1737,14 @@ class MyConfig { |**3**| Get the handler method. | |**4**| Add the registration. | -#### [](#mvc-ann-methods)1.3.3. Handler Methods #### +#### 1.3.3. Handler Methods [WebFlux](web-reactive.html#webflux-ann-methods) `@RequestMapping` handler methods have a flexible signature and can choose from a range of supported controller method arguments and return values. -##### [](#mvc-ann-arguments)Method Arguments ##### +##### Method Arguments [WebFlux](web-reactive.html#webflux-ann-arguments) @@ -2064,7 +1785,7 @@ and others) and is equivalent to `required=false`. | `@RequestAttribute` | For access to request attributes. See [`@RequestAttribute`](#mvc-ann-requestattrib) for more details. | | Any other argument | If a method argument is not matched to any of the earlier values in this table and it is
a simple type (as determined by[BeanUtils#isSimpleProperty](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-),
it is resolved as a `@RequestParam`. Otherwise, it is resolved as a `@ModelAttribute`. | -##### [](#mvc-ann-return-types)Return Values ##### +##### Return Values [WebFlux](web-reactive.html#webflux-ann-return-types) @@ -2090,7 +1811,7 @@ supported for all return values. | Reactive types — Reactor, RxJava, or others through `ReactiveAdapterRegistry` | Alternative to `DeferredResult` with multi-value streams (for example, `Flux`, `Observable`)
collected to a `List`.

For streaming scenarios (for example, `text/event-stream`, `application/json+stream`),`SseEmitter` and `ResponseBodyEmitter` are used instead, where `ServletOutputStream`blocking I/O is performed on a Spring MVC-managed thread and back pressure is applied
against the completion of each write.

See [Asynchronous Requests](#mvc-ann-async) and [Reactive Types](#mvc-ann-async-reactive-types). | | Any other return value | Any return value that does not match any of the earlier values in this table and that
is a `String` or `void` is treated as a view name (default view name selection through`RequestToViewNameTranslator` applies), provided it is not a simple type, as determined by[BeanUtils#isSimpleProperty](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-).
Values that are simple types remain unresolved. | -##### [](#mvc-ann-typeconversion)Type Conversion ##### +##### Type Conversion [WebFlux](web-reactive.html#webflux-ann-typeconversion) @@ -2110,7 +1831,7 @@ argument as `@Nullable`. | |As of 5.3, non-null arguments will be enforced even after type conversion. If your handler
method intends to accept a null value as well, either declare your argument as `@Nullable`or mark it as `required=false` in the corresponding `@RequestParam`, etc. annotation. This is
a best practice and the recommended solution for regressions encountered in a 5.3 upgrade.

Alternatively, you may specifically handle e.g. the resulting `MissingPathVariableException`in the case of a required `@PathVariable`. A null value after conversion will be treated like
an empty original value, so the corresponding `Missing…​Exception` variants will be thrown.| |---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#mvc-ann-matrix-variables)Matrix Variables ##### +##### Matrix Variables [WebFlux](web-reactive.html#webflux-ann-matrix-variables) @@ -2249,7 +1970,7 @@ fun findPet( Note that you need to enable the use of matrix variables. In the MVC Java configuration, you need to set a `UrlPathHelper` with `removeSemicolonContent=false` through[Path Matching](#mvc-config-path-matching). In the MVC XML namespace, you can set``. -##### [](#mvc-ann-requestparam)`@RequestParam` ##### +##### `@RequestParam` [WebFlux](web-reactive.html#webflux-ann-requestparam) @@ -2324,7 +2045,7 @@ By default, any argument that is a simple value type (as determined by[BeanUtils and is not resolved by any other argument resolver, is treated as if it were annotated with `@RequestParam`. -##### [](#mvc-ann-requestheader)`@RequestHeader` ##### +##### `@RequestHeader` [WebFlux](web-reactive.html#webflux-ann-requestheader) @@ -2382,7 +2103,7 @@ with all header values. | |Built-in support is available for converting a comma-separated string into an
array or collection of strings or other types known to the type conversion system. For
example, a method parameter annotated with `@RequestHeader("Accept")` can be of type`String` but also `String[]` or `List`.| |---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#mvc-ann-cookievalue)`@CookieValue` ##### +##### `@CookieValue` [WebFlux](web-reactive.html#webflux-ann-cookievalue) @@ -2424,7 +2145,7 @@ fun handle(@CookieValue("JSESSIONID") cookie: String) { (1) If the target method parameter type is not `String`, type conversion is applied automatically. See [Type Conversion](#mvc-ann-typeconversion). -##### [](#mvc-ann-modelattrib-method-args)`@ModelAttribute` ##### +##### `@ModelAttribute` [WebFlux](web-reactive.html#webflux-ann-modelattrib-method-args) @@ -2616,7 +2337,7 @@ By default, any argument that is not a simple value type (as determined by[BeanU and is not resolved by any other argument resolver is treated as if it were annotated with `@ModelAttribute`. -##### [](#mvc-ann-sessionattributes)`@SessionAttributes` ##### +##### `@SessionAttributes` [WebFlux](web-reactive.html#webflux-ann-sessionattributes) @@ -2707,7 +2428,7 @@ class EditPetForm { |-----|--------------------------------------------------| |**2**|Clearing the `Pet` value from the Servlet session.| -##### [](#mvc-ann-sessionattribute)`@SessionAttribute` ##### +##### `@SessionAttribute` [WebFlux](web-reactive.html#webflux-ann-sessionattribute) @@ -2742,7 +2463,7 @@ For use cases that require adding or removing session attributes, consider injec For temporary storage of model attributes in the session as part of a controller workflow, consider using `@SessionAttributes` as described in[`@SessionAttributes`](#mvc-ann-sessionattributes). -##### [](#mvc-ann-requestattrib)`@RequestAttribute` ##### +##### `@RequestAttribute` [WebFlux](web-reactive.html#webflux-ann-requestattrib) @@ -2773,7 +2494,7 @@ fun handle(@RequestAttribute client: Client): String { (1) |**1**|Using the `@RequestAttribute` annotation.| |-----|-----------------------------------------| -##### [](#mvc-redirecting-passing-data)Redirect Attributes ##### +##### Redirect Attributes By default, all model attributes are considered to be exposed as URI template variables in the redirect URL. Of the remaining attributes, those that are primitive types or @@ -2822,7 +2543,7 @@ Another way of passing data to the redirect target is by using flash attributes. other redirect attributes, flash attributes are saved in the HTTP session (and, hence, do not appear in the URL). See [Flash Attributes](#mvc-flash-attributes) for more information. -##### [](#mvc-flash-attributes)Flash Attributes ##### +##### Flash Attributes Flash attributes provide a way for one request to store attributes that are intended for use in another. This is most commonly needed when redirecting — for example, the @@ -2858,7 +2579,7 @@ This does not entirely eliminate the possibility of a concurrency issue but reduces it greatly with information that is already available in the redirect URL. Therefore, we recommend that you use flash attributes mainly for redirect scenarios. -##### [](#mvc-multipart-forms)Multipart ##### +##### Multipart [WebFlux](web-reactive.html#webflux-multipart-forms) @@ -3038,7 +2759,7 @@ fun handle(@Valid @RequestPart("meta-data") metadata: MetaData, } ``` -##### [](#mvc-ann-requestbody)`@RequestBody` ##### +##### `@RequestBody` [WebFlux](web-reactive.html#webflux-ann-requestbody) @@ -3090,7 +2811,7 @@ fun handle(@Valid @RequestBody account: Account, result: BindingResult) { } ``` -##### [](#mvc-ann-httpentity)HttpEntity ##### +##### HttpEntity [WebFlux](web-reactive.html#webflux-ann-httpentity) @@ -3115,7 +2836,7 @@ fun handle(entity: HttpEntity) { } ``` -##### [](#mvc-ann-responsebody)`@ResponseBody` ##### +##### `@ResponseBody` [WebFlux](web-reactive.html#webflux-ann-responsebody) @@ -3156,7 +2877,7 @@ configure or customize message conversion. You can combine `@ResponseBody` methods with JSON serialization views. See [Jackson JSON](#mvc-ann-jackson) for details. -##### [](#mvc-ann-responseentity)ResponseEntity ##### +##### ResponseEntity [WebFlux](web-reactive.html#webflux-ann-responseentity) @@ -3195,11 +2916,11 @@ types for the body. This allows the following types of async responses: asynchronously at a later point. This allows the response status and headers to vary depending on the outcome of asynchronous request handling. -##### [](#mvc-ann-jackson)Jackson JSON ##### +##### Jackson JSON Spring offers support for the Jackson JSON library. -###### [](#mvc-ann-jsonview)JSON Views ###### +###### JSON Views [WebFlux](web-reactive.html#webflux-ann-jsonview) @@ -3339,7 +3060,7 @@ class UserController : AbstractController() { } ``` -#### [](#mvc-ann-modelattrib-methods)1.3.4. Model #### +#### 1.3.4. Model [WebFlux](web-reactive.html#webflux-ann-modelattrib-methods) @@ -3433,7 +3154,7 @@ fun handle(): Account { } ``` -#### [](#mvc-ann-initbinder)1.3.5. `DataBinder` #### +#### 1.3.5. `DataBinder` [WebFlux](web-reactive.html#webflux-ann-initbinder) @@ -3534,7 +3255,7 @@ class FormController { |**1**|Defining an `@InitBinder` method on a custom formatter.| |-----|-------------------------------------------------------| -#### [](#mvc-ann-exceptionhandler)1.3.6. Exceptions #### +#### 1.3.6. Exceptions [WebFlux](web-reactive.html#webflux-ann-controller-exceptions) @@ -3641,7 +3362,7 @@ the given `@ExceptionHandler` method would not have matched in the first place. Support for `@ExceptionHandler` methods in Spring MVC is built on the `DispatcherServlet`level, [HandlerExceptionResolver](#mvc-exceptionhandlers) mechanism. -##### [](#mvc-ann-exceptionhandler-args)Method Arguments ##### +##### Method Arguments `@ExceptionHandler` methods support the following arguments: @@ -3662,7 +3383,7 @@ Support for `@ExceptionHandler` methods in Spring MVC is built on the `Dispatche | `@SessionAttribute` | For access to any session attribute, in contrast to model attributes stored in the
session as a result of a class-level `@SessionAttributes` declaration.
See [`@SessionAttribute`](#mvc-ann-sessionattribute) for more details. | | `@RequestAttribute` | For access to request attributes. See [`@RequestAttribute`](#mvc-ann-requestattrib) for more details. | -##### [](#mvc-ann-exceptionhandler-return-values)Return Values ##### +##### Return Values `@ExceptionHandler` methods support the following return values: @@ -3678,7 +3399,7 @@ Support for `@ExceptionHandler` methods in Spring MVC is built on the `Dispatche | `void` |A method with a `void` return type (or `null` return value) is considered to have fully
handled the response if it also has a `ServletResponse` an `OutputStream` argument, or
a `@ResponseStatus` annotation. The same is also true if the controller has made a positive`ETag` or `lastModified` timestamp check (see [Controllers](#mvc-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.| | Any other return value | If a return value is not matched to any of the above and is not a simple type (as determined by[BeanUtils#isSimpleProperty](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/beans/BeanUtils.html#isSimpleProperty-java.lang.Class-)),
by default, it is treated as a model attribute to be added to the model. If it is a simple type,
it remains unresolved. | -##### [](#mvc-ann-rest-exceptions)REST API exceptions ##### +##### REST API exceptions [WebFlux](web-reactive.html#webflux-ann-rest-exceptions) @@ -3694,7 +3415,7 @@ which provides handling for exceptions that Spring MVC raises and provides hooks customize the response body. To make use of this, create a subclass of`ResponseEntityExceptionHandler`, annotate it with `@ControllerAdvice`, override the necessary methods, and declare it as a Spring bean. -#### [](#mvc-ann-controller-advice)1.3.7. Controller Advice #### +#### 1.3.7. Controller Advice [WebFlux](web-reactive.html#webflux-ann-controller-advice) @@ -3749,7 +3470,7 @@ class ExampleAdvice3 The selectors in the preceding example are evaluated at runtime and may negatively impact performance if used extensively. See the[`@ControllerAdvice`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/web/bind/annotation/ControllerAdvice.html)javadoc for more details. -### [](#webmvc-fn)1.4. Functional Endpoints ### +### 1.4. Functional Endpoints [WebFlux](web-reactive.html#webflux-fn) @@ -3758,7 +3479,7 @@ are used to route and handle requests and contracts are designed for immutabilit It is an alternative to the annotation-based programming model but otherwise runs on the same [DispatcherServlet](#mvc-servlet). -#### [](#webmvc-fn-overview)1.4.1. Overview #### +#### 1.4.1. Overview [WebFlux](web-reactive.html#webflux-fn-overview) @@ -3848,14 +3569,14 @@ class PersonHandler(private val repository: PersonRepository) { If you register the `RouterFunction` as a bean, for instance by exposing it in a`@Configuration` class, it will be auto-detected by the servlet, as explained in [Running a Server](#webmvc-fn-running). -#### [](#webmvc-fn-handler-functions)1.4.2. HandlerFunction #### +#### 1.4.2. HandlerFunction [WebFlux](web-reactive.html#webflux-fn-handler-functions) `ServerRequest` and `ServerResponse` are immutable interfaces that offer JDK 8-friendly access to the HTTP request and response, including headers, body, method, and status code. -##### [](#webmvc-fn-request)ServerRequest ##### +##### ServerRequest `ServerRequest` provides access to the HTTP method, URI, headers, and query parameters, while access to the body is provided through the `body` methods. @@ -3903,7 +3624,7 @@ Kotlin val map = request.params() ``` -##### [](#webmvc-fn-response)ServerResponse ##### +##### ServerResponse `ServerResponse` provides access to the HTTP response and, since it is immutable, you can use a `build` method to create it. You can use the builder to set the response status, to add response @@ -4023,7 +3744,7 @@ sseBuilder.id("42") sseBuilder.complete() ``` -##### [](#webmvc-fn-handler-classes)Handler Classes ##### +##### Handler Classes We can write a handler function as a lambda, as the following example shows: @@ -4121,7 +3842,7 @@ class PersonHandler(private val repository: PersonRepository) { |**2**| `createPerson` is a handler function that stores a new `Person` contained in the request body. | |**3**|`getPerson` is a handler function that returns a single person, identified by the `id` path
variable. We retrieve that `Person` from the repository and create a JSON response, if it is
found. If it is not found, we return a 404 Not Found response.| -##### [](#webmvc-fn-handler-validation)Validation ##### +##### Validation A functional endpoint can use Spring’s [validation facilities](core.html#validation) to apply validation to the request body. For example, given a custom Spring[Validator](core.html#validation) implementation for a `Person`: @@ -4192,7 +3913,7 @@ Handlers can also use the standard bean validation API (JSR-303) by creating and a global `Validator` instance based on `LocalValidatorFactoryBean`. See [Spring Validation](core.html#validation-beanvalidation). -#### [](#webmvc-fn-router-functions)1.4.3. `RouterFunction` #### +#### 1.4.3. `RouterFunction` [WebFlux](web-reactive.html#webflux-fn-router-functions) @@ -4211,7 +3932,7 @@ predicates when mapping to requests. For each HTTP method there is an overloaded variant that takes a `RequestPredicate` as a parameter, through which additional constraints can be expressed. -##### [](#webmvc-fn-predicates)Predicates ##### +##### Predicates You can write your own `RequestPredicate`, but the `RequestPredicates` utility class offers commonly used implementations, based on the request path, HTTP method, content-type, @@ -4248,7 +3969,7 @@ Many of the predicates from `RequestPredicates` are composed. For example, `RequestPredicates.GET(String)` is composed from `RequestPredicates.method(HttpMethod)`and `RequestPredicates.path(String)`. The example shown above also uses two request predicates, as the builder uses`RequestPredicates.GET` internally, and composes that with the `accept` predicate. -##### [](#webmvc-fn-routes)Routes ##### +##### Routes Router functions are evaluated in order: if the first route does not match, the second is evaluated, and so on. @@ -4318,7 +4039,7 @@ val route = router { |**3**| `POST /person` with no additional predicates is mapped to`PersonHandler.createPerson`, and | |**4**| `otherRoute` is a router function that is created elsewhere, and added to the route built. | -##### [](#nested-routes)Nested Routes ##### +##### Nested Routes It is common for a group of router functions to have a shared predicate, for instance a shared path. @@ -4389,7 +4110,7 @@ val route = router { } ``` -#### [](#webmvc-fn-running)1.4.4. Running a Server #### +#### 1.4.4. Running a Server [WebFlux](web-reactive.html#webflux-fn-running) @@ -4479,7 +4200,7 @@ class WebConfig : WebMvcConfigurer { } ``` -#### [](#webmvc-fn-handler-filter-function)1.4.5. Filtering Handler Functions #### +#### 1.4.5. Filtering Handler Functions [WebFlux](web-reactive.html#webflux-fn-handler-filter-function) @@ -4600,13 +4321,13 @@ filter to an existing router function via `RouterFunction.filter(HandlerFilterFu | |CORS support for functional endpoints is provided through a dedicated[`CorsFilter`](webmvc-cors.html#mvc-cors-filter).| |---|----------------------------------------------------------------------------------------------------------------------| -### [](#mvc-uri-building)1.5. URI Links ### +### 1.5. URI Links [WebFlux](web-reactive.html#webflux-uri-building) This section describes various options available in the Spring Framework to work with URI’s. -#### [](#web-uricomponents)1.5.1. UriComponents #### +#### 1.5.1. UriComponents Spring MVC and Spring WebFlux @@ -4714,7 +4435,7 @@ val uri = UriComponentsBuilder .build("Westin", "123") ``` -#### [](#web-uribuilder)1.5.2. UriBuilder #### +#### 1.5.2. UriBuilder Spring MVC and Spring WebFlux @@ -4804,7 +4525,7 @@ val uri = uriBuilderFactory.uriString("/hotels/{hotel}") .build("Westin", "123") ``` -#### [](#web-uri-encoding)1.5.3. URI Encoding #### +#### 1.5.3. URI Encoding Spring MVC and Spring WebFlux @@ -4947,7 +4668,7 @@ reasons and for backwards compatibility. The `WebClient` relies on the default v in `DefaultUriBuilderFactory`, which was changed from `EncodingMode.URI_COMPONENT` in 5.0.x to `EncodingMode.TEMPLATE_AND_VALUES` in 5.1. -#### [](#mvc-servleturicomponentsbuilder)1.5.4. Relative Servlet Requests #### +#### 1.5.4. Relative Servlet Requests You can use `ServletUriComponentsBuilder` to create URIs relative to the current request, as the following example shows: @@ -5036,7 +4757,7 @@ val uri = ServletUriComponentsBuilder.fromServletMapping(request) | |As of 5.1, `ServletUriComponentsBuilder` ignores information from the `Forwarded` and`X-Forwarded-*` headers, which specify the client-originated address. Consider using the[`ForwardedHeaderFilter`](#filters-forwarded-headers) to extract and use or to discard
such headers.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#mvc-links-to-controllers)1.5.5. Links to Controllers #### +#### 1.5.5. Links to Controllers Spring MVC provides a mechanism to prepare links to controller methods. For example, the following MVC controller allows for link creation: @@ -5155,7 +4876,7 @@ val uri = uriComponents.encode().toUri() | |As of 5.1, `MvcUriComponentsBuilder` ignores information from the `Forwarded` and`X-Forwarded-*` headers, which specify the client-originated address. Consider using the[ForwardedHeaderFilter](#filters-forwarded-headers) to extract and use or to discard
such headers.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#mvc-links-to-controllers-from-views)1.5.6. Links in Views #### +#### 1.5.6. Links in Views In views such as Thymeleaf, FreeMarker, or JSP, you can build links to annotated controllers by referring to the implicitly or explicitly assigned name for each request mapping. @@ -5200,7 +4921,7 @@ Here is how this works. On startup, every `@RequestMapping` is assigned a defaul through `HandlerMethodMappingNamingStrategy`, whose default implementation uses the capital letters of the class and the method name (for example, the `getThing` method in`ThingController` becomes "TC#getThing"). If there is a name clash, you can use`@RequestMapping(name="..")` to assign an explicit name or implement your own`HandlerMethodMappingNamingStrategy`. -### [](#mvc-ann-async)1.6. Asynchronous Requests ### +### 1.6. Asynchronous Requests [Compared to WebFlux](#mvc-ann-async-vs-webflux) @@ -5213,7 +4934,7 @@ Spring MVC has an extensive integration with Servlet 3.0 asynchronous request[pr * Controllers can use reactive clients and return[reactive types](#mvc-ann-async-reactive-types) for response handling. -#### [](#mvc-ann-async-deferredresult)1.6.1. `DeferredResult` #### +#### 1.6.1. `DeferredResult` [Compared to WebFlux](#mvc-ann-async-vs-webflux) @@ -5253,7 +4974,7 @@ deferredResult.setResult(result) The controller can produce the return value asynchronously, from a different thread — for example, in response to an external event (JMS message), a scheduled task, or other event. -#### [](#mvc-ann-async-callable)1.6.2. `Callable` #### +#### 1.6.2. `Callable` [Compared to WebFlux](#mvc-ann-async-vs-webflux) @@ -5287,7 +5008,7 @@ fun processUpload(file: MultipartFile) = Callable { The return value can then be obtained by running the given task through the[configured](#mvc-ann-async-configuration-spring-mvc) `TaskExecutor`. -#### [](#mvc-ann-async-processing)1.6.3. Processing #### +#### 1.6.3. Processing [Compared to WebFlux](#mvc-ann-async-vs-webflux) @@ -5341,7 +5062,7 @@ Here is a very concise overview of Servlet asynchronous request processing: For further background and context, you can also read[the blog posts](https://spring.io/blog/2012/05/07/spring-mvc-3-2-preview-introducing-servlet-3-async-support) that introduced asynchronous request processing support in Spring MVC 3.2. -##### [](#mvc-ann-async-exceptions)Exception Handling ##### +##### Exception Handling When you use a `DeferredResult`, you can choose whether to call `setResult` or`setErrorResult` with an exception. In both cases, Spring MVC dispatches the request back to the Servlet container to complete processing. It is then treated either as if the @@ -5351,7 +5072,7 @@ The exception then goes through the regular exception handling mechanism (for ex When you use `Callable`, similar processing logic occurs, the main difference being that the result is returned from the `Callable` or an exception is raised by it. -##### [](#mvc-ann-async-interception)Interception ##### +##### Interception `HandlerInterceptor` instances can be of type `AsyncHandlerInterceptor`, to receive the`afterConcurrentHandlingStarted` callback on the initial request that starts asynchronous processing (instead of `postHandle` and `afterCompletion`). @@ -5363,7 +5084,7 @@ lifecycle of an asynchronous request (for example, to handle a timeout event). S See the [javadoc of `DeferredResult`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/web/context/request/async/DeferredResult.html)for more details. `Callable` can be substituted for `WebAsyncTask` that exposes additional methods for timeout and completion callbacks. -##### [](#mvc-ann-async-vs-webflux)Compared to WebFlux ##### +##### Compared to WebFlux The Servlet API was originally built for making a single pass through the Filter-Servlet chain. Asynchronous request processing, added in Servlet 3.0, lets applications exit @@ -5390,7 +5111,7 @@ types in controller method arguments (for example, `@RequestBody`, `@RequestPart nor does it have any explicit support for asynchronous and reactive types as model attributes. Spring WebFlux does support all that. -#### [](#mvc-ann-async-http-streaming)1.6.4. HTTP Streaming #### +#### 1.6.4. HTTP Streaming [WebFlux](web-reactive.html#webflux-codecs-streaming) @@ -5398,7 +5119,7 @@ You can use `DeferredResult` and `Callable` for a single asynchronous return val What if you want to produce multiple asynchronous values and have those written to the response? This section describes how to do so. -##### [](#mvc-ann-async-objects)Objects ##### +##### Objects You can use the `ResponseBodyEmitter` return value to produce a stream of objects, where each object is serialized with an[`HttpMessageConverter`](integration.html#rest-message-conversion) and written to the @@ -5450,7 +5171,7 @@ are not responsible for cleaning up the connection and should not invoke `emitte This call, in turn, performs one final `ASYNC` dispatch to the application, during which Spring MVC invokes the configured exception resolvers and completes the request. -##### [](#mvc-ann-async-sse)SSE ##### +##### SSE `SseEmitter` (a subclass of `ResponseBodyEmitter`) provides support for[Server-Sent Events](https://www.w3.org/TR/eventsource/), where events sent from the server are formatted according to the W3C SSE specification. To produce an SSE @@ -5500,7 +5221,7 @@ a wide range of browsers. See also [previous section](#mvc-ann-async-objects) for notes on exception handling. -##### [](#mvc-ann-async-output-stream)Raw Data ##### +##### Raw Data Sometimes, it is useful to bypass message conversion and stream directly to the response`OutputStream` (for example, for a file download). You can use the `StreamingResponseBody`return value type to do so, as the following example shows: @@ -5530,7 +5251,7 @@ fun handle() = StreamingResponseBody { You can use `StreamingResponseBody` as the body in a `ResponseEntity` to customize the status and headers of the response. -#### [](#mvc-ann-async-reactive-types)1.6.5. Reactive Types #### +#### 1.6.5. Reactive Types [WebFlux](web-reactive.html#webflux-codecs-streaming) @@ -5559,7 +5280,7 @@ blocking the upstream source (such as a `Flux` returned from `WebClient`). By default, `SimpleAsyncTaskExecutor` is used for the blocking writes, but that is not suitable under load. If you plan to stream with a reactive type, you should use the[MVC configuration](#mvc-ann-async-configuration-spring-mvc) to configure a task executor. -#### [](#mvc-ann-async-disconnects)1.6.6. Disconnects #### +#### 1.6.6. Disconnects [WebFlux](web-reactive.html#webflux-codecs-streaming) @@ -5572,14 +5293,14 @@ as a heartbeat and ignore. Alternatively, consider using web messaging solutions (such as[STOMP over WebSocket](#websocket-stomp) or WebSocket with [SockJS](#websocket-fallback)) that have a built-in heartbeat mechanism. -#### [](#mvc-ann-async-configuration)1.6.7. Configuration #### +#### 1.6.7. Configuration [Compared to WebFlux](#mvc-ann-async-vs-webflux) The asynchronous request processing feature must be enabled at the Servlet container level. The MVC configuration also exposes several options for asynchronous requests. -##### [](#mvc-ann-async-configuration-servlet3)Servlet Container ##### +##### Servlet Container Filter and Servlet declarations have an `asyncSupported` flag that needs to be set to `true`to enable asynchronous request processing. In addition, Filter mappings should be declared to handle the `ASYNC` `javax.servlet.DispatchType`. @@ -5588,7 +5309,7 @@ In Java configuration, when you use `AbstractAnnotationConfigDispatcherServletIn In `web.xml` configuration, you can add `true` to the`DispatcherServlet` and to `Filter` declarations and add`ASYNC` to filter mappings. -##### [](#mvc-ann-async-configuration-spring-mvc)Spring MVC ##### +##### Spring MVC The MVC configuration exposes the following options related to asynchronous request processing: @@ -5611,14 +5332,14 @@ You can configure the following: Note that you can also set the default timeout value on a `DeferredResult`, a `ResponseBodyEmitter`, and an `SseEmitter`. For a `Callable`, you can use`WebAsyncTask` to provide a timeout value. -### [](#mvc-cors)1.7. CORS ### +### 1.7. CORS [WebFlux](web-reactive.html#webflux-cors) Spring MVC lets you handle CORS (Cross-Origin Resource Sharing). This section describes how to do so. -#### [](#mvc-cors-intro)1.7.1. Introduction #### +#### 1.7.1. Introduction [WebFlux](web-reactive.html#webflux-cors-intro) @@ -5631,7 +5352,7 @@ Cross-Origin Resource Sharing (CORS) is a [W3C specification](https://www.w3.org what kind of cross-domain requests are authorized, rather than using less secure and less powerful workarounds based on IFRAME or JSONP. -#### [](#mvc-cors-processing)1.7.2. Processing #### +#### 1.7.2. Processing [WebFlux](web-reactive.html#webflux-cors-processing) @@ -5666,7 +5387,7 @@ accepted, e.g. `allowCredentials` and `maxAge`, the local overrides the global v | |To learn more from the source or make advanced customizations, check the code behind:

* `CorsConfiguration`

* `CorsProcessor`, `DefaultCorsProcessor`

* `AbstractHandlerMapping`| |---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#mvc-cors-controller)1.7.3. `@CrossOrigin` #### +#### 1.7.3. `@CrossOrigin` [WebFlux](web-reactive.html#webflux-cors-controller) @@ -5816,7 +5537,7 @@ class AccountController { } ``` -#### [](#mvc-cors-global)1.7.4. Global Configuration #### +#### 1.7.4. Global Configuration [WebFlux](web-reactive.html#webflux-cors-global) @@ -5840,7 +5561,7 @@ the `allowOriginPatterns` property may be used to match to a dynamic set of orig `maxAge` is set to 30 minutes. -##### [](#mvc-cors-global-java)Java Configuration ##### +##### Java Configuration [WebFlux](web-reactive.html#webflux-cors-global) @@ -5890,7 +5611,7 @@ class WebConfig : WebMvcConfigurer { } ``` -##### [](#mvc-cors-global-xml)XML Configuration ##### +##### XML Configuration To enable CORS in the XML namespace, you can use the `` element, as the following example shows: @@ -5911,7 +5632,7 @@ as the following example shows: ``` -#### [](#mvc-cors-filter)1.7.5. CORS Filter #### +#### 1.7.5. CORS Filter [WebFlux](webflux-cors.html#webflux-cors-webfilter) @@ -5960,7 +5681,7 @@ source.registerCorsConfiguration("/**", config) val filter = CorsFilter(source) ``` -### [](#mvc-web-security)1.8. Web Security ### +### 1.8. Web Security [WebFlux](web-reactive.html#webflux-web-security) @@ -5978,7 +5699,7 @@ reference documentation, including: [HDIV](https://hdiv.org/) is another web security framework that integrates with Spring MVC. -### [](#mvc-caching)1.9. HTTP Caching ### +### 1.9. HTTP Caching [WebFlux](web-reactive.html#webflux-caching) @@ -5992,7 +5713,7 @@ the `Last-Modified` header. This section describes the HTTP caching-related options that are available in Spring Web MVC. -#### [](#mvc-caching-cachecontrol)1.9.1. `CacheControl` #### +#### 1.9.1. `CacheControl` [WebFlux](web-reactive.html#webflux-caching-cachecontrol) @@ -6051,7 +5772,7 @@ works as follows: * An `n > 0` value caches the given response for `n` seconds by using the`'Cache-Control: max-age=n'` directive. -#### [](#mvc-caching-etag-lastmodified)1.9.2. Controllers #### +#### 1.9.2. Controllers [WebFlux](web-reactive.html#webflux-caching-etag-lastmodified) @@ -6146,19 +5867,19 @@ There are three variants for checking conditional requests against `eTag` values 304 (NOT\_MODIFIED). For conditional `POST`, `PUT`, and `DELETE`, you can instead set the response to 412 (PRECONDITION\_FAILED), to prevent concurrent modification. -#### [](#mvc-caching-static-resources)1.9.3. Static Resources #### +#### 1.9.3. Static Resources [WebFlux](web-reactive.html#webflux-caching-static-resources) You should serve static resources with a `Cache-Control` and conditional response headers for optimal performance. See the section on configuring [Static Resources](#mvc-config-static-resources). -#### [](#mvc-httpcaching-shallowetag)1.9.4. `ETag` Filter #### +#### 1.9.4. `ETag` Filter You can use the `ShallowEtagHeaderFilter` to add “shallow” `eTag` values that are computed from the response content and, thus, save bandwidth but not CPU time. See [Shallow ETag](#filters-shallow-etag). -### [](#mvc-view)1.10. View Technologies ### +### 1.10. View Technologies [WebFlux](web-reactive.html#webflux-view) @@ -6170,7 +5891,7 @@ We assume you are already familiar with [View Resolution](#mvc-viewresolver). | |The views of a Spring MVC application live within the internal trust boundaries
of that application. Views have access to all the beans of your application context. As
such, it is not recommended to use Spring MVC’s template support in applications where
the templates are editable by external sources, since this can have security implications.| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#mvc-view-thymeleaf)1.10.1. Thymeleaf #### +#### 1.10.1. Thymeleaf [WebFlux](web-reactive.html#webflux-view-thymeleaf) @@ -6185,7 +5906,7 @@ The Thymeleaf integration with Spring MVC is managed by the Thymeleaf project. The configuration involves a few bean declarations, such as`ServletContextTemplateResolver`, `SpringTemplateEngine`, and `ThymeleafViewResolver`. See [Thymeleaf+Spring](https://www.thymeleaf.org/documentation.html) for more details. -#### [](#mvc-view-freemarker)1.10.2. FreeMarker #### +#### 1.10.2. FreeMarker [WebFlux](web-reactive.html#webflux-view-freemarker) @@ -6193,7 +5914,7 @@ See [Thymeleaf+Spring](https://www.thymeleaf.org/documentation.html) for more de kind of text output from HTML to email and others. The Spring Framework has built-in integration for using Spring MVC with FreeMarker templates. -##### [](#mvc-view-freemarker-contextconfig)View Configuration ##### +##### View Configuration [WebFlux](web-reactive.html#webflux-view-freemarker-contextconfig) @@ -6269,7 +5990,7 @@ properties, as the following example shows: Your templates need to be stored in the directory specified by the `FreeMarkerConfigurer`shown in the preceding example. Given the preceding configuration, if your controller returns a view name of `welcome`, the resolver looks for the`/WEB-INF/freemarker/welcome.ftl` template. -##### [](#mvc-views-freemarker)FreeMarker Configuration ##### +##### FreeMarker Configuration [WebFlux](web-reactive.html#webflux-views-freemarker) @@ -6293,14 +6014,14 @@ a `java.util.Properties` object, and the `freemarkerVariables` property requires See the FreeMarker documentation for details of settings and variables as they apply to the `Configuration` object. -##### [](#mvc-view-freemarker-forms)Form Handling ##### +##### Form Handling Spring provides a tag library for use in JSPs that contains, among others, a`` element. This element primarily lets forms display values from form-backing objects and show the results of failed validations from a `Validator` in the web or business tier. Spring also has support for the same functionality in FreeMarker, with additional convenience macros for generating form input elements themselves. -###### [](#mvc-view-bind-macros)The Bind Macros ###### +###### The Bind Macros [WebFlux](web-reactive.html#webflux-view-bind-macros) @@ -6313,7 +6034,7 @@ to calling code and user templates. The following sections concentrate only on t you need to directly call from within your templates. If you wish to view the macro code directly, the file is called `spring.ftl` and is in the`org.springframework.web.servlet.view.freemarker` package. -###### [](#mvc-view-simple-binding)Simple Binding ###### +###### Simple Binding In your HTML forms based on FreeMarker templates that act as a form view for a Spring MVC controller, you can use code similar to the next example to bind to field values and @@ -6353,7 +6074,7 @@ messages or values. You can set it to `true` or `false` as required. Additional handling macros simplify the use of HTML escaping, and you should use these macros wherever possible. They are explained in the next section. -###### [](#mvc-views-form-macros)Input Macros ###### +###### Input Macros Additional convenience macros for FreeMarker simplify both binding and form generation (including validation error display). It is never necessary to use these macros to @@ -6409,7 +6130,7 @@ The parameters to any of the above macros have consistent meanings: The following sections outline examples of the macros. -[](#mvc-views-form-macros-input)Input Fields +## Input Fields The `formInput` macro takes the `path` parameter (`command.name`) and an additional `attributes`parameter (which is empty in the upcoming example). The macro, along with all other form generation macros, performs an implicit Spring bind on the path parameter. The binding @@ -6445,7 +6166,7 @@ The `formTextarea` macro works the same way as the `formInput` macro and accepts parameter list. Commonly, the second parameter (`attributes`) is used to pass style information or `rows` and `cols` attributes for the `textarea`. -[](#mvc-views-form-macros-select)Selection Fields +## Selection Fields You can use four selection field macros to generate common UI value selection inputs in your HTML forms: @@ -6528,7 +6249,7 @@ Town: New York ``` -###### [](#mvc-views-form-macros-html-escaping)HTML Escaping ###### +###### HTML Escaping Default usage of the form macros described earlier results in HTML elements that are HTML 4.01 compliant and that use the default value for HTML escaping defined in your `web.xml` file, as @@ -6562,7 +6283,7 @@ In similar fashion, you can specify HTML escaping per field, as the following ex <#-- all future fields will be bound with HTML escaping off --> ``` -#### [](#mvc-view-groovymarkup)1.10.3. Groovy Markup #### +#### 1.10.3. Groovy Markup The [Groovy Markup Template Engine](http://groovy-lang.org/templating.html#_the_markuptemplateengine)is primarily aimed at generating XML-like markup (XML, XHTML, HTML5, and others), but you can use it to generate any text-based content. The Spring Framework has a built-in @@ -6571,7 +6292,7 @@ integration for using Spring MVC with Groovy Markup. | |The Groovy Markup Template engine requires Groovy 2.3.1+.| |---|---------------------------------------------------------| -##### [](#mvc-view-groovymarkup-configuration)Configuration ##### +##### Configuration The following example shows how to configure the Groovy Markup Template Engine: @@ -6631,7 +6352,7 @@ The following example shows how to configure the same in XML: ``` -##### [](#mvc-view-groovymarkup-example)Example ##### +##### Example Unlike traditional template engines, Groovy Markup relies on a DSL that uses a builder syntax. The following example shows a sample template for an HTML page: @@ -6649,7 +6370,7 @@ html(lang:'en') { } ``` -#### [](#mvc-view-script)1.10.4. Script Views #### +#### 1.10.4. Script Views [WebFlux](web-reactive.html#webflux-view-script) @@ -6670,7 +6391,7 @@ templating libraries on different script engines: | |The basic rule for integrating any other script engine is that it must implement the`ScriptEngine` and `Invocable` interfaces.| |---|------------------------------------------------------------------------------------------------------------------------------| -##### [](#mvc-view-script-dependencies)Requirements ##### +##### Requirements [WebFlux](web-reactive.html#webflux-view-script-dependencies) @@ -6688,7 +6409,7 @@ You need to have the script engine on your classpath, the details of which vary You need to have the script templating library. One way to do that for JavaScript is through [WebJars](https://www.webjars.org/). -##### [](#mvc-view-script-integrate)Script Templates ##### +##### Script Templates [WebFlux](web-reactive.html#webflux-script-integrate) @@ -6886,11 +6607,11 @@ function render(template, model) { Check out the Spring Framework unit tests,[Java](https://github.com/spring-projects/spring-framework/tree/main/spring-webmvc/src/test/java/org/springframework/web/servlet/view/script), and[resources](https://github.com/spring-projects/spring-framework/tree/main/spring-webmvc/src/test/resources/org/springframework/web/servlet/view/script), for more configuration examples. -#### [](#mvc-view-jsp)1.10.5. JSP and JSTL #### +#### 1.10.5. JSP and JSTL The Spring Framework has a built-in integration for using Spring MVC with JSP and JSTL. -##### [](#mvc-view-jsp-resolver)View Resolvers ##### +##### View Resolvers When developing with JSPs, you typically declare an `InternalResourceViewResolver` bean. @@ -6906,12 +6627,12 @@ a directory under the `'WEB-INF'` directory so there can be no direct access by ``` -##### [](#mvc-view-jsp-jstl)JSPs versus JSTL ##### +##### JSPs versus JSTL When using the JSP Standard Tag Library (JSTL) you must use a special view class, the`JstlView`, as JSTL needs some preparation before things such as the I18N features can work. -##### [](#mvc-view-jsp-tags)Spring’s JSP Tag Library ##### +##### Spring’s JSP Tag Library Spring provides data binding of request parameters to command objects, as described in earlier chapters. To facilitate the development of JSP pages in combination with those @@ -6921,7 +6642,7 @@ Spring tags have HTML escaping features to enable or disable escaping of charact The `spring.tld` tag library descriptor (TLD) is included in the `spring-webmvc.jar`. For a comprehensive reference on individual tags, browse the[API reference](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/web/servlet/tags/package-summary.html#package.description)or see the tag library description. -##### [](#mvc-view-jsp-formtaglib)Spring’s form tag library ##### +##### Spring’s form tag library As of version 2.0, Spring provides a comprehensive set of data binding-aware tags for handling form elements when using JSP and Spring Web MVC. Each tag provides support for @@ -6936,7 +6657,7 @@ JSPs easier to develop, read, and maintain. We go through the form tags and look at an example of how each tag is used. We have included generated HTML snippets where certain tags require further commentary. -###### [](#mvc-view-jsp-formtaglib-configuration)Configuration ###### +###### Configuration The form tag library comes bundled in `spring-webmvc.jar`. The library descriptor is called `spring-form.tld`. @@ -6950,7 +6671,7 @@ page: where `form` is the tag name prefix you want to use for the tags from this library. -###### [](#mvc-view-jsp-formtaglib-formtag)The Form Tag ###### +###### The Form Tag This tag renders an HTML 'form' element and exposes a binding path to inner tags for binding. It puts the command object in the `PageContext` so that the command object can @@ -7031,13 +6752,13 @@ following example shows: ``` -###### [](#mvc-view-jsp-formtaglib-inputtag)The `input` Tag ###### +###### The `input` Tag This tag renders an HTML `input` element with the bound value and `type='text'` by default. For an example of this tag, see [The Form Tag](#mvc-view-jsp-formtaglib-formtag). You can also use HTML5-specific types, such as `email`, `tel`, `date`, and others. -###### [](#mvc-view-jsp-formtaglib-checkboxtag)The `checkbox` Tag ###### +###### The `checkbox` Tag This tag renders an HTML `input` tag with the `type` set to `checkbox`. @@ -7155,7 +6876,7 @@ prefixed by an underscore (`_`) for each checkbox. By doing this, you are effect telling Spring that “the checkbox was visible in the form, and I want my object to which the form data binds to reflect the state of the checkbox, no matter what.” -###### [](#mvc-view-jsp-formtaglib-checkboxestag)The `checkboxes` Tag ###### +###### The `checkboxes` Tag This tag renders multiple HTML `input` tags with the `type` set to `checkbox`. @@ -7187,7 +6908,7 @@ the map entry key is used as the value, and the map entry’s value is used as the label to be displayed. You can also use a custom object where you can provide the property names for the value by using `itemValue` and the label by using `itemLabel`. -###### [](#mvc-view-jsp-formtaglib-radiobuttontag)The `radiobutton` Tag ###### +###### The `radiobutton` Tag This tag renders an HTML `input` element with the `type` set to `radio`. @@ -7204,7 +6925,7 @@ but with different values, as the following example shows: ``` -###### [](#mvc-view-jsp-formtaglib-radiobuttonstag)The `radiobuttons` Tag ###### +###### The `radiobuttons` Tag This tag renders multiple HTML `input` elements with the `type` set to `radio`. @@ -7222,7 +6943,7 @@ by using `itemValue` and the label by using `itemLabel`, as the following exampl ``` -###### [](#mvc-view-jsp-formtaglib-passwordtag)The `password` Tag ###### +###### The `password` Tag This tag renders an HTML `input` tag with the type set to `password` with the bound value. @@ -7247,7 +6968,7 @@ password value to be shown, you can set the value of the `showPassword` attribut ``` -###### [](#mvc-view-jsp-formtaglib-selecttag)The `select` Tag ###### +###### The `select` Tag This tag renders an HTML 'select' element. It supports data binding to the selected option as well as the use of nested `option` and `options` tags. @@ -7277,7 +6998,7 @@ as follows: ``` -###### [](#mvc-view-jsp-formtaglib-optiontag)The `option` Tag ###### +###### The `option` Tag This tag renders an HTML `option` element. It sets `selected`, based on the bound value. The following HTML shows typical output for it: @@ -7316,7 +7037,7 @@ as follows: |**1**|Note the addition of a `selected` attribute.| |-----|--------------------------------------------| -###### [](#mvc-view-jsp-formtaglib-optionstag)The `options` Tag ###### +###### The `options` Tag This tag renders a list of HTML `option` elements. It sets the `selected` attribute, based on the bound value. The following HTML shows typical output for it: @@ -7364,7 +7085,7 @@ values and the map values correspond to option labels. If `itemValue` or `itemLa happen to be specified as well, the item value property applies to the map key, and the item label property applies to the map value. -###### [](#mvc-view-jsp-formtaglib-textareatag)The `textarea` Tag ###### +###### The `textarea` Tag This tag renders an HTML `textarea` element. The following HTML shows typical output for it: @@ -7376,7 +7097,7 @@ This tag renders an HTML `textarea` element. The following HTML shows typical ou ``` -###### [](#mvc-view-jsp-formtaglib-hiddeninputtag)The `hidden` Tag ###### +###### The `hidden` Tag This tag renders an HTML `input` tag with the `type` set to `hidden` with the bound value. To submit an unbound hidden value, use the HTML `input` tag with the `type` set to `hidden`. @@ -7392,7 +7113,7 @@ If we choose to submit the `house` value as a hidden one, the HTML would be as f ``` -###### [](#mvc-view-jsp-formtaglib-errorstag)The `errors` Tag ###### +###### The `errors` Tag This tag renders field errors in an HTML `span` element. It provides access to the errors created in your controller or those that were created by any validators associated with @@ -7552,7 +7273,7 @@ The HTML would be as follows: The `spring-form.tld` tag library descriptor (TLD) is included in the `spring-webmvc.jar`. For a comprehensive reference on individual tags, browse the[API reference](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/web/servlet/tags/form/package-summary.html#package.description)or see the tag library description. -###### [](#mvc-rest-method-conversion)HTTP Method Conversion ###### +###### HTTP Method Conversion A key principle of REST is the use of the “Uniform Interface”. This means that all resources (URLs) can be manipulated by using the same four HTTP methods: GET, PUT, POST, @@ -7616,7 +7337,7 @@ fun deletePet(@PathVariable ownerId: Int, @PathVariable petId: Int): String { } ``` -###### [](#mvc-view-jsp-formtaglib-html5)HTML5 Tags ###### +###### HTML5 Tags The Spring form tag library allows entering dynamic attributes, which means you can enter any HTML5 specific attributes. @@ -7624,7 +7345,7 @@ enter any HTML5 specific attributes. The form `input` tag supports entering a type attribute other than `text`. This is intended to allow rendering new HTML5 specific input types, such as `email`, `date`,`range`, and others. Note that entering `type='text'` is not required, since `text`is the default type. -#### [](#mvc-view-tiles)1.10.6. Tiles #### +#### 1.10.6. Tiles You can integrate Tiles - just as any other view technology - in web applications that use Spring. This section describes, in a broad way, how to do so. @@ -7632,12 +7353,12 @@ applications that use Spring. This section describes, in a broad way, how to do | |This section focuses on Spring’s support for Tiles version 3 in the`org.springframework.web.servlet.view.tiles3` package.| |---|-------------------------------------------------------------------------------------------------------------------------| -##### [](#mvc-view-tiles-dependencies)Dependencies ##### +##### Dependencies To be able to use Tiles, you have to add a dependency on Tiles version 3.0.1 or higher and [its transitive dependencies](https://tiles.apache.org/framework/dependency-management.html)to your project. -##### [](#mvc-view-tiles-integrate)Configuration ##### +##### Configuration To be able to use Tiles, you have to configure it by using files that contain definitions (for basic information on definitions and other Tiles concepts, see[https://tiles.apache.org](https://tiles.apache.org)). In Spring, this is done by using the `TilesConfigurer`. @@ -7683,7 +7404,7 @@ and `tiles.xml` is used by default. | |Since underscores are used to indicate locales, we recommended not using
them otherwise in the file names for Tiles definitions.| |---|------------------------------------------------------------------------------------------------------------------------------------| -###### [](#mvc-view-tiles-url)`UrlBasedViewResolver` ###### +###### `UrlBasedViewResolver` The `UrlBasedViewResolver` instantiates the given `viewClass` for each view it has to resolve. The following bean defines a `UrlBasedViewResolver`: @@ -7694,7 +7415,7 @@ resolve. The following bean defines a `UrlBasedViewResolver`: ``` -###### [](#mvc-view-tiles-preparer)`SimpleSpringPreparerFactory` and `SpringBeanPreparerFactory` ###### +###### `SimpleSpringPreparerFactory` and `SpringBeanPreparerFactory` As an advanced feature, Spring also supports two special Tiles `PreparerFactory`implementations. See the Tiles documentation for details on how to use`ViewPreparer` references in your Tiles definition files. @@ -7732,7 +7453,7 @@ how to define a `SpringBeanPreparerFactory` property on a `TilesConfigurer` bean ``` -#### [](#mvc-view-feeds)1.10.7. RSS and Atom #### +#### 1.10.7. RSS and Atom Both `AbstractAtomFeedView` and `AbstractRssFeedView` inherit from the`AbstractFeedView` base class and are used to provide Atom and RSS Feed views, respectively. They are based on [ROME](https://rometools.github.io/rome/) project and are located in the @@ -7823,12 +7544,12 @@ object after the method returns. For an example of creating an Atom view, see Alef Arendsen’s Spring Team Blog[entry](https://spring.io/blog/2009/03/16/adding-an-atom-view-to-an-application-using-spring-s-rest-support). -#### [](#mvc-view-document)1.10.8. PDF and Excel #### +#### 1.10.8. PDF and Excel Spring offers ways to return output other than HTML, including PDF and Excel spreadsheets. This section describes how to use those features. -##### [](#mvc-view-document-intro)Introduction to Document Views ##### +##### Introduction to Document Views An HTML page is not always the best way for the user to view the model output, and Spring makes it simple to generate a PDF document or an Excel spreadsheet @@ -7842,7 +7563,7 @@ For PDF generation, you need to add (preferably) the OpenPDF library. | |You should use the latest versions of the underlying document-generation libraries,
if possible. In particular, we strongly recommend OpenPDF (for example, OpenPDF 1.2.12)
instead of the outdated original iText 2.1.7, since OpenPDF is actively maintained and
fixes an important vulnerability for untrusted PDF content.| |---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -##### [](#mvc-view-document-pdf)PDF Views ##### +##### PDF Views A simple PDF view for a word list could extend`org.springframework.web.servlet.view.document.AbstractPdfView` and implement the`buildPdfDocument()` method, as the following example shows: @@ -7881,7 +7602,7 @@ class PdfWordList : AbstractPdfView() { A controller can return such a view either from an external view definition (referencing it by name) or as a `View` instance from the handler method. -##### [](#mvc-view-document-excel)Excel Views ##### +##### Excel Views Since Spring Framework 4.2,`org.springframework.web.servlet.view.document.AbstractXlsView` is provided as a base class for Excel views. It is based on Apache POI, with specialized subclasses (`AbstractXlsxView`and `AbstractXlsxStreamingView`) that supersede the outdated `AbstractExcelView` class. @@ -7889,13 +7610,13 @@ class for Excel views. It is based on Apache POI, with specialized subclasses (` The programming model is similar to `AbstractPdfView`, with `buildExcelDocument()`as the central template method and controllers being able to return such a view from an external definition (by name) or as a `View` instance from the handler method. -#### [](#mvc-view-jackson)1.10.9. Jackson #### +#### 1.10.9. Jackson [WebFlux](web-reactive.html#webflux-view-httpmessagewriter) Spring offers support for the Jackson JSON library. -##### [](#mvc-view-json-mapping)Jackson-based JSON MVC Views ##### +##### Jackson-based JSON MVC Views [WebFlux](web-reactive.html#webflux-view-httpmessagewriter) @@ -7910,7 +7631,7 @@ You can customize JSON mapping as needed by using Jackson’s provided annotations. When you need further control, you can inject a custom `ObjectMapper`through the `ObjectMapper` property, for cases where you need to provide custom JSON serializers and deserializers for specific types. -##### [](#mvc-view-xml-mapping)Jackson-based XML Views ##### +##### Jackson-based XML Views [WebFlux](web-reactive.html#webflux-view-httpmessagewriter) @@ -7922,14 +7643,14 @@ You can customized XML mapping as needed by using JAXB or Jackson’s provided annotations. When you need further control, you can inject a custom `XmlMapper`through the `ObjectMapper` property, for cases where custom XML you need to provide serializers and deserializers for specific types. -#### [](#mvc-view-xml-marshalling)1.10.10. XML Marshalling #### +#### 1.10.10. XML Marshalling The `MarshallingView` uses an XML `Marshaller` (defined in the `org.springframework.oxm`package) to render the response content as XML. You can explicitly set the object to be marshalled by using a `MarshallingView` instance’s `modelKey` bean property. Alternatively, the view iterates over all model properties and marshals the first type that is supported by the `Marshaller`. For more information on the functionality in the`org.springframework.oxm` package, see [Marshalling XML using O/X Mappers](data-access.html#oxm). -#### [](#mvc-view-xslt)1.10.11. XSLT Views #### +#### 1.10.11. XSLT Views XSLT is a transformation language for XML and is popular as a view technology within web applications. XSLT can be a good choice as a view technology if your application @@ -7941,7 +7662,7 @@ This example is a trivial Spring application that creates a list of words in the name of our XSLT view. See [Annotated Controllers](#mvc-controller) for details of Spring Web MVC’s`Controller` interface. The XSLT controller turns the list of words into a simple XML document ready for transformation. -##### [](#mvc-view-xslt-beandefs)Beans ##### +##### Beans Configuration is standard for a simple Spring web application: The MVC configuration has to define an `XsltViewResolver` bean and regular MVC annotation configuration. @@ -7981,7 +7702,7 @@ class WebConfig : WebMvcConfigurer { } ``` -##### [](#mvc-view-xslt-controllercode)Controller ##### +##### Controller We also need a Controller that encapsulates our word-generation logic. @@ -8049,7 +7770,7 @@ from your model in any way you choose. This prevents the transformation of XML p too great a part in the structure of your model data, which is a danger when using tools to manage the DOMification process. -##### [](#mvc-view-xslt-transforming)Transformation ##### +##### Transformation Finally, the `XsltViewResolver` resolves the “home” XSLT template file and merges the DOM document into it to generate our view. As shown in the `XsltViewResolver`configuration, XSLT templates live in the `war` file in the `WEB-INF/xsl` directory @@ -8101,7 +7822,7 @@ The preceding transform is rendered as the following HTML: ``` -### [](#mvc-config)1.11. MVC Config ### +### 1.11. MVC Config [WebFlux](web-reactive.html#webflux-config) @@ -8114,7 +7835,7 @@ see [Advanced Java Config](#mvc-config-advanced-java) and [Advanced XML Config]( You do not need to understand the underlying beans created by the MVC Java configuration and the MVC namespace. If you want to learn more, see [Special Bean Types](#mvc-servlet-special-bean-types)and [Web MVC Config](#mvc-servlet-config). -#### [](#mvc-config-enable)1.11.1. Enable MVC Configuration #### +#### 1.11.1. Enable MVC Configuration [WebFlux](web-reactive.html#webflux-config-enable) @@ -8160,7 +7881,7 @@ configuration, as the following example shows: The preceding example registers a number of Spring MVC[infrastructure beans](#mvc-servlet-special-bean-types) and adapts to dependencies available on the classpath (for example, payload converters for JSON, XML, and others). -#### [](#mvc-config-customize)1.11.2. MVC Config API #### +#### 1.11.2. MVC Config API [WebFlux](web-reactive.html#webflux-config-customize) @@ -8194,7 +7915,7 @@ view the [Spring MVC XML schema](https://schema.spring.io/mvc/spring-mvc.xsd) or the code completion feature of your IDE to discover what attributes and sub-elements are available. -#### [](#mvc-config-conversion)1.11.3. Type Conversion #### +#### 1.11.3. Type Conversion [WebFlux](web-reactive.html#webflux-config-conversion) @@ -8307,7 +8028,7 @@ class WebConfig : WebMvcConfigurer { | |See [the `FormatterRegistrar` SPI](core.html#format-FormatterRegistrar-SPI)and the `FormattingConversionServiceFactoryBean` for more information on when to use
FormatterRegistrar implementations.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#mvc-config-validation)1.11.4. Validation #### +#### 1.11.4. Validation [WebFlux](web-reactive.html#webflux-config-validation) @@ -8395,7 +8116,7 @@ class MyController { | |If you need to have a `LocalValidatorFactoryBean` injected somewhere, create a bean and
mark it with `@Primary` in order to avoid conflict with the one declared in the MVC configuration.| |---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#mvc-config-interceptors)1.11.5. Interceptors #### +#### 1.11.5. Interceptors In Java configuration, you can register interceptors to apply to incoming requests, as the following example shows: @@ -8448,7 +8169,7 @@ The following example shows how to achieve the same configuration in XML: ``` -#### [](#mvc-config-content-negotiation)1.11.6. Content Types #### +#### 1.11.6. Content Types [WebFlux](web-reactive.html#webflux-config-content-negotiation) @@ -8508,7 +8229,7 @@ The following example shows how to achieve the same configuration in XML: ``` -#### [](#mvc-config-message-converters)1.11.7. Message Converters #### +#### 1.11.7. Message Converters [WebFlux](web-reactive.html#webflux-config-message-codecs) @@ -8602,7 +8323,7 @@ The following example shows how to achieve the same configuration in XML: ``` -#### [](#mvc-config-view-controller)1.11.8. View Controllers #### +#### 1.11.8. View Controllers This is a shortcut for defining a `ParameterizableViewController` that immediately forwards to a view when invoked. You can use it in static cases when there is no Java controller @@ -8651,7 +8372,7 @@ that a 405 (METHOD\_NOT\_ALLOWED), a 415 (UNSUPPORTED\_MEDIA\_TYPE), or similar be sent to the client to help with debugging. For this reason it is recommended to avoid splitting URL handling across an annotated controller and a view controller. -#### [](#mvc-config-view-resolvers)1.11.9. View Resolvers #### +#### 1.11.9. View Resolvers [WebFlux](web-reactive.html#webflux-config-view-resolvers) @@ -8766,7 +8487,7 @@ class WebConfig : WebMvcConfigurer { } ``` -#### [](#mvc-config-static-resources)1.11.10. Static Resources #### +#### 1.11.10. Static Resources [WebFlux](web-reactive.html#webflux-config-static-resources) @@ -8892,7 +8613,7 @@ without versions — for example, from `/jquery/jquery.min.js` to`/jquery/1. | |The Java configuration based on `ResourceHandlerRegistry` provides further options
for fine-grained control, e.g. last-modified behavior and optimized resource resolution.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#mvc-default-servlet-handler)1.11.11. Default Servlet #### +#### 1.11.11. Default Servlet Spring MVC allows for mapping the `DispatcherServlet` to `/` (thus overriding the mapping of the container’s default Servlet), while still allowing static resource requests to be @@ -8981,7 +8702,7 @@ The following example shows how to achieve the same configuration in XML: ``` -#### [](#mvc-config-path-matching)1.11.12. Path Matching #### +#### 1.11.12. Path Matching [WebFlux](web-reactive.html#webflux-config-path-matching) @@ -9043,7 +8764,7 @@ The following example shows how to achieve the same configuration in XML: ``` -#### [](#mvc-config-advanced-java)1.11.13. Advanced Java Config #### +#### 1.11.13. Advanced Java Config [WebFlux](web-reactive.html#webflux-config-advanced-java) @@ -9080,7 +8801,7 @@ You can keep existing methods in `WebConfig`, but you can now also override bean from the base class, and you can still have any number of other `WebMvcConfigurer` implementations on the classpath. -#### [](#mvc-config-advanced-xml)1.11.14. Advanced XML Config #### +#### 1.11.14. Advanced XML Config The MVC namespace does not have an advanced mode. If you need to customize a property on a bean that you cannot change otherwise, you can use the `BeanPostProcessor` lifecycle @@ -9113,7 +8834,7 @@ class MyPostProcessor : BeanPostProcessor { Note that you need to declare `MyPostProcessor` as a bean, either explicitly in XML or by letting it be detected through a `` declaration. -### [](#mvc-http2)1.12. HTTP/2 ### +### 1.12. HTTP/2 [WebFlux](web-reactive.html#webflux-http2) @@ -9125,12 +8846,11 @@ For more details, see the[HTTP/2 wiki page](https://github.com/spring-projects/s The Servlet API does expose one construct related to HTTP/2. You can use the`javax.servlet.http.PushBuilder` to proactively push resources to clients, and it is supported as a [method argument](#mvc-ann-arguments) to `@RequestMapping` methods. -[](#webmvc-client)2. REST Clients ----------- +## 2. REST Clients This section describes options for client-side access to REST endpoints. -### [](#webmvc-resttemplate)2.1. `RestTemplate` ### +### 2.1. `RestTemplate` `RestTemplate` is a synchronous client to perform HTTP requests. It is the original Spring REST client and exposes a simple, template-method API over underlying HTTP client @@ -9141,7 +8861,7 @@ libraries. See [REST Endpoints](integration.html#rest-client-access) for details. -### [](#webmvc-webclient)2.2. `WebClient` ### +### 2.2. `WebClient` `WebClient` is a non-blocking, reactive client to perform HTTP requests. It was introduced in 5.0 and offers a modern alternative to the `RestTemplate`, with efficient @@ -9163,8 +8883,7 @@ In contrast to `RestTemplate`, `WebClient` supports the following: See [WebClient](web-reactive.html#webflux-client) for more details. -[](#testing)3. Testing ----------- +## 3. Testing [Same in Spring WebFlux](web-reactive.html#webflux-test) @@ -9192,8 +8911,7 @@ This section summarizes the options available in `spring-test` for Spring MVC ap non-blocking, reactive client and is well suited for testing asynchronous and streaming scenarios. -[](#websocket)4. WebSockets ----------- +## 4. WebSockets [WebFlux](web-reactive.html#webflux-websocket) @@ -9201,7 +8919,7 @@ This part of the reference documentation covers support for Servlet stack, WebSo messaging that includes raw WebSocket interactions, WebSocket emulation through SockJS, and publish-subscribe messaging through STOMP as a sub-protocol over WebSocket. -### [](#websocket-intro)4.1. Introduction to WebSocket ### +### 4.1. Introduction to WebSocket The WebSocket protocol, [RFC 6455](https://tools.ietf.org/html/rfc6455), provides a standardized way to establish a full-duplex, two-way communication channel between client and server @@ -9253,7 +8971,7 @@ likely need to configure it to pass WebSocket upgrade requests on to the WebSock server. Likewise, if the application runs in a cloud environment, check the instructions of the cloud provider related to WebSocket support. -#### [](#websocket-intro-architecture)4.1.1. HTTP Versus WebSocket #### +#### 4.1.1. HTTP Versus WebSocket Even though WebSocket is designed to be HTTP-compatible and starts with an HTTP request, it is important to understand that the two protocols lead to very different @@ -9275,7 +8993,7 @@ WebSocket clients and servers can negotiate the use of a higher-level, messaging (for example, STOMP), through the `Sec-WebSocket-Protocol` header on the HTTP handshake request. In the absence of that, they need to come up with their own conventions. -#### [](#websocket-intro-when-to-use)4.1.2. When to Use WebSockets #### +#### 4.1.2. When to Use WebSockets WebSockets can make a web page be dynamic and interactive. However, in many cases, a combination of Ajax and HTTP streaming or long polling can provide a simple and @@ -9295,14 +9013,14 @@ may preclude WebSocket interactions, either because they are not configured to p means that the use of WebSocket for internal applications within the firewall is a more straightforward decision than it is for public facing applications. -### [](#websocket-server)4.2. WebSocket API ### +### 4.2. WebSocket API [WebFlux](web-reactive.html#webflux-websocket-server) The Spring Framework provides a WebSocket API that you can use to write client- and server-side applications that handle WebSocket messages. -#### [](#websocket-server-handler)4.2.1. `WebSocketHandler` #### +#### 4.2.1. `WebSocketHandler` [WebFlux](web-reactive.html#webflux-websocket-server-handler) @@ -9380,7 +9098,7 @@ When using the `WebSocketHandler` API directly vs indirectly, e.g. through the[S since the underlying standard WebSocket session (JSR-356) does not allow concurrent sending. One option is to wrap the `WebSocketSession` with[`ConcurrentWebSocketSessionDecorator`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/web/socket/handler/ConcurrentWebSocketSessionDecorator.html). -#### [](#websocket-server-handshake)4.2.2. WebSocket Handshake #### +#### 4.2.2. WebSocket Handshake [WebFlux](web-reactive.html#webflux-websocket-server-handshake) @@ -9439,7 +9157,7 @@ Both the Java configuration and XML namespace make it possible to configure a cu | |Spring provides a `WebSocketHandlerDecorator` base class that you can use to decorate
a `WebSocketHandler` with additional behavior. Logging and exception handling
implementations are provided and added by default when using the WebSocket Java configuration
or XML namespace. The `ExceptionWebSocketHandlerDecorator` catches all uncaught
exceptions that arise from any `WebSocketHandler` method and closes the WebSocket
session with status `1011`, which indicates a server error.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#websocket-server-deployment)4.2.3. Deployment #### +#### 4.2.3. Deployment The Spring WebSocket API is easy to integrate into a Spring MVC application where the `DispatcherServlet` serves both HTTP WebSocket handshake and other @@ -9500,7 +9218,7 @@ Java initialization API. The following example shows how to do so: ``` -#### [](#websocket-server-runtime-configuration)4.2.4. Server Configuration #### +#### 4.2.4. Server Configuration [WebFlux](web-reactive.html#webflux-websocket-server-config) @@ -9617,7 +9335,7 @@ The following example shows the XML configuration equivalent of the preceding ex ``` -#### [](#websocket-server-allowed-origins)4.2.5. Allowed Origins #### +#### 4.2.5. Allowed Origins [WebFlux](web-reactive.html#webflux-websocket-server-cors) @@ -9685,7 +9403,7 @@ The following example shows the XML configuration equivalent of the preceding ex ``` -### [](#websocket-fallback)4.3. SockJS Fallback ### +### 4.3. SockJS Fallback Over the public Internet, restrictive proxies outside your control may preclude WebSocket interactions, either because they are not configured to pass on the `Upgrade` header or @@ -9698,7 +9416,7 @@ interaction and expose the same application-level API. On the Servlet stack, the Spring Framework provides both server (and also client) support for the SockJS protocol. -#### [](#websocket-fallback-sockjs-overview)4.3.1. Overview #### +#### 4.3.1. Overview The goal of SockJS is to let applications use a WebSocket API but fall back to non-WebSocket alternatives when necessary at runtime, without the need to @@ -9757,7 +9475,7 @@ see each transport one at a time. The SockJS client also provides a debug flag, which enables helpful messages in the browser console. On the server side, you can enable`TRACE` logging for `org.springframework.web.socket`. For even more detail, see the SockJS protocol[narrated test](https://sockjs.github.io/sockjs-protocol/sockjs-protocol-0.3.3.html). -#### [](#websocket-fallback-sockjs-enable)4.3.2. Enabling SockJS #### +#### 4.3.2. Enabling SockJS You can enable SockJS through Java configuration, as the following example shows: @@ -9812,7 +9530,7 @@ transport option, depending on the browser in which it runs. See the[sockjs-clie transport types supported by browser. The client also provides several configuration options — for example, to specify which transports to include. -#### [](#websocket-fallback-xhr-vs-iframe)4.3.3. IE 8 and 9 #### +#### 4.3.3. IE 8 and 9 Internet Explorer 8 and 9 remain in use. They are a key reason for having SockJS. This section covers important @@ -9871,7 +9589,7 @@ The XML namespace provides a similar option through the `` ele | |During initial development, do enable the SockJS client `devel` mode that prevents
the browser from caching SockJS requests (like the iframe) that would otherwise
be cached. For details on how to enable it see the[SockJS client](https://github.com/sockjs/sockjs-client/) page.| |---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#websocket-fallback-sockjs-heartbeat)4.3.4. Heartbeats #### +#### 4.3.4. Heartbeats The SockJS protocol requires servers to send heartbeat messages to preclude proxies from concluding that a connection is hung. The Spring SockJS configuration has a property @@ -9887,7 +9605,7 @@ schedule heartbeats tasks. The task scheduler is backed by a thread pool, with default settings based on the number of available processors. Your should consider customizing the settings according to your specific needs. -#### [](#websocket-fallback-sockjs-servlet3-async)4.3.5. Client Disconnects #### +#### 4.3.5. Client Disconnects HTTP streaming and HTTP long polling SockJS transports require a connection to remain open longer than usual. For an overview of these techniques, see[this blog post](https://spring.io/blog/2012/05/08/spring-mvc-3-2-preview-techniques-for-real-time-updates/). @@ -9906,7 +9624,7 @@ time period (or earlier, if messages are sent more frequently). | |As a result, network I/O failures can occur because a client has disconnected, which
can fill the log with unnecessary stack traces. Spring makes a best effort to identify
such network failures that represent client disconnects (specific to each server) and log
a minimal message by using the dedicated log category, `DISCONNECTED_CLIENT_LOG_CATEGORY`(defined in `AbstractSockJsSession`). If you need to see the stack traces, you can set that
log category to TRACE.| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#websocket-fallback-cors)4.3.6. SockJS and CORS #### +#### 4.3.6. SockJS and CORS If you allow cross-origin requests (see [Allowed Origins](#websocket-server-allowed-origins)), the SockJS protocol uses CORS for cross-domain support in the XHR streaming and polling transports. Therefore, @@ -9934,7 +9652,7 @@ the `TransportType` enum in the source code. Alternatively, if the CORS configuration allows it, consider excluding URLs with the SockJS endpoint prefix, thus letting Spring’s `SockJsService` handle it. -#### [](#websocket-fallback-sockjs-client)4.3.7. `SockJsClient` #### +#### 4.3.7. `SockJsClient` Spring provides a SockJS Java client to connect to remote SockJS endpoints without using a browser. This can be especially useful when there is a need for bidirectional @@ -10008,7 +9726,7 @@ public class WebSocketConfig extends WebSocketMessageBrokerConfigurationSupport |**2**| Set the `httpMessageCacheSize` property to 1,000 (the default is `100`). | |**3**|Set the `disconnectDelay` property to 30 property seconds (the default is five seconds — `5 * 1000`).| -### [](#websocket-stomp)4.4. STOMP ### +### 4.4. STOMP The WebSocket protocol defines two types of messages (text and binary), but their content is undefined. The protocol defines a mechanism for client and server to negotiate a @@ -10017,7 +9735,7 @@ define what kind of messages each can send, what the format is, the content of e message, and so on. The use of a sub-protocol is optional but, either way, the client and the server need to agree on some protocol that defines message content. -#### [](#websocket-stomp-overview)4.4.1. Overview #### +#### 4.4.1. Overview [STOMP](https://stomp.github.io/stomp-specification-1.2.html#Abstract) (Simple Text Oriented Messaging Protocol) was originally created for scripting languages @@ -10109,7 +9827,7 @@ client subscription. The preceding overview is intended to provide the most basic understanding of the STOMP protocol. We recommended reviewing the protocol[specification](https://stomp.github.io/stomp-specification-1.2.html) in full. -#### [](#websocket-stomp-benefits)4.4.2. Benefits #### +#### 4.4.2. Benefits Using STOMP as a sub-protocol lets the Spring Framework and Spring Security provide a richer programming model versus using raw WebSockets. The same point can be @@ -10129,7 +9847,7 @@ provide rich functionality. The following is a list of benefits: * You can use Spring Security to secure messages based on STOMP destinations and message types. -#### [](#websocket-stomp-enable)4.4.3. Enable STOMP #### +#### 4.4.3. Enable STOMP STOMP over WebSocket support is available in the `spring-messaging` and`spring-websocket` modules. Once you have those dependencies, you can expose a STOMP endpoints, over WebSocket with [SockJS Fallback](#websocket-fallback), as the following example shows: @@ -10221,7 +9939,7 @@ For more example code see: * [Stock Portfolio](https://github.com/rstoyanchev/spring-websocket-portfolio) — a sample application. -#### [](#websocket-stomp-server-config)4.4.4. WebSocket Server #### +#### 4.4.4. WebSocket Server To configure the underlying WebSocket server, the information in[Server Configuration](#websocket-server-runtime-configuration) applies. For Jetty, however you need to set the `HandshakeHandler` and `WebSocketPolicy` through the `StompEndpointRegistry`: @@ -10249,7 +9967,7 @@ public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { } ``` -#### [](#websocket-stomp-message-flow)4.4.5. Flow of Messages #### +#### 4.4.5. Flow of Messages Once a STOMP endpoint is exposed, the Spring application becomes a STOMP broker for connected clients. This section describes the flow of messages on the server side. @@ -10362,7 +10080,7 @@ The preceding example supports the following flow: The next section provides more details on annotated methods, including the kinds of arguments and return values that are supported. -#### [](#websocket-stomp-handle-annotations)4.4.6. Annotated Controllers #### +#### 4.4.6. Annotated Controllers Applications can use annotated `@Controller` classes to handle messages from clients. Such classes can declare `@MessageMapping`, `@SubscribeMapping`, and `@ExceptionHandler`methods, as described in the following topics: @@ -10373,7 +10091,7 @@ Such classes can declare `@MessageMapping`, `@SubscribeMapping`, and `@Exception * [`@MessageExceptionHandler`](#websocket-stomp-exception-handler) -##### [](#websocket-stomp-message-mapping)`@MessageMapping` ##### +##### `@MessageMapping` You can use `@MessageMapping` to annotate methods that route messages based on their destination. It is supported at the method level as well as at the type level. At the type @@ -10385,7 +10103,7 @@ including support for template variables (for example, `/thing/{id}`). The value referenced through `@DestinationVariable` method arguments. Applications can also switch to a dot-separated destination convention for mappings, as explained in[Dots as Separators](#websocket-stomp-destination-separator). -###### [](#supported-method-arguments)Supported Method Arguments ###### +###### Supported Method Arguments The following table describes the method arguments: @@ -10400,7 +10118,7 @@ The following table describes the method arguments: | `@DestinationVariable` | For access to template variables extracted from the message destination.
Values are converted to the declared method argument type as necessary. | | `java.security.Principal` | Reflects the user logged in at the time of the WebSocket HTTP handshake. | -###### [](#return-values)Return Values ###### +###### Return Values By default, the return value from a `@MessageMapping` method is serialized to a payload through a matching `MessageConverter` and sent as a `Message` to the `brokerChannel`, @@ -10423,7 +10141,7 @@ Note that `@SendTo` and `@SendToUser` are merely a convenience that amounts to u This can be done instead of, or possibly in addition to, returning a value. See [Sending Messages](#websocket-stomp-handle-send). -##### [](#websocket-stomp-subscribe-mapping)`@SubscribeMapping` ##### +##### `@SubscribeMapping` `@SubscribeMapping` is similar to `@MessageMapping` but narrows the mapping to subscription messages only. It supports the same[method arguments](#websocket-stomp-message-mapping) as `@MessageMapping`. However @@ -10464,7 +10182,7 @@ stompSession.subscribe(headers, handler).addReceiptTask(() -> { A server side option is [to register](#websocket-stomp-interceptors) an`ExecutorChannelInterceptor` on the `brokerChannel` and implement the `afterMessageHandled`method that is invoked after messages, including subscriptions, have been handled. -##### [](#websocket-stomp-exception-handler)`@MessageExceptionHandler` ##### +##### `@MessageExceptionHandler` An application can use `@MessageExceptionHandler` methods to handle exceptions from`@MessageMapping` methods. You can declare exceptions in the annotation itself or through a method argument if you want to get access to the exception instance. @@ -10491,7 +10209,7 @@ Typically, `@MessageExceptionHandler` methods apply within the `@Controller` cla (or class hierarchy) in which they are declared. If you want such methods to apply more globally (across controllers), you can declare them in a class marked with`@ControllerAdvice`. This is comparable to the[similar support](#mvc-ann-controller-advice) available in Spring MVC. -#### [](#websocket-stomp-handle-send)4.4.7. Sending Messages #### +#### 4.4.7. Sending Messages What if you want to send messages to connected clients from any part of the application? Any application component can send messages to the `brokerChannel`. @@ -10522,7 +10240,7 @@ public class GreetingController { However, you can also qualify it by its name (`brokerMessagingTemplate`), if another bean of the same type exists. -#### [](#websocket-stomp-handle-simple-broker)4.4.8. Simple Broker #### +#### 4.4.8. Simple Broker The built-in simple message broker handles subscription requests from clients, stores them in memory, and broadcasts messages to connected clients that have matching @@ -10561,7 +10279,7 @@ public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { } ``` -#### [](#websocket-stomp-handle-broker-relay)4.4.9. External Broker #### +#### 4.4.9. External Broker The simple broker is great for getting started but supports only a subset of STOMP commands (it does not support acks, receipts, and some other features), @@ -10631,7 +10349,7 @@ in [Sending Messages](#websocket-stomp-handle-send), to broadcast messages to su In effect, the broker relay enables robust and scalable message broadcasting. -#### [](#websocket-stomp-handle-broker-relay-configure)4.4.10. Connecting to a Broker #### +#### 4.4.10. Connecting to a Broker A STOMP broker relay maintains a single “system” TCP connection to the broker. This connection is used for messages originating from the server-side application @@ -10690,7 +10408,7 @@ and can be useful (for example, in a cloud environment where the actual host to the TCP connection is established differs from the host that provides the cloud-based STOMP service). -#### [](#websocket-stomp-destination-separator)4.4.11. Dots as Separators #### +#### 4.4.11. Dots as Separators When messages are routed to `@MessageMapping` methods, they are matched with`AntPathMatcher`. By default, patterns are expected to use slash (`/`) as the separator. This is a good convention in web applications and similar to HTTP URLs. However, if @@ -10763,7 +10481,7 @@ The “simple broker”, on the other hand, does rely on the configured `PathMat you switch the separator, that change also applies to the broker and the way the broker matches destinations from a message to patterns in subscriptions. -#### [](#websocket-stomp-authentication)4.4.12. Authentication #### +#### 4.4.12. Authentication Every STOMP over WebSocket messaging session begins with an HTTP request. That can be a request to upgrade to WebSockets (that is, a WebSocket handshake) @@ -10793,7 +10511,7 @@ over WebSocket, by default, Spring ignores authentication headers at the STOMP p level, and assumes that the user is already authenticated at the HTTP transport level. The expectation is that the WebSocket or SockJS session contain the authenticated user. -#### [](#websocket-stomp-authentication-token-based)4.4.13. Token Authentication #### +#### 4.4.13. Token Authentication [Spring Security OAuth](https://github.com/spring-projects/spring-security-oauth)provides support for token based security, including JSON Web Token (JWT). You can use this as the authentication mechanism in Web applications, @@ -10859,12 +10577,12 @@ you need to ensure that the authentication `ChannelInterceptor` config is ordere ahead of Spring Security’s. This is best done by declaring the custom interceptor in its own implementation of `WebSocketMessageBrokerConfigurer` that is marked with`@Order(Ordered.HIGHEST_PRECEDENCE + 99)`. -#### [](#websocket-stomp-authorization)4.4.14. Authorization #### +#### 4.4.14. Authorization Spring Security provides[WebSocket sub-protocol authorization](https://docs.spring.io/spring-security/reference/servlet/integrations/websocket.html#websocket-authorization)that uses a `ChannelInterceptor` to authorize messages based on the user header in them. Also, Spring Session provides[WebSocket integration](https://docs.spring.io/spring-session/reference/web-socket.html)that ensures the user’s HTTP session does not expire while the WebSocket session is still active. -#### [](#websocket-stomp-user-destination)4.4.15. User Destinations #### +#### 4.4.15. User Destinations An application can send messages that target a specific user, and Spring’s STOMP support recognizes destinations prefixed with `/user/` for this purpose. @@ -10961,7 +10679,7 @@ destination to broadcast unresolved messages so that other servers have a chance This can be done through the `userDestinationBroadcast` property of the`MessageBrokerRegistry` in Java configuration and the `user-destination-broadcast` attribute of the `message-broker` element in XML. -#### [](#websocket-stomp-ordered-messages)4.4.16. Order of Messages #### +#### 4.4.16. Order of Messages Messages from the broker are published to the `clientOutboundChannel`, from where they are written to WebSocket sessions. As the channel is backed by a `ThreadPoolExecutor`, messages @@ -11006,7 +10724,7 @@ The following example shows the XML configuration equivalent of the preceding ex When the flag is set, messages within the same client session are published to the`clientOutboundChannel` one at a time, so that the order of publication is guaranteed. Note that this incurs a small performance overhead, so you should enable it only if it is required. -#### [](#websocket-stomp-appplication-context-events)4.4.17. Events #### +#### 4.4.17. Events Several `ApplicationContext` events are published and can be received by implementing Spring’s `ApplicationListener` interface: @@ -11043,7 +10761,7 @@ received by implementing Spring’s `ApplicationListener` interface: | |When you use a full-featured broker, the STOMP “broker relay” automatically reconnects the
“system” connection if broker becomes temporarily unavailable. Client connections,
however, are not automatically reconnected. Assuming heartbeats are enabled, the client
typically notices the broker is not responding within 10 seconds. Clients need to
implement their own reconnecting logic.| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#websocket-stomp-interceptors)4.4.18. Interception #### +#### 4.4.18. Interception [Events](#websocket-stomp-appplication-context-events) provide notifications for the lifecycle of a STOMP connection but not for every client message. Applications can also register a`ChannelInterceptor` to intercept any message and in any part of the processing chain. @@ -11086,7 +10804,7 @@ the WebSocket session is closed. In some cases, an interceptor may intercept thi message more than once for each session. Components should be idempotent with regard to multiple disconnect events. -#### [](#websocket-stomp-client)4.4.19. STOMP Client #### +#### 4.4.19. STOMP Client Spring provides a STOMP over WebSocket client and a STOMP over TCP client. @@ -11177,7 +10895,7 @@ it handle ERROR frames in addition to the `handleException` callback for exceptions from the handling of messages and `handleTransportError` for transport-level errors including `ConnectionLostException`. -#### [](#websocket-stomp-websocket-scope)4.4.20. WebSocket Scope #### +#### 4.4.20. WebSocket Scope Each WebSocket session has a map of attributes. The map is attached as a header to inbound client messages and may be accessed from a controller method, as the following example shows: @@ -11241,7 +10959,7 @@ session attributes. The same instance is subsequently returned until the session ends. WebSocket-scoped beans have all Spring lifecycle methods invoked, as shown in the preceding examples. -#### [](#websocket-stomp-configuration-performance)4.4.21. Performance #### +#### 4.4.21. Performance There is no silver bullet when it comes to performance. Many factors affect it, including the size and volume of messages, whether application @@ -11380,7 +11098,7 @@ instance connects to the broker, and messages broadcast from one application instance can be broadcast through the broker to WebSocket clients connected through any other application instances. -#### [](#websocket-stomp-stats)4.4.22. Monitoring #### +#### 4.4.22. Monitoring When you use `@EnableWebSocketMessageBroker` or ``, key infrastructure components automatically gather statisticss and counters that provide @@ -11468,7 +11186,7 @@ Statistics from the thread pool of the SockJS task scheduler that is used to send heartbeats. Note that, when heartbeats are negotiated on the STOMP level, the SockJS heartbeats are disabled. -#### [](#websocket-stomp-testing)4.4.23. Testing #### +#### 4.4.23. Testing There are two main approaches to testing applications when you use Spring’s STOMP-over-WebSocket support. The first is to write server-side tests to verify the functionality @@ -11506,8 +11224,7 @@ that sends WebSocket messages containing STOMP frames. The [tests for the stock portfolio](https://github.com/rstoyanchev/spring-websocket-portfolio/tree/master/src/test/java/org/springframework/samples/portfolio/web)sample application also demonstrate this approach by using Tomcat as the embedded WebSocket server and a simple STOMP client for test purposes. -[](#web-integration)5. Other Web Frameworks ----------- +## 5. Other Web Frameworks This chapter details Spring’s integration with third-party web frameworks. @@ -11519,7 +11236,7 @@ arguably most evident in the web area, where Spring provides its own web framewo ([Spring MVC](#mvc) and [Spring WebFlux](webflux.html#webflux)) while, at the same time, supporting integration with a number of popular third-party web frameworks. -### [](#web-integration-common)5.1. Common Configuration ### +### 5.1. Common Configuration Before diving into the integration specifics of each supported web framework, let us first take a look at common Spring configuration that is not specific to any one web @@ -11583,7 +11300,7 @@ Not only do they make it easy to get beans from a Spring container, but they als use dependency injection on their controllers. Each web framework section has more detail on its specific integration strategies. -### [](#jsf)5.2. JSF ### +### 5.2. JSF JavaServer Faces (JSF) is the JCP’s standard component-based, event-driven web user interface framework. It is an official part of the Java EE umbrella but also @@ -11596,7 +11313,7 @@ exists for migration purposes when modernizing older JSF-based applications. The key element in Spring’s JSF integration is the JSF `ELResolver` mechanism. -#### [](#jsf-springbeanfaceselresolver)5.2.1. Spring Bean Resolver #### +#### 5.2.1. Spring Bean Resolver `SpringBeanFacesELResolver` is a JSF compliant `ELResolver` implementation, integrating with the standard Unified EL as used by JSF and JSP. It delegates to @@ -11614,7 +11331,7 @@ Configuration-wise, you can define `SpringBeanFacesELResolver` in your JSF`faces ``` -#### [](#jsf-facescontextutils)5.2.2. Using `FacesContextUtils` #### +#### 5.2.2. Using `FacesContextUtils` A custom `ELResolver` works well when mapping your properties to beans in`faces-config.xml`, but, at times, you may need to explicitly grab a bean. The [`FacesContextUtils`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/web/jsf/FacesContextUtils.html)class makes this easy. It is similar to `WebApplicationContextUtils`, except that @@ -11626,7 +11343,7 @@ The following example shows how to use `FacesContextUtils`: ApplicationContext ctx = FacesContextUtils.getWebApplicationContext(FacesContext.getCurrentInstance()); ``` -### [](#struts)5.3. Apache Struts 2.x ### +### 5.3. Apache Struts 2.x Invented by Craig McClanahan, [Struts](https://struts.apache.org) is an open-source project hosted by the Apache Software Foundation. At the time, it greatly simplified the @@ -11638,7 +11355,7 @@ Java web developers. As a successor to the original Struts 1.x, check out Struts 2.x and the Struts-provided[Spring Plugin](https://struts.apache.org/release/2.3.x/docs/spring-plugin.html) for the built-in Spring integration. -### [](#tapestry)5.4. Apache Tapestry 5.x ### +### 5.4. Apache Tapestry 5.x [Tapestry](https://tapestry.apache.org/) is a ""Component oriented framework for creating dynamic, robust, highly scalable web applications in Java."" @@ -11649,7 +11366,7 @@ for the web user interface and the Spring container for the lower layers. For more information, see Tapestry’s dedicated[integration module for Spring](https://tapestry.apache.org/integrating-with-spring-framework.html). -### [](#web-integration-resources)5.5. Further Resources ### +### 5.5. Further Resources The following links go to further resources about the various web frameworks described in this chapter. -- GitLab