Update documentation and fix nullable annotations.
Original Pull Request: #3093
This commit is contained in:
@@ -296,14 +296,9 @@ class DefaultSearchExtension<T> implements SearchExtension<T> {
|
||||
----
|
||||
====
|
||||
|
||||
In the snipped above we use `RepositoryMethodMetadata.get()` to get hold of metadata for the actual method invocation. In doing so we can access additional information attached to the repository. In this case we use the repositories domain type to identify the name of the index to be searched.
|
||||
In the snipped above we use `RepositoryMethodContext.currentMethod()` to get hold of metadata for the actual method invocation. In doing so we can access additional information attached to the repository. In this case we use the repositories domain type to identify the name of the index to be searched.
|
||||
|
||||
[TIP]
|
||||
====
|
||||
For testing you can use `TransactionSynchronizationManager.bindResource(RepositoryMethodMetadata.class, metadata)` to provide repository method metadata.
|
||||
====
|
||||
|
||||
Now that we've got both, the fragments declaration and implementation we can register it in the `META-INF/spring.factories` file, package things up if needed and we're good to go.
|
||||
Now that we've got both, the fragments declaration and implementation we can register it in the `META-INF/spring.factories` file, package things up if needed and we're almost good to go.
|
||||
|
||||
====
|
||||
[source,properties]
|
||||
@@ -312,8 +307,41 @@ com.acme.search.SearchExtension=com.acme.search.DefaultSearchExtension
|
||||
----
|
||||
====
|
||||
|
||||
To make use of the extension simply add the interface to the repository as shown below.
|
||||
The infrastructure will take care placing the required `RepositoryMethodContext` so all that
|
||||
Since we're using additional metadata, that comes with additional cost, via `RepositoryMethodContext.currentMethod()` we need to advise the repository factory responsible for creating the actual repository to expose method metadata by setting the `exposeMetadata` flag.
|
||||
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
@Configuration
|
||||
class Cfg implements BeanPostProcessor {
|
||||
|
||||
@Bean
|
||||
public BeanPostProcessor exposeMethodMetadata() {
|
||||
|
||||
return new BeanPostProcessor() {
|
||||
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) {
|
||||
|
||||
if(bean instanceof RepositoryFactoryBeanSupport<?,?,?> factoryBean) {
|
||||
factoryBean.setExposeMetadata(true);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
----
|
||||
The above snippet outlines how to set the `exposeMetadata` flag using a `BeanPostProcessor`.
|
||||
Please do not just copy/paste the above but think about your actual use case which may require a more fine grained approach as the above will simply enable the flag on each and every repository. You may want to have a look at our https://github.com/spring-projects/spring-data-examples/tree/main/bom[spring-data-examples] project to draw inspiration.
|
||||
====
|
||||
|
||||
Now we are ready to make use of the extension.
|
||||
Simply add the interface to the repository.
|
||||
|
||||
====
|
||||
[source,java]
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.springframework.lang.Nullable;
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
* @since 3.4.0
|
||||
*/
|
||||
class DefaultRepositoryMethodContext implements RepositoryMethodContext {
|
||||
|
||||
@@ -39,18 +40,19 @@ class DefaultRepositoryMethodContext implements RepositoryMethodContext {
|
||||
private final RepositoryMetadata repositoryMetadata;
|
||||
private final Method method;
|
||||
|
||||
public DefaultRepositoryMethodContext(RepositoryMetadata repositoryMetadata, Method method) {
|
||||
DefaultRepositoryMethodContext(RepositoryMetadata repositoryMetadata, Method method) {
|
||||
|
||||
this.repositoryMetadata = repositoryMetadata;
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static RepositoryMethodContext getMetadata() {
|
||||
static RepositoryMethodContext getMetadata() {
|
||||
return currentMethod.get();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static RepositoryMethodContext setMetadata(@Nullable RepositoryMethodContext metadata) {
|
||||
static RepositoryMethodContext setMetadata(@Nullable RepositoryMethodContext metadata) {
|
||||
|
||||
RepositoryMethodContext old = currentMethod.get();
|
||||
if (metadata != null) {
|
||||
|
||||
@@ -115,6 +115,8 @@ public abstract class RepositoryFactoryBeanSupport<T extends Repository<S, ID>,
|
||||
* <p>
|
||||
* Default is "false", in order to avoid unnecessary extra interception. This means that no guarantees are provided
|
||||
* that {@code RepositoryMethodContext} access will work consistently within any method of the advised object.
|
||||
*
|
||||
* @since 3.4.0
|
||||
*/
|
||||
public void setExposeMetadata(boolean exposeMetadata) {
|
||||
this.exposeMetadata = exposeMetadata;
|
||||
|
||||
@@ -30,8 +30,6 @@ import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.aop.interceptor.ExposeInvocationInterceptor;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
@@ -129,8 +127,10 @@ public abstract class RepositoryFactorySupport implements BeanClassLoaderAware,
|
||||
* retrieval via the {@code RepositoryMethodContext} class. This is useful if an advised object needs to obtain
|
||||
* repository information.
|
||||
* <p>
|
||||
* Default is "false", in order to avoid unnecessary extra interception. This means that no guarantees are provided
|
||||
* Default is {@literal "false"}, in order to avoid unnecessary extra interception. This means that no guarantees are provided
|
||||
* that {@code RepositoryMethodContext} access will work consistently within any method of the advised object.
|
||||
*
|
||||
* @since 3.4.0
|
||||
*/
|
||||
public void setExposeMetadata(boolean exposeMetadata) {
|
||||
this.exposeMetadata = exposeMetadata;
|
||||
@@ -665,7 +665,8 @@ public abstract class RepositoryFactorySupport implements BeanClassLoaderAware,
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Object invoke(@NotNull MethodInvocation invocation) throws Throwable {
|
||||
public Object invoke(MethodInvocation invocation) throws Throwable {
|
||||
|
||||
RepositoryMethodContext oldMetadata = null;
|
||||
try {
|
||||
oldMetadata = RepositoryMethodContext
|
||||
|
||||
@@ -35,6 +35,7 @@ import org.springframework.lang.Nullable;
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
* @since 3.4.0
|
||||
*/
|
||||
public interface RepositoryMethodContext {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user