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 da67a01..f77e692 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,6 +1,7 @@ package group.flyfish.rest.configuration; -import group.flyfish.rest.annotation.EnableRestApiProxy; +import group.flyfish.rest.core.factory.HttpClientFactoryBean; +import group.flyfish.rest.core.factory.HttpClientProvider; import group.flyfish.rest.mapping.RestResultMapping; import group.flyfish.rest.registry.RestApiRegistry; import group.flyfish.rest.registry.proxy.support.RestArgumentResolver; @@ -10,14 +11,11 @@ import group.flyfish.rest.registry.proxy.support.resolvers.RestHeaderArgumentRes import group.flyfish.rest.registry.proxy.support.resolvers.RestParamArgumentResolver; import group.flyfish.rest.registry.proxy.support.resolvers.RestPathParamArgumentResolver; import group.flyfish.rest.utils.DataUtils; -import group.flyfish.rest.utils.IocBeans; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.apache.http.impl.client.CloseableHttpClient; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +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.Conditional; import org.springframework.context.annotation.Lazy; import java.util.Arrays; @@ -28,9 +26,42 @@ import java.util.List; * * @author wangyu */ -@EnableConfigurationProperties(RestClientProperties.class) public class RestClientConfiguration { + /** + * 实例化参数bean + * + * @return 结果 + */ + @ConfigurationProperties(prefix = "rest.client", ignoreUnknownFields = false) + @Bean + public RestClientProperties restClientProperties() { + return new RestClientProperties(); + } + + /** + * http client工厂bean + * + * @param properties 属性 + * @return 结果 + */ + @Bean + @ConditionalOnMissingBean(CloseableHttpClient.class) + public HttpClientFactoryBean httpClientFactoryBean(RestClientProperties properties) { + return new HttpClientFactoryBean(properties); + } + + /** + * 创建默认的提供者,默认使用factory bean创建的client + * + * @return 结果 + */ + @Bean + @ConditionalOnMissingBean + public HttpClientProvider httpClientProvider(CloseableHttpClient client) { + return () -> client; + } + /** * 注册rest自动代理 * @@ -38,25 +69,14 @@ public class RestClientConfiguration { */ @Bean @Lazy - public RestApiRegistry restApiRegistry(RestArgumentResolverComposite composite, - List mappings) { + public RestApiRegistry restApiRegistry(RestArgumentResolverComposite composite, HttpClientProvider provider, + List mappings, RestClientProperties properties) { // 先注册映射们 if (DataUtils.isNotEmpty(mappings)) { mappings.forEach(mapping -> RestResultMapping.MAPPINGS.put(mapping.getClass(), mapping)); } // 最后实例化 - return new RestApiRegistry(composite); - } - - /** - * IOC容器操作 - * - * @return 结果 - */ - @Bean - @ConditionalOnMissingBean(name = "iocBeans") - public IocBeans iocBeans() { - return new IocBeans(); + return new RestApiRegistry(composite, properties, 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 2fbedf8..dc07ade 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,13 +1,9 @@ package group.flyfish.rest.configuration; -import group.flyfish.rest.registry.RestApiRegistry; import group.flyfish.rest.utils.DataUtils; import lombok.Data; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.boot.context.properties.ConfigurationProperties; -import javax.annotation.Resource; import java.time.Duration; import java.util.HashMap; import java.util.Map; @@ -19,12 +15,8 @@ import java.util.Map; * 整合入spring boot,简化配置,提高业务复用性 */ @Data -@ConfigurationProperties(prefix = "rest.client", ignoreUnknownFields = false) @Slf4j -public class RestClientProperties implements InitializingBean { - - @Resource - private RestApiRegistry restApiRegistry; +public class RestClientProperties { /** * 超时时间,默认30s @@ -58,10 +50,4 @@ public class RestClientProperties implements InitializingBean { } return urls.get(key); } - - @Override - public void afterPropertiesSet() throws Exception { - log.info("initialized rest client properties。 baseUrl is:{}", this.baseUrl); - restApiRegistry.initialize(this); - } } diff --git a/rest-proxy-core/src/main/java/group/flyfish/rest/core/client/DefaultRestClient.java b/rest-proxy-core/src/main/java/group/flyfish/rest/core/client/DefaultRestClient.java index 74c899f..be4f9c3 100644 --- a/rest-proxy-core/src/main/java/group/flyfish/rest/core/client/DefaultRestClient.java +++ b/rest-proxy-core/src/main/java/group/flyfish/rest/core/client/DefaultRestClient.java @@ -3,6 +3,7 @@ package group.flyfish.rest.core.client; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JavaType; import group.flyfish.rest.core.exception.RestClientException; +import group.flyfish.rest.core.factory.HttpClientProvider; import group.flyfish.rest.enums.ResponseType; import group.flyfish.rest.utils.JacksonUtil; import lombok.extern.slf4j.Slf4j; @@ -47,6 +48,17 @@ final class DefaultRestClient implements RestClient { private Class resultClass; private TypeReference typeReference; private JavaType resultType; + private HttpClientProvider clientProvider; + + /** + * 内部构造方法,不对外公开 + * + * @param request 请求信息 + */ + DefaultRestClient(HttpRequestBase request, HttpClientProvider provider) { + this.request = request; + this.clientProvider = provider; + } /** * 内部构造方法,不对外公开 @@ -94,6 +106,16 @@ final class DefaultRestClient implements RestClient { return this; } + /** + * 设置客户端提供者 + * + * @param provider 客户端提供者 + */ + @Override + public void setClient(HttpClientProvider provider) { + this.clientProvider = provider; + } + /** * 标记线程池执行 * @@ -260,7 +282,7 @@ final class DefaultRestClient implements RestClient { */ private T innerExecute() throws IOException { log.info("【Rest Invoke】{} {}", request.getMethod(), request.getURI()); - try (CloseableHttpResponse response = HttpClientCache.getClient().execute(request)) { + try (CloseableHttpResponse response = clientProvider.getClient().execute(request)) { StatusLine statusLine = response.getStatusLine(); if (200 == statusLine.getStatusCode()) { HttpEntity entity = response.getEntity(); diff --git a/rest-proxy-core/src/main/java/group/flyfish/rest/core/client/HttpClientCache.java b/rest-proxy-core/src/main/java/group/flyfish/rest/core/client/HttpClientCache.java deleted file mode 100644 index c5f1b95..0000000 --- a/rest-proxy-core/src/main/java/group/flyfish/rest/core/client/HttpClientCache.java +++ /dev/null @@ -1,41 +0,0 @@ -package group.flyfish.rest.core.client; - -import group.flyfish.rest.core.produce.HttpClientProducer; -import org.apache.http.impl.client.CloseableHttpClient; - -import java.io.IOException; - -/** - * http请求客户端缓存 - * - * @author wangyu - */ -class HttpClientCache { - - private volatile CloseableHttpClient client; - - private static final HttpClientCache INSTANCE = new HttpClientCache(); - - /** - * 获取共享client - * - * @return 结果 - */ - CloseableHttpClient computeClient() throws IOException { - if (null == client) { - synchronized (INSTANCE) { - if (null != client) return client; - return client = HttpClientProducer.produce(); - } - } - return client; - } - - public static CloseableHttpClient getClient() throws IOException { - return INSTANCE.computeClient(); - } - - public static void setClient(CloseableHttpClient client) { - INSTANCE.client = client; - } -} diff --git a/rest-proxy-core/src/main/java/group/flyfish/rest/core/client/RestClient.java b/rest-proxy-core/src/main/java/group/flyfish/rest/core/client/RestClient.java index 5528bf3..2a69ca7 100644 --- a/rest-proxy-core/src/main/java/group/flyfish/rest/core/client/RestClient.java +++ b/rest-proxy-core/src/main/java/group/flyfish/rest/core/client/RestClient.java @@ -3,9 +3,9 @@ package group.flyfish.rest.core.client; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JavaType; import group.flyfish.rest.core.exception.RestClientException; +import group.flyfish.rest.core.factory.HttpClientProvider; import group.flyfish.rest.enums.ResponseType; import org.apache.http.HttpEntity; -import org.apache.http.impl.client.CloseableHttpClient; import org.springframework.lang.Nullable; import java.io.IOException; @@ -37,13 +37,11 @@ public interface RestClient { } /** - * 设置单例的客户端 + * 设置客户端提供者 * - * @param client 客户端 + * @param provider 客户端提供者 */ - static void setClient(CloseableHttpClient client) { - HttpClientCache.setClient(client); - } + void setClient(HttpClientProvider provider); /** * 标记线程池执行 diff --git a/rest-proxy-core/src/main/java/group/flyfish/rest/core/produce/HttpClientProducer.java b/rest-proxy-core/src/main/java/group/flyfish/rest/core/factory/HttpClientFactoryBean.java similarity index 65% rename from rest-proxy-core/src/main/java/group/flyfish/rest/core/produce/HttpClientProducer.java rename to rest-proxy-core/src/main/java/group/flyfish/rest/core/factory/HttpClientFactoryBean.java index 2a0035c..5c1db87 100644 --- a/rest-proxy-core/src/main/java/group/flyfish/rest/core/produce/HttpClientProducer.java +++ b/rest-proxy-core/src/main/java/group/flyfish/rest/core/factory/HttpClientFactoryBean.java @@ -1,15 +1,16 @@ -package group.flyfish.rest.core.produce; +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; import org.apache.http.impl.client.HttpClients; import org.apache.http.ssl.SSLContextBuilder; +import org.springframework.beans.factory.FactoryBean; import javax.net.ssl.SSLContext; -import java.io.NotActiveException; import java.security.KeyManagementException; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; @@ -21,63 +22,22 @@ import java.util.concurrent.locks.ReentrantLock; * @author wangyu */ @Slf4j -public final class HttpClientProducer { +@RequiredArgsConstructor +public final class HttpClientFactoryBean implements FactoryBean { // 使用非公平锁 - private static final ReentrantLock lock = new ReentrantLock(); + private final ReentrantLock lock = new ReentrantLock(); // 客户端实例,单例 private static volatile CloseableHttpClient client; // 配置,配置没进来就不初始化 - private static RestClientProperties properties; - - /** - * 配置信息 - * - * @param properties 属性 - */ - public static void configure(RestClientProperties properties) { - HttpClientProducer.properties = properties; - } - - /** - * 获取属性 - * - * @return 结果 - */ - public static RestClientProperties getProperties() { - return properties; - } - - /** - * 生产客户端 - * - * @return 结果 - */ - public static CloseableHttpClient produce() throws NotActiveException { - if (properties == null) { - log.warn("【rest客户端】未初始化rest客户端配置,生产者未就绪!将使用默认配置!!!"); - properties = new RestClientProperties(); - } - if (client == null) { - // 非公平锁,二次判定,定位volatile - lock.lock(); - try { - if (client == null) { - client = getClient(); - } - } finally { - lock.unlock(); - } - } - return client; - } + private final RestClientProperties properties; /** * 构建单例的httpClient * * @return 结果 */ - private static CloseableHttpClient getClient() { + private CloseableHttpClient getClient() { return DataUtils.isTrue(properties.getAlwaysTrust()) ? createSSLClient() : HttpClients.createDefault(); } @@ -98,4 +58,24 @@ public final class HttpClientProducer { return null; } + @Override + public CloseableHttpClient getObject() throws Exception { + if (client == null) { + // 非公平锁,二次判定,定位volatile + lock.lock(); + try { + if (client == null) { + client = getClient(); + } + } finally { + lock.unlock(); + } + } + return client; + } + + @Override + public Class getObjectType() { + return CloseableHttpClient.class; + } } diff --git a/rest-proxy-core/src/main/java/group/flyfish/rest/core/factory/HttpClientProvider.java b/rest-proxy-core/src/main/java/group/flyfish/rest/core/factory/HttpClientProvider.java new file mode 100644 index 0000000..154c213 --- /dev/null +++ b/rest-proxy-core/src/main/java/group/flyfish/rest/core/factory/HttpClientProvider.java @@ -0,0 +1,19 @@ +package group.flyfish.rest.core.factory; + +import org.apache.http.impl.client.CloseableHttpClient; + +/** + * http客户端提供者 + * + * @author wangyu + */ +@FunctionalInterface +public interface HttpClientProvider { + + /** + * 获取client,可以自由替换 + * + * @return 结果 + */ + CloseableHttpClient getClient(); +} 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 947182b..6a3b234 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,12 +2,12 @@ package group.flyfish.rest.registry; import group.flyfish.rest.annotation.EnableRestApiProxy; import group.flyfish.rest.annotation.RestService; -import group.flyfish.rest.core.client.RestClient; import group.flyfish.rest.configuration.RestClientProperties; -import group.flyfish.rest.core.produce.HttpClientProducer; +import group.flyfish.rest.core.factory.HttpClientProvider; import group.flyfish.rest.registry.proxy.RestProxyInvoker; import group.flyfish.rest.registry.proxy.support.RestArgumentResolverComposite; import group.flyfish.rest.utils.DataUtils; +import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; @@ -15,11 +15,11 @@ import org.reflections.Reflections; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; +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 java.io.NotActiveException; import java.util.ArrayList; import java.util.List; import java.util.Set; @@ -33,20 +33,18 @@ import java.util.Set; @Slf4j public class RestApiRegistry implements BeanDefinitionRegistryPostProcessor, BeanFactoryAware { + @Getter private final RestArgumentResolverComposite composite; - // 包名 - private final List packageNames = new ArrayList<>(); + @Getter + private final RestClientProperties properties; - // 注册的执行器们,最终会使用配置进行初始化 - private final List> invokers = new ArrayList<>(); + @Getter + private final HttpClientProvider provider; // bean工厂 private ConfigurableListableBeanFactory beanFactory; - // rest请求参数 - private RestClientProperties properties; - /** * 动态注册bean * @@ -55,6 +53,8 @@ public class RestApiRegistry implements BeanDefinitionRegistryPostProcessor, Bea */ @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { + // 包名 + List packageNames = new ArrayList<>(); // 找基本包,找不到立马报错 beanFactory.getBeansWithAnnotation(EnableRestApiProxy.class) .forEach((key, value) -> { @@ -73,11 +73,7 @@ public class RestApiRegistry implements BeanDefinitionRegistryPostProcessor, Bea // 得到Resource注解的类 Set> classSet = reflections.getTypesAnnotatedWith(RestService.class); // 代理并生成子类,并注册到ioc容器 - classSet.forEach(clazz -> registry.registerBeanDefinition(clazz.getName(), - BeanDefinitionBuilder.genericBeanDefinition(clazz, () -> DataUtils.cast(RestProxyInvoker - .produce(clazz, composite, this::bindInvoker))) - .setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE).getRawBeanDefinition()) - ); + classSet.forEach(clazz -> registry.registerBeanDefinition(clazz.getName(), generate(clazz))); } catch (IllegalStateException e) { log.error("初始化Rest映射时出错", e); } @@ -87,35 +83,15 @@ public class RestApiRegistry implements BeanDefinitionRegistryPostProcessor, Bea } /** - * 初始化bean们 + * 生成bean定义 * - * @param properties 属性 - * @throws NotActiveException 未活动异常 + * @param clazz 目标类型 + * @return bean定义 */ - public void initialize(RestClientProperties properties) throws NotActiveException { - log.info("bean加载完成"); - // 真正加载完成的回调 - this.properties = properties; - // 配置参数 - HttpClientProducer.configure(properties); - // 最后再配置,生成 - RestClient.setClient(HttpClientProducer.produce()); - // 初始化 - this.invokers.forEach(invoker -> invoker.configure(properties)); - } - - /** - * 绑定执行器 - * - * @param invoker 执行器 - * @param 泛型 - */ - private void bindInvoker(RestProxyInvoker invoker) { - if (properties == null) { - this.invokers.add(invoker); - } else { - invoker.configure(properties); - } + private BeanDefinition generate(Class clazz) { + return BeanDefinitionBuilder.genericBeanDefinition(clazz, + () -> DataUtils.cast(RestProxyInvoker.produce(clazz, this))) + .setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE).getRawBeanDefinition(); } @SneakyThrows 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 b31136d..2c9bf34 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 @@ -8,6 +8,7 @@ import group.flyfish.rest.configuration.RestClientProperties; import group.flyfish.rest.core.client.RestClient; import group.flyfish.rest.core.client.RestClientBuilder; import group.flyfish.rest.mapping.RestResultMapping; +import group.flyfish.rest.registry.RestApiRegistry; import group.flyfish.rest.registry.proxy.support.ArgumentResolveContext; import group.flyfish.rest.registry.proxy.support.RestArgumentResolverComposite; import group.flyfish.rest.registry.proxy.support.UrlCompiler; @@ -18,6 +19,7 @@ import lombok.extern.slf4j.Slf4j; import org.apache.http.client.config.RequestConfig; import org.springframework.aop.support.AopUtils; import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import java.beans.Transient; @@ -28,7 +30,6 @@ 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; /** @@ -41,31 +42,35 @@ public class RestProxyInvoker implements InvocationHandler { // 要代理的目标类 private final Class targetType; - // 解析集合 - private final RestArgumentResolverComposite composite; // 服务映射 private final RestService restService; // 初始的基本路径 - private String baseUrl; + private final String baseUrl; // 超时时间 - private RequestConfig config; - // 基础url - private RestClientProperties properties; + private final RequestConfig config; + // 注册器,包含基础信息 + private final RestApiRegistry registry; // 结果映射 private RestResultMapping mapping; - /** * 构造器 * * @param targetType 目标类型 - * @param composite 解析器 + * @param registry 注册器 */ - public RestProxyInvoker(Class targetType, RestArgumentResolverComposite composite) { + private RestProxyInvoker(Class targetType, RestApiRegistry registry) { this.targetType = targetType; - this.composite = composite; + this.registry = registry; // 注解的优先级高于全局基本路径 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(); } /** @@ -75,27 +80,11 @@ public class RestProxyInvoker implements InvocationHandler { * @param 泛型 * @return 结果 */ - public static T produce(Class target, RestArgumentResolverComposite composite, Consumer> consumer) { - RestProxyInvoker invoker = new RestProxyInvoker<>(target, composite); - consumer.accept(invoker); + public static T produce(Class target, RestApiRegistry registry) { + RestProxyInvoker invoker = new RestProxyInvoker<>(target, registry); return DataUtils.cast(Proxy.newProxyInstance(target.getClassLoader(), new Class[]{target}, invoker)); } - /** - * 使用配置信息对接口进行配置 - * - * @param properties 配置 - */ - 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请求的地方,这里很简单易懂 * @@ -121,6 +110,7 @@ public class RestProxyInvoker implements InvocationHandler { if (null == restApi) { throw new IllegalAccessException("【Rest调用】未声明rest配置的方法被调用!请检查代码!"); } + RestArgumentResolverComposite composite = registry.getComposite(); // 第一步就解析参数 ArgumentResolveContext context = composite.resolve(restApi, method, args); // 构造和调用,这里的restClient不保存状态 @@ -146,6 +136,8 @@ public class RestProxyInvoker implements InvocationHandler { } // 赋值头部 RestClient client = builder.build(); + // 设置客户端 + client.setClient(registry.getProvider()); // 是否对结果进行映射 boolean map = null != mapping && null == AnnotationUtils.findAnnotation(method, Transient.class); // 执行请求 @@ -188,6 +180,7 @@ public class RestProxyInvoker implements InvocationHandler { * 找到配置固化的基本url */ private String findBaseUrl() { + RestClientProperties properties = registry.getProperties(); // 当且仅当存在时进入 if (null != restService) { // 注解的路径解析 @@ -227,6 +220,7 @@ 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) diff --git a/rest-proxy-core/src/main/java/group/flyfish/rest/utils/IocBeans.java b/rest-proxy-core/src/main/java/group/flyfish/rest/utils/IocBeans.java deleted file mode 100644 index 68b160c..0000000 --- a/rest-proxy-core/src/main/java/group/flyfish/rest/utils/IocBeans.java +++ /dev/null @@ -1,95 +0,0 @@ -package group.flyfish.rest.utils; - -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.support.BeanDefinitionBuilder; -import org.springframework.beans.factory.support.DefaultListableBeanFactory; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.lang.Nullable; - -import java.util.Optional; -import java.util.function.Supplier; - -public class IocBeans implements ApplicationContextAware { - - private static IocBeans instance; - - private ApplicationContext applicationContext; - - public IocBeans() { - instance = this; - } - - public static IocBeans sharedInstance() { - return instance; - } - - public static IocBeans sharedInstance(ApplicationContext applicationContext) { - if (null != instance && null == instance.applicationContext) { - instance.applicationContext = applicationContext; - } - return instance; - } - - - /** - * 注册bean - * - * @param name bean的名称 - * @param beanClass bean的类 - * @param beanSupplier bean实例化 - */ - public static T registerBean(String name, Class beanClass, Supplier beanSupplier) { - return sharedInstance().register(name, beanClass, beanSupplier); - } - - /** - * 注册bean - * - * @param name bean的名称 - * @param beanClass bean的类 - * @param beanSupplier bean实例化 - */ - @SuppressWarnings("unchecked") - public T register(String name, Class beanClass, Supplier beanSupplier) { - // 已经包含bean - if (applicationContext.containsBean(name)) { - Object wired = applicationContext.getBean(name); - if (wired.getClass().isAssignableFrom(beanClass)) { - return (T) wired; - } else { - throw new RuntimeException("注册RMI实例出错,Bean名称重复:" + name); - } - } - // 构建bean定义 - BeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(beanClass, beanSupplier) - .getRawBeanDefinition(); - // 写入 - return Optional.ofNullable(getBeanFactory()) - .map(factory -> { - factory.registerBeanDefinition(name, beanDefinition); - return applicationContext.getBean(name, beanClass); - }).orElseThrow(() -> new RuntimeException("注册RMI实例出错,BeanFactory不存在!")); - } - - /** - * 获取beanFactory - * - * @return 结果 - */ - @Nullable - public DefaultListableBeanFactory getBeanFactory() { - BeanFactory beanFactory = applicationContext.getAutowireCapableBeanFactory(); - if (beanFactory == null) { - beanFactory = applicationContext.getParentBeanFactory(); - } - return (DefaultListableBeanFactory) beanFactory; - } - - @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - this.applicationContext = applicationContext; - } -}