Add ifPresent utility methods on RuntimeHints
This commit adds a utility method to register a type for reflection if it is available on the classpath. It also adds a method to register a resource pattern if a given location is available. Closes gh-28617
This commit is contained in:
parent
c4e8ffece1
commit
d6d4b98780
|
|
@ -30,6 +30,7 @@ import java.util.stream.Stream;
|
|||
|
||||
import org.springframework.aot.hint.TypeHint.Builder;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* Gather the need for reflection at runtime.
|
||||
|
|
@ -95,6 +96,22 @@ public class ReflectionHints {
|
|||
return registerType(TypeReference.of(type), typeHint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register or customize reflection hints for the specified type if it
|
||||
* is available using the specified {@link ClassLoader}.
|
||||
* @param classLoader the classloader to use to check if the type is present
|
||||
* @param typeName the type to customize
|
||||
* @param typeHint a builder to further customize hints for that type
|
||||
* @return {@code this}, to facilitate method chaining
|
||||
*/
|
||||
public ReflectionHints registerTypeIfPresent(@Nullable ClassLoader classLoader,
|
||||
String typeName, Consumer<TypeHint.Builder> typeHint) {
|
||||
if (ClassUtils.isPresent(typeName, classLoader)) {
|
||||
registerType(TypeReference.of(typeName), typeHint);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register or customize reflection hints for the types defined by the
|
||||
* specified list of {@link TypeReference type references}. The specified
|
||||
|
|
|
|||
|
|
@ -65,6 +65,24 @@ public class ResourceHints {
|
|||
return this.resourceBundleHints.stream();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a pattern if the given {@code location} is available on the
|
||||
* classpath. This delegates to {@link ClassLoader#getResource(String)}
|
||||
* which validates directories as well. The location is not included in
|
||||
* the hint.
|
||||
* @param classLoader the classloader to use
|
||||
* @param location a '/'-separated path name that should exist
|
||||
* @param resourceHint a builder to customize the resource pattern
|
||||
* @return {@code this}, to facilitate method chaining
|
||||
*/
|
||||
public ResourceHints registerPatternIfPresent(@Nullable ClassLoader classLoader, String location, Consumer<ResourcePatternHints.Builder> resourceHint) {
|
||||
ClassLoader classLoaderToUse = (classLoader != null) ? classLoader : getClass().getClassLoader();
|
||||
if (classLoaderToUse.getResource(location) != null) {
|
||||
registerPattern(resourceHint);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register that the resources matching the specified pattern should be
|
||||
* made available at runtime.
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ import org.springframework.lang.Nullable;
|
|||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verifyNoInteractions;
|
||||
|
||||
/**
|
||||
* Tests for {@link ReflectionHints}.
|
||||
|
|
@ -45,6 +47,23 @@ class ReflectionHintsTests {
|
|||
typeWithMemberCategories(String.class, MemberCategory.DECLARED_FIELDS));
|
||||
}
|
||||
|
||||
@Test
|
||||
void registerTypeIfPresentRegisterExistingClass() {
|
||||
this.reflectionHints.registerTypeIfPresent(null, String.class.getName(),
|
||||
hint -> hint.withMembers(MemberCategory.DECLARED_FIELDS));
|
||||
assertThat(this.reflectionHints.typeHints()).singleElement().satisfies(
|
||||
typeWithMemberCategories(String.class, MemberCategory.DECLARED_FIELDS));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void registerTypeIfPresentIgnoreMissingClass() {
|
||||
Consumer<TypeHint.Builder> hintBuilder = mock(Consumer.class);
|
||||
this.reflectionHints.registerTypeIfPresent(null, "com.example.DoesNotExist", hintBuilder);
|
||||
assertThat(this.reflectionHints.typeHints()).isEmpty();
|
||||
verifyNoInteractions(hintBuilder);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getTypeUsingType() {
|
||||
this.reflectionHints.registerType(TypeReference.of(String.class),
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ import org.junit.jupiter.api.Test;
|
|||
import org.springframework.aot.hint.ResourceHintsTests.Nested.Inner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verifyNoInteractions;
|
||||
|
||||
/**
|
||||
* Tests for {@link ResourceHints}.
|
||||
|
|
@ -91,6 +93,23 @@ class ResourceHintsTests {
|
|||
List.of("com/example/to-ignore.properties")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void registerIfPresentRegisterExistingLocation() {
|
||||
this.resourceHints.registerPatternIfPresent(null, "META-INF/",
|
||||
resourceHint -> resourceHint.includes("com/example/*.properties"));
|
||||
assertThat(this.resourceHints.resourcePatterns()).singleElement().satisfies(
|
||||
patternOf("com/example/*.properties"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void registerIfPresentIgnoreMissingLocation() {
|
||||
Consumer<ResourcePatternHints.Builder> hintBuilder = mock(Consumer.class);
|
||||
this.resourceHints.registerPatternIfPresent(null, "location/does-not-exist/", hintBuilder);
|
||||
assertThat(this.resourceHints.resourcePatterns()).isEmpty();
|
||||
verifyNoInteractions(hintBuilder);
|
||||
}
|
||||
|
||||
@Test
|
||||
void registerResourceBundle() {
|
||||
this.resourceHints.registerResourceBundle("com.example.message");
|
||||
|
|
|
|||
Loading…
Reference in New Issue