diff --git a/spring-core/src/main/java/org/springframework/aot/hint/ClassProxyHint.java b/spring-core/src/main/java/org/springframework/aot/hint/ClassProxyHint.java index 3fe04b4f35d..8fab0281f84 100644 --- a/spring-core/src/main/java/org/springframework/aot/hint/ClassProxyHint.java +++ b/spring-core/src/main/java/org/springframework/aot/hint/ClassProxyHint.java @@ -20,7 +20,6 @@ import java.util.Arrays; import java.util.LinkedList; import java.util.List; import java.util.Objects; -import java.util.stream.Collectors; /** * A hint that describes the need for a proxy against a concrete class. @@ -55,6 +54,9 @@ public final class ClassProxyHint { * @return a builder for the hint */ public static Builder of(Class targetClass) { + if (targetClass.isInterface()) { + throw new IllegalArgumentException("Should not be an interface: " + targetClass); + } return of(TypeReference.of(targetClass)); } @@ -103,7 +105,7 @@ public final class ClassProxyHint { private final LinkedList proxiedInterfaces = new LinkedList<>(); - public Builder(TypeReference targetClass) { + Builder(TypeReference targetClass) { this.targetClass = targetClass; } @@ -124,7 +126,7 @@ public final class ClassProxyHint { */ public Builder proxiedInterfaces(Class... proxiedInterfaces) { this.proxiedInterfaces.addAll(Arrays.stream(proxiedInterfaces) - .map(TypeReference::of).collect(Collectors.toList())); + .map(TypeReference::of).toList()); return this; } @@ -132,7 +134,7 @@ public final class ClassProxyHint { * Create a {@link ClassProxyHint} based on the state of this builder. * @return a class proxy hint */ - public ClassProxyHint build() { + ClassProxyHint build() { return new ClassProxyHint(this); } diff --git a/spring-core/src/main/java/org/springframework/aot/hint/ExecutableHint.java b/spring-core/src/main/java/org/springframework/aot/hint/ExecutableHint.java index f654f2ff134..db06fafd890 100644 --- a/spring-core/src/main/java/org/springframework/aot/hint/ExecutableHint.java +++ b/spring-core/src/main/java/org/springframework/aot/hint/ExecutableHint.java @@ -86,7 +86,7 @@ public final class ExecutableHint extends MemberHint { /** * Builder for {@link ExecutableHint}. */ - public static final class Builder { + public static class Builder { private final String name; @@ -95,7 +95,7 @@ public final class ExecutableHint extends MemberHint { private final Set modes = new LinkedHashSet<>(); - private Builder(String name, List parameterTypes) { + Builder(String name, List parameterTypes) { this.name = name; this.parameterTypes = parameterTypes; } @@ -127,7 +127,7 @@ public final class ExecutableHint extends MemberHint { * Create an {@link ExecutableHint} based on the state of this builder. * @return an executable hint */ - public ExecutableHint build() { + ExecutableHint build() { return new ExecutableHint(this); } diff --git a/spring-core/src/main/java/org/springframework/aot/hint/FieldHint.java b/spring-core/src/main/java/org/springframework/aot/hint/FieldHint.java index d5ef47b2976..d6976f20349 100644 --- a/spring-core/src/main/java/org/springframework/aot/hint/FieldHint.java +++ b/spring-core/src/main/java/org/springframework/aot/hint/FieldHint.java @@ -66,7 +66,7 @@ public final class FieldHint extends MemberHint { private boolean allowUnsafeAccess; - public Builder(String name) { + Builder(String name) { this.name = name; } @@ -94,7 +94,7 @@ public final class FieldHint extends MemberHint { * Create a {@link FieldHint} based on the state of this builder. * @return a field hint */ - public FieldHint build() { + FieldHint build() { return new FieldHint(this); } diff --git a/spring-core/src/main/java/org/springframework/aot/hint/JdkProxyHint.java b/spring-core/src/main/java/org/springframework/aot/hint/JdkProxyHint.java index a4989e07200..546b0ae6bb8 100644 --- a/spring-core/src/main/java/org/springframework/aot/hint/JdkProxyHint.java +++ b/spring-core/src/main/java/org/springframework/aot/hint/JdkProxyHint.java @@ -21,7 +21,6 @@ import java.util.Arrays; import java.util.LinkedList; import java.util.List; import java.util.Objects; -import java.util.stream.Collectors; /** * A hint that describes the need of a JDK {@link Proxy}, that is an @@ -39,6 +38,24 @@ public final class JdkProxyHint { this.proxiedInterfaces = List.copyOf(builder.proxiedInterfaces); } + /** + * Initialize a builder with the proxied interfaces to use. + * @param proxiedInterfaces the interfaces the proxy should implement + * @return a builder for the hint + */ + public static Builder of(TypeReference... proxiedInterfaces) { + return new Builder().proxiedInterfaces(proxiedInterfaces); + } + + /** + * Initialize a builder with the proxied interfaces to use. + * @param proxiedInterfaces the interfaces the proxy should implement + * @return a builder for the hint + */ + public static Builder of(Class... proxiedInterfaces) { + return new Builder().proxiedInterfaces(proxiedInterfaces); + } + /** * Return the interfaces to be proxied. * @return the interfaces that the proxy should implement @@ -70,8 +87,11 @@ public final class JdkProxyHint { */ public static class Builder { - private final LinkedList proxiedInterfaces = new LinkedList<>(); + private final LinkedList proxiedInterfaces; + Builder() { + this.proxiedInterfaces = new LinkedList<>(); + } /** * Add the specified interfaces that the proxy should implement. @@ -89,8 +109,7 @@ public final class JdkProxyHint { * @return {@code this}, to facilitate method chaining */ public Builder proxiedInterfaces(Class... proxiedInterfaces) { - this.proxiedInterfaces.addAll(Arrays.stream(proxiedInterfaces) - .map(TypeReference::of).collect(Collectors.toList())); + this.proxiedInterfaces.addAll(toTypeReferences(proxiedInterfaces)); return this; } @@ -98,10 +117,19 @@ public final class JdkProxyHint { * Create a {@link JdkProxyHint} based on the state of this builder. * @return a jdk proxy hint */ - public JdkProxyHint build() { + JdkProxyHint build() { return new JdkProxyHint(this); } + private static List toTypeReferences(Class... proxiedInterfaces) { + List concreteTypes = Arrays.stream(proxiedInterfaces) + .filter(candidate -> !candidate.isInterface()).map(Class::getName).toList(); + if (!concreteTypes.isEmpty()) { + throw new IllegalArgumentException("Not an interface: " + concreteTypes); + } + return Arrays.stream(proxiedInterfaces).map(TypeReference::of).toList(); + } + } } diff --git a/spring-core/src/main/java/org/springframework/aot/hint/ProxyHints.java b/spring-core/src/main/java/org/springframework/aot/hint/ProxyHints.java index a1ad157240e..d0ba6cafa48 100644 --- a/spring-core/src/main/java/org/springframework/aot/hint/ProxyHints.java +++ b/spring-core/src/main/java/org/springframework/aot/hint/ProxyHints.java @@ -16,13 +16,9 @@ package org.springframework.aot.hint; -import java.util.Arrays; import java.util.LinkedHashSet; -import java.util.List; import java.util.Set; import java.util.function.Consumer; -import java.util.function.Supplier; -import java.util.stream.Collectors; import java.util.stream.Stream; import org.springframework.aot.hint.ClassProxyHint.Builder; @@ -58,11 +54,13 @@ public class ProxyHints { /** * Register a {@link JdkProxyHint}. - * @param hint the supplier to the hint + * @param jdkProxyHint the supplier to the hint * @return {@code this}, to facilitate method chaining */ - public ProxyHints registerJdkProxy(Supplier hint) { - this.jdkProxies.add(hint.get()); + public ProxyHints registerJdkProxy(Consumer jdkProxyHint) { + JdkProxyHint.Builder builder = new JdkProxyHint.Builder(); + jdkProxyHint.accept(builder); + this.jdkProxies.add(builder.build()); return this; } @@ -73,8 +71,8 @@ public class ProxyHints { * @return {@code this}, to facilitate method chaining */ public ProxyHints registerJdkProxy(TypeReference... proxiedInterfaces) { - return registerJdkProxy(() -> new JdkProxyHint.Builder() - .proxiedInterfaces(proxiedInterfaces).build()); + return registerJdkProxy(jdkProxyHint -> + jdkProxyHint.proxiedInterfaces(proxiedInterfaces)); } /** @@ -84,13 +82,8 @@ public class ProxyHints { * @return {@code this}, to facilitate method chaining */ public ProxyHints registerJdkProxy(Class... proxiedInterfaces) { - List concreteTypes = Arrays.stream(proxiedInterfaces) - .filter(candidate -> !candidate.isInterface()).map(Class::getName).collect(Collectors.toList()); - if (!concreteTypes.isEmpty()) { - throw new IllegalArgumentException("Not an interface: " + concreteTypes); - } - return registerJdkProxy(() -> new JdkProxyHint.Builder() - .proxiedInterfaces(proxiedInterfaces).build()); + return registerJdkProxy(jdkProxyHint -> + jdkProxyHint.proxiedInterfaces(proxiedInterfaces)); } /** @@ -101,10 +94,7 @@ public class ProxyHints { * @return {@code this}, to facilitate method chaining */ public ProxyHints registerClassProxy(TypeReference targetClass, Consumer classProxyHint) { - Builder builder = ClassProxyHint.of(targetClass); - classProxyHint.accept(builder); - this.classProxies.add(builder.build()); - return this; + return addClassProxyHint(ClassProxyHint.of(targetClass), classProxyHint); } /** @@ -114,10 +104,13 @@ public class ProxyHints { * @return {@code this}, to facilitate method chaining */ public ProxyHints registerClassProxy(Class targetClass, Consumer classProxyHint) { - if (targetClass.isInterface()) { - throw new IllegalArgumentException("Should not be an interface: " + targetClass); - } - return registerClassProxy(TypeReference.of(targetClass), classProxyHint); + return addClassProxyHint(ClassProxyHint.of(targetClass), classProxyHint); + } + + private ProxyHints addClassProxyHint(ClassProxyHint.Builder builder, Consumer classProxyHint) { + classProxyHint.accept(builder); + this.classProxies.add(builder.build()); + return this; } } diff --git a/spring-core/src/main/java/org/springframework/aot/hint/ResourceHints.java b/spring-core/src/main/java/org/springframework/aot/hint/ResourceHints.java index c4db5c9d825..48208fa2784 100644 --- a/spring-core/src/main/java/org/springframework/aot/hint/ResourceHints.java +++ b/spring-core/src/main/java/org/springframework/aot/hint/ResourceHints.java @@ -25,6 +25,7 @@ import java.util.function.Consumer; import java.util.stream.Stream; import org.springframework.aot.hint.ResourcePatternHint.Builder; +import org.springframework.lang.Nullable; /** * Gather the need for resources available at runtime. @@ -72,7 +73,7 @@ public class ResourceHints { * @param resourceHint a builder to further customize the resource pattern * @return {@code this}, to facilitate method chaining */ - public ResourceHints registerPattern(String include, Consumer resourceHint) { + public ResourceHints registerPattern(String include, @Nullable Consumer resourceHint) { Builder builder = new Builder().includes(include); if (resourceHint != null) { resourceHint.accept(builder); @@ -136,7 +137,7 @@ public class ResourceHints { return candidate.replace(".", "/") + ".class"; } - private void buildName(TypeReference type, StringBuilder sb) { + private void buildName(@Nullable TypeReference type, StringBuilder sb) { if (type == null) { return; } diff --git a/spring-core/src/main/java/org/springframework/aot/hint/ResourcePatternHint.java b/spring-core/src/main/java/org/springframework/aot/hint/ResourcePatternHint.java index a48d59eaae9..891c0808fac 100644 --- a/spring-core/src/main/java/org/springframework/aot/hint/ResourcePatternHint.java +++ b/spring-core/src/main/java/org/springframework/aot/hint/ResourcePatternHint.java @@ -96,7 +96,7 @@ public final class ResourcePatternHint { * builder. * @return a resource pattern hint */ - public ResourcePatternHint build() { + ResourcePatternHint build() { return new ResourcePatternHint(this); } diff --git a/spring-core/src/main/java/org/springframework/aot/hint/TypeHint.java b/spring-core/src/main/java/org/springframework/aot/hint/TypeHint.java index ff7a1956541..3536eadf840 100644 --- a/spring-core/src/main/java/org/springframework/aot/hint/TypeHint.java +++ b/spring-core/src/main/java/org/springframework/aot/hint/TypeHint.java @@ -223,7 +223,7 @@ public final class TypeHint { * Create a {@link TypeHint} based on the state of this builder. * @return a type hint */ - public TypeHint build() { + TypeHint build() { return new TypeHint(this); } diff --git a/spring-core/src/test/java/org/springframework/aot/hint/ProxyHintsTests.java b/spring-core/src/test/java/org/springframework/aot/hint/ProxyHintsTests.java index 337df262e3e..016a432cace 100644 --- a/spring-core/src/test/java/org/springframework/aot/hint/ProxyHintsTests.java +++ b/spring-core/src/test/java/org/springframework/aot/hint/ProxyHintsTests.java @@ -21,13 +21,10 @@ import java.util.Arrays; import java.util.Properties; import java.util.function.Consumer; import java.util.function.Function; -import java.util.function.Supplier; import java.util.stream.Stream; import org.junit.jupiter.api.Test; -import org.springframework.aot.hint.JdkProxyHint.Builder; - import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; @@ -78,6 +75,16 @@ class ProxyHintsTests { assertThat(this.proxyHints.jdkProxies()).singleElement().satisfies(proxiedInterfaces(Function.class)); } + @Test + void registerClassProxyWithTargetClassName() { + this.proxyHints.registerClassProxy(TypeReference.of(Properties.class.getName()), classProxyHint -> + classProxyHint.proxiedInterfaces(Serializable.class)); + assertThat(this.proxyHints.classProxies()).singleElement().satisfies(classProxyHint -> { + assertThat(classProxyHint.getTargetClass()).isEqualTo(TypeReference.of(Properties.class)); + assertThat(classProxyHint.getProxiedInterfaces()).containsOnly(TypeReference.of(Serializable.class)); + }); + } + @Test void registerClassProxyWithTargetClass() { this.proxyHints.registerClassProxy(Properties.class, classProxyHint -> @@ -94,11 +101,11 @@ class ProxyHintsTests { })).withMessageContaining(Serializable.class.getName()); } - private static Supplier springProxy(TypeReference proxiedInterface) { - return () -> new Builder().proxiedInterfaces(Stream.of("org.springframework.aop.SpringProxy", + private static Consumer springProxy(TypeReference proxiedInterface) { + return builder -> builder.proxiedInterfaces(Stream.of("org.springframework.aop.SpringProxy", "org.springframework.aop.framework.Advised", "org.springframework.core.DecoratingProxy") .map(TypeReference::of).toArray(TypeReference[]::new)) - .proxiedInterfaces(proxiedInterface).build(); + .proxiedInterfaces(proxiedInterface); } private Consumer proxiedInterfaces(String... proxiedInterfaces) {