From c44782d8b4e70871712519c265ebe66ea741b834 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Wed, 30 Nov 2022 19:33:14 +0100 Subject: [PATCH] Add native image support. --- .../openfeign/FeignAutoConfiguration.java | 19 +++++++++++++++++++ .../openfeign/FeignClientsRegistrar.java | 2 +- ...BeanFactoryInitializationAotProcessor.java | 11 ++++++++--- .../resources/META-INF/spring/aot.factories | 2 ++ .../cloud/openfeign/aot/FeignAotTests.java | 1 - 5 files changed, 30 insertions(+), 5 deletions(-) create mode 100644 spring-cloud-openfeign-core/src/main/resources/META-INF/spring/aot.factories diff --git a/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignAutoConfiguration.java b/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignAutoConfiguration.java index eff4d407..cf1906ae 100644 --- a/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignAutoConfiguration.java +++ b/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignAutoConfiguration.java @@ -44,6 +44,10 @@ import okhttp3.ConnectionPool; import org.apache.commons.logging.Log; 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.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; @@ -73,6 +77,7 @@ import org.springframework.security.oauth2.client.AuthorizedClientServiceOAuth2A import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager; import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService; import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; +import org.springframework.util.ClassUtils; /** * @author Spencer Gibb @@ -373,3 +378,17 @@ public class FeignAutoConfiguration { } } + +class FeignHints implements RuntimeHintsRegistrar { + + @Override + public void registerHints(RuntimeHints hints, ClassLoader classLoader) { + if (!ClassUtils.isPresent("feign.Feign", classLoader)) { + return; + } + hints.reflection().registerType(TypeReference.of(FeignClientFactoryBean.class), + hint -> hint.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, + MemberCategory.INVOKE_DECLARED_METHODS, MemberCategory.DECLARED_FIELDS)); + } + +} diff --git a/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignClientsRegistrar.java b/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignClientsRegistrar.java index 39ccf2c6..4fed0bb1 100644 --- a/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignClientsRegistrar.java +++ b/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignClientsRegistrar.java @@ -71,7 +71,7 @@ import org.springframework.util.StringUtils; class FeignClientsRegistrar implements ImportBeanDefinitionRegistrar, ResourceLoaderAware, EnvironmentAware { // patterned after Spring Integration IntegrationComponentScanRegistrar - // and RibbonClientsConfigurationRegistgrar + // and RibbonClientsConfigurationRegistrar private ResourceLoader resourceLoader; diff --git a/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/aot/FeignClientBeanFactoryInitializationAotProcessor.java b/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/aot/FeignClientBeanFactoryInitializationAotProcessor.java index d219d7db..ff32f5ba 100644 --- a/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/aot/FeignClientBeanFactoryInitializationAotProcessor.java +++ b/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/aot/FeignClientBeanFactoryInitializationAotProcessor.java @@ -25,6 +25,7 @@ import javax.lang.model.element.Modifier; import org.springframework.aot.generate.GenerationContext; import org.springframework.aot.generate.MethodReference; +import org.springframework.aot.hint.ProxyHints; import org.springframework.beans.MutablePropertyValues; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.FactoryBean; @@ -100,16 +101,20 @@ public class FeignClientBeanFactoryInitializationAotProcessor @Override public void applyTo(GenerationContext generationContext, BeanFactoryInitializationCode beanFactoryInitializationCode) { + ProxyHints proxyHints = generationContext.getRuntimeHints().proxies(); Set feignClientRegistrationMethods = feignClientBeanDefinitions.values().stream() .map(beanDefinition -> { Assert.notNull(beanDefinition, "beanDefinition cannot be null"); Assert.isInstanceOf(GenericBeanDefinition.class, beanDefinition); GenericBeanDefinition registeredBeanDefinition = (GenericBeanDefinition) beanDefinition; MutablePropertyValues feignClientProperties = registeredBeanDefinition.getPropertyValues(); + String className = (String) feignClientProperties.get("type"); + Assert.notNull(className, "className cannot be null"); + Class clazz = ClassUtils.resolveClassName(className, null); + proxyHints.registerJdkProxy(clazz); return beanFactoryInitializationCode.getMethods() - .add(buildMethodName((String) feignClientProperties.get("type")), - method -> generateFeignClientRegistrationMethod(method, feignClientProperties, - registeredBeanDefinition)) + .add(buildMethodName(className), method -> generateFeignClientRegistrationMethod(method, + feignClientProperties, registeredBeanDefinition)) .getName(); }).collect(Collectors.toSet()); MethodReference initializerMethod = beanFactoryInitializationCode.getMethods() diff --git a/spring-cloud-openfeign-core/src/main/resources/META-INF/spring/aot.factories b/spring-cloud-openfeign-core/src/main/resources/META-INF/spring/aot.factories new file mode 100644 index 00000000..9662b382 --- /dev/null +++ b/spring-cloud-openfeign-core/src/main/resources/META-INF/spring/aot.factories @@ -0,0 +1,2 @@ +org.springframework.aot.hint.RuntimeHintsRegistrar=\ +org.springframework.cloud.openfeign.FeignHints diff --git a/spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/aot/FeignAotTests.java b/spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/aot/FeignAotTests.java index de4061b2..f262b946 100644 --- a/spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/aot/FeignAotTests.java +++ b/spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/aot/FeignAotTests.java @@ -160,7 +160,6 @@ public class FeignAotTests { } - // TODO: verify other annotation parameters @FeignClient(value = "test-with-config", configuration = TestConfiguration.class) interface TestFeignClientWithConfig {