Skip to content

Commit 14096f8

Browse files
committed
Support convention based @ImportHttpServices imports
Update `@ImportHttpServices` to support convention based imports when neither types or base packages are specified. This update allows `@ImportHttpServices` to work in a similar way to `@ComponentScan` where the annotation alone is enough to find HTTP interface clients. For example: package com.example; @configuration @ImportHttpServices(group = "test") static class MyConfig { // this config scans for interface clients in `com.example` } See gh-35447
1 parent 7012add commit 14096f8

File tree

5 files changed

+55
-6
lines changed

5 files changed

+55
-6
lines changed

spring-web/src/main/java/org/springframework/web/service/registry/ImportHttpServiceRegistrar.java

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
import org.springframework.core.annotation.MergedAnnotation;
2020
import org.springframework.core.type.AnnotationMetadata;
21+
import org.springframework.util.ClassUtils;
22+
import org.springframework.util.ObjectUtils;
2123

2224
/**
2325
* Built-in implementation of {@link AbstractHttpServiceRegistrar} that uses
@@ -37,23 +39,31 @@ protected void registerHttpServices(GroupRegistry registry, AnnotationMetadata m
3739
MergedAnnotation<?> groupsAnnot = metadata.getAnnotations().get(ImportHttpServices.Container.class);
3840
if (groupsAnnot.isPresent()) {
3941
for (MergedAnnotation<?> annot : groupsAnnot.getAnnotationArray("value", ImportHttpServices.class)) {
40-
processImportAnnotation(annot, registry);
42+
processImportAnnotation(annot, registry, metadata);
4143
}
4244
}
4345

4446
metadata.getAnnotations().stream(ImportHttpServices.class)
45-
.forEach(annot -> processImportAnnotation(annot, registry));
47+
.forEach(annot -> processImportAnnotation(annot, registry, metadata));
4648
}
4749

48-
private void processImportAnnotation(MergedAnnotation<?> annotation, GroupRegistry groupRegistry) {
50+
private void processImportAnnotation(MergedAnnotation<?> annotation, GroupRegistry groupRegistry,
51+
AnnotationMetadata metadata) {
4952

5053
String groupName = annotation.getString("group");
5154
HttpServiceGroup.ClientType clientType = annotation.getEnum("clientType", HttpServiceGroup.ClientType.class);
55+
Class<?>[] types = annotation.getClassArray("types");
56+
Class<?>[] basePackageClasses = annotation.getClassArray("basePackageClasses");
57+
String[] basePackages = annotation.getStringArray("basePackages");
58+
59+
if (ObjectUtils.isEmpty(types) && ObjectUtils.isEmpty(basePackages) && ObjectUtils.isEmpty(basePackageClasses)) {
60+
basePackages = new String[] { ClassUtils.getPackageName(metadata.getClassName()) };
61+
}
5262

5363
groupRegistry.forGroup(groupName, clientType)
54-
.register(annotation.getClassArray("types"))
55-
.detectInBasePackages(annotation.getStringArray("basePackages"))
56-
.detectInBasePackages(annotation.getClassArray("basePackageClasses"));
64+
.register(types)
65+
.detectInBasePackages(basePackageClasses)
66+
.detectInBasePackages(basePackages);
5767
}
5868

5969
}

spring-web/src/main/java/org/springframework/web/service/registry/ImportHttpServices.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@
3939
*
4040
* <p>The HTTP Services for each group can be listed via {@link #types()}, or
4141
* detected via {@link #basePackageClasses()} or {@link #basePackages()}.
42+
* If neither types or base packages are defined, detection will occur recursively
43+
* beginning with the package of the class that declares this annotation.
4244
*
4345
* <p>An application can autowire HTTP Service proxy beans, or autowire the
4446
* {@link HttpServiceProxyRegistry} from which to obtain proxies.

spring-web/src/test/java/org/springframework/web/service/registry/ImportHttpServiceRegistrarTests.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import org.springframework.web.service.registry.HttpServiceGroup.ClientType;
3434
import org.springframework.web.service.registry.echo.EchoA;
3535
import org.springframework.web.service.registry.echo.EchoB;
36+
import org.springframework.web.service.registry.echo.ScanConventionConfig;
3637
import org.springframework.web.service.registry.greeting.GreetingA;
3738
import org.springframework.web.service.registry.greeting.GreetingB;
3839

@@ -83,6 +84,12 @@ void basicScan() {
8384
TestGroup.ofPackageClasses(GREETING_GROUP, GreetingA.class));
8485
}
8586

87+
@Test
88+
void basicScanByConvention() {
89+
doRegister(ScanConventionConfig.class);
90+
assertGroups(TestGroup.ofPackageNames(ECHO_GROUP, ClientType.UNSPECIFIED, EchoA.class.getPackage().getName()));
91+
}
92+
8693
@Test
8794
@CompileWithForkedClassLoader
8895
void basicScanWithAot() {

spring-web/src/test/java/org/springframework/web/service/registry/TestGroup.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,10 @@ public static TestGroup ofPackageClasses(String name, ClientType clientType, Cla
5353
return group;
5454
}
5555

56+
public static TestGroup ofPackageNames(String name, ClientType clientType, String... packageNames) {
57+
TestGroup group = new TestGroup(name, clientType);
58+
group.packageNames().addAll(Arrays.asList(packageNames));
59+
return group;
60+
}
61+
5662
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Copyright 2002-present 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+
17+
package org.springframework.web.service.registry.echo;
18+
19+
import org.springframework.web.service.registry.ImportHttpServices;
20+
21+
@ImportHttpServices(group = "echo")
22+
public class ScanConventionConfig {
23+
24+
}

0 commit comments

Comments
 (0)