diff --git a/pom.xml b/pom.xml index 7f72f6b..6a978da 100644 --- a/pom.xml +++ b/pom.xml @@ -41,7 +41,7 @@ 4.13.1 1.3.2 1.7.25 - 2.1.1.RELEASE + 2.0.0.RELEASE 3.14.9 1.17.5 1.6.3 @@ -59,7 +59,7 @@ org.springframework.cloud spring-cloud-commons - 2.1.6.RELEASE + ${spring-boot.version} provided diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/annotation/InterceptMark.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/annotation/InterceptMark.java deleted file mode 100644 index 4def384..0000000 --- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/annotation/InterceptMark.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.github.lianjiatech.retrofit.spring.boot.annotation; - -import java.lang.annotation.*; - -/** - * 拦截标记注解 - * Intercept mark - * - * @author 陈添明 - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.ANNOTATION_TYPE) -@Documented -public @interface InterceptMark { - -} diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/annotation/Intercepts.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/annotation/Intercepts.java deleted file mode 100644 index cfc24d8..0000000 --- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/annotation/Intercepts.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.github.lianjiatech.retrofit.spring.boot.annotation; - -import java.lang.annotation.*; - -/** - * @author 陈添明 - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.TYPE) -public @interface Intercepts { - - Intercept[] value(); -} diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/config/RetrofitAutoConfiguration.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/config/RetrofitAutoConfiguration.java index 1d24e1e..3140ccd 100644 --- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/config/RetrofitAutoConfiguration.java +++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/config/RetrofitAutoConfiguration.java @@ -5,8 +5,6 @@ import java.util.Map; import java.util.concurrent.TimeUnit; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; @@ -14,8 +12,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; -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.context.annotation.Import; @@ -24,8 +20,12 @@ import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.github.lianjiatech.retrofit.spring.boot.core.AutoConfiguredRetrofitScannerRegistrar; +import com.github.lianjiatech.retrofit.spring.boot.core.BasicTypeConverterFactory; +import com.github.lianjiatech.retrofit.spring.boot.core.BodyCallAdapterFactory; +import com.github.lianjiatech.retrofit.spring.boot.core.DefaultErrorDecoder; import com.github.lianjiatech.retrofit.spring.boot.core.NoValidServiceInstanceChooser; import com.github.lianjiatech.retrofit.spring.boot.core.PathMatchInterceptorBdfProcessor; +import com.github.lianjiatech.retrofit.spring.boot.core.ResponseCallAdapterFactory; import com.github.lianjiatech.retrofit.spring.boot.core.RetrofitFactoryBean; import com.github.lianjiatech.retrofit.spring.boot.core.ServiceInstanceChooser; import com.github.lianjiatech.retrofit.spring.boot.degrade.DefaultResourceNameParser; @@ -50,12 +50,10 @@ @EnableConfigurationProperties(RetrofitProperties.class) @AutoConfigureAfter({JacksonAutoConfiguration.class}) @Slf4j -public class RetrofitAutoConfiguration implements ApplicationContextAware { +public class RetrofitAutoConfiguration { private final RetrofitProperties retrofitProperties; - private ApplicationContext applicationContext; - public RetrofitAutoConfiguration(RetrofitProperties retrofitProperties) { this.retrofitProperties = retrofitProperties; } @@ -102,6 +100,26 @@ public RetrofitConfigBean retrofitConfigBean(@Autowired(required = false) Resour return retrofitConfigBean; } + @Bean + public BodyCallAdapterFactory bodyCallAdapterFactory() { + return new BodyCallAdapterFactory(); + } + + @Bean + public ResponseCallAdapterFactory responseCallAdapterFactory() { + return new ResponseCallAdapterFactory(); + } + + @Bean + public BasicTypeConverterFactory basicTypeConverterFactory() { + return new BasicTypeConverterFactory(); + } + + @Bean + public DefaultErrorDecoder defaultErrorDecoder() { + return new DefaultErrorDecoder(); + } + @Bean @ConditionalOnMissingBean public ErrorDecoderInterceptor errorDecoderInterceptor() { @@ -149,32 +167,16 @@ public DegradeInterceptor degradeInterceptor(ResourceNameParser resourceNamePars @Bean @ConditionalOnMissingBean - public ObjectMapper jacksonObjectMapper() { - return new ObjectMapper() + public JacksonConverterFactory jacksonConverterFactory() { + ObjectMapper objectMapper = new ObjectMapper() .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) .setSerializationInclusion(JsonInclude.Include.NON_NULL); - } - - @Bean - @ConditionalOnMissingBean - @Autowired - public JacksonConverterFactory jacksonConverterFactory(ObjectMapper objectMapper) { return JacksonConverterFactory.create(objectMapper); } - @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - this.applicationContext = applicationContext; - } - @Configuration @Import({AutoConfiguredRetrofitScannerRegistrar.class}) @ConditionalOnMissingBean(RetrofitFactoryBean.class) - public static class RetrofitScannerRegistrarNotFoundConfiguration implements InitializingBean { - @Override - public void afterPropertiesSet() { - log.debug("No {} found.", RetrofitFactoryBean.class.getName()); - } - } + public static class RetrofitScannerRegistrarNotFoundConfiguration {} } diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/config/RetrofitProperties.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/config/RetrofitProperties.java index 79d7185..aaa86c0 100644 --- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/config/RetrofitProperties.java +++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/config/RetrofitProperties.java @@ -52,11 +52,6 @@ public class RetrofitProperties { @NestedConfigurationProperty private LogProperty log = new LogProperty(); - /** - * Disable Void return type - */ - private boolean disableVoidReturnType = false; - /** * 全局连接超时时间 */ diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/AutoConfiguredRetrofitScannerRegistrar.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/AutoConfiguredRetrofitScannerRegistrar.java index 776f6c9..5df4faa 100644 --- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/AutoConfiguredRetrofitScannerRegistrar.java +++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/AutoConfiguredRetrofitScannerRegistrar.java @@ -1,5 +1,6 @@ package com.github.lianjiatech.retrofit.spring.boot.core; +import java.util.Arrays; import java.util.List; import org.springframework.beans.BeansException; @@ -17,7 +18,7 @@ /** * This will just scan the same base package as Spring Boot does. If you want more power, you can explicitly use - * {@link com.github.lianjiatech.retrofit.spring.boot.annotation.RetrofitScan} but this will get typed mappers working correctly, out-of-the-box, + * {@link RetrofitScan} but this will get typed mappers working correctly, out-of-the-box, * similar to using Spring Data JPA repositories. * * @author 陈添明 @@ -40,17 +41,10 @@ public void setBeanFactory(BeanFactory beanFactory) throws BeansException { @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { if (!AutoConfigurationPackages.has(this.beanFactory)) { - log.debug("Could not determine auto-configuration package, automatic retrofit scanning disabled."); + log.warn("Could not determine auto-configuration package, automatic retrofit scanning disabled."); return; } - - log.debug("Searching for retrofits annotated with @RetrofitClient"); - List packages = AutoConfigurationPackages.get(this.beanFactory); - if (log.isDebugEnabled()) { - packages.forEach(pkg -> log.debug("Using auto-configuration base package '{}'", pkg)); - } - // Scan the @RetrofitClient annotated interface under the specified path and register it to the // BeanDefinitionRegistry ClassPathRetrofitClientScanner scanner = new ClassPathRetrofitClientScanner(registry, classLoader); @@ -58,6 +52,8 @@ public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, B scanner.setResourceLoader(resourceLoader); } String[] packageArr = packages.toArray(new String[0]); + log.info("Scan the @RetrofitClient annotated interface using the auto-configuration package. packages={}", + Arrays.toString(packageArr)); scanner.registerFilters(); // Scan and register to BeanDefinition scanner.doScan(packageArr); diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/BodyCallAdapterFactory.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/BodyCallAdapterFactory.java index 3319de1..92f1a8f 100644 --- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/BodyCallAdapterFactory.java +++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/BodyCallAdapterFactory.java @@ -29,7 +29,7 @@ import retrofit2.Retrofit; /** - * 同步调用,如果返回的http状态码是是成功,返回responseBody 反序列化之后的对象。否则,抛出异常!异常信息中包含请求和响应相关信息。 + * 同步调用,如果返回的http状态码是是成功,返回responseBody 反序列化之后的对象。否则,抛出异常!异常信息中包含请求和响应相关信息。
* Synchronous call, if the returned http status code is successful, return the responseBody object after deserialization. * Otherwise, throw an exception! The exception information includes request and response related information. * @@ -48,16 +48,16 @@ public final class BodyCallAdapterFactory extends CallAdapter.Factory { if (Response.class.isAssignableFrom(getRawType(returnType))) { return null; } - return new BodyCallAdapter(returnType, annotations, retrofit); + return new BodyCallAdapter<>(returnType, annotations, retrofit); } - final class BodyCallAdapter implements CallAdapter { + static final class BodyCallAdapter implements CallAdapter { - private Type returnType; + private final Type returnType; - private Retrofit retrofit; + private final Retrofit retrofit; - private Annotation[] annotations; + private final Annotation[] annotations; BodyCallAdapter(Type returnType, Annotation[] annotations, Retrofit retrofit) { this.returnType = returnType; diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/ClassPathRetrofitClientScanner.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/ClassPathRetrofitClientScanner.java index 95889ba..c5a835b 100644 --- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/ClassPathRetrofitClientScanner.java +++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/ClassPathRetrofitClientScanner.java @@ -12,8 +12,6 @@ import org.springframework.core.type.filter.AnnotationTypeFilter; import org.springframework.util.ClassUtils; -import com.github.lianjiatech.retrofit.spring.boot.annotation.RetrofitClient; - import lombok.extern.slf4j.Slf4j; /** diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/DefaultErrorDecoder.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/DefaultErrorDecoder.java index 499cb8e..ebb60cf 100644 --- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/DefaultErrorDecoder.java +++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/DefaultErrorDecoder.java @@ -4,6 +4,4 @@ * * @author 陈添明 */ -public class DefaultErrorDecoder implements ErrorDecoder { - -} +public class DefaultErrorDecoder implements ErrorDecoder {} diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/annotation/OkHttpClientBuilder.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/OkHttpClientBuilder.java similarity index 84% rename from src/main/java/com/github/lianjiatech/retrofit/spring/boot/annotation/OkHttpClientBuilder.java rename to src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/OkHttpClientBuilder.java index 212fe9e..02144e9 100644 --- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/annotation/OkHttpClientBuilder.java +++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/OkHttpClientBuilder.java @@ -1,4 +1,4 @@ -package com.github.lianjiatech.retrofit.spring.boot.annotation; +package com.github.lianjiatech.retrofit.spring.boot.core; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/ResponseCallAdapterFactory.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/ResponseCallAdapterFactory.java index 9f5a282..610f898 100644 --- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/ResponseCallAdapterFactory.java +++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/ResponseCallAdapterFactory.java @@ -29,10 +29,8 @@ import retrofit2.Retrofit; /** - *

- * 同步调用执行,直接返回 #{@link Response} 对象 + * 同步调用执行,直接返回 #{@link Response} 对象。
* Synchronous call execution, directly return #{@link Response} object - *

* * @author 陈添明 */ @@ -41,7 +39,7 @@ public final class ResponseCallAdapterFactory extends CallAdapter.Factory { @Override public CallAdapter get(Type returnType, Annotation[] annotations, Retrofit retrofit) { if (Response.class.isAssignableFrom(getRawType(returnType))) { - return new ResponseCallAdapter(returnType); + return new ResponseCallAdapter<>(returnType); } return null; } diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/annotation/RetrofitClient.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/RetrofitClient.java similarity index 96% rename from src/main/java/com/github/lianjiatech/retrofit/spring/boot/annotation/RetrofitClient.java rename to src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/RetrofitClient.java index 1a7cf72..3c61bdc 100644 --- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/annotation/RetrofitClient.java +++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/RetrofitClient.java @@ -1,4 +1,4 @@ -package com.github.lianjiatech.retrofit.spring.boot.annotation; +package com.github.lianjiatech.retrofit.spring.boot.core; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; @@ -6,9 +6,6 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import com.github.lianjiatech.retrofit.spring.boot.core.DefaultErrorDecoder; -import com.github.lianjiatech.retrofit.spring.boot.core.ErrorDecoder; - import retrofit2.CallAdapter; import retrofit2.Converter; import retrofit2.Retrofit; @@ -66,7 +63,6 @@ */ Class fallback() default void.class; - /** * Define a fallback factory for the specified Feign client interface. The fallback * factory must produce instances of fallback classes that implement the interface @@ -75,19 +71,9 @@ */ Class fallbackFactory() default void.class; - - /** - * When calling {@link Retrofit#create(Class)} on the resulting {@link Retrofit} instance, eagerly validate the - * configuration of all methods in the supplied interface. - * - * @return validateEagerly - */ - boolean validateEagerly() default false; - /** * 当前接口采用的错误解码器,当请求发生异常或者收到无效响应结果的时候,将HTTP相关信息解码到异常中,无效响应由业务自己判断。 - * 一般情况下,每个服务对应的无效响应各不相同,可以自定义对应的{@link ErrorDecoder},然后配置在这里。 - *

+ * 一般情况下,每个服务对应的无效响应各不相同,可以自定义对应的{@link ErrorDecoder},然后配置在这里。
* The error decoder used in the current interface will decode HTTP related information into the exception when an exception occurs in the request or an invalid response result is received. * The invalid response is determined by the business itself. * In general, the invalid response corresponding to each service is different, you can customize the corresponding {@link ErrorDecoder}, and then configure it here. @@ -103,6 +89,14 @@ */ String poolName() default "default"; + /** + * When calling {@link Retrofit#create(Class)} on the resulting {@link Retrofit} instance, eagerly validate the + * configuration of all methods in the supplied interface. + * + * @return validateEagerly + */ + boolean validateEagerly() default false; + /** * Sets the default connect timeout for new connections. A value of 0 means no timeout, * otherwise values must be between 1 and Integer.MAX_VALUE when converted to milliseconds. @@ -130,7 +124,6 @@ */ int writeTimeoutMs() default -1; - /** * Sets the default timeout for complete calls. A value of 0 means no timeout, * otherwise values must be between 1 and Integer.MAX_VALUE when converted to milliseconds. @@ -148,7 +141,6 @@ */ int pingIntervalMs() default 0; - /** * Configure this client to allow protocol redirects from HTTPS to HTTP and from HTTP to HTTPS. * Redirects are still first restricted by followRedirects. Defaults to true. diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/RetrofitClientScannerRegistrar.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/RetrofitClientScannerRegistrar.java index 668bc1a..c5fd785 100644 --- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/RetrofitClientScannerRegistrar.java +++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/RetrofitClientScannerRegistrar.java @@ -15,11 +15,12 @@ import org.springframework.util.ClassUtils; import org.springframework.util.ObjectUtils; -import com.github.lianjiatech.retrofit.spring.boot.annotation.RetrofitScan; +import lombok.extern.slf4j.Slf4j; /** * @author 陈添明 */ +@Slf4j public class RetrofitClientScannerRegistrar implements ImportBeanDefinitionRegistrar, ResourceLoaderAware, BeanClassLoaderAware { @@ -42,6 +43,8 @@ public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionR } // Specify the base package for scanning String[] basePackages = getPackagesToScan(attributes); + log.info("Scan the @RetrofitClient annotated interface using the @RetrofitScan configuration. packages={}", + Arrays.toString(basePackages)); scanner.registerFilters(); // Scan and register to BeanDefinition scanner.doScan(basePackages); diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/RetrofitFactoryBean.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/RetrofitFactoryBean.java index ef283ca..f114424 100644 --- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/RetrofitFactoryBean.java +++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/RetrofitFactoryBean.java @@ -20,24 +20,20 @@ import org.springframework.core.annotation.AnnotationUtils; import org.springframework.core.env.Environment; import org.springframework.util.Assert; -import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule; import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager; -import com.github.lianjiatech.retrofit.spring.boot.annotation.Intercept; -import com.github.lianjiatech.retrofit.spring.boot.annotation.InterceptMark; -import com.github.lianjiatech.retrofit.spring.boot.annotation.Intercepts; -import com.github.lianjiatech.retrofit.spring.boot.annotation.OkHttpClientBuilder; -import com.github.lianjiatech.retrofit.spring.boot.annotation.RetrofitClient; import com.github.lianjiatech.retrofit.spring.boot.config.DegradeProperty; import com.github.lianjiatech.retrofit.spring.boot.config.RetrofitConfigBean; import com.github.lianjiatech.retrofit.spring.boot.config.RetrofitProperties; import com.github.lianjiatech.retrofit.spring.boot.degrade.DegradeProxy; import com.github.lianjiatech.retrofit.spring.boot.degrade.DegradeType; -import com.github.lianjiatech.retrofit.spring.boot.degrade.FallbackFactory; import com.github.lianjiatech.retrofit.spring.boot.degrade.sentinel.SentinelDegrade; import com.github.lianjiatech.retrofit.spring.boot.interceptor.BasePathMatchInterceptor; +import com.github.lianjiatech.retrofit.spring.boot.interceptor.Intercept; +import com.github.lianjiatech.retrofit.spring.boot.interceptor.InterceptMark; +import com.github.lianjiatech.retrofit.spring.boot.interceptor.Intercepts; import com.github.lianjiatech.retrofit.spring.boot.util.AnnotationExtendUtils; import com.github.lianjiatech.retrofit.spring.boot.util.AppContextUtils; import com.github.lianjiatech.retrofit.spring.boot.util.BeanExtendUtils; @@ -46,8 +42,6 @@ import okhttp3.ConnectionPool; import okhttp3.Interceptor; import okhttp3.OkHttpClient; -import retrofit2.CallAdapter; -import retrofit2.Converter; import retrofit2.Retrofit; /** @@ -55,10 +49,7 @@ */ public class RetrofitFactoryBean implements FactoryBean, EnvironmentAware, ApplicationContextAware { - private static final Map, CallAdapter.Factory> CALL_ADAPTER_FACTORIES_CACHE = - new HashMap<>(4); - - private Class retrofitInterface; + private final Class retrofitInterface; private Environment environment; @@ -68,17 +59,12 @@ public class RetrofitFactoryBean implements FactoryBean, EnvironmentAware, private ApplicationContext applicationContext; - private static final Map, Converter.Factory> CONVERTER_FACTORIES_CACHE = - new HashMap<>(4); - public RetrofitFactoryBean(Class retrofitInterface) { this.retrofitInterface = retrofitInterface; } @Override public T getObject() throws Exception { - checkRetrofitInterface(); - // source T source = createRetrofit().create(retrofitInterface); if (!isEnableSentinelDegrade(retrofitProperties.getDegrade(), retrofitInterface)) { return source; @@ -123,61 +109,12 @@ private void loadSentinelDegradeRules() { .setCount(sentinelDegrade.count()) .setTimeWindow(sentinelDegrade.timeWindow()) .setGrade(sentinelDegrade.grade()); - degradeRule.setResource(retrofitConfigBean.getResourceNameParser().extractResourceName(method)); + degradeRule.setResource(retrofitConfigBean.getResourceNameParser().extractResourceNameCache(method)); rules.add(degradeRule); } DegradeRuleManager.loadRules(rules); } - private void checkRetrofitInterface() { - // check class type - Assert.isTrue(retrofitInterface.isInterface(), "@RetrofitClient can only be marked on the interface type!"); - Method[] methods = retrofitInterface.getMethods(); - - RetrofitClient retrofitClient = retrofitInterface.getAnnotation(RetrofitClient.class); - Assert.isTrue(StringUtils.hasText(retrofitClient.baseUrl()) || StringUtils.hasText(retrofitClient.serviceId()), - "@RetrofitClient's baseUrl and serviceId must be configured with one!"); - - for (Method method : methods) { - Class returnType = method.getReturnType(); - if (method.isAnnotationPresent(OkHttpClientBuilder.class)) { - Assert.isTrue(returnType.equals(OkHttpClient.Builder.class), - "For methods annotated by @OkHttpClientBuilder, the return value must be OkHttpClient.Builder!"); - Assert.isTrue(Modifier.isStatic(method.getModifiers()), - "only static method can annotated by @OkHttpClientBuilder!"); - continue; - } - - Assert.isTrue(!void.class.isAssignableFrom(returnType), - "The void keyword is not supported as the return type, please use java.lang.Void! method=" - + method); - if (retrofitProperties.isDisableVoidReturnType()) { - Assert.isTrue(!Void.class.isAssignableFrom(returnType), - "Configured to disable Void as the return value, please specify another return type!method=" - + method); - } - } - - Class fallbackClass = retrofitClient.fallback(); - if (!void.class.isAssignableFrom(fallbackClass)) { - Assert.isTrue(retrofitInterface.isAssignableFrom(fallbackClass), - "The fallback type must implement the current interface!the fallback type is " + fallbackClass); - Object fallback = AppContextUtils.getBeanOrNull(applicationContext, fallbackClass); - Assert.notNull(fallback, "fallback must be a valid spring bean! the fallback class is " + fallbackClass); - } - - Class fallbackFactoryClass = retrofitClient.fallbackFactory(); - if (!void.class.isAssignableFrom(fallbackFactoryClass)) { - Assert.isTrue(FallbackFactory.class.isAssignableFrom(fallbackFactoryClass), - "The fallback factory type must implement FallbackFactory!the fallback factory is " - + fallbackFactoryClass); - Object fallbackFactory = AppContextUtils.getBeanOrNull(applicationContext, fallbackFactoryClass); - Assert.notNull(fallbackFactory, - "fallback factory must be a valid spring bean! the fallback factory class is " - + fallbackFactoryClass); - } - } - @Override public Class getObjectType() { return this.retrofitInterface; @@ -260,8 +197,7 @@ private Method findOkHttpClientBuilderMethod() { } @SuppressWarnings("unchecked") - private List findInterceptorByAnnotation() - throws InstantiationException, IllegalAccessException { + private List findInterceptorByAnnotation() throws InstantiationException, IllegalAccessException { Annotation[] classAnnotations = retrofitInterface.getAnnotations(); List interceptors = new ArrayList<>(); // 找出被@InterceptMark标记的注解。Find the annotation marked by @InterceptMark @@ -309,11 +245,9 @@ private List findInterceptorByAnnotation() } private Retrofit createRetrofit() - throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { + throws InstantiationException, IllegalAccessException, InvocationTargetException { RetrofitClient retrofitClient = retrofitInterface.getAnnotation(RetrofitClient.class); - String baseUrl = retrofitClient.baseUrl(); - - baseUrl = RetrofitUtils.convertBaseUrl(retrofitClient, baseUrl, environment); + String baseUrl = RetrofitUtils.convertBaseUrl(retrofitClient, retrofitClient.baseUrl(), environment); OkHttpClient client = createOkHttpClient(); Retrofit.Builder retrofitBuilder = new Retrofit.Builder() @@ -321,87 +255,27 @@ private Retrofit createRetrofit() .validateEagerly(retrofitClient.validateEagerly()) .client(client); - // 添加CallAdapter.Factory - Class[] callAdapterFactoryClasses = retrofitClient.callAdapterFactories(); - Class[] globalCallAdapterFactoryClasses = - retrofitConfigBean.getGlobalCallAdapterFactoryClasses(); - List callAdapterFactories = - getCallAdapterFactories(callAdapterFactoryClasses, globalCallAdapterFactoryClasses); - if (!CollectionUtils.isEmpty(callAdapterFactories)) { - callAdapterFactories.forEach(retrofitBuilder::addCallAdapterFactory); - } - // 添加Converter.Factory - Class[] converterFactoryClasses = retrofitClient.converterFactories(); - Class[] globalConverterFactoryClasses = - retrofitConfigBean.getGlobalConverterFactoryClasses(); - - List converterFactories = - getConverterFactories(converterFactoryClasses, globalConverterFactoryClasses); - if (!CollectionUtils.isEmpty(converterFactories)) { - converterFactories.forEach(retrofitBuilder::addConverterFactory); - } - return retrofitBuilder.build(); - } - - private List getCallAdapterFactories( - Class[] callAdapterFactoryClasses, - Class[] globalCallAdapterFactoryClasses) - throws IllegalAccessException, InstantiationException { - List> combineCallAdapterFactoryClasses = new ArrayList<>(); - - if (callAdapterFactoryClasses != null && callAdapterFactoryClasses.length != 0) { - combineCallAdapterFactoryClasses.addAll(Arrays.asList(callAdapterFactoryClasses)); - } - - if (globalCallAdapterFactoryClasses != null && globalCallAdapterFactoryClasses.length != 0) { - combineCallAdapterFactoryClasses.addAll(Arrays.asList(globalCallAdapterFactoryClasses)); - } - - if (combineCallAdapterFactoryClasses.isEmpty()) { - return Collections.emptyList(); - } - - List callAdapterFactories = new ArrayList<>(); + combineAndCreate(retrofitClient.callAdapterFactories(), retrofitConfigBean.getGlobalCallAdapterFactoryClasses()) + .forEach(retrofitBuilder::addCallAdapterFactory); - for (Class callAdapterFactoryClass : combineCallAdapterFactoryClasses) { - CallAdapter.Factory callAdapterFactory = CALL_ADAPTER_FACTORIES_CACHE.get(callAdapterFactoryClass); - if (callAdapterFactory == null) { - callAdapterFactory = AppContextUtils.getBeanOrNew(applicationContext, callAdapterFactoryClass); - CALL_ADAPTER_FACTORIES_CACHE.put(callAdapterFactoryClass, callAdapterFactory); - } - callAdapterFactories.add(callAdapterFactory); - } - return callAdapterFactories; + combineAndCreate(retrofitClient.converterFactories(), retrofitConfigBean.getGlobalConverterFactoryClasses()) + .forEach(retrofitBuilder::addConverterFactory); + return retrofitBuilder.build(); } - private List getConverterFactories(Class[] converterFactoryClasses, - Class[] globalConverterFactoryClasses) - throws IllegalAccessException, InstantiationException { - List> combineConverterFactoryClasses = new ArrayList<>(); - - if (converterFactoryClasses != null && converterFactoryClasses.length != 0) { - combineConverterFactoryClasses.addAll(Arrays.asList(converterFactoryClasses)); - } - - if (globalConverterFactoryClasses != null && globalConverterFactoryClasses.length != 0) { - combineConverterFactoryClasses.addAll(Arrays.asList(globalConverterFactoryClasses)); - } - - if (combineConverterFactoryClasses.isEmpty()) { + private List combineAndCreate(Class[] clz, Class[] globalClz) { + if (clz.length == 0 && globalClz.length == 0) { return Collections.emptyList(); } + List> combineClz = new ArrayList<>(clz.length + globalClz.length); + combineClz.addAll(Arrays.asList(clz)); + combineClz.addAll(Arrays.asList(globalClz)); - List converterFactories = new ArrayList<>(); - - for (Class converterFactoryClass : combineConverterFactoryClasses) { - Converter.Factory converterFactory = CONVERTER_FACTORIES_CACHE.get(converterFactoryClass); - if (converterFactory == null) { - converterFactory = AppContextUtils.getBeanOrNew(applicationContext, converterFactoryClass); - CONVERTER_FACTORIES_CACHE.put(converterFactoryClass, converterFactory); - } - converterFactories.add(converterFactory); + List result = new ArrayList<>(combineClz.size()); + for (Class aClass : combineClz) { + result.add(AppContextUtils.getBeanOrNew(applicationContext, aClass)); } - return converterFactories; + return result; } @Override diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/annotation/RetrofitScan.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/RetrofitScan.java similarity index 84% rename from src/main/java/com/github/lianjiatech/retrofit/spring/boot/annotation/RetrofitScan.java rename to src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/RetrofitScan.java index 7c8aca4..93121d5 100644 --- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/annotation/RetrofitScan.java +++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/RetrofitScan.java @@ -1,4 +1,4 @@ -package com.github.lianjiatech.retrofit.spring.boot.annotation; +package com.github.lianjiatech.retrofit.spring.boot.core; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; @@ -8,8 +8,6 @@ import org.springframework.context.annotation.Import; -import com.github.lianjiatech.retrofit.spring.boot.core.RetrofitClientScannerRegistrar; - /** * @author 陈添明 */ diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/DefaultResourceNameParser.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/DefaultResourceNameParser.java index d8cef9d..9cc8bc5 100644 --- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/DefaultResourceNameParser.java +++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/DefaultResourceNameParser.java @@ -1,13 +1,11 @@ package com.github.lianjiatech.retrofit.spring.boot.degrade; import java.lang.reflect.Method; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; import org.springframework.context.EnvironmentAware; import org.springframework.core.env.Environment; -import com.github.lianjiatech.retrofit.spring.boot.annotation.RetrofitClient; +import com.github.lianjiatech.retrofit.spring.boot.core.RetrofitClient; import com.github.lianjiatech.retrofit.spring.boot.util.RetrofitUtils; /** @@ -15,16 +13,11 @@ */ public class DefaultResourceNameParser implements ResourceNameParser, EnvironmentAware { - private static final Map RESOURCE_NAME_CACHE = new ConcurrentHashMap<>(128); - - private Environment environment; + protected Environment environment; @Override public String extractResourceName(Method method) { - String resourceName = RESOURCE_NAME_CACHE.get(method); - if (resourceName != null) { - return resourceName; - } + String resourceName; Class declaringClass = method.getDeclaringClass(); RetrofitClient retrofitClient = declaringClass.getAnnotation(RetrofitClient.class); String baseUrl = retrofitClient.baseUrl(); @@ -32,7 +25,6 @@ public String extractResourceName(Method method) { HttpMethodPath httpMethodPath = parseHttpMethodPath(method); resourceName = String.format("%s:%s:%s", HTTP_OUT, httpMethodPath.getMethod(), baseUrl + httpMethodPath.getPath()); - RESOURCE_NAME_CACHE.put(method, resourceName); return resourceName; } diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/DegradeProxy.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/DegradeProxy.java index 42206ff..7d19b53 100644 --- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/DegradeProxy.java +++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/DegradeProxy.java @@ -6,8 +6,7 @@ import org.springframework.context.ApplicationContext; -import com.github.lianjiatech.retrofit.spring.boot.annotation.RetrofitClient; -import com.github.lianjiatech.retrofit.spring.boot.util.AppContextUtils; +import com.github.lianjiatech.retrofit.spring.boot.core.RetrofitClient; /** * @author 陈添明 @@ -27,13 +26,12 @@ public static T create(Object source, Class retrofitInterface, Applicatio Class fallbackClass = retrofitClient.fallback(); Object fallback = null; if (!void.class.isAssignableFrom(fallbackClass)) { - fallback = AppContextUtils.getBeanOrNull(applicationContext, fallbackClass); + fallback = applicationContext.getBean(fallbackClass); } Class fallbackFactoryClass = retrofitClient.fallbackFactory(); FallbackFactory fallbackFactory = null; if (!void.class.isAssignableFrom(fallbackFactoryClass)) { - fallbackFactory = - (FallbackFactory)AppContextUtils.getBeanOrNull(applicationContext, fallbackFactoryClass); + fallbackFactory = (FallbackFactory)applicationContext.getBean(fallbackFactoryClass); } DegradeProxy degradeProxy = new DegradeProxy(source, fallback, fallbackFactory); return (T)Proxy.newProxyInstance(retrofitInterface.getClassLoader(), diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/ResourceNameParser.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/ResourceNameParser.java index 1aaf0ad..2039903 100644 --- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/ResourceNameParser.java +++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/ResourceNameParser.java @@ -1,6 +1,8 @@ package com.github.lianjiatech.retrofit.spring.boot.degrade; import java.lang.reflect.Method; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import retrofit2.http.DELETE; import retrofit2.http.GET; @@ -18,6 +20,23 @@ public interface ResourceNameParser { String HTTP_OUT = "HTTP_OUT"; + Map RESOURCE_NAME_CACHE = new ConcurrentHashMap<>(128); + + /** + * 提取资源名称,支持缓存 + * @param method 方法 + * @return 资源名称 + */ + default String extractResourceNameCache(Method method) { + String resourceName = RESOURCE_NAME_CACHE.get(method); + if (resourceName != null) { + return resourceName; + } + resourceName = extractResourceName(method); + RESOURCE_NAME_CACHE.put(method, resourceName); + return resourceName; + } + /** * 提取资源名称 * @param method 方法 diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/sentinel/SentinelDegradeInterceptor.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/sentinel/SentinelDegradeInterceptor.java index ed8d4a5..577e753 100644 --- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/sentinel/SentinelDegradeInterceptor.java +++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/sentinel/SentinelDegradeInterceptor.java @@ -23,7 +23,7 @@ */ public class SentinelDegradeInterceptor implements DegradeInterceptor { - private final ResourceNameParser resourceNameParser; + protected final ResourceNameParser resourceNameParser; public SentinelDegradeInterceptor(ResourceNameParser resourceNameParser) { this.resourceNameParser = resourceNameParser; @@ -36,7 +36,7 @@ public Response intercept(Chain chain) throws IOException { if (AnnotationExtendUtils.findAnnotation(method, SentinelDegrade.class) == null) { return chain.proceed(request); } - String resourceName = resourceNameParser.extractResourceName(method); + String resourceName = resourceNameParser.extractResourceNameCache(method); Entry entry = null; try { entry = SphU.entry(resourceName, ResourceTypeConstants.COMMON_WEB, EntryType.OUT); diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/interceptor/BasePathMatchInterceptor.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/interceptor/BasePathMatchInterceptor.java index 07a478b..bd368e8 100644 --- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/interceptor/BasePathMatchInterceptor.java +++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/interceptor/BasePathMatchInterceptor.java @@ -5,7 +5,7 @@ import org.springframework.util.AntPathMatcher; import org.springframework.util.PathMatcher; -import lombok.Data; +import lombok.Setter; import okhttp3.Interceptor; import okhttp3.Request; import okhttp3.Response; @@ -15,17 +15,17 @@ * * @author 陈添明 */ -@Data +@Setter public abstract class BasePathMatchInterceptor implements Interceptor { - private String[] include; + protected String[] include; - private String[] exclude; + protected String[] exclude; - private PathMatcher pathMatcher = new AntPathMatcher(); + protected PathMatcher pathMatcher = new AntPathMatcher(); @Override - public final Response intercept(Chain chain) throws IOException { + public Response intercept(Chain chain) throws IOException { Request request = chain.request(); String path = request.url().encodedPath(); @@ -50,10 +50,8 @@ public final Response intercept(Chain chain) throws IOException { protected abstract Response doIntercept(Chain chain) throws IOException; /** - *

- * 当前http的url路径是否与指定的patterns匹配 + * 当前http的url路径是否与指定的patterns匹配。
* Whether the current http URL path matches the specified patterns - *

* * @param patterns the specified patterns * @param path http URL path diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/interceptor/ErrorDecoderInterceptor.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/interceptor/ErrorDecoderInterceptor.java index 2b4f0d5..0ba9ce7 100644 --- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/interceptor/ErrorDecoderInterceptor.java +++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/interceptor/ErrorDecoderInterceptor.java @@ -8,8 +8,8 @@ import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; -import com.github.lianjiatech.retrofit.spring.boot.annotation.RetrofitClient; import com.github.lianjiatech.retrofit.spring.boot.core.ErrorDecoder; +import com.github.lianjiatech.retrofit.spring.boot.core.RetrofitClient; import com.github.lianjiatech.retrofit.spring.boot.util.AppContextUtils; import lombok.SneakyThrows; diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/annotation/Intercept.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/interceptor/Intercept.java similarity index 90% rename from src/main/java/com/github/lianjiatech/retrofit/spring/boot/annotation/Intercept.java rename to src/main/java/com/github/lianjiatech/retrofit/spring/boot/interceptor/Intercept.java index caba97d..0b8c0d9 100644 --- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/annotation/Intercept.java +++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/interceptor/Intercept.java @@ -1,4 +1,4 @@ -package com.github.lianjiatech.retrofit.spring.boot.annotation; +package com.github.lianjiatech.retrofit.spring.boot.interceptor; import java.lang.annotation.ElementType; import java.lang.annotation.Repeatable; @@ -6,8 +6,6 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import com.github.lianjiatech.retrofit.spring.boot.interceptor.BasePathMatchInterceptor; - /** * 自动将注解上的参数值赋值到handleInterceptor实例上 * Automatically assign the parameter value on the annotation to the handleInterceptor instance diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/interceptor/InterceptMark.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/interceptor/InterceptMark.java new file mode 100644 index 0000000..2ed3ea6 --- /dev/null +++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/interceptor/InterceptMark.java @@ -0,0 +1,20 @@ +package com.github.lianjiatech.retrofit.spring.boot.interceptor; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 拦截标记注解 + * Intercept mark + * + * @author 陈添明 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.ANNOTATION_TYPE) +@Documented +public @interface InterceptMark { + +} diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/interceptor/Intercepts.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/interceptor/Intercepts.java new file mode 100644 index 0000000..9e62699 --- /dev/null +++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/interceptor/Intercepts.java @@ -0,0 +1,16 @@ +package com.github.lianjiatech.retrofit.spring.boot.interceptor; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @author 陈添明 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface Intercepts { + + Intercept[] value(); +} diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/interceptor/ServiceChooseInterceptor.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/interceptor/ServiceChooseInterceptor.java index 32b5ebb..c056291 100644 --- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/interceptor/ServiceChooseInterceptor.java +++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/interceptor/ServiceChooseInterceptor.java @@ -7,7 +7,7 @@ import org.springframework.util.StringUtils; -import com.github.lianjiatech.retrofit.spring.boot.annotation.RetrofitClient; +import com.github.lianjiatech.retrofit.spring.boot.core.RetrofitClient; import com.github.lianjiatech.retrofit.spring.boot.core.ServiceInstanceChooser; import okhttp3.HttpUrl; @@ -21,7 +21,7 @@ */ public class ServiceChooseInterceptor implements Interceptor { - private final ServiceInstanceChooser serviceInstanceChooser; + protected final ServiceInstanceChooser serviceInstanceChooser; public ServiceChooseInterceptor(ServiceInstanceChooser serviceDiscovery) { this.serviceInstanceChooser = serviceDiscovery; diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/log/LoggingInterceptor.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/log/LoggingInterceptor.java index cd8f0cc..8207118 100644 --- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/log/LoggingInterceptor.java +++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/log/LoggingInterceptor.java @@ -20,7 +20,7 @@ @Slf4j public class LoggingInterceptor implements Interceptor { - private final LogProperty logProperty; + protected final LogProperty logProperty; public LoggingInterceptor(LogProperty logProperty) { this.logProperty = logProperty; diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/retry/RetryInterceptor.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/retry/RetryInterceptor.java index 5d723f9..b6bce8a 100644 --- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/retry/RetryInterceptor.java +++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/retry/RetryInterceptor.java @@ -10,7 +10,6 @@ import com.github.lianjiatech.retrofit.spring.boot.config.RetryProperty; import com.github.lianjiatech.retrofit.spring.boot.util.AnnotationExtendUtils; -import lombok.Data; import lombok.extern.slf4j.Slf4j; import okhttp3.Interceptor; import okhttp3.Request; @@ -21,10 +20,9 @@ * @author 陈添明 */ @Slf4j -@Data public class RetryInterceptor implements Interceptor { - private final RetryProperty retryProperty; + protected final RetryProperty retryProperty; public RetryInterceptor(RetryProperty retryProperty) { this.retryProperty = retryProperty; diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/util/AppContextUtils.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/util/AppContextUtils.java index ee2a23b..098aae6 100644 --- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/util/AppContextUtils.java +++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/util/AppContextUtils.java @@ -2,39 +2,37 @@ import org.springframework.aop.framework.Advised; import org.springframework.aop.support.AopUtils; -import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import lombok.experimental.UtilityClass; +import lombok.extern.slf4j.Slf4j; /** * @author 陈添明 */ @UtilityClass +@Slf4j public final class AppContextUtils { - public static T getBeanOrNull(ApplicationContext context, Class clz) { - try { - return context.getBean(clz); - } catch (BeansException e) { - return null; - } - } - - public static T getBeanOrDefault(ApplicationContext context, Class clz, T t) { - try { - return context.getBean(clz); - } catch (BeansException e) { - return t; - } - } - - public static T getBeanOrNew(ApplicationContext context, Class clz) - throws InstantiationException, IllegalAccessException { + /** + * 优先从Spring容器获取实例,如果获取失败,调用无参方法创建,如果再失败,尝试调用无参create静态方法创建 + */ + @SuppressWarnings("unchecked") + public static T getBeanOrNew(ApplicationContext context, Class clz) { try { return context.getBean(clz); - } catch (BeansException e) { - return clz.newInstance(); + } catch (Exception e1) { + try { + log.warn("Failed to get bean from applicationContext!", e1); + return clz.newInstance(); + } catch (Exception e2) { + log.warn("Failed to create instance by reflection.", e2); + try { + return (T)clz.getMethod("create").invoke(null); + } catch (Exception e3) { + throw new RuntimeException("Failed to create instance through create static method.", e3); + } + } } } @@ -45,7 +43,7 @@ public static T getTargetInstanceIfNecessary(T bean) { try { object = ((Advised)object).getTargetSource().getTarget(); } catch (Exception e) { - throw new RuntimeException("get target bean failed", e); + log.warn("Failed to get target source!", e); } } return (T)object; diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/util/RetrofitUtils.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/util/RetrofitUtils.java index 2421a48..17fad2f 100644 --- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/util/RetrofitUtils.java +++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/util/RetrofitUtils.java @@ -7,7 +7,7 @@ import org.springframework.core.env.Environment; import org.springframework.util.StringUtils; -import com.github.lianjiatech.retrofit.spring.boot.annotation.RetrofitClient; +import com.github.lianjiatech.retrofit.spring.boot.core.RetrofitClient; import com.github.lianjiatech.retrofit.spring.boot.exception.ReadResponseBodyException; import lombok.experimental.UtilityClass; diff --git a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/other/OtherPathApi.java b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/other/OtherPathApi.java new file mode 100644 index 0000000..305a0b0 --- /dev/null +++ b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/other/OtherPathApi.java @@ -0,0 +1,29 @@ +package com.github.lianjiatech.retrofit.spring.boot.other; + +import com.github.lianjiatech.retrofit.spring.boot.core.RetrofitClient; +import com.github.lianjiatech.retrofit.spring.boot.degrade.sentinel.SentinelDegrade; +import com.github.lianjiatech.retrofit.spring.boot.test.entity.Person; +import com.github.lianjiatech.retrofit.spring.boot.test.entity.Result; + +import retrofit2.http.GET; +import retrofit2.http.Query; + +/** + * @author 陈添明 + * @since 2022/1/21 4:19 下午 + */ +@RetrofitClient(baseUrl = "${test.baseUrl}") +@SentinelDegrade(count = 100) +public interface OtherPathApi { + + /** + * 其他任意Java类型
+ * 将响应体内容适配成一个对应的Java类型对象返回,如果http状态码不是2xx,直接抛错!
+ * + * @param id id + * @return 其他任意Java类型 + */ + @GET("person") + Result getPerson(@Query("id") Long id); + +} diff --git a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/OtherPathTest.java b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/OtherPathTest.java new file mode 100644 index 0000000..d297ecd --- /dev/null +++ b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/OtherPathTest.java @@ -0,0 +1,81 @@ +package com.github.lianjiatech.retrofit.spring.boot.test; + +import java.io.IOException; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.github.lianjiatech.retrofit.spring.boot.other.OtherPathApi; +import com.github.lianjiatech.retrofit.spring.boot.test.entity.Person; +import com.github.lianjiatech.retrofit.spring.boot.test.entity.Result; + +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; + +/** + * @author 陈添明 + */ +@SpringBootTest(classes = RetrofitTestApplication.class) +@RunWith(SpringRunner.class) +public class OtherPathTest { + + @Autowired + private OtherPathApi otherPathApi; + + private MockWebServer server; + + private static final ObjectMapper objectMapper = + new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) + .setSerializationInclusion(JsonInclude.Include.NON_NULL); + + @Before + public void before() throws IOException { + System.out.println("=========开启MockWebServer==========="); + server = new MockWebServer(); + server.start(8080); + + } + + @After + public void after() throws IOException { + System.out.println("=========关闭MockWebServer==========="); + server.close(); + } + + @Test + public void test() throws JsonProcessingException { + // mock + Person mockPerson = new Person().setId(1L) + .setName("test") + .setAge(10); + Result mockResult = new Result<>() + .setCode(0) + .setMsg("ok") + .setData(mockPerson); + MockResponse response = new MockResponse() + .setResponseCode(200) + .addHeader("Content-Type", "application/json; charset=utf-8") + .addHeader("Cache-Control", "no-cache") + .setBody(objectMapper.writeValueAsString(mockResult)); + server.enqueue(response); + + // http check + Result person = otherPathApi.getPerson(1L); + Person data = person.getData(); + Assert.assertNotNull(data); + Assert.assertEquals("test", data.getName()); + Assert.assertEquals(10, data.getAge().intValue()); + + } + +} diff --git a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/RetrofitTestApplication.java b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/RetrofitTestApplication.java index fb17afd..49edb78 100644 --- a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/RetrofitTestApplication.java +++ b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/RetrofitTestApplication.java @@ -4,6 +4,8 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; +import com.github.lianjiatech.retrofit.spring.boot.core.RetrofitScan; + import retrofit2.converter.gson.GsonConverterFactory; import retrofit2.converter.jaxb.JaxbConverterFactory; @@ -11,6 +13,7 @@ * @author 陈添明 */ @SpringBootApplication +@RetrofitScan("com.github.lianjiatech.retrofit.spring.boot") public class RetrofitTestApplication { public static void main(String[] args) { diff --git a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/ConvertFactoriesTestApi.java b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/ConvertFactoriesTestApi.java index 10c2613..98a6195 100644 --- a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/ConvertFactoriesTestApi.java +++ b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/ConvertFactoriesTestApi.java @@ -1,6 +1,6 @@ package com.github.lianjiatech.retrofit.spring.boot.test.http; -import com.github.lianjiatech.retrofit.spring.boot.annotation.RetrofitClient; +import com.github.lianjiatech.retrofit.spring.boot.core.RetrofitClient; import com.github.lianjiatech.retrofit.spring.boot.test.entity.Person; import com.github.lianjiatech.retrofit.spring.boot.test.entity.Result; diff --git a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/DegradeApi.java b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/DegradeApi.java index b8c8ccb..37307df 100644 --- a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/DegradeApi.java +++ b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/DegradeApi.java @@ -1,6 +1,6 @@ package com.github.lianjiatech.retrofit.spring.boot.test.http; -import com.github.lianjiatech.retrofit.spring.boot.annotation.RetrofitClient; +import com.github.lianjiatech.retrofit.spring.boot.core.RetrofitClient; import com.github.lianjiatech.retrofit.spring.boot.degrade.sentinel.SentinelDegrade; import com.github.lianjiatech.retrofit.spring.boot.test.entity.Person; import com.github.lianjiatech.retrofit.spring.boot.test.entity.Result; diff --git a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/DownloadApi.java b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/DownloadApi.java index 904ad8d..d5bd5ab 100644 --- a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/DownloadApi.java +++ b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/DownloadApi.java @@ -1,6 +1,7 @@ package com.github.lianjiatech.retrofit.spring.boot.test.http; -import com.github.lianjiatech.retrofit.spring.boot.annotation.RetrofitClient; +import com.github.lianjiatech.retrofit.spring.boot.core.RetrofitClient; + import okhttp3.ResponseBody; import retrofit2.Response; import retrofit2.http.GET; diff --git a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/ErrorDecoderTestApi.java b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/ErrorDecoderTestApi.java index 66872dd..0669193 100644 --- a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/ErrorDecoderTestApi.java +++ b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/ErrorDecoderTestApi.java @@ -1,6 +1,6 @@ package com.github.lianjiatech.retrofit.spring.boot.test.http; -import com.github.lianjiatech.retrofit.spring.boot.annotation.RetrofitClient; +import com.github.lianjiatech.retrofit.spring.boot.core.RetrofitClient; import com.github.lianjiatech.retrofit.spring.boot.log.LogStrategy; import com.github.lianjiatech.retrofit.spring.boot.log.Logging; import com.github.lianjiatech.retrofit.spring.boot.test.InvalidRespErrorDecoder; diff --git a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/HttpApi.java b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/HttpApi.java index 7335583..be7fe2b 100644 --- a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/HttpApi.java +++ b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/HttpApi.java @@ -3,8 +3,8 @@ import java.util.List; import java.util.concurrent.CompletableFuture; -import com.github.lianjiatech.retrofit.spring.boot.annotation.Intercept; -import com.github.lianjiatech.retrofit.spring.boot.annotation.RetrofitClient; +import com.github.lianjiatech.retrofit.spring.boot.core.RetrofitClient; +import com.github.lianjiatech.retrofit.spring.boot.interceptor.Intercept; import com.github.lianjiatech.retrofit.spring.boot.test.entity.Person; import com.github.lianjiatech.retrofit.spring.boot.test.entity.Result; import com.github.lianjiatech.retrofit.spring.boot.test.ex.TestErrorDecoder; diff --git a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/HttpApi2.java b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/HttpApi2.java index f88afd7..ed3f811 100644 --- a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/HttpApi2.java +++ b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/HttpApi2.java @@ -2,8 +2,8 @@ import java.util.Map; -import com.github.lianjiatech.retrofit.spring.boot.annotation.Intercept; -import com.github.lianjiatech.retrofit.spring.boot.annotation.RetrofitClient; +import com.github.lianjiatech.retrofit.spring.boot.core.RetrofitClient; +import com.github.lianjiatech.retrofit.spring.boot.interceptor.Intercept; import com.github.lianjiatech.retrofit.spring.boot.test.entity.Person; import com.github.lianjiatech.retrofit.spring.boot.test.entity.Result; import com.github.lianjiatech.retrofit.spring.boot.test.interceptor.EnumIntercept; diff --git a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/HttpApi3.java b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/HttpApi3.java index 703b72d..86681f5 100644 --- a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/HttpApi3.java +++ b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/HttpApi3.java @@ -2,8 +2,8 @@ import java.util.concurrent.TimeUnit; -import com.github.lianjiatech.retrofit.spring.boot.annotation.OkHttpClientBuilder; -import com.github.lianjiatech.retrofit.spring.boot.annotation.RetrofitClient; +import com.github.lianjiatech.retrofit.spring.boot.core.OkHttpClientBuilder; +import com.github.lianjiatech.retrofit.spring.boot.core.RetrofitClient; import com.github.lianjiatech.retrofit.spring.boot.test.entity.Person; import com.github.lianjiatech.retrofit.spring.boot.test.entity.Result; diff --git a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/IllegalBaseUrlTestApi.java b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/IllegalBaseUrlTestApi.java deleted file mode 100644 index 790ae0b..0000000 --- a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/IllegalBaseUrlTestApi.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.github.lianjiatech.retrofit.spring.boot.test.http; - -import com.github.lianjiatech.retrofit.spring.boot.annotation.RetrofitClient; -import com.github.lianjiatech.retrofit.spring.boot.test.entity.Person; -import com.github.lianjiatech.retrofit.spring.boot.test.entity.Result; - -import retrofit2.converter.gson.GsonConverterFactory; -import retrofit2.converter.jaxb.JaxbConverterFactory; -import retrofit2.http.GET; -import retrofit2.http.Query; - -/** - * @author 陈添明 - */ -@RetrofitClient(baseUrl = "${not.baseUrl}", - converterFactories = {GsonConverterFactory.class, JaxbConverterFactory.class}) -public interface IllegalBaseUrlTestApi { - - @GET("person") - Result getPerson(@Query("id") Long id); -} diff --git a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/InterceptApi.java b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/InterceptApi.java index 1fc27e7..e755949 100644 --- a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/InterceptApi.java +++ b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/InterceptApi.java @@ -1,6 +1,6 @@ package com.github.lianjiatech.retrofit.spring.boot.test.http; -import com.github.lianjiatech.retrofit.spring.boot.annotation.RetrofitClient; +import com.github.lianjiatech.retrofit.spring.boot.core.RetrofitClient; import com.github.lianjiatech.retrofit.spring.boot.test.entity.Person; import com.github.lianjiatech.retrofit.spring.boot.test.entity.Result; diff --git a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/interceptor/EnumIntercept.java b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/interceptor/EnumIntercept.java index 60e5f8c..8b71f5c 100644 --- a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/interceptor/EnumIntercept.java +++ b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/interceptor/EnumIntercept.java @@ -6,8 +6,8 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import com.github.lianjiatech.retrofit.spring.boot.annotation.InterceptMark; import com.github.lianjiatech.retrofit.spring.boot.interceptor.BasePathMatchInterceptor; +import com.github.lianjiatech.retrofit.spring.boot.interceptor.InterceptMark; /** * 自动将注解上的参数值赋值到handleInterceptor实例上 diff --git a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/interceptor/Sign.java b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/interceptor/Sign.java index 7362e7f..20944ab 100644 --- a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/interceptor/Sign.java +++ b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/interceptor/Sign.java @@ -6,8 +6,8 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import com.github.lianjiatech.retrofit.spring.boot.annotation.InterceptMark; import com.github.lianjiatech.retrofit.spring.boot.interceptor.BasePathMatchInterceptor; +import com.github.lianjiatech.retrofit.spring.boot.interceptor.InterceptMark; /** * 自动将注解上的参数值赋值到handleInterceptor实例上 diff --git a/src/test/resources/application.yml b/src/test/resources/application.yml index fda3b6a..7146113 100644 --- a/src/test/resources/application.yml +++ b/src/test/resources/application.yml @@ -9,10 +9,6 @@ retrofit: # 连接保活时间(秒) keep-alive-second: 100 - # 是否禁用void返回值类型 - disable-void-return-type: false - - # 全局转换器工厂 global-converter-factories: - com.github.lianjiatech.retrofit.spring.boot.core.BasicTypeConverterFactory diff --git a/src/test/resources/default-config.yml b/src/test/resources/default-config.yml index e7e4e58..5e062f5 100644 --- a/src/test/resources/default-config.yml +++ b/src/test/resources/default-config.yml @@ -54,5 +54,3 @@ retrofit: global-write-timeout-ms: 10000 # 全局完整调用超时时间 global-call-timeout-ms: 0 - # 是否禁用void返回值类型 - disable-void-return-type: false