|
|
@ -16,12 +16,21 @@ |
|
|
|
|
|
|
|
|
|
|
|
package org.springframework.cloud.loadbalancer.config; |
|
|
|
package org.springframework.cloud.loadbalancer.config; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import java.util.Objects; |
|
|
|
|
|
|
|
import java.util.Set; |
|
|
|
|
|
|
|
import java.util.stream.Collectors; |
|
|
|
|
|
|
|
|
|
|
|
import com.github.benmanes.caffeine.cache.Caffeine; |
|
|
|
import com.github.benmanes.caffeine.cache.Caffeine; |
|
|
|
import com.stoyanr.evictor.ConcurrentMapWithTimedEviction; |
|
|
|
import com.stoyanr.evictor.ConcurrentMapWithTimedEviction; |
|
|
|
import org.apache.commons.logging.Log; |
|
|
|
import org.apache.commons.logging.Log; |
|
|
|
import org.apache.commons.logging.LogFactory; |
|
|
|
import org.apache.commons.logging.LogFactory; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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.InitializingBean; |
|
|
|
import org.springframework.beans.factory.InitializingBean; |
|
|
|
|
|
|
|
import org.springframework.beans.factory.config.BeanDefinition; |
|
|
|
import org.springframework.boot.autoconfigure.AutoConfigureAfter; |
|
|
|
import org.springframework.boot.autoconfigure.AutoConfigureAfter; |
|
|
|
import org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration; |
|
|
|
import org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration; |
|
|
|
import org.springframework.boot.autoconfigure.condition.AllNestedConditions; |
|
|
|
import org.springframework.boot.autoconfigure.condition.AllNestedConditions; |
|
|
@ -39,8 +48,11 @@ import org.springframework.cloud.loadbalancer.cache.DefaultLoadBalancerCacheMana |
|
|
|
import org.springframework.cloud.loadbalancer.cache.LoadBalancerCacheManager; |
|
|
|
import org.springframework.cloud.loadbalancer.cache.LoadBalancerCacheManager; |
|
|
|
import org.springframework.cloud.loadbalancer.cache.LoadBalancerCacheProperties; |
|
|
|
import org.springframework.cloud.loadbalancer.cache.LoadBalancerCacheProperties; |
|
|
|
import org.springframework.context.annotation.Bean; |
|
|
|
import org.springframework.context.annotation.Bean; |
|
|
|
|
|
|
|
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; |
|
|
|
import org.springframework.context.annotation.Conditional; |
|
|
|
import org.springframework.context.annotation.Conditional; |
|
|
|
import org.springframework.context.annotation.Configuration; |
|
|
|
import org.springframework.context.annotation.Configuration; |
|
|
|
|
|
|
|
import org.springframework.core.type.filter.AssignableTypeFilter; |
|
|
|
|
|
|
|
import org.springframework.util.ClassUtils; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* An AutoConfiguration that automatically enables caching when Spring Boot, and Spring |
|
|
|
* An AutoConfiguration that automatically enables caching when Spring Boot, and Spring |
|
|
@ -149,3 +161,52 @@ public class LoadBalancerCacheAutoConfiguration { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Remove after adding hints to GraalVM reachability metadata repo
|
|
|
|
|
|
|
|
class CaffeineHints implements RuntimeHintsRegistrar { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static final Log LOG = LogFactory.getLog(CaffeineHints.class); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static final String CAFFEINE_BOUNDED_LOCAL_CACHE_CLASS_NAME = "com.github.benmanes.caffeine.cache.BoundedLocalCache"; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static final String CAFFEINE_CACHE_BASE_PACKAGE = "com/github/benmanes/caffeine/cache"; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static final String CAFFEINE_NODE_CLASS_NAME = "com.github.benmanes.caffeine.cache.Node"; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public void registerHints(RuntimeHints hints, ClassLoader classLoader) { |
|
|
|
|
|
|
|
if (!ClassUtils.isPresent("com.github.benmanes.caffeine.cache.Caffeine", classLoader)) { |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
hints.reflection() |
|
|
|
|
|
|
|
.registerType(TypeReference.of(Caffeine.class), |
|
|
|
|
|
|
|
hint -> hint.withMembers(MemberCategory.INVOKE_DECLARED_METHODS, |
|
|
|
|
|
|
|
MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)) |
|
|
|
|
|
|
|
.registerType(TypeReference.of("com.github.benmanes.caffeine.cache.BoundedLocalCache"), |
|
|
|
|
|
|
|
hint -> hint.withMembers(MemberCategory.INVOKE_DECLARED_METHODS, |
|
|
|
|
|
|
|
MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)) |
|
|
|
|
|
|
|
.registerType(TypeReference.of("com.github.benmanes.caffeine.cache.LocalCacheFactory"), |
|
|
|
|
|
|
|
hint -> hint.withMembers(MemberCategory.INVOKE_DECLARED_METHODS, |
|
|
|
|
|
|
|
MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)) |
|
|
|
|
|
|
|
.registerType(TypeReference.of("com.github.benmanes.caffeine.cache.Node"), |
|
|
|
|
|
|
|
hint -> hint.withMembers(MemberCategory.INVOKE_DECLARED_METHODS, |
|
|
|
|
|
|
|
MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)); |
|
|
|
|
|
|
|
getCaffeineSubtypes().forEach(cacheType -> hints.reflection().registerType(TypeReference.of(cacheType), |
|
|
|
|
|
|
|
hint -> hint.withMembers(MemberCategory.INVOKE_DECLARED_METHODS, |
|
|
|
|
|
|
|
MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS))); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private Set<String> getCaffeineSubtypes() { |
|
|
|
|
|
|
|
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false); |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
provider.addIncludeFilter(new AssignableTypeFilter(Class.forName(CAFFEINE_BOUNDED_LOCAL_CACHE_CLASS_NAME))); |
|
|
|
|
|
|
|
provider.addIncludeFilter(new AssignableTypeFilter(Class.forName(CAFFEINE_NODE_CLASS_NAME))); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
catch (ClassNotFoundException e) { |
|
|
|
|
|
|
|
LOG.warn("Could not get class for name: " + CAFFEINE_BOUNDED_LOCAL_CACHE_CLASS_NAME); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return provider.findCandidateComponents(CAFFEINE_CACHE_BASE_PACKAGE).stream().filter(Objects::nonNull) |
|
|
|
|
|
|
|
.map(BeanDefinition::getBeanClassName).filter(Objects::nonNull).collect(Collectors.toSet()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|