Browse Source

Refine documentation to prefer Java configuration over XML.

Closes #2666
pull/2696/head
Mark Paluch 3 years ago
parent
commit
1d7fc40068
No known key found for this signature in database
GPG Key ID: 4406B84C1661DCD1
  1. 197
      src/main/asciidoc/repositories.adoc
  2. 2
      src/main/asciidoc/repository-namespace-reference.adoc
  3. 2
      src/main/asciidoc/repository-populator-namespace-reference.adoc

197
src/main/asciidoc/repositories.adoc

@ -1,6 +1,10 @@ @@ -1,6 +1,10 @@
:spring-framework-docs: https://docs.spring.io/spring-framework/docs/{springVersion}/reference/html
:spring-framework-javadoc: https://docs.spring.io/spring/docs/{springVersion}/javadoc-api
ifndef::store[]
:store: Jpa
endif::[]
[[repositories]]
= Working with Spring Data Repositories
@ -14,7 +18,7 @@ This chapter explains the core concepts and interfaces of Spring Data repositori @@ -14,7 +18,7 @@ This chapter explains the core concepts and interfaces of Spring Data repositori
The information in this chapter is pulled from the Spring Data Commons module.
It uses the configuration and code samples for the Jakarta Persistence API (JPA) module.
ifeval::[{include-xml-namespaces} != false]
You should adapt the XML namespace declaration and the types to be extended to the equivalents of the particular module that you use. "`<<repositories.namespace-reference>>`" covers XML configuration, which is supported across all Spring Data modules that support the repository API.
If you want to use XML configuration you should adapt the XML namespace declaration and the types to be extended to the equivalents of the particular module that you use. "`<<repositories.namespace-reference>>`" covers XML configuration, which is supported across all Spring Data modules that support the repository API.
endif::[]
"`<<repository-query-keywords>>`" covers the query method keywords supported by the repository abstraction in general.
For detailed information on the specific features of your module, see the chapter on that module of this document.
@ -144,24 +148,20 @@ interface PersonRepository extends Repository<Person, Long> { @@ -144,24 +148,20 @@ interface PersonRepository extends Repository<Person, Long> {
====
. Set up Spring to create proxy instances for those interfaces, either with <<repositories.create-instances.java-config,JavaConfig>> or with <<repositories.create-instances,XML configuration>>.
.. To use Java configuration, create a class similar to the following:
+
====
[source,java]
.Java
[source,java,subs="attributes,specialchars",role="primary"]
----
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.data.….repository.config.Enable{store}Repositories;
@EnableJpaRepositories
@Enable{store}Repositories
class Config { … }
----
====
ifeval::[{include-xml-namespaces} != false]
.. To use XML configuration, define a bean similar to the following:
+
====
[source,xml]
.XML
[source,xml,role="secondary"]
----
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
@ -172,19 +172,21 @@ ifeval::[{include-xml-namespaces} != false] @@ -172,19 +172,21 @@ ifeval::[{include-xml-namespaces} != false]
http://www.springframework.org/schema/data/jpa
https://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
<jpa:repositories base-package="com.acme.repositories"/>
<repositories base-package="com.acme.repositories"/>
</beans>
----
endif::[]
====
+
ifeval::[{include-xml-namespaces} != false]
The JPA namespace is used in this example.
If you use the repository abstraction for any other store, you need to change this to the appropriate namespace declaration of your store module.
In other words, you should exchange `jpa` in favor of, for example, `mongodb`.
endif::[]
+
Note that the JavaConfig variant does not configure a package explicitly, because the package of the annotated class is used by default.
To customize the package to scan, use one of the `basePackage…` attributes of the data-store-specific repository's `@Enable${store}Repositories`-annotation.
To customize the package to scan, use one of the `basePackage…` attributes of the data-store-specific repository's `@Enable{store}Repositories`-annotation.
. Inject the repository instance and use it, as shown in the following example:
+
====
@ -372,7 +374,7 @@ However, Spring Data can then no longer determine a unique module with which to @@ -372,7 +374,7 @@ However, Spring Data can then no longer determine a unique module with which to
The last way to distinguish repositories is by scoping repository base packages.
Base packages define the starting points for scanning for repository interface definitions, which implies having repository definitions located in the appropriate packages.
By default, annotation-driven configuration uses the package of the configuration class.
The <<repositories.create-instances.spring,base package in XML-based configuration>> is mandatory.
The <<repositories.create-instances.xml,base package in XML-based configuration>> is mandatory.
The following example shows annotation-driven configuration of base packages:
@ -405,7 +407,7 @@ The following strategies are available for the repository infrastructure to reso @@ -405,7 +407,7 @@ The following strategies are available for the repository infrastructure to reso
ifeval::[{include-xml-namespaces} != false]
With XML configuration, you can configure the strategy at the namespace through the `query-lookup-strategy` attribute.
endif::[]
For Java configuration, you can use the `queryLookupStrategy` attribute of the `Enable${store}Repositories` annotation.
For Java configuration, you can use the `queryLookupStrategy` attribute of the `Enable{store}Repositories` annotation.
Some strategies may not be supported for particular datastores.
- `CREATE` attempts to construct a store-specific query from the query method name.
@ -882,12 +884,36 @@ CompletableFuture<User> findOneByFirstname(String firstname); <2> @@ -882,12 +884,36 @@ CompletableFuture<User> findOneByFirstname(String firstname); <2>
== Creating Repository Instances
This section covers how to create instances and bean definitions for the defined repository interfaces.
ifeval::[{include-xml-namespaces} != false]
One way to do so is by using the Spring namespace that is shipped with each Spring Data module that supports the repository mechanism, although we generally recommend using Java configuration.
endif::[]
[[repositories.create-instances.spring]]
[[repositories.create-instances.java-config]]
=== Java Configuration
Use the store-specific `@Enable{store}Repositories` annotation on a Java configuration class to define a configuration for repository activation.
For an introduction to Java-based configuration of the Spring container, see {spring-framework-docs}/core.html#beans-java[JavaConfig in the Spring reference documentation].
A sample configuration to enable Spring Data repositories resembles the following:
.Sample annotation-based repository configuration
====
[source,java]
----
@Configuration
@EnableJpaRepositories("com.acme.repositories")
class ApplicationConfiguration {
@Bean
EntityManagerFactory entityManagerFactory() {
// …
}
}
----
====
NOTE: The preceding example uses the JPA-specific annotation, which you would change according to the store module you actually use. The same applies to the definition of the `EntityManagerFactory` bean. See the sections covering the store-specific configuration.
ifeval::[{include-xml-namespaces} != false]
[[repositories.create-instances.spring]]
[[repositories.create-instances.xml]]
=== XML Configuration
Each Spring Data module includes a `repositories` element that lets you define a base package that Spring scans for you, as shown in the following example:
@ -905,7 +931,7 @@ Each Spring Data module includes a `repositories` element that lets you define a @@ -905,7 +931,7 @@ Each Spring Data module includes a `repositories` element that lets you define a
http://www.springframework.org/schema/data/jpa
https://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
<repositories base-package="com.acme.repositories" />
<jpa:repositories base-package="com.acme.repositories" />
</beans:beans>
----
@ -915,45 +941,29 @@ In the preceding example, Spring is instructed to scan `com.acme.repositories` a @@ -915,45 +941,29 @@ In the preceding example, Spring is instructed to scan `com.acme.repositories` a
For each interface found, the infrastructure registers the persistence technology-specific `FactoryBean` to create the appropriate proxies that handle invocations of the query methods.
Each bean is registered under a bean name that is derived from the interface name, so an interface of `UserRepository` would be registered under `userRepository`.
Bean names for nested repository interfaces are prefixed with their enclosing type name.
The `base-package` attribute allows wildcards so that you can define a pattern of scanned packages.
The base package attribute allows wildcards so that you can define a pattern of scanned packages.
endif::[]
[[repositories.using-filters]]
==== Using Filters
=== Using Filters
By default, the infrastructure picks up every interface that extends the persistence technology-specific `Repository` sub-interface located under the configured base package and creates a bean instance for it.
However, you might want more fine-grained control over which interfaces have bean instances created for them.
To do so, use `<include-filter />` and `<exclude-filter />` elements inside the `<repositories />` element.
The semantics are exactly equivalent to the elements in Spring's context namespace.
To do so, use filter elements inside the repository declaration.
The semantics are exactly equivalent to the elements in Spring's component filters.
For details, see the {spring-framework-docs}/core.html#beans-scanning-filters[Spring reference documentation] for these elements.
For example, to exclude certain interfaces from instantiation as repository beans, you could use the following configuration:
.Using exclude-filter element
.Using filters
====
[source,xml]
----
<repositories base-package="com.acme.repositories">
<context:exclude-filter type="regex" expression=".*SomeRepository" />
</repositories>
----
====
The preceding example excludes all interfaces ending in `SomeRepository` from being instantiated.
endif::[]
[[repositories.create-instances.java-config]]
=== Java Configuration
You can also trigger the repository infrastructure by using a store-specific `@Enable${store}Repositories` annotation on a Java configuration class. For an introduction to Java-based configuration of the Spring container, see {spring-framework-docs}/core.html#beans-java[JavaConfig in the Spring reference documentation].
A sample configuration to enable Spring Data repositories resembles the following:
.Sample annotation-based repository configuration
====
[source,java]
.Java
[source,java,subs="attributes,specialchars",role="primary"]
----
@Configuration
@EnableJpaRepositories("com.acme.repositories")
@Enable{store}Repositories(basePackages = "com.acme.repositories",
includeFilters = { @Filter(type = FilterType.REGEX, pattern = ".*SomeRepository") },
excludeFilters = { @Filter(type = FilterType.REGEX, pattern = ".*SomeOtherRepository") })
class ApplicationConfiguration {
@Bean
@ -962,9 +972,21 @@ class ApplicationConfiguration { @@ -962,9 +972,21 @@ class ApplicationConfiguration {
}
}
----
ifeval::[{include-xml-namespaces} != false]
.XML
[source,xml,role="secondary"]
----
<repositories base-package="com.acme.repositories">
<context:exclude-filter type="regex" expression=".*SomeRepository" />
<context:include-filter type="regex" expression=".*SomeOtherRepository" />
</repositories>
----
endif::[]
====
NOTE: The preceding example uses the JPA-specific annotation, which you would change according to the store module you actually use. The same applies to the definition of the `EntityManagerFactory` bean. See the sections covering the store-specific configuration.
The preceding example excludes all interfaces ending in `SomeRepository` from being instantiated and includes those ending with `SomeOtherRepository`.
[[repositories.create-instances.standalone]]
=== Standalone Usage
@ -1133,24 +1155,28 @@ interface PersonRepository extends CrudRepository<Person, Long>, CustomizedSave< @@ -1133,24 +1155,28 @@ interface PersonRepository extends CrudRepository<Person, Long>, CustomizedSave<
==== Configuration
The repository infrastructure tries to autodetect custom implementation fragments by scanning for classes below the package in which it found a repository.
These classes need to follow the naming convention of appending
ifeval::[{include-xml-namespaces} != false]
the namespace element's `repository-impl-postfix` attribute to the fragment interface name.
This postfix defaults to `Impl`.
endif::[]
ifeval::[{include-xml-namespaces} == false]
`Impl` to the fragment interface name.
endif::[]
These classes need to follow the naming convention of appending a postfix defaulting to `Impl`.
The following example shows a repository that uses the default postfix and a repository that sets a custom value for the postfix:
.Configuration example
====
[source,xml]
.Java
[source,java,subs="attributes,specialchars",role="primary"]
----
@Enable{store}Repositories(repositoryImplementationPostfix = "MyPostfix")
class Configuration { … }
----
ifeval::[{include-xml-namespaces} != false]
.XML
[source,xml,role="secondary"]
----
<repositories base-package="com.acme.repository" />
<repositories base-package="com.acme.repository" repository-impl-postfix="MyPostfix" />
----
endif::[]
====
The first configuration in the preceding example tries to look up a class called `com.acme.repository.CustomizedUserRepositoryImpl` to act as a custom repository implementation.
@ -1200,7 +1226,20 @@ The following example shows how to manually wire a custom implementation: @@ -1200,7 +1226,20 @@ The following example shows how to manually wire a custom implementation:
.Manual wiring of custom implementations
====
[source,xml]
.Java
[source,java,role="primary"]
----
class MyClass {
MyClass(@Qualifier("userRepositoryImpl") UserRepository userRepository) {
}
}
----
ifeval::[{include-xml-namespaces} != false]
.XML
[source,xml,role="secondary"]
----
<repositories base-package="com.acme.repository" />
@ -1208,6 +1247,8 @@ The following example shows how to manually wire a custom implementation: @@ -1208,6 +1247,8 @@ The following example shows how to manually wire a custom implementation:
<!-- further configuration -->
</beans:bean>
----
endif::[]
====
[[repositories.customize-base-repository]]
@ -1246,30 +1287,27 @@ CAUTION: The class needs to have a constructor of the super class which the stor @@ -1246,30 +1287,27 @@ CAUTION: The class needs to have a constructor of the super class which the stor
If the repository base class has multiple constructors, override the one taking an `EntityInformation` plus a store specific infrastructure object (such as an `EntityManager` or a template class).
The final step is to make the Spring Data infrastructure aware of the customized repository base class.
In Java configuration, you can do so by using the `repositoryBaseClass` attribute of the `@Enable${store}Repositories` annotation, as shown in the following example:
In configuration, you can do so by using the `repositoryBaseClass`, as shown in the following example:
.Configuring a custom repository base class using JavaConfig
.Configuring a custom repository base class
====
[source,java]
.Java
[source,java,subs="attributes,specialchars",role="primary"]
----
@Configuration
@EnableJpaRepositories(repositoryBaseClass = MyRepositoryImpl.class)
@Enable{store}Repositories(repositoryBaseClass = MyRepositoryImpl.class)
class ApplicationConfiguration { … }
----
====
ifeval::[{include-xml-namespaces} != false]
A corresponding attribute is available in the XML namespace, as shown in the following example:
.Configuring a custom repository base class using XML
====
[source,xml]
.XML
[source,xml,role="secondary"]
----
<repositories base-package="com.acme.repository"
base-class="….MyRepositoryImpl" />
----
====
endif::[]
====
[[core.domain-events]]
== Publishing Events from Aggregate Roots
@ -1370,24 +1408,17 @@ In general, the integration support is enabled by using the `@EnableSpringDataWe @@ -1370,24 +1408,17 @@ In general, the integration support is enabled by using the `@EnableSpringDataWe
.Enabling Spring Data web support
====
[source,java]
.Java
[source,java,role="primary"]
----
@Configuration
@EnableWebMvc
@EnableSpringDataWebSupport
class WebConfiguration {}
----
====
The `@EnableSpringDataWebSupport` annotation registers a few components.
We discuss those later in this section.
It also detects Spring HATEOAS on the classpath and registers integration components (if present) for it as well.
Alternatively, if you use XML configuration, register either `SpringDataWebConfiguration` or `HateoasAwareSpringDataWebConfiguration` as Spring beans, as the following example shows (for `SpringDataWebConfiguration`):
.Enabling Spring Data web support in XML
====
[source,xml]
.XML
[source,xml,role="secondary"]
----
<bean class="org.springframework.data.web.config.SpringDataWebConfiguration" />
@ -1396,6 +1427,12 @@ Alternatively, if you use XML configuration, register either `SpringDataWebConfi @@ -1396,6 +1427,12 @@ Alternatively, if you use XML configuration, register either `SpringDataWebConfi
----
====
The `@EnableSpringDataWebSupport` annotation registers a few components.
We discuss those later in this section.
It also detects Spring HATEOAS on the classpath and registers integration components (if present) for it as well.
.Enabling Spring Data web support in XML
[[core.web.basic]]
==== Basic Web Support

2
src/main/asciidoc/repository-namespace-reference.adoc

@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
[[populator.namespace-dao-config]]
== The `<repositories />` Element
The `<repositories />` element triggers the setup of the Spring Data repository infrastructure. The most important attribute is `base-package`, which defines the package to scan for Spring Data repository interfaces. See "`<<repositories.create-instances.spring>>`". The following table describes the attributes of the `<repositories />` element:
The `<repositories />` element triggers the setup of the Spring Data repository infrastructure. The most important attribute is `base-package`, which defines the package to scan for Spring Data repository interfaces. See "`<<repositories.create-instances.xml>>`". The following table describes the attributes of the `<repositories />` element:
.Attributes
[options="header", cols="1,3"]

2
src/main/asciidoc/repository-populator-namespace-reference.adoc

@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
[[namespace-dao-config]]
== The <populator /> element
The `<populator />` element allows to populate the a data store via the Spring Data repository infrastructure.footnote:[see <<repositories.create-instances.spring>>]
The `<populator />` element allows to populate a data store via the Spring Data repository infrastructure.footnote:[see <<repositories.create-instances.xml>>]
.Attributes
[options="header", cols="1,3"]

Loading…
Cancel
Save