From fc8a6293e88767a7199c193d3be13924d18277d6 Mon Sep 17 00:00:00 2001 From: wangyu <727842003@qq.com> Date: Wed, 11 Jan 2023 18:46:06 +0800 Subject: [PATCH] =?UTF-8?q?feat:=201.0.2=E7=89=88=E6=9C=AC=E5=8D=87?= =?UTF-8?q?=E7=BA=A7=EF=BC=8C=E6=9B=B4=E6=96=B0=E6=A0=B8=E5=BF=83=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=EF=BC=8C=E8=A7=A3=E8=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 4 +- rest-proxy-api/pom.xml | 2 +- rest-proxy-core/pom.xml | 2 +- .../RestClientConfiguration.java | 17 +++--- .../configuration/RestClientProperties.java | 9 +++- .../factory/DefaultHttpClientProvider.java | 48 +++++++++++++++++ .../core/factory/HttpClientFactoryBean.java | 20 +++++-- .../core/factory/PropertiesConfigurable.java | 17 ++++++ .../core/factory/PropertiesConfigurator.java | 54 +++++++++++++++++++ .../rest/registry/RestApiRegistry.java | 11 ++-- .../rest/registry/proxy/RestProxyInvoker.java | 35 ++++++++---- 11 files changed, 181 insertions(+), 38 deletions(-) create mode 100644 rest-proxy-core/src/main/java/group/flyfish/rest/core/factory/DefaultHttpClientProvider.java create mode 100644 rest-proxy-core/src/main/java/group/flyfish/rest/core/factory/PropertiesConfigurable.java create mode 100644 rest-proxy-core/src/main/java/group/flyfish/rest/core/factory/PropertiesConfigurator.java diff --git a/pom.xml b/pom.xml index fda3e72..4c69a18 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,7 @@ group.flyfish rest-proxy - 1.0.1 + 1.0.2 8 @@ -22,7 +22,7 @@ 1.8 4.4 2.6 - 1.0.1 + 1.0.2 pom diff --git a/rest-proxy-api/pom.xml b/rest-proxy-api/pom.xml index 2690455..fe0d95e 100644 --- a/rest-proxy-api/pom.xml +++ b/rest-proxy-api/pom.xml @@ -5,7 +5,7 @@ group.flyfish rest-proxy - 1.0.1 + 1.0.2 4.0.0 diff --git a/rest-proxy-core/pom.xml b/rest-proxy-core/pom.xml index b17bc09..d86ad1d 100644 --- a/rest-proxy-core/pom.xml +++ b/rest-proxy-core/pom.xml @@ -5,7 +5,7 @@ group.flyfish rest-proxy - 1.0.1 + 1.0.2 4.0.0 diff --git a/rest-proxy-core/src/main/java/group/flyfish/rest/configuration/RestClientConfiguration.java b/rest-proxy-core/src/main/java/group/flyfish/rest/configuration/RestClientConfiguration.java index f77e692..ceec975 100644 --- a/rest-proxy-core/src/main/java/group/flyfish/rest/configuration/RestClientConfiguration.java +++ b/rest-proxy-core/src/main/java/group/flyfish/rest/configuration/RestClientConfiguration.java @@ -1,5 +1,6 @@ package group.flyfish.rest.configuration; +import group.flyfish.rest.core.factory.DefaultHttpClientProvider; import group.flyfish.rest.core.factory.HttpClientFactoryBean; import group.flyfish.rest.core.factory.HttpClientProvider; import group.flyfish.rest.mapping.RestResultMapping; @@ -14,9 +15,7 @@ import group.flyfish.rest.utils.DataUtils; import org.apache.http.impl.client.CloseableHttpClient; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Lazy; import java.util.Arrays; import java.util.List; @@ -42,13 +41,12 @@ public class RestClientConfiguration { /** * http client工厂bean * - * @param properties 属性 * @return 结果 */ @Bean @ConditionalOnMissingBean(CloseableHttpClient.class) - public HttpClientFactoryBean httpClientFactoryBean(RestClientProperties properties) { - return new HttpClientFactoryBean(properties); + public HttpClientFactoryBean httpClientFactoryBean() { + return new HttpClientFactoryBean(); } /** @@ -58,8 +56,8 @@ public class RestClientConfiguration { */ @Bean @ConditionalOnMissingBean - public HttpClientProvider httpClientProvider(CloseableHttpClient client) { - return () -> client; + public HttpClientProvider httpClientProvider() { + return new DefaultHttpClientProvider(); } /** @@ -68,15 +66,14 @@ public class RestClientConfiguration { * @return 结果 */ @Bean - @Lazy public RestApiRegistry restApiRegistry(RestArgumentResolverComposite composite, HttpClientProvider provider, - List mappings, RestClientProperties properties) { + List mappings) { // 先注册映射们 if (DataUtils.isNotEmpty(mappings)) { mappings.forEach(mapping -> RestResultMapping.MAPPINGS.put(mapping.getClass(), mapping)); } // 最后实例化 - return new RestApiRegistry(composite, properties, provider); + return new RestApiRegistry(composite, provider); } /** diff --git a/rest-proxy-core/src/main/java/group/flyfish/rest/configuration/RestClientProperties.java b/rest-proxy-core/src/main/java/group/flyfish/rest/configuration/RestClientProperties.java index dc07ade..e978a1c 100644 --- a/rest-proxy-core/src/main/java/group/flyfish/rest/configuration/RestClientProperties.java +++ b/rest-proxy-core/src/main/java/group/flyfish/rest/configuration/RestClientProperties.java @@ -1,8 +1,10 @@ package group.flyfish.rest.configuration; +import group.flyfish.rest.core.factory.PropertiesConfigurator; import group.flyfish.rest.utils.DataUtils; import lombok.Data; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.InitializingBean; import java.time.Duration; import java.util.HashMap; @@ -16,7 +18,7 @@ import java.util.Map; */ @Data @Slf4j -public class RestClientProperties { +public class RestClientProperties implements InitializingBean { /** * 超时时间,默认30s @@ -50,4 +52,9 @@ public class RestClientProperties { } return urls.get(key); } + + @Override + public void afterPropertiesSet() { + PropertiesConfigurator.shared().configure(this); + } } diff --git a/rest-proxy-core/src/main/java/group/flyfish/rest/core/factory/DefaultHttpClientProvider.java b/rest-proxy-core/src/main/java/group/flyfish/rest/core/factory/DefaultHttpClientProvider.java new file mode 100644 index 0000000..d8dfb4f --- /dev/null +++ b/rest-proxy-core/src/main/java/group/flyfish/rest/core/factory/DefaultHttpClientProvider.java @@ -0,0 +1,48 @@ +package group.flyfish.rest.core.factory; + +import group.flyfish.rest.configuration.RestClientProperties; +import org.apache.http.impl.client.CloseableHttpClient; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.BeanFactoryAware; + +/** + * 默认的http客户端提供者 + * + * @author wangyu + */ +public class DefaultHttpClientProvider implements HttpClientProvider, BeanFactoryAware, PropertiesConfigurable { + + private CloseableHttpClient client; + + private BeanFactory beanFactory; + + public DefaultHttpClientProvider() { + PropertiesConfigurator.prepare(this); + } + + /** + * 获取client,可以自由替换 + * + * @return 结果 + */ + @Override + public CloseableHttpClient getClient() { + return client; + } + + @Override + public void setBeanFactory(BeanFactory beanFactory) throws BeansException { + this.beanFactory = beanFactory; + } + + /** + * 配置属性,完成初始化 + * + * @param properties 属性 + */ + @Override + public void configure(RestClientProperties properties) { + this.client = beanFactory.getBean(CloseableHttpClient.class); + } +} diff --git a/rest-proxy-core/src/main/java/group/flyfish/rest/core/factory/HttpClientFactoryBean.java b/rest-proxy-core/src/main/java/group/flyfish/rest/core/factory/HttpClientFactoryBean.java index 3e90f70..d2ef47d 100644 --- a/rest-proxy-core/src/main/java/group/flyfish/rest/core/factory/HttpClientFactoryBean.java +++ b/rest-proxy-core/src/main/java/group/flyfish/rest/core/factory/HttpClientFactoryBean.java @@ -2,7 +2,6 @@ package group.flyfish.rest.core.factory; import group.flyfish.rest.configuration.RestClientProperties; import group.flyfish.rest.utils.DataUtils; -import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.impl.client.CloseableHttpClient; @@ -22,15 +21,18 @@ import java.util.concurrent.locks.ReentrantLock; * @author wangyu */ @Slf4j -@RequiredArgsConstructor -public final class HttpClientFactoryBean implements FactoryBean { +public final class HttpClientFactoryBean implements FactoryBean, PropertiesConfigurable { // 使用非公平锁 private final ReentrantLock lock = new ReentrantLock(); // 客户端实例,单例 private volatile CloseableHttpClient client; // 配置,配置没进来就不初始化 - private final RestClientProperties properties; + private RestClientProperties properties; + + public HttpClientFactoryBean() { + PropertiesConfigurator.prepare(this); + } /** * 构建单例的httpClient @@ -78,4 +80,14 @@ public final class HttpClientFactoryBean implements FactoryBean getObjectType() { return CloseableHttpClient.class; } + + /** + * 配置属性,完成初始化 + * + * @param properties 属性 + */ + @Override + public void configure(RestClientProperties properties) { + this.properties = properties; + } } diff --git a/rest-proxy-core/src/main/java/group/flyfish/rest/core/factory/PropertiesConfigurable.java b/rest-proxy-core/src/main/java/group/flyfish/rest/core/factory/PropertiesConfigurable.java new file mode 100644 index 0000000..c46cbca --- /dev/null +++ b/rest-proxy-core/src/main/java/group/flyfish/rest/core/factory/PropertiesConfigurable.java @@ -0,0 +1,17 @@ +package group.flyfish.rest.core.factory; + +import group.flyfish.rest.configuration.RestClientProperties; + +/** + * 属性感知 + * + * @author wangyu + */ +public interface PropertiesConfigurable { + + /** + * 配置属性,完成初始化 + * @param properties 属性 + */ + void configure(RestClientProperties properties); +} diff --git a/rest-proxy-core/src/main/java/group/flyfish/rest/core/factory/PropertiesConfigurator.java b/rest-proxy-core/src/main/java/group/flyfish/rest/core/factory/PropertiesConfigurator.java new file mode 100644 index 0000000..d659ca0 --- /dev/null +++ b/rest-proxy-core/src/main/java/group/flyfish/rest/core/factory/PropertiesConfigurator.java @@ -0,0 +1,54 @@ +package group.flyfish.rest.core.factory; + +import group.flyfish.rest.configuration.RestClientProperties; + +import java.util.ArrayList; +import java.util.List; + +/** + * 属性配置器 + * 解耦bean依赖,解决属性注入失效的问题 + * + * @author wangyu + */ +public class PropertiesConfigurator implements PropertiesConfigurable { + + private static final PropertiesConfigurator INSTANCE = new PropertiesConfigurator(); + + private final List list = new ArrayList<>(); + + private RestClientProperties properties; + + /** + * 配置属性,完成初始化 + * + * @param properties 属性 + */ + @Override + public void configure(RestClientProperties properties) { + this.properties = properties; + list.forEach(item -> item.configure(properties)); + list.clear(); + } + + public void configure(PropertiesConfigurable configurable) { + if (null != properties) { + configurable.configure(properties); + } else { + list.add(configurable); + } + } + + /** + * 预配置 + * + * @param configurable 可配置实例 + */ + public static void prepare(PropertiesConfigurable configurable) { + INSTANCE.configure(configurable); + } + + public static PropertiesConfigurator shared() { + return INSTANCE; + } +} diff --git a/rest-proxy-core/src/main/java/group/flyfish/rest/registry/RestApiRegistry.java b/rest-proxy-core/src/main/java/group/flyfish/rest/registry/RestApiRegistry.java index 6a3b234..d43e7fa 100644 --- a/rest-proxy-core/src/main/java/group/flyfish/rest/registry/RestApiRegistry.java +++ b/rest-proxy-core/src/main/java/group/flyfish/rest/registry/RestApiRegistry.java @@ -2,7 +2,6 @@ package group.flyfish.rest.registry; import group.flyfish.rest.annotation.EnableRestApiProxy; import group.flyfish.rest.annotation.RestService; -import group.flyfish.rest.configuration.RestClientProperties; import group.flyfish.rest.core.factory.HttpClientProvider; import group.flyfish.rest.registry.proxy.RestProxyInvoker; import group.flyfish.rest.registry.proxy.support.RestArgumentResolverComposite; @@ -19,6 +18,7 @@ import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.*; import org.springframework.util.Assert; +import org.springframework.util.CollectionUtils; import java.util.ArrayList; import java.util.List; @@ -36,9 +36,6 @@ public class RestApiRegistry implements BeanDefinitionRegistryPostProcessor, Bea @Getter private final RestArgumentResolverComposite composite; - @Getter - private final RestClientProperties properties; - @Getter private final HttpClientProvider provider; @@ -72,6 +69,8 @@ public class RestApiRegistry implements BeanDefinitionRegistryPostProcessor, Bea Reflections reflections = new Reflections(packageNames.toArray()); // 得到Resource注解的类 Set> classSet = reflections.getTypesAnnotatedWith(RestService.class); + // 不存在,不要浪费性能 + if (CollectionUtils.isEmpty(classSet)) return; // 代理并生成子类,并注册到ioc容器 classSet.forEach(clazz -> registry.registerBeanDefinition(clazz.getName(), generate(clazz))); } catch (IllegalStateException e) { @@ -100,10 +99,6 @@ public class RestApiRegistry implements BeanDefinitionRegistryPostProcessor, Bea // do nothing } - public void setBeanFactory(ConfigurableListableBeanFactory beanFactory) { - this.beanFactory = beanFactory; - } - @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { Assert.isTrue(beanFactory instanceof ConfigurableListableBeanFactory, "当前bean factory不被支持!"); diff --git a/rest-proxy-core/src/main/java/group/flyfish/rest/registry/proxy/RestProxyInvoker.java b/rest-proxy-core/src/main/java/group/flyfish/rest/registry/proxy/RestProxyInvoker.java index 2c9bf34..4b41a66 100644 --- a/rest-proxy-core/src/main/java/group/flyfish/rest/registry/proxy/RestProxyInvoker.java +++ b/rest-proxy-core/src/main/java/group/flyfish/rest/registry/proxy/RestProxyInvoker.java @@ -7,6 +7,8 @@ import group.flyfish.rest.annotation.RestService; import group.flyfish.rest.configuration.RestClientProperties; import group.flyfish.rest.core.client.RestClient; import group.flyfish.rest.core.client.RestClientBuilder; +import group.flyfish.rest.core.factory.PropertiesConfigurable; +import group.flyfish.rest.core.factory.PropertiesConfigurator; import group.flyfish.rest.mapping.RestResultMapping; import group.flyfish.rest.registry.RestApiRegistry; import group.flyfish.rest.registry.proxy.support.ArgumentResolveContext; @@ -30,6 +32,7 @@ import java.lang.reflect.Proxy; import java.lang.reflect.Type; import java.util.Map; import java.util.Optional; +import java.util.function.Consumer; import java.util.stream.Stream; /** @@ -38,16 +41,18 @@ import java.util.stream.Stream; * @author wangyu */ @Slf4j -public class RestProxyInvoker implements InvocationHandler { +public class RestProxyInvoker implements InvocationHandler, PropertiesConfigurable { // 要代理的目标类 private final Class targetType; // 服务映射 private final RestService restService; + // 配置属性 + private RestClientProperties properties; // 初始的基本路径 - private final String baseUrl; + private String baseUrl; // 超时时间 - private final RequestConfig config; + private RequestConfig config; // 注册器,包含基础信息 private final RestApiRegistry registry; // 结果映射 @@ -65,12 +70,7 @@ public class RestProxyInvoker implements InvocationHandler { // 注解的优先级高于全局基本路径 this.restService = AnnotationUtils.findAnnotation(targetType, RestService.class); Assert.notNull(restService, "当前类尚未添加@RestService注解!"); - RestClientProperties properties = registry.getProperties(); - this.config = RequestConfig.custom() - .setConnectTimeout((int) properties.getConnectionTimeout().toMillis()) - .setSocketTimeout(restService.timeout()) - .build(); - this.baseUrl = this.findBaseUrl(); + PropertiesConfigurator.prepare(this); } /** @@ -85,6 +85,21 @@ public class RestProxyInvoker implements InvocationHandler { return DataUtils.cast(Proxy.newProxyInstance(target.getClassLoader(), new Class[]{target}, invoker)); } + /** + * 完成配置 + * + * @param properties 属性 + */ + @Override + public void configure(RestClientProperties properties) { + this.properties = properties; + this.config = RequestConfig.custom() + .setConnectTimeout((int) properties.getConnectionTimeout().toMillis()) + .setSocketTimeout(restService.timeout()) + .build(); + this.baseUrl = this.findBaseUrl(); + } + /** * 执行rest请求的地方,这里很简单易懂 * @@ -180,7 +195,6 @@ public class RestProxyInvoker implements InvocationHandler { * 找到配置固化的基本url */ private String findBaseUrl() { - RestClientProperties properties = registry.getProperties(); // 当且仅当存在时进入 if (null != restService) { // 注解的路径解析 @@ -220,7 +234,6 @@ public class RestProxyInvoker implements InvocationHandler { if (DataUtils.isNotBlank(restApi.url())) { url = restApi.url(); } else { - RestClientProperties properties = registry.getProperties(); // 构建基础url,优先级从小到大依次找。同时尝试取字典值 Optional baseUrl = Stream.of(restApi.baseUrl(), this.baseUrl) .filter(DataUtils::isNotBlank)