diff --git a/CHANGELOG.md b/CHANGELOG.md index 0085b56c7..cde3a78d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,4 +2,5 @@ --- - [Bugfix: optimize ratelimit actuator](https://github.com/Tencent/spring-cloud-tencent/pull/420) -- [Feature: add rate limit filter debug log](https://github.com/Tencent/spring-cloud-tencent/pull/437) +- [Optimize: add EncodeTransferMedataRestTemplateInterceptor to RestTemplate](https://github.com/Tencent/spring-cloud-tencent/pull/440) +- [Feature: add rate limit filter debug log](https://github.com/Tencent/spring-cloud-tencent/pull/437) \ No newline at end of file diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/config/MetadataTransferAutoConfiguration.java b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/config/MetadataTransferAutoConfiguration.java index e1e8b0912..ed5d9c8fa 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/config/MetadataTransferAutoConfiguration.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/config/MetadataTransferAutoConfiguration.java @@ -18,8 +18,9 @@ package com.tencent.cloud.metadata.config; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; -import java.util.Map; import com.tencent.cloud.common.constant.MetadataConstant; import com.tencent.cloud.metadata.core.DecodeTransferMetadataReactiveFilter; @@ -28,19 +29,15 @@ import com.tencent.cloud.metadata.core.EncodeTransferMedataFeignInterceptor; import com.tencent.cloud.metadata.core.EncodeTransferMedataRestTemplateInterceptor; import com.tencent.cloud.metadata.core.EncodeTransferMedataScgFilter; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.beans.factory.SmartInitializingSingleton; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.cloud.gateway.filter.GlobalFilter; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.client.ClientHttpRequestInterceptor; -import org.springframework.lang.NonNull; -import org.springframework.util.CollectionUtils; import org.springframework.web.client.RestTemplate; import static javax.servlet.DispatcherType.ASYNC; @@ -124,9 +121,10 @@ public class MetadataTransferAutoConfiguration { */ @Configuration(proxyBeanMethods = false) @ConditionalOnClass(name = "org.springframework.web.client.RestTemplate") - protected static class MetadataTransferRestTemplateConfig implements ApplicationContextAware { + protected static class MetadataTransferRestTemplateConfig { - private ApplicationContext context; + @Autowired(required = false) + private List restTemplates = Collections.emptyList(); @Bean public EncodeTransferMedataRestTemplateInterceptor encodeTransferMedataRestTemplateInterceptor() { @@ -134,60 +132,12 @@ public class MetadataTransferAutoConfiguration { } @Bean - BeanPostProcessor encodeTransferMetadataRestTemplatePostProcessor( - EncodeTransferMedataRestTemplateInterceptor encodeTransferMedataRestTemplateInterceptor) { - // Coping with multiple bean injection scenarios - Map beans = this.context - .getBeansOfType(RestTemplate.class); - // If the restTemplate has been created when the - // MetadataRestTemplatePostProcessor Bean - // is initialized, then manually set the interceptor. - if (!CollectionUtils.isEmpty(beans)) { - for (RestTemplate restTemplate : beans.values()) { - List interceptors = restTemplate.getInterceptors(); - // Avoid setting interceptor repeatedly. - if (!interceptors.contains(encodeTransferMedataRestTemplateInterceptor)) { - interceptors.add(encodeTransferMedataRestTemplateInterceptor); - restTemplate.setInterceptors(interceptors); - } - } - } - return new EncodeTransferMetadataRestTemplatePostProcessor(encodeTransferMedataRestTemplateInterceptor); - } - - @Override - public void setApplicationContext(@NonNull ApplicationContext applicationContext) throws BeansException { - this.context = applicationContext; - } - - public static class EncodeTransferMetadataRestTemplatePostProcessor - implements BeanPostProcessor { - - private final EncodeTransferMedataRestTemplateInterceptor encodeTransferMedataRestTemplateInterceptor; - - EncodeTransferMetadataRestTemplatePostProcessor( - EncodeTransferMedataRestTemplateInterceptor encodeTransferMedataRestTemplateInterceptor) { - this.encodeTransferMedataRestTemplateInterceptor = encodeTransferMedataRestTemplateInterceptor; - } - - @Override - public Object postProcessBeforeInitialization(@NonNull Object bean, @NonNull String beanName) { - return bean; - } - - @Override - public Object postProcessAfterInitialization(@NonNull Object bean, @NonNull String beanName) { - if (bean instanceof RestTemplate) { - RestTemplate restTemplate = (RestTemplate) bean; - List interceptors = restTemplate.getInterceptors(); - // Avoid setting interceptor repeatedly. - if (!interceptors.contains(encodeTransferMedataRestTemplateInterceptor)) { - interceptors.add(this.encodeTransferMedataRestTemplateInterceptor); - restTemplate.setInterceptors(interceptors); - } - } - return bean; - } + public SmartInitializingSingleton addEncodeTransferMedataInterceptorForRestTemplate(EncodeTransferMedataRestTemplateInterceptor interceptor) { + return () -> restTemplates.forEach(restTemplate -> { + List list = new ArrayList<>(restTemplate.getInterceptors()); + list.add(interceptor); + restTemplate.setInterceptors(list); + }); } } } diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/config/MetadataTransferAutoConfigurationTest.java b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/config/MetadataTransferAutoConfigurationTest.java index a6b266431..f95036fe4 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/config/MetadataTransferAutoConfigurationTest.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/config/MetadataTransferAutoConfigurationTest.java @@ -18,6 +18,12 @@ package com.tencent.cloud.metadata.config; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + import com.tencent.cloud.metadata.core.EncodeTransferMedataFeignInterceptor; import com.tencent.cloud.metadata.core.EncodeTransferMedataRestTemplateInterceptor; import org.assertj.core.api.Assertions; @@ -25,7 +31,12 @@ import org.junit.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.cloud.gateway.filter.GlobalFilter; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.client.ClientHttpRequestInterceptor; +import org.springframework.web.client.RestTemplate; /** * Test for {@link MetadataTransferAutoConfiguration}. @@ -49,12 +60,49 @@ public class MetadataTransferAutoConfigurationTest { Assertions.assertThat(context) .hasSingleBean(MetadataTransferAutoConfiguration.MetadataTransferRestTemplateConfig.class); Assertions.assertThat(context).hasSingleBean(EncodeTransferMedataRestTemplateInterceptor.class); - Assertions.assertThat(context).hasSingleBean( - MetadataTransferAutoConfiguration.MetadataTransferRestTemplateConfig - .EncodeTransferMetadataRestTemplatePostProcessor.class); Assertions.assertThat(context) .hasSingleBean(MetadataTransferAutoConfiguration.MetadataTransferScgFilterConfig.class); Assertions.assertThat(context).hasSingleBean(GlobalFilter.class); }); } + + + @Test + public void test2() { + this.applicationContextRunner + .withConfiguration( + AutoConfigurations.of(MetadataTransferAutoConfiguration.class, RestTemplateConfiguration.class)) + .run(context -> { + Assertions.assertThat(context) + .hasSingleBean(EncodeTransferMedataFeignInterceptor.class); + EncodeTransferMedataRestTemplateInterceptor encodeTransferMedataRestTemplateInterceptor = context.getBean(EncodeTransferMedataRestTemplateInterceptor.class); + Map restTemplateMap = context.getBeansOfType(RestTemplate.class); + Assertions.assertThat(restTemplateMap.size()).isEqualTo(2); + for (String beanName : Arrays.asList("restTemplate", "loadBalancedRestTemplate")) { + RestTemplate restTemplate = restTemplateMap.get(beanName); + Assertions.assertThat(restTemplate).isNotNull(); + List encodeTransferMedataFeignInterceptorList = restTemplate.getInterceptors() + .stream() + .filter(interceptor -> Objects.equals(interceptor, encodeTransferMedataRestTemplateInterceptor)) + .collect(Collectors.toList()); + //EncodeTransferMedataFeignInterceptor is not added repeatedly + Assertions.assertThat(encodeTransferMedataFeignInterceptorList.size()).isEqualTo(1); + } + }); + } + + @Configuration + static class RestTemplateConfiguration { + + @Bean + public RestTemplate restTemplate() { + return new RestTemplate(); + } + + @LoadBalanced + @Bean + public RestTemplate loadBalancedRestTemplate() { + return new RestTemplate(); + } + } }