In the AI ​​​​era, Python programmers are reveling and Java programmers are anxious. But the release of Spring AI 1.0 finally allows Java developers to elegantly access large models.

Hello everyone, I am Curly.

As a 9-year Java veteran, I admit that I was a little envious of Python’s AI ecosystem before. But after Spring AI 1.0 was officially released, I completed the large model access in one afternoon——All Java, zero Python code

This article will teach you step by step how to access a large model from 0 to 1.Complete runnable code attached


1. What is Spring AI?

In short:Spring AI is an AI application development framework officially launched by Spring, allowing you to develop AI applications using Spring.

Its core capabilities:

abilityillustrate
Chat ClientUnified large model dialogue interface, supporting OpenAI/Claude/Tongyi Qianwen, etc.
EmbeddingText vectorization for RAG and semantic search
Vector StoreVector database integration (Milvus/Pinecone/Redis, etc.)
Function CallingLet the big model call your Java methods
RAGRetrieve enhanced generation and let AI answer questions based on your private data
MemoryConversation memory management
ToolsTool calling framework

biggest advantage: Seamlessly integrated with Spring Boot, all familiar dependency injection, configuration management, and Actuator monitoring are available.


2. Quick access in 5 minutes

Step 1: Add dependencies

<!-- pom.xml -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.4.0</version>
</parent>

<dependencies>
    <!-- Spring AI核心 -->
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-starter-model-openai</artifactId>
    </dependency>

    <!-- 向量数据库(用于RAG) -->
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-starter-vector-store-redis</artifactId>
    </dependency>
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-bom</artifactId>
            <version>1.0.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

Step 2: Configure the large model

# application.yml
spring:
  ai:
    openai:
      api-key: ${AI_API_KEY}
      base-url: https://api.deepseek.com  # 支持DeepSeek/通义千问/OpenAI等
      chat:
        options:
          model: deepseek-chat
          temperature: 0.7
          max-tokens: 2000
      embedding:
        options:
          model: text-embedding-v1

Step 3: First AI conversation

@Service
public class ChatService {

    private final ChatClient chatClient;

    // Spring自动注入,和注入其他Bean一样简单
    public ChatService(ChatClient.Builder builder) {
        this.chatClient = builder
            .defaultSystem("你是一个专业的Java技术助手,回答简洁准确。")
            .build();
    }

    public String chat(String userMessage) {
        return chatClient.prompt()
            .user(userMessage)
            .call()
            .content();
    }

    // 流式输出(打字机效果)
    public Flux<String> chatStream(String userMessage) {
        return chatClient.prompt()
            .user(userMessage)
            .stream()
            .content();
    }
}
@RestController
@RequestMapping("/api/ai")
public class ChatController {

    private final ChatService chatService;

    public ChatController(ChatService chatService) {
        this.chatService = chatService;
    }

    @PostMapping("/chat")
    public Map<String, String> chat(@RequestBody Map<String, String> request) {
        String answer = chatService.chat(request.get("message"));
        return Map.of("answer", answer);
    }

    @GetMapping(value = "/chat/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> chatStream(@RequestParam String message) {
        return chatService.chatStream(message);
    }
}

Just like that, your Java application can talk to AI. Is it easier than you think?


3. Advanced: Let AI call your Java method (Function Calling)

This is the most practical function——Let the large model call Java methods you define

Scenario: Intelligent customer service, AI can check order status

// 1. 定义工具函数
@Bean
public Function<OrderQueryRequest, OrderQueryResponse> queryOrderStatus(OrderService orderService) {
    return request -> {
        Order order = orderService.findById(request.orderId());
        return new OrderQueryResponse(
            order.getId(),
            order.getStatus().toString(),
            order.getCreatedAt().toString()
        );
    };
}

// 2. 记录定义
public record OrderQueryRequest(String orderId) {}
public record OrderQueryResponse(String orderId, String status, String createdAt) {}

// 3. 使用
@Service
public class CustomerService {

    private final ChatClient chatClient;

    public String handleCustomerQuestion(String question) {
        return chatClient.prompt()
            .user(question)
            .functions("queryOrderStatus")  // 绑定工具函数
            .call()
            .content();
    }
}

Test it out:

// 用户问:"帮我查一下订单ORD-2026-001的状态"
// AI会自动:
// 1. 识别意图:用户想查订单
// 2. 调用queryOrderStatus("ORD-2026-001")
// 3. 拿到结果后组织自然语言回复
// AI回复:"您的订单ORD-2026-001当前状态为已发货,下单时间为2026年6月20日。"

AI automatically understands the user intent and calls your Java method! This is the power of Function Calling.


4. RAG in action: Let AI answer questions based on your private data

Scenario: Q&A in the enterprise’s internal knowledge base

@Service
public class KnowledgeBaseService {

    private final VectorStore vectorStore;
    private final ChatClient chatClient;

    // 1. 导入文档到向量数据库
    public void importDocuments(List<Document> documents) {
        vectorStore.add(documents);
    }

    // 2. RAG问答
    public String ask(String question) {
        // 检索相关文档
        List<Document> relevantDocs = vectorStore.similaritySearch(
            SearchRequest.builder()
                .query(question)
                .topK(3)  // 取最相关的3个文档
                .similarityThreshold(0.7)
                .build()
        );

        // 拼接上下文
        String context = relevantDocs.stream()
            .map(Document::getText)
            .collect(Collectors.joining("\n\n"));

        // 构造prompt
        return chatClient.prompt()
            .system("""
                你是企业知识库助手。基于以下参考资料回答问题。
                如果参考资料中没有答案,请说"我无法回答这个问题"。
                不要编造信息。

                参考资料:
                """ + context)
            .user(question)
            .call()
            .content();
    }
}

Import PDF documents

@Component
public class DocumentImporter {

    private final VectorStore vectorStore;

    public void importPdf(String pdfPath) {
        // Spring AI内置PDF读取
        PagePdfDocumentReader reader = new PagePdfDocumentReader(pdfPath);
        List<Document> documents = reader.get();

        // 文本分块(避免单块太长)
        TokenTextSplitter splitter = new TokenTextSplitter();
        List<Document> chunks = splitter.apply(documents);

        // 写入向量数据库
        vectorStore.add(chunks);
    }
}

5. Dialogue memory management

@Service
public class ChatMemoryService {

    private final ChatClient chatClient;
    private final ChatMemory chatMemory;

    public ChatMemoryService(ChatClient.Builder builder) {
        this.chatMemory = new InMemoryChatMemory();  // 生产环境用Redis

        this.chatClient = builder
            .defaultSystem("你是Java技术助手。")
            .defaultAdvisors(new MessageChatMemoryAdvisor(chatMemory))
            .build();
    }

    // 带记忆的对话
    public String chat(String sessionId, String message) {
        return chatClient.prompt()
            .user(message)
            .advisors(a -> a.param(ChatMemory.CONVERSATION_ID, sessionId))
            .call()
            .content();
    }
}

Test results:

用户: 我叫张三
AI: 你好,张三!

用户: 我叫什么名字?
AI: 你叫张三。(← 记住了!)

6. Complete project structure

spring-ai-demo/
├── src/main/java/com/juanmao/ai/
│   ├── config/
│   │   └── AiConfig.java              # AI相关配置
│   ├── controller/
│   │   └── ChatController.java         # 对话接口
│   ├── service/
│   │   ├── ChatService.java            # 对话服务
│   │   ├── KnowledgeBaseService.java   # RAG服务
│   │   └── FunctionCallService.java    # 工具调用服务
│   ├── function/
│   │   ├── OrderQueryFunction.java     # 查订单工具
│   │   └── WeatherQueryFunction.java   # 查天气工具
│   └── Application.java
├── src/main/resources/
│   └── application.yml
└── pom.xml

7. Cost control suggestions

Large model APIs are charged by token. If you are not careful, your bill will explode:

// 1. 设置token上限
spring.ai.openai.chat.options.max-tokens=500

// 2. 使用缓存减少重复调用
@Cacheable(value = "ai-responses", key = "#prompt.hashCode()")
public String chat(String prompt) {
    return chatClient.prompt().user(prompt).call().content();
}

// 3. 轻量级问题用小模型,复杂问题用大模型
public String smartRoute(String question) {
    if (question.length() < 50) {
        // 简单问题用轻量模型
        return lightChatClient.prompt().user(question).call().content();
    }
    // 复杂问题用主力模型
    return chatClient.prompt().user(question).call().content();
}

// 4. 监控token使用量
// 通过Actuator endpoint查看:/actuator/metrics/spring.ai.token.usage

write at the end

Spring AI allows Java developers to finally no longer be left behind in the AI ​​era. You don’t need to learn Python or understand PyTorch,Use the familiar Spring to build AI applications

I have currently implemented it in the project using Spring AI:

  • Intelligent customer service (Function Calling + RAG)
  • Code review assistant
  • Intelligent analysis of operation and maintenance alarms
  • Internal knowledge base Q&A

A series of tutorials will be released later, explaining each step in depth.


📌 I am Curly Hair. I have been developing Java for 9 years and am exploring the best practices of Java + AI.

The code in this article can be run directly.Favorite for later use

Follow "Curly's Technical Notes", Spring AI series continues to be updated! 🔥

Are you using Spring AI? If you have any questions, chat in the comment area 👇