Browse Source

Fix registration of hints for Configurables conditional on classes.

fix-hints-for-configurables-with-conditionals
Olga Maciaszek-Sharma 2 years ago
parent
commit
2c30b70f77
  1. 45
      spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/ConfigurableHintsRegistrationProcessor.java

45
spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/ConfigurableHintsRegistrationProcessor.java

@ -17,7 +17,9 @@
package org.springframework.cloud.gateway.config; package org.springframework.cloud.gateway.config;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -32,6 +34,12 @@ import org.springframework.beans.factory.aot.BeanFactoryInitializationAotContrib
import org.springframework.beans.factory.aot.BeanFactoryInitializationAotProcessor; import org.springframework.beans.factory.aot.BeanFactoryInitializationAotProcessor;
import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.cloud.gateway.filter.factory.FallbackHeadersGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.factory.JsonToGrpcGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.factory.SpringCloudCircuitBreakerResilience4JFilterFactory;
import org.springframework.cloud.gateway.filter.factory.TokenRelayGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.factory.cache.LocalResponseCacheGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.ratelimit.RedisRateLimiter;
import org.springframework.cloud.gateway.support.Configurable; import org.springframework.cloud.gateway.support.Configurable;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.ResolvableType; import org.springframework.core.ResolvableType;
@ -51,6 +59,26 @@ class ConfigurableHintsRegistrationProcessor implements BeanFactoryInitializatio
private static final String ROOT_GATEWAY_PACKAGE_NAME = "org.springframework.cloud.gateway"; private static final String ROOT_GATEWAY_PACKAGE_NAME = "org.springframework.cloud.gateway";
private static final Set<String> circuitBreakerConditionalClasses = Set.of(
"org.springframework.web.reactive.DispatcherHandler",
"org.springframework.cloud.circuitbreaker.resilience4j.ReactiveResilience4JAutoConfiguration",
"org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreakerFactory",
"org.springframework.cloud.circuitbreaker.resilience4j.ReactiveResilience4JCircuitBreakerFactory");
private static final Map<Class<?>, Set<String>> beansConditionalOnClasses = Map.of(
TokenRelayGatewayFilterFactory.class,
Set.of("org.springframework.security.oauth2.client.OAuth2AuthorizedClient",
"org.springframework.security.web.server.SecurityWebFilterChain",
"org.springframework.boot.autoconfigure.security.SecurityProperties"),
JsonToGrpcGatewayFilterFactory.class, Set.of("io.grpc.Channel"), RedisRateLimiter.class,
Set.of("org.springframework.data.redis.core.RedisTemplate",
"org.springframework.web.reactive.DispatcherHandler"),
SpringCloudCircuitBreakerResilience4JFilterFactory.class, circuitBreakerConditionalClasses,
FallbackHeadersGatewayFilterFactory.class, circuitBreakerConditionalClasses,
LocalResponseCacheGatewayFilterFactory.class,
Set.of("com.github.benmanes.caffeine.cache.Weigher", "com.github.benmanes.caffeine.cache.Caffeine",
"org.springframework.cache.caffeine.CaffeineCacheManager"));
@Override @Override
public BeanFactoryInitializationAotContribution processAheadOfTime(ConfigurableListableBeanFactory beanFactory) { public BeanFactoryInitializationAotContribution processAheadOfTime(ConfigurableListableBeanFactory beanFactory) {
return (generationContext, beanFactoryInitializationCode) -> { return (generationContext, beanFactoryInitializationCode) -> {
@ -86,7 +114,9 @@ class ConfigurableHintsRegistrationProcessor implements BeanFactoryInitializatio
Class clazz; Class clazz;
try { try {
clazz = Class.forName(component.getBeanClassName()); clazz = Class.forName(component.getBeanClassName());
classesToAdd.add(clazz); if (shouldRegisterClass(clazz)) {
classesToAdd.add(clazz);
}
} }
catch (NoClassDefFoundError | ClassNotFoundException exception) { catch (NoClassDefFoundError | ClassNotFoundException exception) {
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
@ -97,4 +127,17 @@ class ConfigurableHintsRegistrationProcessor implements BeanFactoryInitializatio
return classesToAdd; return classesToAdd;
} }
private static boolean shouldRegisterClass(Class<?> clazz) {
Set<String> conditionClasses = beansConditionalOnClasses.getOrDefault(clazz, Collections.emptySet());
for (String conditionClass : conditionClasses) {
try {
ConfigurableHintsRegistrationProcessor.class.getClassLoader().loadClass(conditionClass);
}
catch (ClassNotFoundException e) {
return false;
}
}
return true;
}
} }

Loading…
Cancel
Save