Hide builder implementations in RuntimeHints API
This commit is contained in:
parent
c28fd91a10
commit
780d07217b
|
@ -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<TypeReference> 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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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<ExecutableMode> modes = new LinkedHashSet<>();
|
||||
|
||||
|
||||
private Builder(String name, List<TypeReference> parameterTypes) {
|
||||
Builder(String name, List<TypeReference> 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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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<TypeReference> proxiedInterfaces = new LinkedList<>();
|
||||
private final LinkedList<TypeReference> 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<TypeReference> toTypeReferences(Class<?>... proxiedInterfaces) {
|
||||
List<String> 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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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<JdkProxyHint> hint) {
|
||||
this.jdkProxies.add(hint.get());
|
||||
public ProxyHints registerJdkProxy(Consumer<JdkProxyHint.Builder> 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<String> 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<Builder> 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<Builder> 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.Builder> classProxyHint) {
|
||||
classProxyHint.accept(builder);
|
||||
this.classProxies.add(builder.build());
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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<Builder> resourceHint) {
|
||||
public ResourceHints registerPattern(String include, @Nullable Consumer<Builder> 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;
|
||||
}
|
||||
|
|
|
@ -96,7 +96,7 @@ public final class ResourcePatternHint {
|
|||
* builder.
|
||||
* @return a resource pattern hint
|
||||
*/
|
||||
public ResourcePatternHint build() {
|
||||
ResourcePatternHint build() {
|
||||
return new ResourcePatternHint(this);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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<JdkProxyHint> springProxy(TypeReference proxiedInterface) {
|
||||
return () -> new Builder().proxiedInterfaces(Stream.of("org.springframework.aop.SpringProxy",
|
||||
private static Consumer<JdkProxyHint.Builder> 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<JdkProxyHint> proxiedInterfaces(String... proxiedInterfaces) {
|
||||
|
|
Loading…
Reference in New Issue