diff --git a/src/main/java/org/springframework/data/annotation/Persistent.java b/src/main/java/org/springframework/data/annotation/Persistent.java
index 59bd14265..76341af19 100644
--- a/src/main/java/org/springframework/data/annotation/Persistent.java
+++ b/src/main/java/org/springframework/data/annotation/Persistent.java
@@ -20,6 +20,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
+import org.springframework.aot.hint.annotation.Reflective;
import org.springframework.stereotype.Indexed;
/**
@@ -30,6 +31,7 @@ import org.springframework.stereotype.Indexed;
*/
@Indexed
@Retention(RetentionPolicy.RUNTIME)
+@Reflective
@Target(value = { ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER })
public @interface Persistent {
}
diff --git a/src/main/java/org/springframework/data/aot/DataRuntimeHints.java b/src/main/java/org/springframework/data/aot/DataRuntimeHints.java
new file mode 100644
index 000000000..9b784f19c
--- /dev/null
+++ b/src/main/java/org/springframework/data/aot/DataRuntimeHints.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2022 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.data.aot;
+
+import java.util.Arrays;
+import java.util.Properties;
+
+import org.springframework.aop.SpringProxy;
+import org.springframework.aop.framework.Advised;
+import org.springframework.aot.hint.MemberCategory;
+import org.springframework.aot.hint.RuntimeHints;
+import org.springframework.aot.hint.RuntimeHintsRegistrar;
+import org.springframework.aot.hint.TypeReference;
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.core.DecoratingProxy;
+import org.springframework.core.io.InputStreamSource;
+import org.springframework.data.domain.AuditorAware;
+import org.springframework.data.mapping.context.MappingContext;
+import org.springframework.data.repository.core.RepositoryMetadata;
+import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport;
+import org.springframework.data.repository.core.support.RepositoryFragment;
+import org.springframework.data.repository.core.support.RepositoryFragmentsFactoryBean;
+import org.springframework.data.repository.core.support.TransactionalRepositoryFactoryBeanSupport;
+import org.springframework.data.repository.query.QueryByExampleExecutor;
+import org.springframework.lang.Nullable;
+
+/**
+ * @author Christoph Strobl
+ * @since 3.0
+ */
+public class DataRuntimeHints implements RuntimeHintsRegistrar {
+
+ /*
+ NativeHint(trigger = MappingContext.class,
+ types = {
+ @TypeHint(types = {
+ RepositoryFactoryBeanSupport.class,
+ RepositoryFragmentsFactoryBean.class,
+ RepositoryFragment.class,
+ TransactionalRepositoryFactoryBeanSupport.class,
+ QueryByExampleExecutor.class,
+ MappingContext.class,
+ RepositoryMetadata.class,
+ RepositoryMetadata.class,
+ }),
+ @TypeHint(types = {ReadingConverter.class, WritingConverter.class}),
+ @TypeHint(types = {Properties.class, BeanFactory.class, InputStreamSource[].class}),
+ @TypeHint(types = Throwable.class, access = { TypeAccess.DECLARED_CONSTRUCTORS, TypeAccess.DECLARED_FIELDS}),
+ @TypeHint(typeNames = {
+ "org.springframework.data.projection.SpelEvaluatingMethodInterceptor$TargetWrapper",
+ }, access = { TypeAccess.DECLARED_CONSTRUCTORS, TypeAccess.DECLARED_METHODS, TypeAccess.PUBLIC_METHODS })
+ },
+ jdkProxies = @JdkProxyHint(typeNames = {
+ "org.springframework.data.annotation.QueryAnnotation",
+ "org.springframework.core.annotation.SynthesizedAnnotation" }
+ ),
+ initialization = @InitializationHint(types = AbstractMappingContext.class, initTime = InitializationTime.BUILD)
+ )
+ */
+
+ @Override
+ public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) {
+
+ System.out.println("Spring data Runtime Hints");
+
+ hints.reflection()
+ .registerTypes(Arrays.asList(TypeReference.of(RepositoryFactoryBeanSupport.class),
+ TypeReference.of(RepositoryFragmentsFactoryBean.class), TypeReference.of(RepositoryFragment.class),
+ TypeReference.of(TransactionalRepositoryFactoryBeanSupport.class),
+ TypeReference.of(QueryByExampleExecutor.class), TypeReference.of(MappingContext.class),
+ TypeReference.of(RepositoryMetadata.class)), builder -> {
+ builder.withMembers(MemberCategory.INVOKE_PUBLIC_METHODS);
+ });
+ hints.reflection().registerTypes(
+ Arrays.asList(TypeReference.of(Properties.class), TypeReference.of(BeanFactory.class),
+ TypeReference.of(InputStreamSource[].class)),
+ builder -> builder.withMembers(MemberCategory.INVOKE_PUBLIC_METHODS));
+
+ hints.reflection().registerType(Throwable.class,
+ builder -> builder.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS));
+
+ hints.reflection().registerType(
+ TypeReference.of("org.springframework.data.projection.SpelEvaluatingMethodInterceptor$TargetWrapper"),
+ builder -> builder.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
+ MemberCategory.INVOKE_DECLARED_METHODS, MemberCategory.INVOKE_PUBLIC_METHODS));
+
+ hints.proxies().registerJdkProxy(TypeReference.of("org.springframework.data.annotation.QueryAnnotation"),
+ TypeReference.of("org.springframework.core.annotation.SynthesizedAnnotation"));
+
+ hints.proxies().registerJdkProxy(TypeReference.of(AuditorAware.class), TypeReference.of(SpringProxy.class), TypeReference.of(Advised.class), TypeReference.of(DecoratingProxy.class));
+ }
+}
diff --git a/src/main/java/org/springframework/data/aot/PublicMethodReflectiveProcessor.java b/src/main/java/org/springframework/data/aot/PublicMethodReflectiveProcessor.java
new file mode 100644
index 000000000..0388610a5
--- /dev/null
+++ b/src/main/java/org/springframework/data/aot/PublicMethodReflectiveProcessor.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2022 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.data.aot;
+
+import org.springframework.aot.hint.MemberCategory;
+import org.springframework.aot.hint.ReflectionHints;
+import org.springframework.aot.hint.annotation.SimpleReflectiveProcessor;
+
+/**
+ * @author Christoph Strobl
+ */
+public class PublicMethodReflectiveProcessor extends SimpleReflectiveProcessor {
+
+ @Override
+ protected void registerTypeHint(ReflectionHints hints, Class> type) {
+ System.out.println("invoking reflective hint annotation for : " + type);
+ hints.registerType(type, builder -> builder.withMembers(MemberCategory.INVOKE_PUBLIC_METHODS));
+
+ }
+}
diff --git a/src/main/java/org/springframework/data/aot/RepositoryRegistrationAotContribution.java b/src/main/java/org/springframework/data/aot/RepositoryRegistrationAotContribution.java
index c4bfea655..61ab47041 100644
--- a/src/main/java/org/springframework/data/aot/RepositoryRegistrationAotContribution.java
+++ b/src/main/java/org/springframework/data/aot/RepositoryRegistrationAotContribution.java
@@ -286,7 +286,7 @@ public class RepositoryRegistrationAotContribution implements BeanRegistrationAo
.registerType(repositoryInformation.getRepositoryBaseClass(), hint ->
hint.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.INVOKE_PUBLIC_METHODS))
.registerType(repositoryInformation.getDomainType(), hint ->
- hint.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.INVOKE_DECLARED_METHODS));
+ hint.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.INVOKE_DECLARED_METHODS, MemberCategory.DECLARED_FIELDS));
// Repository Fragments
for (RepositoryFragment> fragment : getRepositoryInformation().getFragments()) {
@@ -308,7 +308,7 @@ public class RepositoryRegistrationAotContribution implements BeanRegistrationAo
SpringProxy.class, Advised.class, DecoratingProxy.class);
// Transactional Repository Proxy
- repositoryContext.ifTransactionManagerPresent(transactionManagerBeanNames -> {
+ //repositoryContext.ifTransactionManagerPresent(transactionManagerBeanNames -> {
// TODO: Is the following double JDK Proxy registration above necessary or would a single JDK Proxy
// registration suffice?
@@ -327,7 +327,7 @@ public class RepositoryRegistrationAotContribution implements BeanRegistrationAo
contribution.getRuntimeHints().proxies()
.registerJdkProxy(transactionalRepositoryProxyTypeReferences.toArray(new TypeReference[0]));
}
- });
+ //});
// Reactive Repositories
if (repositoryInformation.isReactiveRepository()) {
@@ -396,39 +396,25 @@ public class RepositoryRegistrationAotContribution implements BeanRegistrationAo
.registerJdkProxy(type, TargetAware.class, SpringProxy.class, DecoratingProxy.class);
}
- protected void contribute(AotRepositoryContext repositoryContext, GenerationContext generationContext) {
-
- repositoryContext.getResolvedTypes().stream()
- .filter(it -> !isJavaOrPrimitiveType(it))
- .forEach(it -> contributeType(it, generationContext));
-
- repositoryContext.getResolvedAnnotations().stream()
- .filter(this::isSpringDataManagedAnnotation)
- .map(MergedAnnotation::getType)
- .forEach(it -> contributeType(it, generationContext));
- }
-
- private boolean isJavaOrPrimitiveType(Class> type) {
+ static boolean isJavaOrPrimitiveType(Class> type) {
return TypeUtils.type(type).isPartOf("java")
|| type.isPrimitive()
|| ClassUtils.isPrimitiveArray(type);
}
- private boolean isSpringDataManagedAnnotation(MergedAnnotation> annotation) {
+ static boolean isSpringDataManagedAnnotation(MergedAnnotation> annotation) {
return annotation != null
&& (isInSpringDataNamespace(annotation.getType()) || annotation.getMetaTypes().stream()
- .anyMatch(this::isInSpringDataNamespace));
+ .anyMatch(RepositoryRegistrationAotContribution::isInSpringDataNamespace));
}
- private boolean isInSpringDataNamespace(Class> type) {
+ static boolean isInSpringDataNamespace(Class> type) {
return type != null && type.getPackage().getName().startsWith(TypeContributor.DATA_NAMESPACE);
}
- protected void contributeType(Class> type, GenerationContext generationContext) {
-
- logTrace("Contributing type information for [%s]", type);
+ static void contributeType(Class> type, GenerationContext generationContext) {
TypeContributor.contribute(type, it -> true, generationContext);
}
diff --git a/src/main/java/org/springframework/data/aot/RepositoryRegistrationAotProcessor.java b/src/main/java/org/springframework/data/aot/RepositoryRegistrationAotProcessor.java
index 4e9752f98..77d89034b 100644
--- a/src/main/java/org/springframework/data/aot/RepositoryRegistrationAotProcessor.java
+++ b/src/main/java/org/springframework/data/aot/RepositoryRegistrationAotProcessor.java
@@ -34,6 +34,7 @@ import org.springframework.beans.factory.aot.BeanRegistrationAotProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.RegisteredBean;
import org.springframework.beans.factory.support.RootBeanDefinition;
+import org.springframework.core.annotation.MergedAnnotation;
import org.springframework.data.repository.config.RepositoryConfigurationExtension;
import org.springframework.data.repository.config.RepositoryMetadata;
import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport;
@@ -51,7 +52,7 @@ import org.springframework.util.StringUtils;
* via the {@link FactoryBean#OBJECT_TYPE_ATTRIBUTE}.
*
*
- * With {@link RepositoryRegistrationAotContribution#contribute(AotRepositoryContext, GenerationContext)}, stores
+ * With {@link RepositoryRegistrationAotProcessor#contribute(AotRepositoryContext, GenerationContext)}, stores
* can provide custom logic for contributing additional (eg. reflection) configuration. By default, reflection
* configuration will be added for types reachable from the repository declaration and query methods as well as
* all used {@link Annotation annotations} from the {@literal org.springframework.data} namespace.
@@ -83,6 +84,19 @@ public class RepositoryRegistrationAotProcessor implements BeanRegistrationAotPr
: null;
}
+ protected void contribute(AotRepositoryContext repositoryContext, GenerationContext generationContext) {
+
+ repositoryContext.getResolvedTypes().stream()
+ .filter(it -> !RepositoryRegistrationAotContribution
+ .isJavaOrPrimitiveType(it))
+ .forEach(it -> RepositoryRegistrationAotContribution.contributeType(it, generationContext));
+
+ repositoryContext.getResolvedAnnotations().stream()
+ .filter(RepositoryRegistrationAotContribution::isSpringDataManagedAnnotation)
+ .map(MergedAnnotation::getType)
+ .forEach(it -> RepositoryRegistrationAotContribution.contributeType(it, generationContext));
+ }
+
private boolean isRepositoryBean(RegisteredBean bean) {
return bean != null && getConfigMap().containsKey(bean.getBeanName());
}
@@ -93,7 +107,7 @@ public class RepositoryRegistrationAotProcessor implements BeanRegistrationAotPr
RepositoryRegistrationAotContribution contribution =
RepositoryRegistrationAotContribution.fromProcessor(this).forBean(repositoryBean);
- return contribution.withModuleContribution(contribution::contribute);
+ return contribution.withModuleContribution(this::contribute);
}
@Override
diff --git a/src/main/java/org/springframework/data/aot/TypeCollector.java b/src/main/java/org/springframework/data/aot/TypeCollector.java
index e7392658c..697280586 100644
--- a/src/main/java/org/springframework/data/aot/TypeCollector.java
+++ b/src/main/java/org/springframework/data/aot/TypeCollector.java
@@ -121,7 +121,7 @@ public class TypeCollector {
private void processType(ResolvableType type, InspectionCache cache, Consumer callback) {
- if (ResolvableType.NONE.equals(type) || cache.contains(type)) {
+ if (ResolvableType.NONE.equals(type) || cache.contains(type) || type.toClass().isSynthetic()) {
return;
}
diff --git a/src/main/java/org/springframework/data/aot/TypeContributor.java b/src/main/java/org/springframework/data/aot/TypeContributor.java
index ca4a7e4bf..26eab785c 100644
--- a/src/main/java/org/springframework/data/aot/TypeContributor.java
+++ b/src/main/java/org/springframework/data/aot/TypeContributor.java
@@ -29,7 +29,7 @@ import org.springframework.core.annotation.SynthesizedAnnotation;
* @author Christoph Strobl
* @since 3.0
*/
-class TypeContributor {
+public class TypeContributor {
public static final String DATA_NAMESPACE = "org.springframework.data";
@@ -39,7 +39,7 @@ class TypeContributor {
* @param type
* @param contribution
*/
- static void contribute(Class> type, GenerationContext contribution) {
+ public static void contribute(Class> type, GenerationContext contribution) {
contribute(type, Collections.emptySet(), contribution);
}
@@ -51,7 +51,7 @@ class TypeContributor {
* @param contribution
*/
@SuppressWarnings("unchecked")
- static void contribute(Class> type, Predicate> filter, GenerationContext contribution) {
+ public static void contribute(Class> type, Predicate> filter, GenerationContext contribution) {
if (type.isPrimitive()) {
return;
@@ -76,7 +76,7 @@ class TypeContributor {
}
contribution.getRuntimeHints().reflection().registerType(type, hint ->
- hint.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.INVOKE_PUBLIC_METHODS));
+ hint.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.INVOKE_PUBLIC_METHODS, MemberCategory.DECLARED_FIELDS));
}
/**
@@ -87,15 +87,15 @@ class TypeContributor {
* @param annotationNamespaces
* @param contribution
*/
- static void contribute(Class> type, Set annotationNamespaces, GenerationContext contribution) {
+ public static void contribute(Class> type, Set annotationNamespaces, GenerationContext contribution) {
contribute(type, it -> isPartOfOrMetaAnnotatedWith(it, annotationNamespaces), contribution);
}
- private static boolean isPartOf(Class> type, Set namespaces) {
+ public static boolean isPartOf(Class> type, Set namespaces) {
return namespaces.stream().anyMatch(namespace -> type.getPackageName().startsWith(namespace));
}
- protected static boolean isPartOfOrMetaAnnotatedWith(Class extends Annotation> annotation, Set namespaces) {
+ public static boolean isPartOfOrMetaAnnotatedWith(Class extends Annotation> annotation, Set namespaces) {
if (isPartOf(annotation, namespaces)) {
return true;
diff --git a/src/main/java/org/springframework/data/convert/ReadingConverter.java b/src/main/java/org/springframework/data/convert/ReadingConverter.java
index 61495d52d..a099d2d2b 100644
--- a/src/main/java/org/springframework/data/convert/ReadingConverter.java
+++ b/src/main/java/org/springframework/data/convert/ReadingConverter.java
@@ -22,7 +22,9 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
+import org.springframework.aot.hint.annotation.Reflective;
import org.springframework.core.convert.converter.Converter;
+import org.springframework.data.aot.PublicMethodReflectiveProcessor;
/**
* Annotation to clarify intended usage of a {@link Converter} as reading converter in case the conversion types leave
@@ -32,6 +34,7 @@ import org.springframework.core.convert.converter.Converter;
*/
@Target(TYPE)
@Documented
+@Reflective({PublicMethodReflectiveProcessor.class})
@Retention(RetentionPolicy.RUNTIME)
public @interface ReadingConverter {
diff --git a/src/main/java/org/springframework/data/convert/WritingConverter.java b/src/main/java/org/springframework/data/convert/WritingConverter.java
index 0e8e962d9..c05b47a89 100644
--- a/src/main/java/org/springframework/data/convert/WritingConverter.java
+++ b/src/main/java/org/springframework/data/convert/WritingConverter.java
@@ -22,7 +22,9 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
+import org.springframework.aot.hint.annotation.Reflective;
import org.springframework.core.convert.converter.Converter;
+import org.springframework.data.aot.PublicMethodReflectiveProcessor;
/**
* Annotation to clarify intended usage of a {@link Converter} as writing converter in case the conversion types leave
@@ -32,6 +34,7 @@ import org.springframework.core.convert.converter.Converter;
*/
@Target(TYPE)
@Documented
+@Reflective({PublicMethodReflectiveProcessor.class})
@Retention(RetentionPolicy.RUNTIME)
public @interface WritingConverter {
diff --git a/src/main/java/org/springframework/data/mapping/callback/EntityCallback.java b/src/main/java/org/springframework/data/mapping/callback/EntityCallback.java
index 7a79b2fdc..84ab469cb 100644
--- a/src/main/java/org/springframework/data/mapping/callback/EntityCallback.java
+++ b/src/main/java/org/springframework/data/mapping/callback/EntityCallback.java
@@ -15,6 +15,9 @@
*/
package org.springframework.data.mapping.callback;
+import org.springframework.aot.hint.annotation.Reflective;
+import org.springframework.data.aot.PublicMethodReflectiveProcessor;
+
/**
* Marker interface for entity callbacks to be implemented in specific callback subtypes. Intended for internal usage
* within store specific implementations.
@@ -59,6 +62,7 @@ package org.springframework.data.mapping.callback;
* @see org.springframework.core.Ordered
* @see org.springframework.core.annotation.Order
*/
+@Reflective({PublicMethodReflectiveProcessor.class})
public interface EntityCallback {
}
diff --git a/src/main/java/org/springframework/data/repository/config/NamedQueriesBeanDefinitionBuilder.java b/src/main/java/org/springframework/data/repository/config/NamedQueriesBeanDefinitionBuilder.java
index 975ff1d98..02574b564 100644
--- a/src/main/java/org/springframework/data/repository/config/NamedQueriesBeanDefinitionBuilder.java
+++ b/src/main/java/org/springframework/data/repository/config/NamedQueriesBeanDefinitionBuilder.java
@@ -15,9 +15,12 @@
*/
package org.springframework.data.repository.config;
+import java.io.IOException;
+
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.core.io.ClassPathResource;
import org.springframework.data.repository.core.NamedQueries;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
diff --git a/src/main/java/org/springframework/data/repository/config/RepositoryBeanDefinitionBuilder.java b/src/main/java/org/springframework/data/repository/config/RepositoryBeanDefinitionBuilder.java
index 464106731..3d1908dbb 100644
--- a/src/main/java/org/springframework/data/repository/config/RepositoryBeanDefinitionBuilder.java
+++ b/src/main/java/org/springframework/data/repository/config/RepositoryBeanDefinitionBuilder.java
@@ -27,6 +27,7 @@ import java.util.stream.Stream;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
@@ -119,7 +120,11 @@ class RepositoryBeanDefinitionBuilder {
extension.getDefaultNamedQueryLocation());
configuration.getNamedQueriesLocation().ifPresent(definitionBuilder::setLocations);
- builder.addPropertyValue("namedQueries", definitionBuilder.build(configuration.getSource()));
+ String namedQueriesBeanName = BeanDefinitionReaderUtils.uniqueBeanName(extension.getModulePrefix() + ".named-queries", registry);
+ BeanDefinition namedQueries = definitionBuilder.build(configuration.getSource());
+ registry.registerBeanDefinition(namedQueriesBeanName, namedQueries);
+
+ builder.addPropertyValue("namedQueries", new RuntimeBeanReference(namedQueriesBeanName));
registerCustomImplementation(configuration).ifPresent(it -> {
builder.addPropertyReference("customImplementation", it);
diff --git a/src/main/java/org/springframework/data/repository/config/RepositoryConfigurationDelegate.java b/src/main/java/org/springframework/data/repository/config/RepositoryConfigurationDelegate.java
index 804ac244b..6b9a7a2cb 100644
--- a/src/main/java/org/springframework/data/repository/config/RepositoryConfigurationDelegate.java
+++ b/src/main/java/org/springframework/data/repository/config/RepositoryConfigurationDelegate.java
@@ -50,7 +50,6 @@ import org.springframework.core.metrics.ApplicationStartup;
import org.springframework.core.metrics.StartupStep;
import org.springframework.data.ManagedTypes;
import org.springframework.data.aot.TypeScanner;
-import org.springframework.data.repository.config.RepositoryConfigurationDelegate.LazyRepositoryInjectionPointResolver.ManagedTypesBean;
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
import org.springframework.data.util.Lazy;
import org.springframework.lang.NonNull;
@@ -116,8 +115,8 @@ public class RepositoryConfigurationDelegate {
*
* @param environment can be {@literal null}.
* @param resourceLoader can be {@literal null}.
- * @return the given {@link Environment} if not {@literal null}, a configured {@link Environment},
- * or a default {@link Environment}.
+ * @return the given {@link Environment} if not {@literal null}, a configured {@link Environment}, or a default
+ * {@link Environment}.
*/
private static Environment defaultEnvironment(@Nullable Environment environment,
@Nullable ResourceLoader resourceLoader) {
@@ -213,13 +212,14 @@ public class RepositoryConfigurationDelegate {
repoScan.end();
if (logger.isInfoEnabled()) {
- logger.info(LogMessage.format("Finished Spring Data repository scanning in %s ms. Found %s %s repository interfaces.",
- watch.getLastTaskTimeMillis(), configurations.size(), extension.getModuleName()));
+ logger.info(
+ LogMessage.format("Finished Spring Data repository scanning in %s ms. Found %s %s repository interfaces.",
+ watch.getLastTaskTimeMillis(), configurations.size(), extension.getModuleName()));
}
// TODO: AOT Processing -> guard this one with a flag so it's not always present
// TODO: With regard to AOT Processing, perhaps we need to be smart and detect whether "core" AOT components are
- // (or rather configuration is) present on the classpath to enable Spring Data AOT component registration.
+ // (or rather configuration is) present on the classpath to enable Spring Data AOT component registration.
registerAotComponents(registry, extension, metadataByRepositoryBeanName);
return definitions;
@@ -239,16 +239,14 @@ public class RepositoryConfigurationDelegate {
Supplier>> args = () -> {
Set packages = metadataByRepositoryBeanName.values().stream()
- .flatMap(it -> it.getBasePackages().stream())
- .collect(Collectors.toSet());
+ .flatMap(it -> it.getBasePackages().stream()).collect(Collectors.toSet());
return new TypeScanner(resourceLoader.getClassLoader())
- .scanForTypesAnnotatedWith(extensionSupport.getIdentifyingAnnotations())
- .inPackages(packages);
+ .scanForTypesAnnotatedWith(extensionSupport.getIdentifyingAnnotations()).inPackages(packages);
};
- registry.registerBeanDefinition(targetManagedTypesBeanName, BeanDefinitionBuilder
- .rootBeanDefinition(ManagedTypesBean.class).addConstructorArgValue(args).getBeanDefinition());
+// registry.registerBeanDefinition(targetManagedTypesBeanName, BeanDefinitionBuilder
+// .rootBeanDefinition(ManagedTypesBean.class).addConstructorArgValue(args).getBeanDefinition());
}
}
@@ -259,8 +257,7 @@ public class RepositoryConfigurationDelegate {
if (!registry.isBeanNameInUse(repositoryAotProcessorBeanName)) {
BeanDefinitionBuilder repositoryAotProcessor = BeanDefinitionBuilder
- .rootBeanDefinition(extension.getRepositoryAotProcessor())
- .setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
+ .rootBeanDefinition(extension.getRepositoryAotProcessor()).setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
repositoryAotProcessor.addPropertyValue("configMap", metadataByRepositoryBeanName);
@@ -314,8 +311,8 @@ public class RepositoryConfigurationDelegate {
* than a single type is considered a multi-store configuration scenario which will trigger stricter repository
* scanning.
*
- * @return {@literal true} if multiple data store repository implementations are present in the application.
- * This typically means an Spring application is using more than 1 type of data store.
+ * @return {@literal true} if multiple data store repository implementations are present in the application. This
+ * typically means an Spring application is using more than 1 type of data store.
*/
private boolean multipleStoresDetected() {
@@ -360,12 +357,12 @@ public class RepositoryConfigurationDelegate {
}
/**
- * Returns a new {@link LazyRepositoryInjectionPointResolver} that will have its configurations augmented with
- * the given ones.
+ * Returns a new {@link LazyRepositoryInjectionPointResolver} that will have its configurations augmented with the
+ * given ones.
*
* @param configurations must not be {@literal null}.
- * @return a new {@link LazyRepositoryInjectionPointResolver} that will have its configurations augmented with
- * the given ones.
+ * @return a new {@link LazyRepositoryInjectionPointResolver} that will have its configurations augmented with the
+ * given ones.
*/
LazyRepositoryInjectionPointResolver withAdditionalConfigurations(
Map> configurations) {
@@ -397,18 +394,19 @@ public class RepositoryConfigurationDelegate {
return lazyInit;
}
- static class ManagedTypesBean implements ManagedTypes {
+ }
- private final Lazy>> types;
+ public static class ManagedTypesBean implements ManagedTypes {
- public ManagedTypesBean(Supplier>> types) {
- this.types = Lazy.of(types);
- }
+ private final Lazy>> types;
- @Override
- public void forEach(@NonNull Consumer> action) {
- types.get().forEach(action);
- }
+ public ManagedTypesBean(Supplier>> types) {
+ this.types = Lazy.of(types);
+ }
+
+ @Override
+ public void forEach(@NonNull Consumer> action) {
+ types.get().forEach(action);
}
}
}
diff --git a/src/main/resources/META-INF/spring/aot.factories b/src/main/resources/META-INF/spring/aot.factories
index 5d378a6dd..1d7fea66b 100644
--- a/src/main/resources/META-INF/spring/aot.factories
+++ b/src/main/resources/META-INF/spring/aot.factories
@@ -1,2 +1,4 @@
org.springframework.beans.factory.aot.BeanFactoryInitializationAotProcessor=\
org.springframework.data.aot.SpringDataBeanFactoryInitializationAotProcessor
+org.springframework.aot.hint.RuntimeHintsRegistrar=\
+ org.springframework.data.aot.DataRuntimeHints