From 2458478d0a0ee70475b84322f72a2f3adbd52463 Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Tue, 17 May 2022 23:09:37 +0200 Subject: [PATCH] Remove RepositoryMethodReference from RepositoryItemReaderBuilder This class and its usage have been reported to be confusing and causing context startup failures without real added value. This commit removes that class to simplify the creation of a RepositoryItemReader through its builder. Issue #793 --- .../batch/item/data/RepositoryItemReader.java | 8 +- .../builder/RepositoryItemReaderBuilder.java | 107 +----------------- .../item/data/RepositoryItemReaderTests.java | 2 +- .../RepositoryItemReaderBuilderTests.java | 36 ------ 4 files changed, 9 insertions(+), 144 deletions(-) diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/RepositoryItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/RepositoryItemReader.java index d2590a71fd..3aea2a982e 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/RepositoryItemReader.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/RepositoryItemReader.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -72,13 +72,14 @@ * * @author Michael Minella * @author Antoine Kapps + * @author Mahmoud Ben Hassine * @since 2.2 */ public class RepositoryItemReader extends AbstractItemCountingItemStreamItemReader implements InitializingBean { protected Log logger = LogFactory.getLog(getClass()); - private PagingAndSortingRepository repository; + private PagingAndSortingRepository repository; private Sort sort; @@ -130,8 +131,9 @@ public void setPageSize(int pageSize) { * implementation used to read input from. * * @param repository underlying repository for input to be read from. + * @param type of the repositoryt to use to read items */ - public void setRepository(PagingAndSortingRepository repository) { + public > void setRepository(R repository) { this.repository = repository; } diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/RepositoryItemReaderBuilder.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/RepositoryItemReaderBuilder.java index aa9e245fe7..2df47706a5 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/RepositoryItemReaderBuilder.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/RepositoryItemReaderBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2018 the original author or authors. + * Copyright 2017-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,7 +43,7 @@ */ public class RepositoryItemReaderBuilder { - private PagingAndSortingRepository repository; + private PagingAndSortingRepository repository; private Map sorts; @@ -53,8 +53,6 @@ public class RepositoryItemReaderBuilder { private String methodName; - private RepositoryMethodReference repositoryMethodReference; - private boolean saveState = true; private String name; @@ -176,7 +174,7 @@ public RepositoryItemReaderBuilder pageSize(int pageSize) { * @return The current instance of the builder. * @see RepositoryItemReader#setRepository(PagingAndSortingRepository) */ - public RepositoryItemReaderBuilder repository(PagingAndSortingRepository repository) { + public RepositoryItemReaderBuilder repository(PagingAndSortingRepository repository) { this.repository = repository; return this; @@ -196,44 +194,12 @@ public RepositoryItemReaderBuilder methodName(String methodName) { return this; } - /** - * Specifies a repository and the type-safe method to call for the reader. The method - * configured via this mechanism must take - * {@link org.springframework.data.domain.Pageable} as the last - * argument. This method can be used in place of {@link #repository(PagingAndSortingRepository)}, - * {@link #methodName(String)}, and {@link #arguments(List)}. - * - * Note: The repository that is used by the repositoryMethodReference must be - * non-final. - * - * @param repositoryMethodReference of the used to get a repository and type-safe - * method for use by the reader. - * @return The current instance of the builder. - * @see RepositoryItemReader#setMethodName(String) - * @see RepositoryItemReader#setRepository(PagingAndSortingRepository) - * - */ - public RepositoryItemReaderBuilder repository(RepositoryMethodReference repositoryMethodReference) { - this.repositoryMethodReference = repositoryMethodReference; - - return this; - } - /** * Builds the {@link RepositoryItemReader}. * * @return a {@link RepositoryItemReader} */ public RepositoryItemReader build() { - if (this.repositoryMethodReference != null) { - this.methodName = this.repositoryMethodReference.getMethodName(); - this.repository = this.repositoryMethodReference.getRepository(); - - if(CollectionUtils.isEmpty(this.arguments)) { - this.arguments = this.repositoryMethodReference.getArguments(); - } - } - Assert.notNull(this.sorts, "sorts map is required."); Assert.notNull(this.repository, "repository is required."); Assert.hasText(this.methodName, "methodName is required."); @@ -254,71 +220,4 @@ public RepositoryItemReader build() { return reader; } - /** - * Establishes a proxy that will capture a the Repository and the associated - * methodName that will be used by the reader. - * @param The type of repository that will be used by the reader. The class must - * not be final. - */ - public static class RepositoryMethodReference { - private RepositoryMethodInterceptor repositoryInvocationHandler; - - private PagingAndSortingRepository repository; - - public RepositoryMethodReference(PagingAndSortingRepository repository) { - this.repository = repository; - this.repositoryInvocationHandler = new RepositoryMethodInterceptor(); - } - - /** - * The proxy returned prevents actual method execution and is only used to gather, - * information about the method. - * @return T is a proxy of the object passed in in the constructor - */ - @SuppressWarnings("unchecked") - public T methodIs() { - Enhancer enhancer = new Enhancer(); - enhancer.setSuperclass(this.repository.getClass()); - enhancer.setCallback(this.repositoryInvocationHandler); - return (T) enhancer.create(); - } - - PagingAndSortingRepository getRepository() { - return this.repository; - } - - String getMethodName() { - return this.repositoryInvocationHandler.getMethodName(); - } - - List getArguments() { - return this.repositoryInvocationHandler.getArguments(); - } - } - - private static class RepositoryMethodInterceptor implements MethodInterceptor { - private String methodName; - - private List arguments; - - @Override - public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { - this.methodName = method.getName(); - if (objects != null && objects.length > 1) { - arguments = new ArrayList<>(Arrays.asList(objects)); - // remove last entry because that will be provided by the - // RepositoryItemReader - arguments.remove(objects.length - 1); - } - return null; - } - - String getMethodName() { - return this.methodName; - } - - List getArguments() { - return arguments; - } - } } diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/RepositoryItemReaderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/RepositoryItemReaderTests.java index b35698a50c..e52a2f0332 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/RepositoryItemReaderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/RepositoryItemReaderTests.java @@ -367,7 +367,7 @@ public void testResetOfPage() throws Exception { assertEquals("3", reader.read()); } - public interface TestRepository extends PagingAndSortingRepository { + public interface TestRepository extends PagingAndSortingRepository { Page findFirstNames(Pageable pageable); } diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/builder/RepositoryItemReaderBuilderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/builder/RepositoryItemReaderBuilderTests.java index fc825a5233..01f4fa3181 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/builder/RepositoryItemReaderBuilderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/builder/RepositoryItemReaderBuilderTests.java @@ -90,42 +90,6 @@ public void testBasicRead() throws Exception { assertEquals("page size was not expected value.", 10, this.pageRequestContainer.getValue().getPageSize()); } - @Test - public void testRepositoryMethodReference() throws Exception { - RepositoryItemReaderBuilder.RepositoryMethodReference repositoryMethodReference = - new RepositoryItemReaderBuilder.RepositoryMethodReference<>(this.repository); - repositoryMethodReference.methodIs().foo(null); - RepositoryItemReader reader = new RepositoryItemReaderBuilder<>() - .repository(repositoryMethodReference) - .sorts(this.sorts) - .maxItemCount(5) - .name("bar").build(); - String result = (String) reader.read(); - assertEquals("Result returned from reader was not expected value.", TEST_CONTENT, result); - assertEquals("page size was not expected value.", 10, this.pageRequestContainer.getValue().getPageSize()); - } - - @Test - public void testRepositoryMethodReferenceWithArgs() throws Exception { - RepositoryItemReaderBuilder.RepositoryMethodReference repositoryMethodReference = - new RepositoryItemReaderBuilder.RepositoryMethodReference<>(this.repository); - repositoryMethodReference.methodIs().foo(ARG1, ARG2, ARG3, null); - RepositoryItemReader reader = new RepositoryItemReaderBuilder<>() - .repository(repositoryMethodReference) - .sorts(this.sorts) - .maxItemCount(5) - .name("bar").build(); - ArgumentCaptor arg1Captor = ArgumentCaptor.forClass(String.class); - ArgumentCaptor arg2Captor = ArgumentCaptor.forClass(String.class); - ArgumentCaptor arg3Captor = ArgumentCaptor.forClass(String.class); - when(this.repository.foo(arg1Captor.capture(), arg2Captor.capture(), arg3Captor.capture(), - this.pageRequestContainer.capture())).thenReturn(this.page); - - String result = (String) reader.read(); - assertEquals("Result returned from reader was not expected value.", TEST_CONTENT, result); - verifyMultiArgRead(arg1Captor, arg2Captor, arg3Captor, result); - } - @Test public void testCurrentItemCount() throws Exception { RepositoryItemReader reader = new RepositoryItemReaderBuilder<>().repository(this.repository)