MCPcopy Index your code
hub / github.com/easyretrofit/retrofit-spring-boot-starter

github.com/easyretrofit/retrofit-spring-boot-starter @v1.3.1

Chat with this repo
repository ↗ · DeepWiki ↗ · release v1.3.1 ↗ · + Follow
126 symbols 255 edges 43 files 23 documented · 18% updated 11mo agov1.3.1 · 2025-07-10★ 331 open issues
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

Version Build License License License

easy-retrofit-spring-boot-starter

目录

介绍

在SpringBoot项目中快速使用Retrofit2,easy-retrofit-spring-boot-starter提供了一个基于注解的配置创建Retrofit实例,并通过更多的注释实现了通用功能的增强。 本项目使用Springboot的动态代理机制,在Spring上下文的生命周期前期,将Retrofit实例注入到Spring上下文。

安装

Maven:

<dependency>
    <groupId>io.github.easyretrofit</groupId>
    <artifactId>spring-boot-starter</artifactId>
    <version>${latest-version}</version>
</dependency>

Gradle:

dependencies {
    implementation 'io.github.easyretrofit:spring-boot-starter:${latest-version}'
}

retrofit-spring-boot-starter与 JDK和Springboot版本对应关系

jdk version Springboot2 version Springboot3 version
jdk8 2.0.0.RELEASE - 2.7.x NA
jdk11 2.0.0.RELEASE - 2.7.x NA
jdk17 2.4.2 - 2.7.x 3.0.0 - latest
jdk21 2.7.16 - 2.7.x 3.1.0 - latest(*)

快速开始

前提条件:你已经掌握了Retrofit的基本用法

如下代码展示了在在传统Retrofit2的使用中,GitHubService接口需要被显式的创建。

public interface GitHubService {
    @GET("users/{user}/repos")
    Call<List<Repo>> listRepos(@Path("user") String user);
}


Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("https://api.github.com/")
        .build();

GitHubService service = retrofit.create(GitHubService.class);

在传统Retrofit2的使用中,GitHubService接口需要被显式的创建。

通过retrofit-spring-boot-starter, GitHubService不再需要显式的创建,而是被Spring容器动态代理创建。

如下展示了如何使用retrofit-spring-boot-starter快速使用Retrofit2的方式。

添加 @EnableRetrofit

在Springboot的启动类上增加@EnableRetrofit注解,代表可以开启Retrofit2的自动配置。


@EnableRetrofit
@SpringBootApplication
public class QuickStartApplication {
    public static void main(String[] args) {
        SpringApplication.run(QuickStartApplication.class, args);
    }
}

您可以指定basePackages,比如@EnableRetrofit(basePackages = "xxx.demo.api"),"xxx.demo.api"是您的Retrofit api 文件夹名。默认情况下,将扫描starter类文件所在目录中的所有文件

创建一个接口文件, 并且使用@RetrofitBuilder

@RetrofitBuilder 注解可以用来配置Retrofit2的配置信息,如baseUrl等。他完整的代替了显式的Retrofit.Builder() 来创建Retrofit实例。


@RetrofitBuilder(baseUrl = "${app.hello.url}")
public interface HelloApi {
    /**
     * call hello API method of backend service
     *
     * @param message message
     * @return
     */
    @GET("v1/hello/{message}")
    Call<ResponseBody> hello(@Path("message") String message);
}

application.yml

app:
  hello:
    url: http://localhost:8080/

请保持app.hello.url 在你的资源配置文件中, baseUrl 也可以是一个URL, 就像 http://localhost:8080/ 一样。

当然你也可以直接写成@RetrofitBuilder(baseUrl = "http://localhost:8080/")

注入 Retrofit API 接口

可以在Spring的Controller中注入Retrofit API接口。


@RestController
@RequestMapping("/v1/hello")
public class HelloController {

    @Autowired
    private HelloApi helloApi;

    @GetMapping("/{message}")
    public ResponseEntity<String> hello(@PathVariable String message) throws IOException {
        final ResponseBody body = helloApi.hello(message).execute().body();
        return ResponseEntity.ok(body.string());
    }
}

你可以参考 retrofit-spring-boot-starter-sample-quickstart & retrofit-spring-boot-starter-sample-backend-services

是的,恭喜你,你的代码应该能正常工作。

更多设置

添加其他的Retrofit属性到 @RetrofitBuilder, 如果你需要

你可以在@RetrofitBuilder中设置Retrofit的其他属性, @RetrofitBuilder中的属性名称与Retrofit.Builder()中的方法名是相同的

你可以按需的添加其他的Retrofit属性到 @RetrofitBuilder


@RetrofitBuilder(baseUrl = "${app.hello.url}",
        addConverterFactory = {GsonConvertFactoryBuilder.class},
        addCallAdapterFactory = {RxJavaCallAdapterFactoryBuilder.class},
        callbackExecutor = CallBackExecutorBuilder.class,
        client = OkHttpClientBuilder.class,
        validateEagerly = false)
@RetrofitInterceptor(handler = LoggingInterceptor.class)
@RetrofitInterceptor(handler = MyRetrofitInterceptor.class)
public interface HelloApi {
    /**
     * call hello API method of backend service
     *
     * @param message message
     * @return
     */
    @GET("v1/hello/{message}")
    Call<HelloBean> hello(@Path("message") String message);
}

创建自定义的 ConverterFactory

创建一个自定义的ConvertFactory类 需要继承BaseConverterFactoryBuilder

public class GsonConvertFactoryBuilder extends BaseConverterFactoryBuilder {
    @Override
    public Converter.Factory buildConverterFactory() {
        return GsonConverterFactory.create();
    }
}

创建自定义的 CallAdapterFactory

创建一个自定义的CallAdapterFactory类 需要继承BaseCallAdapterFactoryBuilder

public class RxJavaCallAdapterFactoryBuilder extends BaseCallAdapterFactoryBuilder {
    @Override
    public CallAdapter.Factory buildCallAdapterFactory() {
        return RxJavaCallAdapterFactory.create();
    }
}

创建自定义的 CallBackExecutor

创建一个自定义的CallBackExecutor 需要继承 BaseCallBackExecutorBuilder

public class CallBackExecutorBuilder extends BaseCallBackExecutorBuilder {

    @Override
    public Executor buildCallBackExecutor() {
        return command -> command.run();
    }
}

创建自定义的 OKHttpClient

创建一个自定义的OKHttpClient 需要继承 BaseOkHttpClientBuilder

public class OkHttpClientBuilder extends BaseOkHttpClientBuilder {
    @Override
    public OkHttpClient.Builder buildOkHttpClientBuilder(OkHttpClient.Builder builder) {
        return builder.connectTimeout(Duration.ofMillis(30000));
    }
}

重要事项:

当需要在自定义的Builder中使用spring容器管理的对象时,只需在类头上使用@Component,并注入所需的对象


@Component
public class MyOkHttpClient extends BaseOkHttpClientBuilder {

    @Value("${okhttpclient.timeout}")
    private int timeout;

    @Override
    public OkHttpClient.Builder buildOkHttpClientBuilder(OkHttpClient.Builder builder) {
        return builder.connectTimeout(Duration.ofMillis(timeout));
    }
}
okhttpclient:
  timeout: 30000

创建自定义的 OKHttpClient Interceptor

创建一个自定义的 OKHttpClient Interceptor 需要继承BaseInterceptor ,并且在接口名上声明如@RetrofitInterceptor(handler = MyRetrofitInterceptor.class)


@RetrofitBuilder(baseUrl = "${app.hello.url}",
        addConverterFactory = {GsonConvertFactoryBuilder.class},
        client = OkHttpClientBuilder.class)
@RetrofitInterceptor(handler = LoggingInterceptor.class)
@RetrofitInterceptor(handler = MyRetrofitInterceptor.class)
public interface BaseApi {
}

@Component
public class MyRetrofitInterceptor extends BaseInterceptor {

    /**
     * The context is created and registered in the spring container by retrofit-spring-boot-starter. The context object includes all retrofit-spring-boot-starter context objects
     */
    @Autowired
    private RetrofitResourceContext context;

    @SneakyThrows
    @Override
    protected Response executeIntercept(Chain chain) {
        Request request = chain.request();
        String clazzName = Objects.requireNonNull(request.tag(Invocation.class)).method().getDeclaringClass().getName();
        final RetrofitServiceBean currentServiceBean = context.getRetrofitServiceBean(clazzName);
        // TODO if you need
        return chain.proceed(request);
    }
}

重要事项:

当需要在自定义的Builder中使用spring容器管理的对象时,只需在类头上使用@Component,并注入所需的对象

使用 OkHttpClient HttpLoggingInterceptor

public class LoggingInterceptor extends BaseInterceptor {

    private HttpLoggingInterceptor httpLoggingInterceptor;

    public LoggingInterceptor() {
        httpLoggingInterceptor = new HttpLoggingInterceptor();
        httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BASIC);
    }

    @SneakyThrows
    @Override
    protected Response executeIntercept(Chain chain) {
        return httpLoggingInterceptor.intercept(chain);
    }
}

小贴士:

如果只想设置拦截器,而不想对OKHttpClient对象进行其他修改,则可以从@RetrofitBuilder 删除client = OkHttpClientBuilder.class属性,无需自定义OKHttpClient

为@RetrofitInterceptor 设置 include,exclude,type 和 sort

你可以在@RetrofitInterceptor 上设置 include,exclude, typesort 属性 like @RetrofitInterceptor(handler = MyRetrofitInterceptor.class, exclude = {"/v1/hello/*"})

当使用exclude, 相应的API将忽略此拦截器

当使用sort, 请确保所有拦截器都使用了sort属性,因为默认情况下,sort为0. 您可以通过int类型的值确保拦截器的执行顺序。 默认的,拦截器从上到下装载。**

当使用type, type是一个Interceptor的枚举类, 你可以指定此拦截器是OkHttpClient 的addInterceptor() 方式或addNetworkInterceptor()方式

你可以参考 retrofit-spring-boot-starter-sample-builder & retrofit-spring-boot-starter-sample-backend-services

接口继承

如果你有成百上千个接口方法,它来自同一个HTTP URL源,你希望你的代码结构更有序,看起来与后台服务Controller结构一致,你可以这样做

接口文件 extends 模式

使用 extends 关键字来继承声明RetrofitBuilder的接口

定义一个空的接口文件,并设置属性


@RetrofitBuilder(baseUrl = "${app.hello.url}",
        addConverterFactory = {GsonConvertFactoryBuilder.class},
        client = OkHttpClientBuilder.class)
@RetrofitInterceptor(handler = LoggingInterceptor.class)
@RetrofitInterceptor(handler = MyRetrofitInterceptor.class)
public interface BaseApi {
}

创建另一个接口文件继承父接口

public interface HelloApi extends BaseApi {
    /**
     * call hello API method of backend service
     *
     * @param message message
     * @return
     */
    @GET("v1/hello/{message}")
    Call<HelloBean> hello(@Path("message") String message);
}

@RetrofitBase 模式

使用@RetrofitBase 来设置有@RetrofitBuilder的接口


@RetrofitBase(baseInterface = BaseApi.class)
public interface HelloApi {
    /**
     * call hello API method of backend service
     *
     * @param message message
     * @return
     */
    @GET("v1/hello/{message}")
    Call<HelloBean> hello(@Path("message") String message);
}

如果 HelloApi 使用 extends BaseApi 并且使用了 @RetrofitBase(baseInterface = BaseApi.class), starter会优先去使用 @RetrofitBase(baseInterface = BaseApi.class)

URL前缀

你可以使用@RetrofitUrlPrefix去定义一个URL前缀,就像SpringBoot MVC中的@RequestMapping


@RetrofitUrlPrefix("/v1/hello/")
public interface HelloApi extends BaseApi {
    /**
     * call hello API method of backend service
     *
     * @param message message
     * @return
     */
    @GET("{message}")
    Call<HelloBean> hello(@Path("message") String message);
}
public interface HelloApi extends BaseApi {
    /**
     * call hello API method of backend service
     *
     * @param message message
     * @return
     */
    @GET("v1/hello/{message}")
    Call<HelloBean> hello(@Path("message") String message);
}

在运行中,这两个接口会生成相同的URL /v1/hello/{message}

你可以参考 retrofit-spring-boot-starter-sample-inherit & retrofit-spring-boot-starter-sample-backend-services Warning: 如果在同一Controller注入父接口和子接口,可能会发生以下错误

Description:

Field api in io.liuziyuan.demo.controller.HelloController required a single bean, but 2 were found:
    - io.github.easyretrofit.samples.inherit.api.BaseApi: defined in null
    - io.github.easyretrofit.samples.inherit.api.HelloApi: defined in null

Action:

Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed

所以,需要使用@Qualifier(""),其值为API接口类全名, 请尽量不要混用父接口与子接口


@RestController
@RequestMapping("/v1/hello")
public class HelloController {

    @Autowired
    @Qualifier("io.github.easyretrofit.samples.inherit.api.BaseApi")
    private BaseApi baseApi;
    @Autowired
    @Qualifier("io.github.easyretrofit.samples.inherit.api.helloApi")
    private HelloApi helloApi;

    @GetMapping("/{message}")
    public ResponseEntity<String> hello(@PathVariable String message) throws IOException {
        final HelloBean helloBody = helloApi.hello(message).execute().body();
        return ResponseEntity.ok(helloBody.getMessage());
    }
}

单Retrofit实例

当Retrofit配置相同且仅为baseUrl的后缀部分不同时,会只创建一个Retrofit实例。

retrofit-spring-boot-starter中可以看到,一个retrofit实例被称之为RetrofitClient ,一个Retrofit实例的接口被称之为RetrofitApiService

你可以通过Demo中的Log查看到RetrofitClient和RetrofitApiService之间的关系。

通过这样的方式,可以减少Retrofit实例的数量,降低内存占用。

你可以参考 retrofit-spring-boot-starter-sample-single-instance & retrofit-spring-boot-starter-sample-backend-services

动态URL

你可以使用@RetrofitDynamicBaseUrl 动态的改变@RetrofitBuilder中的baseUrl

你可以参考 [retrofit-spring-boot-starter-sample-dynamic-url](https://github.com/liuziyuan/easy-retrofit-demo/tree/main/retrofit-spring

Extension points exported contracts — how you extend this code

HelloApiV2 (Interface)
Base URLs should always end in /. Endpoint values which contain a leading / are absolute [2 implementers]
easy-retrofit-spring-boot-integration-tests/single-instance-integration-test/src/main/java/io/github/easyretrofit/spring/boot/it/single/api/HelloApiV2.java
G2L1Api (Interface)
(no doc)
easy-retrofit-spring-boot-integration-tests/inherit-integration-test/src/main/java/io/github/easyretrofit/spring/boot/it/inherit/G2L1Api.java
HelloApi (Interface)
Base URLs should always end in /. Endpoint values which contain a leading / are absolute [2 implementers]
easy-retrofit-spring-boot-integration-tests/single-instance-integration-test/src/main/java/io/github/easyretrofit/spring/boot/it/single/api/HelloApi.java
OtherApi (Interface)
(no doc)
easy-retrofit-spring-boot-integration-tests/inherit-integration-test/src/main/java/io/github/easyretrofit/spring/boot/it/inherit/OtherApi.java
ComplexL4Api (Interface)
(no doc)
easy-retrofit-spring-boot-integration-tests/inherit-integration-test/src/main/java/io/github/easyretrofit/spring/boot/it/inherit/ComplexL4Api.java
ComplexL2Api (Interface)
(no doc)
easy-retrofit-spring-boot-integration-tests/inherit-integration-test/src/main/java/io/github/easyretrofit/spring/boot/it/inherit/ComplexL2Api.java
MixedApi (Interface)
(no doc)
easy-retrofit-spring-boot-integration-tests/inherit-integration-test/src/main/java/io/github/easyretrofit/spring/boot/it/inherit/MixedApi.java

Core symbols most depended-on inside this repo

resolveRequiredPlaceholders
called by 8
easy-retrofit-spring-boot-starter/src/main/java/io/github/easyretrofit/spring/boot/global/RetrofitBuilderGlobalConfigProperties.java
propertiesEnable
called by 7
easy-retrofit-spring-boot-starter/src/main/java/io/github/easyretrofit/spring/boot/global/RetrofitBuilderGlobalConfig.java
getBean
called by 4
easy-retrofit-spring-boot-starter/src/main/java/io/github/easyretrofit/spring/boot/util/SpringContextUtil.java
hello
called by 3
easy-retrofit-spring-boot-integration-tests/single-instance-integration-test/src/main/java/io/github/easyretrofit/spring/boot/it/single/api/HelloApi.java
getEnable
called by 3
easy-retrofit-spring-boot-starter/src/main/java/io/github/easyretrofit/spring/boot/global/RetrofitBuilderGlobalConfigProperties.java
transformClass
called by 3
easy-retrofit-spring-boot-starter/src/main/java/io/github/easyretrofit/spring/boot/global/RetrofitBuilderGlobalConfigProperties.java
getRetrofitExtension
called by 2
easy-retrofit-spring-boot-starter/src/main/java/io/github/easyretrofit/spring/boot/RetrofitAnnotationBean.java
generate
called by 2
easy-retrofit-spring-boot-starter/src/main/java/io/github/easyretrofit/spring/boot/global/RetrofitBuilderGlobalConfigProperties.java

Shape

Method 84
Class 27
Interface 15

Languages

Java100%

Modules by API surface

easy-retrofit-spring-boot-starter/src/main/java/io/github/easyretrofit/spring/boot/global/RetrofitBuilderGlobalConfigProperties.java21 symbols
easy-retrofit-spring-boot-starter/src/main/java/io/github/easyretrofit/spring/boot/RetrofitResourceDefinitionRegistry.java13 symbols
easy-retrofit-spring-boot-starter/src/main/java/io/github/easyretrofit/spring/boot/global/RetrofitBuilderGlobalConfig.java11 symbols
easy-retrofit-spring-boot-starter/src/main/java/io/github/easyretrofit/spring/boot/RetrofitServiceProxyFactory.java6 symbols
easy-retrofit-spring-boot-starter/src/main/java/io/github/easyretrofit/spring/boot/RetrofitAnnotationBean.java5 symbols
easy-retrofit-spring-boot-starter/src/main/java/io/github/easyretrofit/spring/boot/RetrofitResourceImportDefinitionRegistry.java4 symbols
easy-retrofit-spring-boot-integration-tests/inherit-integration-test/src/main/java/io/github/easyretrofit/spring/boot/it/inherit/MyRetrofitInterceptor3.java4 symbols
easy-retrofit-spring-boot-integration-tests/inherit-integration-test/src/main/java/io/github/easyretrofit/spring/boot/it/inherit/MyRetrofitInterceptor2.java4 symbols
easy-retrofit-spring-boot-starter/src/main/java/io/github/easyretrofit/spring/boot/util/SpringContextUtil.java3 symbols
easy-retrofit-spring-boot-starter/src/main/java/io/github/easyretrofit/spring/boot/SpringCDIBeanManager.java3 symbols
easy-retrofit-spring-boot-starter/src/main/java/io/github/easyretrofit/spring/boot/SpringBootRetrofitExtensionScanner.java3 symbols
easy-retrofit-spring-boot-starter/src/main/java/io/github/easyretrofit/spring/boot/SpringBootEnv.java3 symbols

For agents

$ claude mcp add retrofit-spring-boot-starter \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page