Resolve package cycle between repository and aot packages.
Closes #2707
This commit is contained in:
@@ -25,8 +25,6 @@ import org.springframework.beans.factory.support.RegisteredBean;
|
||||
import org.springframework.core.DecoratingProxy;
|
||||
import org.springframework.data.domain.AuditorAware;
|
||||
import org.springframework.data.domain.ReactiveAuditorAware;
|
||||
import org.springframework.data.repository.util.ReactiveWrappers;
|
||||
import org.springframework.data.repository.util.ReactiveWrappers.ReactiveLibrary;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
@@ -40,6 +38,9 @@ import org.springframework.util.ClassUtils;
|
||||
*/
|
||||
class AuditingBeanRegistrationAotProcessor implements BeanRegistrationAotProcessor {
|
||||
|
||||
private static final boolean PROJECT_REACTOR_PRESENT = ClassUtils.isPresent("reactor.core.publisher.Flux",
|
||||
AuditingBeanRegistrationAotProcessor.class.getClassLoader());
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) {
|
||||
@@ -49,7 +50,7 @@ class AuditingBeanRegistrationAotProcessor implements BeanRegistrationAotProcess
|
||||
generationContext.getRuntimeHints());
|
||||
}
|
||||
|
||||
if (ReactiveWrappers.isAvailable(ReactiveLibrary.PROJECT_REACTOR) && isReactiveAuditorAware(registeredBean)) {
|
||||
if (PROJECT_REACTOR_PRESENT && isReactiveAuditorAware(registeredBean)) {
|
||||
return (generationContext, beanRegistrationCode) -> registerSpringProxy(ReactiveAuditorAware.class,
|
||||
generationContext.getRuntimeHints());
|
||||
}
|
||||
|
||||
@@ -13,12 +13,13 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.aot;
|
||||
package org.springframework.data.repository.aot;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.core.annotation.MergedAnnotation;
|
||||
import org.springframework.data.aot.AotContext;
|
||||
import org.springframework.data.repository.core.RepositoryInformation;
|
||||
|
||||
/**
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.aot;
|
||||
package org.springframework.data.repository.aot;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collection;
|
||||
@@ -43,29 +43,29 @@ class AotRepositoryInformation extends RepositoryInformationSupport implements R
|
||||
this.fragments = fragments;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return configured repository fragments.
|
||||
* @since 3.0
|
||||
*/
|
||||
@Override
|
||||
public Set<RepositoryFragment<?>> getFragments() {
|
||||
return new LinkedHashSet<>(fragments.get());
|
||||
}
|
||||
|
||||
// Not required during AOT processing.
|
||||
@Override
|
||||
public boolean isCustomMethod(Method method) {
|
||||
// TODO:
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBaseClassMethod(Method method) {
|
||||
// TODO
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Method getTargetClassMethod(Method method) {
|
||||
// TODO
|
||||
return method;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return configured repository fragments.
|
||||
* @since 3.0
|
||||
*/
|
||||
public Set<RepositoryFragment<?>> getFragments() {
|
||||
return new LinkedHashSet<>(fragments.get());
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.aot;
|
||||
package org.springframework.data.repository.aot;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.LinkedHashSet;
|
||||
@@ -22,6 +22,9 @@ import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.core.annotation.MergedAnnotation;
|
||||
import org.springframework.data.aot.AotContext;
|
||||
import org.springframework.data.aot.TypeCollector;
|
||||
import org.springframework.data.aot.TypeUtils;
|
||||
import org.springframework.data.repository.core.RepositoryInformation;
|
||||
import org.springframework.data.util.Lazy;
|
||||
|
||||
@@ -104,12 +107,12 @@ class DefaultAotRepositoryContext implements AotRepositoryContext {
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeIntrospector introspectType(String typeName) {
|
||||
public AotContext.TypeIntrospector introspectType(String typeName) {
|
||||
return aotContext.introspectType(typeName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IntrospectedBeanDefinition introspectBeanDefinition(String beanName) {
|
||||
public AotContext.IntrospectedBeanDefinition introspectBeanDefinition(String beanName) {
|
||||
return aotContext.introspectBeanDefinition(beanName);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.aot;
|
||||
package org.springframework.data.repository.aot;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@@ -81,9 +81,8 @@ class RepositoryBeanDefinitionReader {
|
||||
}));
|
||||
}
|
||||
|
||||
static Supplier<org.springframework.data.repository.core.RepositoryMetadata> metadataSupplier(
|
||||
private static Supplier<org.springframework.data.repository.core.RepositoryMetadata> metadataSupplier(
|
||||
RepositoryConfiguration<?> metadata, ConfigurableListableBeanFactory beanFactory) {
|
||||
|
||||
return Lazy.of(() -> new DefaultRepositoryMetadata(forName(metadata.getRepositoryInterface(), beanFactory)));
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.aot;
|
||||
package org.springframework.data.repository.aot;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.annotation.Annotation;
|
||||
@@ -41,7 +41,9 @@ import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.core.DecoratingProxy;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.core.annotation.MergedAnnotation;
|
||||
import org.springframework.data.aot.AotContext;
|
||||
import org.springframework.data.aot.TypeContributor;
|
||||
import org.springframework.data.aot.TypeUtils;
|
||||
import org.springframework.data.projection.EntityProjectionIntrospector;
|
||||
import org.springframework.data.projection.TargetAware;
|
||||
import org.springframework.data.repository.Repository;
|
||||
@@ -73,7 +75,7 @@ public class RepositoryRegistrationAotContribution implements BeanRegistrationAo
|
||||
* which this contribution was created.
|
||||
* @return a new instance of {@link RepositoryRegistrationAotContribution}.
|
||||
* @throws IllegalArgumentException if the {@link RepositoryRegistrationAotProcessor} is {@literal null}.
|
||||
* @see org.springframework.data.aot.RepositoryRegistrationAotProcessor
|
||||
* @see RepositoryRegistrationAotProcessor
|
||||
*/
|
||||
public static RepositoryRegistrationAotContribution fromProcessor(
|
||||
RepositoryRegistrationAotProcessor repositoryRegistrationAotProcessor) {
|
||||
@@ -94,7 +96,7 @@ public class RepositoryRegistrationAotContribution implements BeanRegistrationAo
|
||||
* @param repositoryRegistrationAotProcessor reference back to the {@link RepositoryRegistrationAotProcessor} from
|
||||
* which this contribution was created.
|
||||
* @throws IllegalArgumentException if the {@link RepositoryRegistrationAotProcessor} is {@literal null}.
|
||||
* @see org.springframework.data.aot.RepositoryRegistrationAotProcessor
|
||||
* @see RepositoryRegistrationAotProcessor
|
||||
*/
|
||||
protected RepositoryRegistrationAotContribution(
|
||||
RepositoryRegistrationAotProcessor repositoryRegistrationAotProcessor) {
|
||||
@@ -232,10 +234,6 @@ public class RepositoryRegistrationAotContribution implements BeanRegistrationAo
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isRepositoryWithTypeParameters(ResolvableType type) {
|
||||
return type.getGenerics().length == 3;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link BiConsumer Callback} for data module specific contributions.
|
||||
*
|
||||
@@ -380,24 +378,14 @@ public class RepositoryRegistrationAotContribution implements BeanRegistrationAo
|
||||
|| ClassUtils.isPrimitiveArray(type); //
|
||||
}
|
||||
|
||||
static boolean isSpringDataManagedAnnotation(@Nullable MergedAnnotation<?> annotation) {
|
||||
|
||||
return annotation != null && (isInSpringDataNamespace(annotation.getType())
|
||||
|| annotation.getMetaTypes().stream().anyMatch(RepositoryRegistrationAotContribution::isInSpringDataNamespace));
|
||||
}
|
||||
|
||||
static boolean isInSpringDataNamespace(Class<?> type) {
|
||||
return type.getPackage().getName().startsWith(TypeContributor.DATA_NAMESPACE);
|
||||
}
|
||||
|
||||
static void contributeType(Class<?> type, GenerationContext generationContext) {
|
||||
TypeContributor.contribute(type, it -> true, generationContext);
|
||||
}
|
||||
|
||||
// TODO What was this meant to be used for? Was this type filter maybe meant to be used in
|
||||
// the TypeContributor.contribute(:Class, :Predicate :GenerationContext) method
|
||||
// used in the contributeType(..) method above?
|
||||
public Predicate<Class<?>> typeFilter() { // like only document ones. // TODO: As in MongoDB?
|
||||
return it -> true;
|
||||
}
|
||||
|
||||
private static boolean isRepositoryWithTypeParameters(ResolvableType type) {
|
||||
return type.getGenerics().length == 3;
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.aot;
|
||||
package org.springframework.data.repository.aot;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.Collections;
|
||||
@@ -35,6 +35,7 @@ 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.aot.TypeContributor;
|
||||
import org.springframework.data.repository.config.RepositoryConfiguration;
|
||||
import org.springframework.data.repository.config.RepositoryConfigurationExtension;
|
||||
import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport;
|
||||
@@ -83,11 +84,11 @@ public class RepositoryRegistrationAotProcessor implements BeanRegistrationAotPr
|
||||
|
||||
repositoryContext.getResolvedTypes().stream()
|
||||
.filter(it -> !RepositoryRegistrationAotContribution.isJavaOrPrimitiveType(it))
|
||||
.forEach(it -> RepositoryRegistrationAotContribution.contributeType(it, generationContext));
|
||||
.forEach(it -> RepositoryRegistrationAotProcessor.contributeType(it, generationContext));
|
||||
|
||||
repositoryContext.getResolvedAnnotations().stream()
|
||||
.filter(RepositoryRegistrationAotContribution::isSpringDataManagedAnnotation).map(MergedAnnotation::getType)
|
||||
.forEach(it -> RepositoryRegistrationAotContribution.contributeType(it, generationContext));
|
||||
.filter(RepositoryRegistrationAotProcessor::isSpringDataManagedAnnotation).map(MergedAnnotation::getType)
|
||||
.forEach(it -> RepositoryRegistrationAotProcessor.contributeType(it, generationContext));
|
||||
}
|
||||
|
||||
private boolean isRepositoryBean(RegisteredBean bean) {
|
||||
@@ -161,4 +162,18 @@ public class RepositoryRegistrationAotProcessor implements BeanRegistrationAotPr
|
||||
protected void logTrace(String message, Object... arguments) {
|
||||
logAt(Log::isTraceEnabled, Log::trace, message, arguments);
|
||||
}
|
||||
|
||||
private static boolean isSpringDataManagedAnnotation(@Nullable MergedAnnotation<?> annotation) {
|
||||
|
||||
return annotation != null && (isInSpringDataNamespace(annotation.getType())
|
||||
|| annotation.getMetaTypes().stream().anyMatch(RepositoryRegistrationAotProcessor::isInSpringDataNamespace));
|
||||
}
|
||||
|
||||
private static void contributeType(Class<?> type, GenerationContext generationContext) {
|
||||
TypeContributor.contribute(type, it -> true, generationContext);
|
||||
}
|
||||
|
||||
private static boolean isInSpringDataNamespace(Class<?> type) {
|
||||
return type.getPackage().getName().startsWith(TypeContributor.DATA_NAMESPACE);
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.aot.hint;
|
||||
package org.springframework.data.repository.aot.hint;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Properties;
|
||||
@@ -2,4 +2,4 @@
|
||||
* Predefined Runtime Hints.
|
||||
*/
|
||||
@org.springframework.lang.NonNullApi
|
||||
package org.springframework.data.aot.hint;
|
||||
package org.springframework.data.repository.aot.hint;
|
||||
@@ -0,0 +1,5 @@
|
||||
/**
|
||||
* Support for processing of repositories with Ahead of Time compilation.
|
||||
*/
|
||||
@org.springframework.lang.NonNullApi
|
||||
package org.springframework.data.repository.aot;
|
||||
@@ -18,15 +18,13 @@ package org.springframework.data.repository.config;
|
||||
import java.util.Collection;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.springframework.beans.factory.aot.BeanRegistrationAotContribution;
|
||||
import org.springframework.beans.factory.aot.BeanRegistrationAotProcessor;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.data.aot.RepositoryRegistrationAotProcessor;
|
||||
import org.springframework.data.repository.aot.RepositoryRegistrationAotProcessor;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* SPI to implement store specific extension to the repository bean definition registration process.
|
||||
@@ -46,9 +44,7 @@ public interface RepositoryConfigurationExtension {
|
||||
*/
|
||||
default String getModuleIdentifier() {
|
||||
|
||||
return getModuleName()
|
||||
.toLowerCase(Locale.ENGLISH)
|
||||
.replace(' ', '-');
|
||||
return getModuleName().toLowerCase(Locale.ENGLISH).replace(' ', '-');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -63,7 +59,7 @@ public interface RepositoryConfigurationExtension {
|
||||
* required by the Spring Data Repository infrastructure components at native runtime.
|
||||
*
|
||||
* @return the {@link BeanRegistrationAotProcessor} type responsible for contributing AOT/native configuration.
|
||||
* Defaults to {@link RepositoryRegistrationAotProcessor}. Must not be {@literal null}.
|
||||
* Defaults to {@link RepositoryRegistrationAotProcessor}. Must not be {@literal null}.
|
||||
* @see org.springframework.beans.factory.aot.BeanRegistrationAotProcessor
|
||||
* @since 3.0
|
||||
*/
|
||||
@@ -75,8 +71,8 @@ public interface RepositoryConfigurationExtension {
|
||||
/**
|
||||
* Returns all {@link RepositoryConfiguration}s obtained through the given {@link RepositoryConfigurationSource}.
|
||||
*
|
||||
* @param configSource {@link RepositoryConfigurationSource} encapsulating the source (XML, Annotation) of
|
||||
* the repository configuration.
|
||||
* @param configSource {@link RepositoryConfigurationSource} encapsulating the source (XML, Annotation) of the
|
||||
* repository configuration.
|
||||
* @param loader {@link ResourceLoader} used to load resources.
|
||||
* @param strictMatchesOnly whether to return strict repository matches only. Handing in {@literal true} will cause
|
||||
* the repository interfaces and domain types handled to be checked whether they are managed by the current
|
||||
@@ -107,8 +103,8 @@ public interface RepositoryConfigurationExtension {
|
||||
* repositories bean definitions have been registered.
|
||||
*
|
||||
* @param registry {@link BeanDefinitionRegistry} containing bean definitions.
|
||||
* @param configurationSource {@link RepositoryConfigurationSource} encapsulating the source (e.g. XML, Annotation)
|
||||
* of the repository configuration.
|
||||
* @param configurationSource {@link RepositoryConfigurationSource} encapsulating the source (e.g. XML, Annotation) of
|
||||
* the repository configuration.
|
||||
*/
|
||||
void registerBeansForRoot(BeanDefinitionRegistry registry, RepositoryConfigurationSource configurationSource);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user