Add AOT support for redis repositories.
We now use the AOT infrastructure of Spring Framework 6 and data commons to provide AOT support building the foundation for native image compilation. Additionally we register hints for GraalVM native image. See: #2350
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* 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.redis.aot;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
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.lang.Nullable;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
* @since 3.0
|
||||
*/
|
||||
public class DataRedisRuntimeHints implements RuntimeHintsRegistrar {
|
||||
|
||||
@Override
|
||||
public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) {
|
||||
|
||||
// REFLECTION
|
||||
hints.reflection()
|
||||
.registerTypes(
|
||||
Arrays.asList(TypeReference.of(org.springframework.data.redis.connection.RedisConnection.class),
|
||||
TypeReference.of(org.springframework.data.redis.connection.StringRedisConnection.class),
|
||||
TypeReference.of(org.springframework.data.redis.connection.DefaultedRedisConnection.class),
|
||||
TypeReference.of(org.springframework.data.redis.connection.DefaultedRedisClusterConnection.class),
|
||||
TypeReference.of(org.springframework.data.redis.connection.RedisKeyCommands.class),
|
||||
TypeReference.of(org.springframework.data.redis.connection.RedisStringCommands.class),
|
||||
TypeReference.of(org.springframework.data.redis.connection.RedisListCommands.class),
|
||||
TypeReference.of(org.springframework.data.redis.connection.RedisSetCommands.class),
|
||||
TypeReference.of(org.springframework.data.redis.connection.RedisZSetCommands.class),
|
||||
TypeReference.of(org.springframework.data.redis.connection.RedisHashCommands.class),
|
||||
TypeReference.of(org.springframework.data.redis.connection.RedisTxCommands.class),
|
||||
TypeReference.of(org.springframework.data.redis.connection.RedisPubSubCommands.class),
|
||||
TypeReference.of(org.springframework.data.redis.connection.RedisConnectionCommands.class),
|
||||
TypeReference.of(org.springframework.data.redis.connection.RedisServerCommands.class),
|
||||
TypeReference.of(org.springframework.data.redis.connection.RedisStreamCommands.class),
|
||||
TypeReference.of(org.springframework.data.redis.connection.RedisScriptingCommands.class),
|
||||
TypeReference.of(org.springframework.data.redis.connection.RedisGeoCommands.class),
|
||||
TypeReference.of(org.springframework.data.redis.connection.RedisHyperLogLogCommands.class),
|
||||
TypeReference.of(org.springframework.data.redis.connection.RedisClusterCommands.class),
|
||||
TypeReference.of(org.springframework.data.redis.connection.ReactiveRedisConnection.class),
|
||||
TypeReference.of(org.springframework.data.redis.connection.ReactiveKeyCommands.class),
|
||||
TypeReference.of(org.springframework.data.redis.connection.ReactiveStringCommands.class),
|
||||
TypeReference.of(org.springframework.data.redis.connection.ReactiveListCommands.class),
|
||||
TypeReference.of(org.springframework.data.redis.connection.ReactiveSetCommands.class),
|
||||
TypeReference.of(org.springframework.data.redis.connection.ReactiveZSetCommands.class),
|
||||
TypeReference.of(org.springframework.data.redis.connection.ReactiveHashCommands.class),
|
||||
TypeReference.of(org.springframework.data.redis.connection.ReactivePubSubCommands.class),
|
||||
TypeReference.of(org.springframework.data.redis.connection.ReactiveServerCommands.class),
|
||||
TypeReference.of(org.springframework.data.redis.connection.ReactiveStreamCommands.class),
|
||||
TypeReference.of(org.springframework.data.redis.connection.ReactiveScriptingCommands.class),
|
||||
TypeReference.of(org.springframework.data.redis.connection.ReactiveGeoCommands.class),
|
||||
TypeReference.of(org.springframework.data.redis.connection.ReactiveHyperLogLogCommands.class),
|
||||
TypeReference.of(org.springframework.data.redis.connection.ReactiveClusterKeyCommands.class),
|
||||
TypeReference.of(org.springframework.data.redis.connection.ReactiveClusterStringCommands.class),
|
||||
TypeReference.of(org.springframework.data.redis.connection.ReactiveClusterListCommands.class),
|
||||
TypeReference.of(org.springframework.data.redis.connection.ReactiveClusterSetCommands.class),
|
||||
TypeReference.of(org.springframework.data.redis.connection.ReactiveClusterZSetCommands.class),
|
||||
TypeReference.of(org.springframework.data.redis.connection.ReactiveClusterHashCommands.class),
|
||||
TypeReference.of(org.springframework.data.redis.connection.ReactiveClusterServerCommands.class),
|
||||
TypeReference.of(org.springframework.data.redis.connection.ReactiveClusterStreamCommands.class),
|
||||
TypeReference.of(org.springframework.data.redis.connection.ReactiveClusterScriptingCommands.class),
|
||||
TypeReference.of(org.springframework.data.redis.connection.ReactiveClusterGeoCommands.class),
|
||||
TypeReference.of(org.springframework.data.redis.connection.ReactiveClusterHyperLogLogCommands.class),
|
||||
TypeReference.of(org.springframework.data.redis.core.ReactiveRedisOperations.class),
|
||||
TypeReference.of(org.springframework.data.redis.core.ReactiveRedisTemplate.class),
|
||||
TypeReference.of(org.springframework.data.redis.core.RedisOperations.class),
|
||||
TypeReference.of(org.springframework.data.redis.core.RedisTemplate.class),
|
||||
TypeReference.of(org.springframework.data.redis.core.StringRedisTemplate.class),
|
||||
TypeReference.of(org.springframework.data.keyvalue.annotation.KeySpace.class),
|
||||
TypeReference.of(org.springframework.data.keyvalue.core.AbstractKeyValueAdapter.class),
|
||||
TypeReference.of(org.springframework.data.keyvalue.core.KeyValueAdapter.class),
|
||||
TypeReference.of(org.springframework.data.keyvalue.core.KeyValueOperations.class),
|
||||
TypeReference.of(org.springframework.data.keyvalue.core.KeyValueTemplate.class),
|
||||
TypeReference.of(org.springframework.data.keyvalue.core.mapping.context.KeyValueMappingContext.class),
|
||||
TypeReference.of(org.springframework.data.keyvalue.repository.KeyValueRepository.class),
|
||||
TypeReference
|
||||
.of(org.springframework.data.keyvalue.repository.support.KeyValueRepositoryFactoryBean.class),
|
||||
TypeReference.of(org.springframework.data.keyvalue.repository.config.QueryCreatorType.class),
|
||||
TypeReference.of(org.springframework.data.keyvalue.repository.query.KeyValuePartTreeQuery.class),
|
||||
TypeReference.of(org.springframework.data.redis.core.RedisKeyValueAdapter.class),
|
||||
TypeReference.of(org.springframework.data.redis.core.RedisKeyValueTemplate.class),
|
||||
TypeReference.of(org.springframework.data.redis.core.convert.KeyspaceConfiguration.class),
|
||||
TypeReference.of(org.springframework.data.redis.core.convert.MappingConfiguration.class),
|
||||
TypeReference.of(org.springframework.data.redis.core.convert.MappingRedisConverter.class),
|
||||
TypeReference.of(org.springframework.data.redis.core.convert.RedisConverter.class),
|
||||
TypeReference.of(org.springframework.data.redis.core.convert.RedisCustomConversions.class),
|
||||
TypeReference.of(org.springframework.data.redis.core.convert.ReferenceResolver.class),
|
||||
TypeReference.of(org.springframework.data.redis.core.convert.ReferenceResolverImpl.class),
|
||||
TypeReference.of(org.springframework.data.redis.core.index.IndexConfiguration.class),
|
||||
TypeReference.of(org.springframework.data.redis.core.index.ConfigurableIndexDefinitionProvider.class),
|
||||
TypeReference.of(org.springframework.data.redis.core.mapping.RedisMappingContext.class),
|
||||
TypeReference.of(org.springframework.data.redis.repository.support.RedisRepositoryFactoryBean.class),
|
||||
TypeReference.of(org.springframework.data.redis.repository.query.RedisQueryCreator.class)),
|
||||
hint -> hint.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
|
||||
MemberCategory.INVOKE_PUBLIC_METHODS));
|
||||
|
||||
// PROXIES
|
||||
hints.proxies().registerJdkProxy(TypeReference.of(org.springframework.data.redis.connection.RedisConnection.class));
|
||||
hints.proxies()
|
||||
.registerJdkProxy(TypeReference.of(org.springframework.data.redis.connection.DefaultedRedisConnection.class));
|
||||
hints.proxies()
|
||||
.registerJdkProxy(TypeReference.of(org.springframework.data.redis.connection.ReactiveRedisConnection.class));
|
||||
hints.proxies().registerJdkProxy(
|
||||
TypeReference.of(org.springframework.data.redis.connection.StringRedisConnection.class),
|
||||
TypeReference.of(org.springframework.data.redis.connection.DecoratedRedisConnection.class));
|
||||
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,7 @@ import java.util.Collections;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.data.keyvalue.repository.config.KeyValueRepositoryConfigurationExtension;
|
||||
@@ -51,6 +52,7 @@ public class RedisRepositoryConfigurationExtension extends KeyValueRepositoryCon
|
||||
private static final String REDIS_REFERENCE_RESOLVER_BEAN_NAME = "redisReferenceResolver";
|
||||
private static final String REDIS_ADAPTER_BEAN_NAME = "redisKeyValueAdapter";
|
||||
private static final String REDIS_CUSTOM_CONVERSIONS_BEAN_NAME = "redisCustomConversions";
|
||||
private static final String REDIS_MAPPING_CONFIG_BEAN_NAME = "redisMappingConfiguration";
|
||||
|
||||
@Override
|
||||
public String getModuleName() {
|
||||
@@ -77,8 +79,29 @@ public class RedisRepositoryConfigurationExtension extends KeyValueRepositoryCon
|
||||
"@EnableRedisRepositories(redisTemplateRef = … ) must be configured to a non empty value");
|
||||
}
|
||||
|
||||
registerIfNotAlreadyRegistered(() -> createRedisMappingContext(configuration), registry, MAPPING_CONTEXT_BEAN_NAME,
|
||||
configuration.getSource());
|
||||
// Mapping config
|
||||
|
||||
String mappingConfigBeanName = BeanDefinitionReaderUtils.uniqueBeanName(REDIS_MAPPING_CONFIG_BEAN_NAME, registry);
|
||||
String indexConfigurationBeanName = BeanDefinitionReaderUtils.uniqueBeanName("redisIndexConfiguration", registry);
|
||||
String keyspaceConfigurationBeanName = BeanDefinitionReaderUtils.uniqueBeanName("redisKeyspaceConfiguration",
|
||||
registry);
|
||||
|
||||
registerIfNotAlreadyRegistered(() -> BeanDefinitionBuilder
|
||||
.rootBeanDefinition(configuration.getRequiredAttribute("indexConfiguration", Class.class)) //
|
||||
.setRole(BeanDefinition.ROLE_INFRASTRUCTURE) //
|
||||
.getBeanDefinition(), registry, indexConfigurationBeanName, configuration.getSource());
|
||||
|
||||
registerIfNotAlreadyRegistered(() -> BeanDefinitionBuilder
|
||||
.rootBeanDefinition(configuration.getRequiredAttribute("keyspaceConfiguration", Class.class)) //
|
||||
.setRole(BeanDefinition.ROLE_INFRASTRUCTURE) //
|
||||
.getBeanDefinition(), registry, keyspaceConfigurationBeanName, configuration.getSource());
|
||||
|
||||
registerIfNotAlreadyRegistered(
|
||||
() -> createMappingConfigBeanDef(indexConfigurationBeanName, keyspaceConfigurationBeanName), registry,
|
||||
mappingConfigBeanName, configuration.getSource());
|
||||
|
||||
registerIfNotAlreadyRegistered(() -> createRedisMappingContext(mappingConfigBeanName), registry,
|
||||
MAPPING_CONTEXT_BEAN_NAME, configuration.getSource());
|
||||
|
||||
// Register custom conversions
|
||||
registerIfNotAlreadyRegistered(() -> new RootBeanDefinition(RedisCustomConversions.class), registry,
|
||||
@@ -122,8 +145,7 @@ public class RedisRepositoryConfigurationExtension extends KeyValueRepositoryCon
|
||||
configuration.getRequiredAttribute("enableKeyspaceEvents", EnableKeyspaceEvents.class)) //
|
||||
.addPropertyValue("keyspaceNotificationsConfigParameter",
|
||||
configuration.getAttribute("keyspaceNotificationsConfigParameter", String.class).orElse("")) //
|
||||
.addPropertyValue("shadowCopy",
|
||||
configuration.getRequiredAttribute("shadowCopy", ShadowCopy.class)) //
|
||||
.addPropertyValue("shadowCopy", configuration.getRequiredAttribute("shadowCopy", ShadowCopy.class)) //
|
||||
.getBeanDefinition();
|
||||
}
|
||||
|
||||
@@ -134,26 +156,17 @@ public class RedisRepositoryConfigurationExtension extends KeyValueRepositoryCon
|
||||
.getBeanDefinition();
|
||||
}
|
||||
|
||||
private static AbstractBeanDefinition createRedisMappingContext(RepositoryConfigurationSource configurationSource) {
|
||||
private static AbstractBeanDefinition createRedisMappingContext(String mappingConfigRef) {
|
||||
|
||||
return BeanDefinitionBuilder.rootBeanDefinition(RedisMappingContext.class) //
|
||||
.addConstructorArgValue(createMappingConfigBeanDef(configurationSource)) //
|
||||
.getBeanDefinition();
|
||||
.addConstructorArgReference(mappingConfigRef).getBeanDefinition();
|
||||
}
|
||||
|
||||
private static BeanDefinition createMappingConfigBeanDef(RepositoryConfigurationSource configuration) {
|
||||
|
||||
BeanDefinition indexDefinition = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(configuration.getRequiredAttribute("indexConfiguration", Class.class)) //
|
||||
.getBeanDefinition();
|
||||
|
||||
BeanDefinition keyspaceDefinition = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(configuration.getRequiredAttribute("keyspaceConfiguration", Class.class)) //
|
||||
.getBeanDefinition();
|
||||
private static AbstractBeanDefinition createMappingConfigBeanDef(String indexConfigRef, String keyspaceConfigRef) {
|
||||
|
||||
return BeanDefinitionBuilder.genericBeanDefinition(MappingConfiguration.class) //
|
||||
.addConstructorArgValue(indexDefinition) //
|
||||
.addConstructorArgValue(keyspaceDefinition) //
|
||||
.addConstructorArgReference(indexConfigRef) //
|
||||
.addConstructorArgReference(keyspaceConfigRef) //
|
||||
.getBeanDefinition();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user