Skip to content

Commit c732728

Browse files
committed
Register indirect fragment introduced by super interfaces
Fix spring-projectsGH-3212
1 parent 4718c45 commit c732728

File tree

4 files changed

+83
-2
lines changed

4 files changed

+83
-2
lines changed

src/main/java/org/springframework/data/repository/config/FragmentMetadata.java

+19-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
package org.springframework.data.repository.config;
1717

1818
import java.io.IOException;
19-
import java.util.Arrays;
19+
import java.util.LinkedHashSet;
20+
import java.util.Set;
2021
import java.util.stream.Stream;
2122

2223
import org.springframework.beans.factory.BeanDefinitionStoreException;
@@ -32,6 +33,7 @@
3233
* @author Mark Paluch
3334
* @author Oliver Gierke
3435
* @author Johannes Englmeier
36+
* @author Yanming Zhou
3537
* @since 2.1
3638
*/
3739
public class FragmentMetadata {
@@ -52,10 +54,25 @@ public Stream<String> getFragmentInterfaces(String interfaceName) {
5254

5355
Assert.hasText(interfaceName, "Interface name must not be null or empty");
5456

55-
return Arrays.stream(getClassMetadata(interfaceName).getInterfaceNames()) //
57+
return getAllSuperInterfaces(interfaceName).stream() //
5658
.filter(this::isCandidate);
5759
}
5860

61+
/**
62+
* Returns all super interfaces of the given interface.
63+
*
64+
* @param interfaceName must not be {@literal null} or empty.
65+
* @return
66+
*/
67+
private Set<String> getAllSuperInterfaces(String interfaceName) {
68+
Set<String> interfaces = new LinkedHashSet<>();
69+
for (String ifc : getClassMetadata(interfaceName).getInterfaceNames()) {
70+
interfaces.add(ifc);
71+
interfaces.addAll(getAllSuperInterfaces(ifc));
72+
}
73+
return interfaces;
74+
}
75+
5976
/**
6077
* Returns whether the given interface is a fragment candidate.
6178
*

src/test/java/org/springframework/data/repository/config/RepositoryBeanDefinitionRegistrarSupportUnitTests.java

+16
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
*
4747
* @author Oliver Gierke
4848
* @author Mark Paluch
49+
* @author Yanming Zhou
4950
*/
5051
@ExtendWith(MockitoExtension.class)
5152
class RepositoryBeanDefinitionRegistrarSupportUnitTests {
@@ -124,6 +125,18 @@ void shouldLimitImplementationBasePackages() {
124125
assertBeanDefinitionRegisteredFor("spiContribution");
125126
}
126127

128+
129+
@Test // GH-3212
130+
void shouldRegisterIndirectSpiFragment() {
131+
132+
AnnotationMetadata metadata = new StandardAnnotationMetadata(ExcludedWithSpiFragement.class, true);
133+
134+
registrar.registerBeanDefinitions(metadata, registry);
135+
136+
assertBeanDefinitionRegisteredFor("personRepository");
137+
assertBeanDefinitionRegisteredFor("spiFragmentImplFragment");
138+
}
139+
127140
@Test // DATACMNS-360
128141
void registeredProfileRepositoriesIfProfileActivated() {
129142

@@ -203,6 +216,9 @@ static class FragmentExclusionConfiguration {}
203216
@EnableRepositories(basePackageClasses = FragmentImpl.class)
204217
static class LimitsImplementationBasePackages {}
205218

219+
@EnableRepositories(basePackageClasses = org.springframework.data.repository.config.indirectspifragment.PersonRepository.class)
220+
static class ExcludedWithSpiFragement {}
221+
206222
@EnableRepositories(basePackageClasses = MyNestedRepository.class, considerNestedRepositories = true,
207223
excludeFilters = {
208224
@Filter(type = FilterType.ASSIGNABLE_TYPE,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Copyright 2017-2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.repository.config.indirectspifragment;
17+
18+
import org.springframework.data.mapping.Person;
19+
import org.springframework.data.repository.NoRepositoryBean;
20+
import org.springframework.data.repository.Repository;
21+
import org.springframework.data.repository.config.spifragment.SpiFragment;
22+
23+
/**
24+
* @author Yanming Zhou
25+
*/
26+
@NoRepositoryBean
27+
public interface ExcludedRepository extends Repository<Person, String>, SpiFragment {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
* Copyright 2017-2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.repository.config.indirectspifragment;
17+
18+
/**
19+
* @author Yanming Zhou
20+
*/
21+
public interface PersonRepository extends ExcludedRepository {}

0 commit comments

Comments
 (0)