diff --git a/README.md b/README.md index d86265d..dc47271 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,7 @@ gitee项目地址:[https://gitee.com/lianjiatech/retrofit-spring-boot-starter] - [x] [全局拦截器](#全局拦截器) - [x] [调用适配器](#调用适配器) - [x] [数据转换器](#数据转码器) +- [x] [元注解](#元注解) - [x] [其他功能示例](#其他功能示例) ## 快速使用 @@ -51,7 +52,7 @@ gitee项目地址:[https://gitee.com/lianjiatech/retrofit-spring-boot-starter] com.github.lianjiatech retrofit-spring-boot-starter - 2.3.1 + 2.3.2 ``` @@ -64,7 +65,7 @@ gitee项目地址:[https://gitee.com/lianjiatech/retrofit-spring-boot-starter] com.github.lianjiatech retrofit-spring-boot-starter - 2.3.1 + 2.3.2 com.squareup.okhttp3 @@ -854,6 +855,29 @@ retrofit: 针对每个Java接口,还可以通过`@RetrofitClient`注解的`converterFactories()`指定当前接口采用的`Converter.Factory`,指定的转换器工厂实例依然优先从Spring容器获取。 +### 元注解 + +`@RetrofitClient`、`@Retry`、`@Logging`、`@Resilience4jDegrade`等注解支持元注解、继承以及`@AliasFor`。 我们可以随意组合、调整相关注解: + +```java + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +@Documented +@Inherited +@RetrofitClient(baseUrl = "${test.baseUrl}") +@Logging(logLevel = LogLevel.WARN) +@Retry(intervalMs = 200) +public @interface MyRetrofitClient { + + @AliasFor(annotation = RetrofitClient.class, attribute = "converterFactories") + Class[] converterFactories() default {GsonConverterFactory.class}; + + @AliasFor(annotation = Logging.class, attribute = "logStrategy") + LogStrategy logStrategy() default LogStrategy.BODY; +} +``` + ## 其他功能示例 ### form参数接口调用 diff --git a/pom.xml b/pom.xml index 79e827c..d440821 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.github.lianjiatech retrofit-spring-boot-starter - 2.3.1 + 2.3.2 retrofit-spring-boot-starter retrofit-spring-boot-starter 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 8970ee2..5f9c3f8 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 @@ -10,6 +10,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.concurrent.TimeUnit; import org.springframework.beans.BeansException; @@ -17,6 +18,7 @@ import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.EnvironmentAware; +import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.core.env.Environment; import org.springframework.util.Assert; @@ -87,7 +89,8 @@ public boolean isSingleton() { } private okhttp3.ConnectionPool parseConnectionPool() { - RetrofitClient retrofitClient = retrofitInterface.getAnnotation(RetrofitClient.class); + RetrofitClient retrofitClient = + AnnotatedElementUtils.findMergedAnnotation(retrofitInterface, RetrofitClient.class); String poolName = retrofitClient.poolName(); Map poolRegistry = retrofitConfigBean.getPoolRegistry(); Assert.notNull(poolRegistry, "poolRegistry does not exist! Please set retrofitConfigBean.poolRegistry!"); @@ -99,7 +102,8 @@ private okhttp3.ConnectionPool parseConnectionPool() { private OkHttpClient createOkHttpClient() throws IllegalAccessException, InvocationTargetException { OkHttpClient.Builder okHttpClientBuilder = createOkHttpClientBuilder(); - RetrofitClient retrofitClient = retrofitInterface.getAnnotation(RetrofitClient.class); + RetrofitClient retrofitClient = + AnnotatedElementUtils.findMergedAnnotation(retrofitInterface, RetrofitClient.class); if (isEnableDegrade(retrofitInterface)) { okHttpClientBuilder.addInterceptor(retrofitConfigBean.getRetrofitDegrade()); } @@ -116,7 +120,8 @@ private OkHttpClient createOkHttpClient() throws IllegalAccessException, Invocat } private OkHttpClient.Builder createOkHttpClientBuilder() throws InvocationTargetException, IllegalAccessException { - RetrofitClient retrofitClient = retrofitInterface.getAnnotation(RetrofitClient.class); + RetrofitClient retrofitClient = + AnnotatedElementUtils.findMergedAnnotation(retrofitInterface, RetrofitClient.class); Method method = findOkHttpClientBuilderMethod(); if (method != null) { return (OkHttpClient.Builder)method.invoke(null); @@ -158,11 +163,11 @@ private Method findOkHttpClientBuilderMethod() { @SuppressWarnings("unchecked") private List findInterceptorByAnnotation() { - Annotation[] classAnnotations = retrofitInterface.getAnnotations(); + Annotation[] classAnnotations = AnnotationUtils.getAnnotations(retrofitInterface); List interceptors = new ArrayList<>(); // 找出被@InterceptMark标记的注解。Find the annotation marked by @InterceptMark List interceptAnnotations = new ArrayList<>(); - for (Annotation classAnnotation : classAnnotations) { + for (Annotation classAnnotation : Objects.requireNonNull(classAnnotations)) { Class annotationType = classAnnotation.annotationType(); if (annotationType.isAnnotationPresent(InterceptMark.class)) { interceptAnnotations.add(classAnnotation); @@ -204,9 +209,9 @@ private List findInterceptorByAnnotation() { return interceptors; } - private Retrofit createRetrofit() - throws InstantiationException, IllegalAccessException, InvocationTargetException { - RetrofitClient retrofitClient = retrofitInterface.getAnnotation(RetrofitClient.class); + private Retrofit createRetrofit() throws IllegalAccessException, InvocationTargetException { + RetrofitClient retrofitClient = + AnnotatedElementUtils.findMergedAnnotation(retrofitInterface, RetrofitClient.class); String baseUrl = RetrofitUtils.convertBaseUrl(retrofitClient, retrofitClient.baseUrl(), environment); OkHttpClient client = createOkHttpClient(); diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/RetrofitScan.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/RetrofitScan.java index 93121d5..dd83be8 100644 --- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/RetrofitScan.java +++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/RetrofitScan.java @@ -2,6 +2,7 @@ import java.lang.annotation.Documented; import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @@ -15,6 +16,7 @@ @Target(ElementType.TYPE) @Documented @Import(RetrofitClientScannerRegistrar.class) +@Inherited public @interface RetrofitScan { /** diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/BaseRetrofitDegrade.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/BaseRetrofitDegrade.java index 50794e1..ad8c634 100644 --- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/BaseRetrofitDegrade.java +++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/BaseRetrofitDegrade.java @@ -6,6 +6,7 @@ import java.util.concurrent.ConcurrentHashMap; import org.springframework.context.EnvironmentAware; +import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.core.env.Environment; import com.github.lianjiatech.retrofit.spring.boot.core.RetrofitClient; @@ -29,7 +30,8 @@ public String parseResourceName(Method method) { if (resourceName != null) { return resourceName; } - RetrofitClient retrofitClient = method.getDeclaringClass().getAnnotation(RetrofitClient.class); + RetrofitClient retrofitClient = + AnnotatedElementUtils.findMergedAnnotation(method.getDeclaringClass(), RetrofitClient.class); String baseUrl = RetrofitUtils.convertBaseUrl(retrofitClient, retrofitClient.baseUrl(), environment); HttpMethodPath httpMethodPath = parseHttpMethodPath(method); resourceName = formatResourceName(baseUrl, httpMethodPath); 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 7d19b53..9d130f1 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 @@ -5,6 +5,7 @@ import java.lang.reflect.Proxy; import org.springframework.context.ApplicationContext; +import org.springframework.core.annotation.AnnotatedElementUtils; import com.github.lianjiatech.retrofit.spring.boot.core.RetrofitClient; @@ -22,7 +23,8 @@ public class DegradeProxy implements InvocationHandler { @SuppressWarnings("unchecked") public static T create(Object source, Class retrofitInterface, ApplicationContext applicationContext) { - RetrofitClient retrofitClient = retrofitInterface.getAnnotation(RetrofitClient.class); + RetrofitClient retrofitClient = + AnnotatedElementUtils.findMergedAnnotation(retrofitInterface, RetrofitClient.class); Class fallbackClass = retrofitClient.fallback(); Object fallback = null; if (!void.class.isAssignableFrom(fallbackClass)) { 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 a675e0d..172e4ff 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 @@ -30,38 +30,38 @@ public interface ResourceNameParser { */ default HttpMethodPath parseHttpMethodPath(Method method) { - if (method.isAnnotationPresent(HTTP.class)) { - HTTP http = method.getAnnotation(HTTP.class); + HTTP http = method.getAnnotation(HTTP.class); + if (http != null) { return new HttpMethodPath(http.method(), http.path()); } - if (method.isAnnotationPresent(GET.class)) { - GET get = method.getAnnotation(GET.class); + GET get = method.getAnnotation(GET.class); + if (get != null) { return new HttpMethodPath("GET", get.value()); } - if (method.isAnnotationPresent(POST.class)) { - POST post = method.getAnnotation(POST.class); + POST post = method.getAnnotation(POST.class); + if (post != null) { return new HttpMethodPath("POST", post.value()); } - if (method.isAnnotationPresent(PUT.class)) { - PUT put = method.getAnnotation(PUT.class); + PUT put = method.getAnnotation(PUT.class); + if (put != null) { return new HttpMethodPath("PUT", put.value()); } - if (method.isAnnotationPresent(DELETE.class)) { - DELETE delete = method.getAnnotation(DELETE.class); + DELETE delete = method.getAnnotation(DELETE.class); + if (delete != null) { return new HttpMethodPath("DELETE", delete.value()); } - if (method.isAnnotationPresent(HEAD.class)) { - HEAD head = method.getAnnotation(HEAD.class); + HEAD head = method.getAnnotation(HEAD.class); + if (head != null) { return new HttpMethodPath("HEAD", head.value()); } - if (method.isAnnotationPresent(PATCH.class)) { - PATCH patch = method.getAnnotation(PATCH.class); + PATCH patch = method.getAnnotation(PATCH.class); + if (patch != null) { return new HttpMethodPath("PATCH", patch.value()); } throw new UnsupportedOperationException("unsupported method!" + method); diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/resilience4j/Resilience4jRetrofitDegrade.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/resilience4j/Resilience4jRetrofitDegrade.java index d4328eb..5b3d972 100644 --- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/resilience4j/Resilience4jRetrofitDegrade.java +++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/resilience4j/Resilience4jRetrofitDegrade.java @@ -43,7 +43,8 @@ public void loadDegradeRules(Class retrofitInterface) { continue; } Resilience4jDegrade resilience4jDegrade = - AnnotationExtendUtils.findAnnotationIncludeClass(method, Resilience4jDegrade.class); + AnnotationExtendUtils.findMergedAnnotation(method, method.getDeclaringClass(), + Resilience4jDegrade.class); if (resilience4jDegrade == null) { continue; } diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/sentinel/SentinelRetrofitDegrade.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/sentinel/SentinelRetrofitDegrade.java index 440549b..aadbb43 100644 --- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/sentinel/SentinelRetrofitDegrade.java +++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/degrade/sentinel/SentinelRetrofitDegrade.java @@ -42,7 +42,8 @@ public void loadDegradeRules(Class retrofitInterface) { } // 获取熔断配置 SentinelDegrade sentinelDegrade = - AnnotationExtendUtils.findAnnotationIncludeClass(method, SentinelDegrade.class); + AnnotationExtendUtils.findMergedAnnotation(method, method.getDeclaringClass(), + SentinelDegrade.class); if (sentinelDegrade == null) { continue; } @@ -61,7 +62,8 @@ public void loadDegradeRules(Class retrofitInterface) { public Response intercept(Chain chain) throws IOException { Request request = chain.request(); Method method = Objects.requireNonNull(request.tag(Invocation.class)).method(); - if (AnnotationExtendUtils.findAnnotationIncludeClass(method, SentinelDegrade.class) == null) { + if (AnnotationExtendUtils.findMergedAnnotation(method, method.getDeclaringClass(), + SentinelDegrade.class) == null) { return chain.proceed(request); } String resourceName = parseResourceName(method); 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 0ba9ce7..d307b69 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 @@ -7,6 +7,7 @@ import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; +import org.springframework.core.annotation.AnnotatedElementUtils; import com.github.lianjiatech.retrofit.spring.boot.core.ErrorDecoder; import com.github.lianjiatech.retrofit.spring.boot.core.RetrofitClient; @@ -30,7 +31,8 @@ public class ErrorDecoderInterceptor implements Interceptor, ApplicationContextA public Response intercept(Chain chain) throws IOException { Request request = chain.request(); Method method = Objects.requireNonNull(request.tag(Invocation.class)).method(); - RetrofitClient retrofitClient = method.getDeclaringClass().getAnnotation(RetrofitClient.class); + RetrofitClient retrofitClient = + AnnotatedElementUtils.findMergedAnnotation(method.getDeclaringClass(), RetrofitClient.class); ErrorDecoder errorDecoder = AppContextUtils.getBeanOrNew(applicationContext, retrofitClient.errorDecoder()); boolean decoded = false; 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 c056291..e1641f3 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 @@ -5,6 +5,7 @@ import java.net.URI; import java.util.Objects; +import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.util.StringUtils; import com.github.lianjiatech.retrofit.spring.boot.core.RetrofitClient; @@ -32,7 +33,8 @@ public Response intercept(Chain chain) throws IOException { Request request = chain.request(); Method method = Objects.requireNonNull(request.tag(Invocation.class)).method(); Class declaringClass = method.getDeclaringClass(); - RetrofitClient retrofitClient = declaringClass.getAnnotation(RetrofitClient.class); + RetrofitClient retrofitClient = + AnnotatedElementUtils.findMergedAnnotation(declaringClass, RetrofitClient.class); String baseUrl = retrofitClient.baseUrl(); if (StringUtils.hasText(baseUrl)) { return chain.proceed(request); 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 8207118..3ea3a03 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 @@ -4,6 +4,8 @@ import java.lang.reflect.Method; import java.util.Objects; +import org.springframework.core.annotation.AnnotatedElementUtils; + import com.github.lianjiatech.retrofit.spring.boot.config.LogProperty; import lombok.extern.slf4j.Slf4j; @@ -30,8 +32,7 @@ public LoggingInterceptor(LogProperty logProperty) { public Response intercept(Chain chain) throws IOException { Request request = chain.request(); Method method = Objects.requireNonNull(request.tag(Invocation.class)).method(); - // 获取重试配置 - Logging logging = method.getDeclaringClass().getAnnotation(Logging.class); + Logging logging = AnnotatedElementUtils.findMergedAnnotation(method.getDeclaringClass(), Logging.class); if (!needLog(logging)) { return chain.proceed(request); } 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 33db520..e8474e3 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 @@ -33,7 +33,7 @@ public Response intercept(Chain chain) throws IOException { Request request = chain.request(); Method method = Objects.requireNonNull(request.tag(Invocation.class)).method(); // 获取重试配置 - Retry retry = AnnotationExtendUtils.findAnnotationIncludeClass(method, Retry.class); + Retry retry = AnnotationExtendUtils.findMergedAnnotation(method, method.getDeclaringClass(), Retry.class); if (!needRetry(retry)) { return chain.proceed(request); } diff --git a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/util/AnnotationExtendUtils.java b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/util/AnnotationExtendUtils.java index 78ed35c..2426c18 100644 --- a/src/main/java/com/github/lianjiatech/retrofit/spring/boot/util/AnnotationExtendUtils.java +++ b/src/main/java/com/github/lianjiatech/retrofit/spring/boot/util/AnnotationExtendUtils.java @@ -3,6 +3,8 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Method; +import org.springframework.core.annotation.AnnotatedElementUtils; + import lombok.experimental.UtilityClass; /** @@ -16,15 +18,17 @@ public class AnnotationExtendUtils { * 查找方法及其类上的指定注解,优先返回方法上的。 * @param 注解泛型参数 * @param method 方法 + * @param clazz 类型 * @param annotationType 注解类型 * @return 方法及其类上的指定注解。 */ - public static A findAnnotationIncludeClass(Method method, Class annotationType) { - A annotation = method.getAnnotation(annotationType); + public static A findMergedAnnotation(Method method, Class clazz, + Class annotationType) { + A annotation = AnnotatedElementUtils.findMergedAnnotation(method, annotationType); if (annotation != null) { return annotation; } - return method.getDeclaringClass().getAnnotation(annotationType); + return AnnotatedElementUtils.findMergedAnnotation(clazz, annotationType); } /** @@ -36,11 +40,11 @@ public static A findAnnotationIncludeClass(Method method, */ public static boolean isAnnotationPresentIncludeMethod(Class clazz, Class annotationType) { - if (clazz.isAnnotationPresent(annotationType)) { + if (AnnotatedElementUtils.findMergedAnnotation(clazz, annotationType) != null) { return true; } for (Method method : clazz.getMethods()) { - if (method.isAnnotationPresent(annotationType)) { + if (AnnotatedElementUtils.findMergedAnnotation(method, annotationType) != null) { return true; } } diff --git a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/MySpringBootApplication.java b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/MySpringBootApplication.java new file mode 100644 index 0000000..c9e82bb --- /dev/null +++ b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/MySpringBootApplication.java @@ -0,0 +1,24 @@ +package com.github.lianjiatech.retrofit.spring.boot.test; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.springframework.boot.autoconfigure.SpringBootApplication; + +import com.github.lianjiatech.retrofit.spring.boot.core.RetrofitScan; + +/** + * @author 陈添明 + * @since 2022/5/7 8:48 下午 + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Inherited +@RetrofitScan("com.github.lianjiatech.retrofit.spring.boot") +@SpringBootApplication +public @interface MySpringBootApplication {} 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 49edb78..cedc617 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 @@ -1,19 +1,15 @@ package com.github.lianjiatech.retrofit.spring.boot.test; import org.springframework.boot.SpringApplication; -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; /** * @author 陈添明 */ -@SpringBootApplication -@RetrofitScan("com.github.lianjiatech.retrofit.spring.boot") +@MySpringBootApplication public class RetrofitTestApplication { public static void main(String[] args) { diff --git a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/ErrorDecoderTest.java b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/decoder/ErrorDecoderTest.java similarity index 94% rename from src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/ErrorDecoderTest.java rename to src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/decoder/ErrorDecoderTest.java index 8d160dd..bdb1ce9 100644 --- a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/ErrorDecoderTest.java +++ b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/decoder/ErrorDecoderTest.java @@ -1,4 +1,4 @@ -package com.github.lianjiatech.retrofit.spring.boot.test; +package com.github.lianjiatech.retrofit.spring.boot.test.decoder; import java.io.IOException; @@ -14,9 +14,9 @@ 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.test.RetrofitTestApplication; 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.http.ErrorDecoderTestApi; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; 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/decoder/ErrorDecoderTestApi.java similarity index 91% rename from src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/ErrorDecoderTestApi.java rename to src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/decoder/ErrorDecoderTestApi.java index 0669193..c33283b 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/decoder/ErrorDecoderTestApi.java @@ -1,4 +1,4 @@ -package com.github.lianjiatech.retrofit.spring.boot.test.http; +package com.github.lianjiatech.retrofit.spring.boot.test.decoder; import com.github.lianjiatech.retrofit.spring.boot.core.RetrofitClient; import com.github.lianjiatech.retrofit.spring.boot.log.LogStrategy; diff --git a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/DegradeR4jApi.java b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/degrade/DegradeR4jApi.java similarity index 97% rename from src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/DegradeR4jApi.java rename to src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/degrade/DegradeR4jApi.java index 535f62e..4448bce 100644 --- a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/DegradeR4jApi.java +++ b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/degrade/DegradeR4jApi.java @@ -1,4 +1,4 @@ -package com.github.lianjiatech.retrofit.spring.boot.test.http; +package com.github.lianjiatech.retrofit.spring.boot.test.degrade; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/DegradeR4jTest.java b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/degrade/DegradeR4jTest.java similarity index 95% rename from src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/DegradeR4jTest.java rename to src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/degrade/DegradeR4jTest.java index d5ac9be..7b4f588 100644 --- a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/DegradeR4jTest.java +++ b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/degrade/DegradeR4jTest.java @@ -1,4 +1,4 @@ -package com.github.lianjiatech.retrofit.spring.boot.test; +package com.github.lianjiatech.retrofit.spring.boot.test.degrade; import java.io.IOException; import java.util.concurrent.TimeUnit; @@ -17,9 +17,9 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; +import com.github.lianjiatech.retrofit.spring.boot.test.RetrofitTestApplication; 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.http.DegradeR4jApi; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; diff --git a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/DegradeSentinelApi.java b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/degrade/DegradeSentinelApi.java similarity index 97% rename from src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/DegradeSentinelApi.java rename to src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/degrade/DegradeSentinelApi.java index 144e2d0..7c5555e 100644 --- a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/http/DegradeSentinelApi.java +++ b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/degrade/DegradeSentinelApi.java @@ -1,4 +1,4 @@ -package com.github.lianjiatech.retrofit.spring.boot.test.http; +package com.github.lianjiatech.retrofit.spring.boot.test.degrade; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/DegradeSentinelTest.java b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/degrade/DegradeSentinelTest.java similarity index 95% rename from src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/DegradeSentinelTest.java rename to src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/degrade/DegradeSentinelTest.java index 025d74a..de5cb02 100644 --- a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/DegradeSentinelTest.java +++ b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/degrade/DegradeSentinelTest.java @@ -1,4 +1,4 @@ -package com.github.lianjiatech.retrofit.spring.boot.test; +package com.github.lianjiatech.retrofit.spring.boot.test.degrade; import java.io.IOException; import java.util.concurrent.TimeUnit; @@ -17,9 +17,9 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; +import com.github.lianjiatech.retrofit.spring.boot.test.RetrofitTestApplication; 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.http.DegradeSentinelApi; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; diff --git a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/meta/MetaAnnotationTest.java b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/meta/MetaAnnotationTest.java new file mode 100644 index 0000000..f530322 --- /dev/null +++ b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/meta/MetaAnnotationTest.java @@ -0,0 +1,78 @@ +package com.github.lianjiatech.retrofit.spring.boot.test.meta; + +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.github.lianjiatech.retrofit.spring.boot.test.RetrofitTestApplication; +import com.github.lianjiatech.retrofit.spring.boot.test.entity.Person; +import com.github.lianjiatech.retrofit.spring.boot.test.entity.Result; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; + +/** + * @author 陈添明 + */ +@SpringBootTest(classes = RetrofitTestApplication.class) +@RunWith(SpringRunner.class) +public class MetaAnnotationTest { + + @Autowired + private MetaAnnotationTestApi metaAnnotationTestApi; + + private MockWebServer server; + + private static Gson gson = new GsonBuilder() + .create(); + + @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() { + + // 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(gson.toJson(mockResult)); + server.enqueue(response); + + // http check + Result person = metaAnnotationTestApi.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/meta/MetaAnnotationTestApi.java b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/meta/MetaAnnotationTestApi.java new file mode 100644 index 0000000..dae9fa8 --- /dev/null +++ b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/meta/MetaAnnotationTestApi.java @@ -0,0 +1,24 @@ +package com.github.lianjiatech.retrofit.spring.boot.test.meta; + +import com.github.lianjiatech.retrofit.spring.boot.log.LogStrategy; +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.http.GET; +import retrofit2.http.Headers; +import retrofit2.http.Query; + +/** + * @author 陈添明 + */ +@MyRetrofitClient(converterFactories = GsonConverterFactory.class, logStrategy = LogStrategy.HEADERS) +public interface MetaAnnotationTestApi { + + @GET("person") + @Headers({ + "X-Foo: Bar", + "X-Ping: Pong" + }) + Result getPerson(@Query("id") Long id); +} diff --git a/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/meta/MyRetrofitClient.java b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/meta/MyRetrofitClient.java new file mode 100644 index 0000000..1ca9cc2 --- /dev/null +++ b/src/test/java/com/github/lianjiatech/retrofit/spring/boot/test/meta/MyRetrofitClient.java @@ -0,0 +1,39 @@ +package com.github.lianjiatech.retrofit.spring.boot.test.meta; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.springframework.core.annotation.AliasFor; + +import com.github.lianjiatech.retrofit.spring.boot.core.RetrofitClient; +import com.github.lianjiatech.retrofit.spring.boot.log.LogLevel; +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.retry.Retry; + +import retrofit2.Converter; +import retrofit2.converter.gson.GsonConverterFactory; + +/** + * @author 陈添明 + * @since 2022/5/7 6:51 下午 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +@Documented +@Inherited +@RetrofitClient(baseUrl = "${test.baseUrl}") +@Logging(logLevel = LogLevel.WARN) +@Retry(intervalMs = 200) +public @interface MyRetrofitClient { + + @AliasFor(annotation = RetrofitClient.class, attribute = "converterFactories") + Class[] converterFactories() default {GsonConverterFactory.class}; + + @AliasFor(annotation = Logging.class, attribute = "logStrategy") + LogStrategy logStrategy() default LogStrategy.BODY; +}