> This page is for SDK, version Current (default).
> For other versions, use one of these documentation indexes:
> - Current (default): https://buildwithfern.com/learn/sdks/current/llms.txt
> - Legacy: https://buildwithfern.com/learn/sdks/legacy/llms.txt

> For clean Markdown content of this page, append .md to this URL. For the complete documentation index, see https://buildwithfern.com/learn/llms.txt.

# 添加自定义代码

> 使用自定义工具增强您的 Java SDK

本页面介绍如何向您的 Java SDK 添加自定义逻辑、方法和依赖项。

> **Note**
>
> These steps cover adding a new custom file to the SDK. To preserve line-level edits to a generated file, use [Replay](/learn/sdks/overview/custom-code#replay) instead.

## 添加自定义逻辑

开始添加自定义代码：

### 创建新文件并添加您的自定义逻辑

**`src/main/java/<package>/Helper.java`**

```java title="src/main/java/<package>/Helper.java"
package com.example.helper;

public class Helper {

public static void myHelper() {
    System.out.println("Hello World!");
}

}
```

### 将您的文件添加到 `.fernignore`

**`.fernignore`**

```yaml {3} title=".fernignore"
# 指定不应被 Fern 修改的文件

src/main/java/<package>/Helper.java
```

### 使用助手方法

Now your users can consume the helper function by importing it from the SDK.

```java
import com.example.helper.Helper;

public class Main {

public static void main(String[] args) {
    Helper.myHelper();
}

}
```

## 添加自定义 SDK 方法

Fern also allows you to add custom methods to the SDK itself (e.g.
`client.my_method()` ) by inheriting the Fern generated client and then
extending it.

### 更新 `generators.yml` 配置

将您的 Fern 生成的客户端命名为类似 `BaseClient` 的名称，以反映此客户端将被扩展。

**`generators.yml`**

```yml {4} title="generators.yml"
- name: fern-java-sdk
    version: "..."
    config:
      client-class-name: BaseClient
```

### 导入并扩展生成的客户端

首先，导入 Fern 生成的基础客户端并扩展它。然后，添加您想要的任何方法。

**`src/main/java/com/example/MyClient.java`**

```java title="src/main/java/com/example/MyClient.java"
package com.example;

import com.example.client.BaseClient;

public class MyClient extends BaseClient { // 扩展 Fern 生成的客户端

  public void myHelper() {
    System.out.println("Hello World!");
  }

}
```

### 更新 `.fernignore`

将 `MyClient.java` 添加到 `.fernignore`。

**`.fernignore`**

```diff title=".fernignore"
+ src/main/java/com/example/MyClient.java
```

### 使用方法

Now your users can consume the helper function by importing it from the SDK.

```java
client.myHelper();
```

## 添加自定义客户端配置

Java SDK 生成器通过可选的自类型模式支持构建器扩展性。当通过 `enable-extensible-builders` 标志启用时，生成的构建器可以被扩展，同时在方法链接过程中保持类型安全。

常见用例包括：

* **动态 URL 构造**：使用运行时值替换占位符（例如，`https://api.${TENANT}.example.com`）
* **自定义身份验证**：实现超出基本令牌认证的复杂认证流程
* **请求转换**：全局添加自定义标头或修改请求
* **多租户支持**：添加特定租户的配置和标头

### 启用可扩展构建器

将标志添加到您的 `generators.yml`：

**`generators.yml`**

```yaml {7} title="generators.yml"
groups:
  local:
    generators:
      - name: fern-java-sdk
        version: 2.39.6
        config:
          enable-extensible-builders: true
```

### 工作原理

生成的构建器使用自类型模式进行类型安全的方法链接：

```java
public abstract class BaseClientBuilder<T extends BaseClientBuilder<T>> {
    protected abstract T self();
    
    public T token(String token) {
        return self();  // 返回您的自定义类型，而不是 BaseClientBuilder
    }
}
```

### 创建自定义构建器

扩展生成的构建器：

**`src/main/java/com/example/CustomApiBuilder.java`**

```java title="src/main/java/com/example/CustomApiBuilder.java"
public class CustomApiBuilder extends BaseClientBuilder<CustomApiBuilder> {
    @Override
    protected CustomApiBuilder self() {
        return this;
    }

    @Override
    protected void setEnvironment(ClientOptions.Builder builder) {
        // 自定义环境 URL
        String url = this.environment.getUrl();
        String expandedUrl = expandEnvironmentVariables(url);
        builder.environment(Environment.custom(expandedUrl));
    }

    @Override
    protected void setAdditional(ClientOptions.Builder builder) {
        // 添加自定义标头
        builder.addHeader("X-Request-ID", () -> UUID.randomUUID().toString());
    }
}
```

### 使用您的自定义构建器

```java
BaseClient client = new CustomApiBuilder()
    .token("my-token")        // 返回 CustomApiBuilder
    .tenantId("tenant-123")   // 返回 CustomApiBuilder  
    .timeout(30)              // 返回 CustomApiBuilder
    .build();

client.users().list();
```

### 更新 `.fernignore`

将您的自定义构建器添加到 `.fernignore`，这样 Fern 就不会覆盖它：

**`.fernignore`**

```diff title=".fernignore"
+ src/main/java/com/example/CustomApiBuilder.java
```

### 默认实现

如果您不需要扩展构建器，请使用提供的 `Impl` 类：

```java
BaseClient client = BaseClientBuilder.Impl()
    .token("my-token")
    .timeout(30)
    .build();
```

### 方法参考

每个方法都有特定的目的，仅在需要时生成：

| 方法                           | 目的                 | 可用时机         |
| ---------------------------- | ------------------ | ------------ |
| `self()`                     | 返回用于链接的具体构建器类型     | 始终（抽象）       |
| `setEnvironment(builder)`    | 自定义环境/URL 配置       | 始终           |
| `setAuthentication(builder)` | 修改或添加身份验证          | 仅当 API 具有认证时 |
| `setCustomHeaders(builder)`  | 添加 API 规范中定义的自定义标头 | 仅当 API 定义标头时 |
| `setVariables(builder)`      | 配置 API 变量          | 仅当 API 具有变量时 |
| `setHttpClient(builder)`     | 自定义 OkHttp 客户端     | 始终           |
| `setTimeouts(builder)`       | 修改超时设置             | 始终           |
| `setRetries(builder)`        | 修改重试设置             | 始终           |
| `setAdditional(builder)`     | 任何自定义配置的最终扩展点      | 始终           |
| `validateConfiguration()`    | 添加自定义验证逻辑          | 始终           |

### 常见模式

#### 多租户 URL

```java
@Override
protected void setEnvironment(ClientOptions.Builder builder) {
    String url = this.environment.getUrl()
        .replace("/api/", "/tenants/" + tenantId + "/");
    builder.environment(Environment.custom(url));
}
```

#### 动态身份验证

```java
@Override
protected void setAuthentication(ClientOptions.Builder builder) {
    super.setAuthentication(builder); // 保留现有认证
    builder.addHeader("Authorization", () ->
        "Bearer " + tokenProvider.getAccessToken()
    );
}
```

#### 环境变量扩展

```java
@Override
protected void setEnvironment(ClientOptions.Builder builder) {
    String url = this.environment.getUrl();
    // 使用环境变量替换 ${VAR_NAME}
    Pattern pattern = Pattern.compile("\\$\\{([^}]+)\\}");
    Matcher matcher = pattern.matcher(url);
    StringBuffer result = new StringBuffer();
    
    while (matcher.find()) {
        String envVar = System.getenv(matcher.group(1));
        matcher.appendReplacement(result, 
            envVar != null ? envVar : matcher.group(0));
    }
    matcher.appendTail(result);
    
    builder.environment(Environment.custom(result.toString()));
}
```

#### 请求跟踪

```java
@Override
protected void setAdditional(ClientOptions.Builder builder) {
    builder.addHeader("X-Request-ID", () -> UUID.randomUUID().toString());
    builder.addHeader("X-Tenant-ID", this.tenantId);
    
    if (FeatureFlags.isEnabled("new-feature")) {
        builder.addHeader("X-Feature-Flag", "new-feature");
    }
}
```

### 要求

* **Fern Java SDK 版本**：2.39.6 或更高版本
* **配置**：在 `generators.yml` 中设置 `enable-extensible-builders: true`

## 添加自定义依赖项

> **企业功能**
>
> 此功能仅适用于[企业计划](https://buildwithfern.com/pricing)。如需开始使用，请联系 [support@buildwithfern.com](mailto:support@buildwithfern.com)。

要添加您的自定义代码所需的包，请更新您的 `generators.yml`。

**`generators.yml`**

```yaml {4-7} title="generators.yml"
- name: fern-java-sdk
  version: "..."
  config:
    custom-dependencies:
      - org.apache.commons:commons-lang3:3.12.0
      - org.slf4j:slf4j-api:2.0.7

```