Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 171f7b9

Browse files
mp911dechristophstrobl
authored andcommitted
Add configurable Predicate for type inclusion to TypeCollector.
Closes: #3362 Original Pull Request: #3363
1 parent 1a45458 commit 171f7b9

File tree

4 files changed

+98
-16
lines changed

4 files changed

+98
-16
lines changed

‎src/main/java/org/springframework/data/aot/ManagedTypesBeanRegistrationAotProcessor.java‎

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import java.util.Collection;
1919
import java.util.Collections;
2020
import java.util.Set;
21+
import java.util.function.Consumer;
2122

2223
import org.apache.commons.logging.Log;
2324
import org.apache.commons.logging.LogFactory;
@@ -35,6 +36,7 @@
3536
import org.springframework.core.env.StandardEnvironment;
3637
import org.springframework.data.domain.ManagedTypes;
3738
import org.springframework.data.util.Lazy;
39+
import org.springframework.data.util.TypeCollector;
3840
import org.springframework.data.util.TypeContributor;
3941
import org.springframework.data.util.TypeUtils;
4042
import org.springframework.util.ClassUtils;
@@ -125,9 +127,18 @@ private ManagedTypes resolveManagedTypes(RegisteredBean registeredBean) {
125127
*/
126128
protected BeanRegistrationAotContribution contribute(AotContext aotContext, ManagedTypes managedTypes,
127129
RegisteredBean registeredBean) {
128-
return new ManagedTypesRegistrationAotContribution(aotContext, managedTypes, registeredBean, this::contributeType);
130+
return new ManagedTypesRegistrationAotContribution(aotContext, managedTypes, registeredBean,
131+
typeCollectorCustomizer(), this::contributeType);
129132
}
130133

134+
/**
135+
* Customization hook to configure {@link TypeCollector}.
136+
*
137+
* @return a {@link Consumer} to customize the {@link TypeCollector}, must not be {@literal null}.
138+
*/
139+
protected Consumer<TypeCollector> typeCollectorCustomizer() {
140+
return typeCollector -> {};
141+
}
131142
/**
132143
* Hook to contribute configuration for a given {@literal type}.
133144
*
@@ -142,14 +153,26 @@ protected void contributeType(ResolvableType type, GenerationContext generationC
142153

143154
Set<String> annotationNamespaces = Collections.singleton(TypeContributor.DATA_NAMESPACE);
144155

145-
aotContext.typeConfiguration(type, config -> config.forDataBinding() //
146-
.contributeAccessors() //
147-
.forQuerydsl().contribute(environment.get(), generationContext));
156+
configureTypeContribution(type.toClass(), aotContext);
157+
158+
aotContext.typeConfiguration(type, config -> {
159+
config.contribute(environment.get(), generationContext);
160+
});
148161

149162
TypeUtils.resolveUsedAnnotations(type.toClass()).forEach(
150163
annotation -> TypeContributor.contribute(annotation.getType(), annotationNamespaces, generationContext));
151164
}
152165

166+
/**
167+
* Customization hook to configure the {@link TypeContributor} used to register the given {@literal type}.
168+
*
169+
* @param type the class to configure the contribution for.
170+
* @param aotContext AOT context for type configuration.
171+
*/
172+
protected void configureTypeContribution(Class<?> type, AotContext aotContext) {
173+
aotContext.typeConfiguration(type, config -> config.forDataBinding().contributeAccessors().forQuerydsl());
174+
}
175+
153176
protected boolean isMatch(@Nullable Class<?> beanType, @Nullable String beanName) {
154177
return matchesByType(beanType) && matchesPrefix(beanName);
155178
}

‎src/main/java/org/springframework/data/aot/ManagedTypesRegistrationAotContribution.java‎

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,12 @@
1818
import java.lang.reflect.Method;
1919
import java.util.Collections;
2020
import java.util.List;
21-
import java.util.function.BiConsumer;
21+
import java.util.function.Consumer;
2222

2323
import javax.lang.model.element.Modifier;
2424

2525
import org.jspecify.annotations.Nullable;
26+
2627
import org.springframework.aot.generate.AccessControl;
2728
import org.springframework.aot.generate.GeneratedMethod;
2829
import org.springframework.aot.generate.GenerationContext;
@@ -76,15 +77,18 @@ class ManagedTypesRegistrationAotContribution implements RegisteredBeanAotContri
7677
private final AotContext aotContext;
7778
private final ManagedTypes managedTypes;
7879
private final Lazy<List<Class<?>>> sourceTypes;
80+
private final Consumer<TypeCollector> typeCollectorCustomizer;
7981
private final TypeRegistration contributionAction;
8082
private final RegisteredBean source;
8183

8284
public ManagedTypesRegistrationAotContribution(AotContext aotContext, ManagedTypes managedTypes,
83-
RegisteredBean registeredBean, TypeRegistration contributionAction) {
85+
RegisteredBean registeredBean, Consumer<TypeCollector> typeCollectorCustomizer,
86+
TypeRegistration contributionAction) {
8487

8588
this.aotContext = aotContext;
8689
this.managedTypes = managedTypes;
8790
this.sourceTypes = Lazy.of(managedTypes::toList);
91+
this.typeCollectorCustomizer = typeCollectorCustomizer;
8892
this.contributionAction = contributionAction;
8993
this.source = registeredBean;
9094
}
@@ -95,18 +99,15 @@ public void applyTo(GenerationContext generationContext, BeanRegistrationCode be
9599
List<Class<?>> types = sourceTypes.get();
96100

97101
if (!types.isEmpty()) {
98-
TypeCollector.inspect(types).forEach(type -> contributionAction.register(type, generationContext, aotContext));
102+
TypeCollector.inspect(typeCollectorCustomizer, types)
103+
.forEach(type -> contributionAction.register(type, generationContext, aotContext));
99104
}
100105
}
101106

102107
@Override
103108
public BeanRegistrationCodeFragments customizeBeanRegistrationCodeFragments(GenerationContext generationContext,
104109
BeanRegistrationCodeFragments codeFragments) {
105110

106-
if (managedTypes == null) {
107-
return codeFragments;
108-
}
109-
110111
ManagedTypesInstanceCodeFragment fragment = new ManagedTypesInstanceCodeFragment(sourceTypes.get(), source,
111112
codeFragments);
112113
return fragment.canGenerateCode() ? fragment : codeFragments;

‎src/main/java/org/springframework/data/util/TypeCollector.java‎

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,40 @@ public static ReachableTypes inspect(Class<?>... types) {
9494
return inspect(Arrays.asList(types));
9595
}
9696

97+
/**
98+
* Inspect the given type and resolve those reachable via fields, methods, generics, ...
99+
*
100+
* @param types the types to inspect
101+
* @return a type model collector for the type
102+
*/
97103
public static ReachableTypes inspect(Collection<Class<?>> types) {
98-
return new ReachableTypes(new TypeCollector(), types);
104+
return inspect(it -> {}, types);
105+
}
106+
107+
/**
108+
* Inspect the given type and resolve those reachable via fields, methods, generics, ...
109+
*
110+
* @param collectorCustomizer the customizer function to configure the {@link TypeCollector}.
111+
* @param types the types to inspect.
112+
* @return a type model collector for the type.
113+
* @since 4.0
114+
*/
115+
public static ReachableTypes inspect(Consumer<TypeCollector> collectorCustomizer, Class<?>... types) {
116+
return inspect(collectorCustomizer, Arrays.asList(types));
117+
}
118+
119+
/**
120+
* Inspect the given type and resolve those reachable via fields, methods, generics, ...
121+
*
122+
* @param collectorCustomizer the customizer function to configure the {@link TypeCollector}.
123+
* @param types the types to inspect.
124+
* @return a type model collector for the type.
125+
* @since 4.0
126+
*/
127+
public static ReachableTypes inspect(Consumer<TypeCollector> collectorCustomizer, Collection<Class<?>> types) {
128+
TypeCollector typeCollector = new TypeCollector();
129+
collectorCustomizer.accept(typeCollector);
130+
return new ReachableTypes(typeCollector, types);
99131
}
100132

101133
private void process(Class<?> root, Consumer<ResolvableType> consumer) {
@@ -225,30 +257,45 @@ private Predicate<Field> createFieldFilter() {
225257
return (Predicate) excludedFieldPredicate.negate();
226258
}
227259

260+
/**
261+
* Container for reachable types starting from a set of root types.
262+
*/
228263
public static class ReachableTypes {
229264

230265
private final Iterable<Class<?>> roots;
231266
private final Lazy<List<Class<?>>> reachableTypes = Lazy.of(this::collect);
232267
private final TypeCollector typeCollector;
233268

234-
publicReachableTypes(TypeCollector typeCollector, Iterable<Class<?>> roots) {
269+
ReachableTypes(TypeCollector typeCollector, Iterable<Class<?>> roots) {
235270

236271
this.typeCollector = typeCollector;
237272
this.roots = roots;
238273
}
239274

240-
public void forEach(Consumer<ResolvableType> consumer) {
241-
roots.forEach(it -> typeCollector.process(it, consumer));
275+
/**
276+
* Performs the given action for each element of the reachable types until all elements have been processed or the
277+
* action throws an exception. Actions are performed in the order of iteration, if that order is specified.
278+
* Exceptions thrown by the action are relayed to the caller.
279+
*
280+
* @param action The action to be performed for each element
281+
*/
282+
public void forEach(Consumer<ResolvableType> action) {
283+
roots.forEach(it -> typeCollector.process(it, action));
242284
}
243285

286+
/**
287+
* Return all reachable types as list of {@link Class classes}. The resulting list is unmodifiable.
288+
*
289+
* @return an unmodifiable list of reachable types.
290+
*/
244291
public List<Class<?>> list() {
245292
return reachableTypes.get();
246293
}
247294

248295
private List<Class<?>> collect() {
249296
List<Class<?>> target = new ArrayList<>();
250297
forEach(it -> target.add(it.toClass()));
251-
return target;
298+
return List.copyOf(target);
252299
}
253300
}
254301

‎src/test/java/org/springframework/data/aot/TypeCollectorUnitTests.java‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@
2222
import org.springframework.data.util.TypeCollector;
2323

2424
/**
25+
* Unit tests for {@link TypeCollector}.
26+
*
2527
* @author Christoph Strobl
28+
* @author Mark Paluch
2629
*/
2730
public class TypeCollectorUnitTests {
2831

@@ -66,4 +69,12 @@ void skipsCoreFrameworkType() {
6669
assertThat(TypeCollector.inspect(org.springframework.core.AliasRegistry.class).list()).isEmpty();
6770
}
6871

72+
@Test // GH-3362
73+
void appliesFilterPredicate() {
74+
assertThat(TypeCollector
75+
.inspect(it -> it.filterTypes(cls -> cls == EmptyType1.class || cls == TypesInMethodSignatures.class),
76+
TypesInMethodSignatures.class)
77+
.list()).containsOnly(TypesInMethodSignatures.class, EmptyType1.class);
78+
}
79+
6980
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /