diff --git a/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/config/GatewayMvcRuntimeHintsProcessor.java b/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/config/GatewayMvcRuntimeHintsProcessor.java index fb78da79..b133a5cc 100644 --- a/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/config/GatewayMvcRuntimeHintsProcessor.java +++ b/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/config/GatewayMvcRuntimeHintsProcessor.java @@ -29,6 +29,7 @@ import org.apache.commons.logging.LogFactory; import org.springframework.aot.hint.MemberCategory; import org.springframework.aot.hint.ReflectionHints; import org.springframework.aot.hint.TypeReference; +import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition; import org.springframework.beans.factory.aot.BeanFactoryInitializationAotContribution; import org.springframework.beans.factory.aot.BeanFactoryInitializationAotProcessor; import org.springframework.beans.factory.config.BeanDefinition; @@ -84,7 +85,7 @@ public class GatewayMvcRuntimeHintsProcessor implements BeanFactoryInitializatio private static Set> getTypesToRegister(String packageName) { Set> classesToAdd = new HashSet<>(); - ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false); + ClassPathScanningCandidateComponentProvider provider = buildProvider(); provider.addIncludeFilter(new AssignableTypeFilter(Object.class)); Set components = provider.findCandidateComponents(packageName); for (BeanDefinition component : components) { @@ -104,6 +105,17 @@ public class GatewayMvcRuntimeHintsProcessor implements BeanFactoryInitializatio return classesToAdd; } + private static ClassPathScanningCandidateComponentProvider buildProvider() { + return new ClassPathScanningCandidateComponentProvider(false) { + @SuppressWarnings("NullableProblems") + @Override + protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) { + // Include both concrete classes and interfaces + return beanDefinition.getMetadata().isIndependent() && !beanDefinition.getMetadata().isAnnotation(); + } + }; + } + private static boolean shouldRegisterClass(Class clazz) { Set conditionClasses = beansConditionalOnClasses.getOrDefault(clazz.getName(), Collections.emptySet()); for (String conditionClass : conditionClasses) {