1. 空目录到可运行项目:Claude Code 生成 SpringBoot 的真实场景
很多人第一次听到「一行代码不写生成一个 SpringBoot 项目」,脑子里浮现的是魔法。实际用下来,它更像你雇了一个手速极快、但需要你把话说清楚的搭档。Claude Code 是 Anthropic 推出的命令行编程代理,它能读你当前目录的文件、执行 shell 命令、改代码、跑 Maven、提交 Git。SpringBoot 则是 Java 生态里最主流的快速开发框架,一个mvn spring-boot:run就能把 Web 服务拉起来。把这两者凑在一起,适合的人群其实很明确:刚学 Java Web 想快速看到一个完整分层结构的新手、很久没写 Java 想快速搭脚手架的老手、以及想验证「AI 代理到底能自主到什么程度」的开发者。
我这次要复现的场景非常具体:本地有一个空的 Git 仓库目录,里面什么都没有。目标是在这个空目录里,让 Claude Code 从零生成一个能跑起来的 SpringBoot 项目,包含 Controller、Service、配置文件、Maven 依赖,最后初始化 Git 并提交。整个过程我不手写任何 Java 代码,只负责写约束文件、下指令、验证结果。
为什么强调「空目录」和「Git 先行」?因为 Claude Code 对 Git 有原生感知,它会自己git add、自己写 commit message、自己分 feature 提交。如果你不给它一个 Git 仓库,它照样能生成代码,但你就失去了最关键的后悔药——回滚。模型很难一次生成完全符合预期的结果,聊上三四轮之后发现方向跑偏,最省事的做法不是在一堆错误代码上继续打补丁,而是git reset回到上一个干净版本,清掉上下文重新来。所以第一步不是写代码,是git init。
还有一个容易被忽略的点:Claude Code 的上下文窗口是有限的。当你和它聊了十几轮需求、又让它生成了几十个文件之后,早期的约定会被压缩甚至丢弃,幻觉随之放大。解决办法就是把关键约束持久化到文件里,让它每次读文件而不是靠记忆。这个文件就是CLAUDE.md,也是整篇文章里唯一需要你「手写」的东西——但它不是代码,是给 AI 看的契约。
TaoToken 在这个流程里扮演的角色是统一 Key 和 API 通道。Claude Code 本身需要调用模型,如果你手上有多个模型的 Key、或者想在一个地方管理调用额度,把它接到 TaoToken 上会省事很多。官网入口在 https://taotoken.net/?utm_source=taotoken_aicg_blog_end ,后面配置环节我会给出具体的接入方式。注意,接入是配置环节的事,不影响你生成 SpringBoot 项目的核心流程,两者可以分开理解。
下面我按真实操作顺序拆开讲:先写 CLAUDE.md 约束技术栈,再让 Claude Code 生成项目骨架,然后配置 Maven 和 TaoToken 通道,接着启动验证接口,最后把常见的报错逐个排掉。每一步都有可复制的片段,你跟着敲就行。
2. 写 CLAUDE.md 约束技术栈与 Maven 依赖:Claude Code 项目脚手架配置模板
CLAUDE.md放在项目根目录,Claude Code 启动时会自动读取它。它的作用相当于你和 AI 之间的技术契约:技术栈、目录结构、命名规范、依赖版本、禁止事项,全写进去。写得越具体,生成结果越贴近预期;写得越模糊,它就越自由发挥,最后你得到的东西可能和你想要的完全不是一回事。
我试过只写一句「生成一个 SpringBoot 项目」,结果它给我塞了一堆我用不上的 starter,目录结构也随它心情。后来我把约束写全,生成质量立刻稳定下来。下面这份模板可以直接复制,按你的实际情况改版本号和包名。
# 项目契约 CLAUDE.md ## 技术栈 - Java 17 - Spring Boot 3.2.x - MyBatis-Plus 3.5.x - Thymeleaf 模板引擎 - MySQL 8.0 - Maven 3.9+ - Lombok ## 包结构 根包:com.example.demo - controller 接收请求,不写业务逻辑 - service 业务逻辑,接口与实现分离 - mapper MyBatis-Plus Mapper 接口 - entity 数据库实体,与表一一对应 - config 配置类 - common 统一返回体、异常处理 ## 编码规范 - 优先使用注解,避免 XML 配置 - Controller 方法统一返回 Result<T> 包装体 - 所有 public 方法必须写 Javadoc 注释 - 禁止在 Controller 中直接调用 Mapper - 数据库字段使用下划线命名,实体使用驼峰 ## Maven 依赖约束 - 只允许引入 spring-boot-starter-web、spring-boot-starter-thymeleaf、 mybatis-plus-boot-starter、mysql-connector-j、lombok - 不引入 spring-boot-starter-security - 依赖版本由 spring-boot-starter-parent 统一管理 ## 交付要求 - 生成后必须能通过 mvn spring-boot:run 启动 - 提供 application.yml 与 application-dev.yml - 提供 schema.sql 初始化脚本 - 每个功能单元单独 git commit这份契约里最关键的三块:技术栈锁定版本、包结构锁定分层、Maven 依赖锁定白名单。尤其是依赖白名单,能有效防止 AI 给你引入一堆用不上的库。SpringBoot 的依赖管理本身有 parent 兜底,你只要写清楚允许哪些 starter,它就不会乱加。
写完CLAUDE.md之后,先别急着让它生成代码。我的经验是,先和它聊一聊,把需求补全。你可以直接说:
我需要创建一个基础的 Java 项目,采用 Spring Boot + MyBatis-Plus + Thymeleaf, 数据库用 MySQL,目录结构遵循 MVC 分层,优先注解。 现在请采访我,补充完善这个脚手架项目。Claude Code 会反过来问你一系列问题:需不需要分页插件、要不要统一异常处理、数据库连接池用哪个、前端页面要不要示例。你一轮轮回答,需求就清晰了。这一步看起来慢,实际上省掉了后面反复返工的时间。聊完之后,让它把最终方案写成一个DESIGN.md存到当前目录,然后清空会话或压缩上下文,再基于这份文档开始生成。这样后续任何时候它都能读文档恢复上下文,不依赖聊天记录。
关于 TaoToken 的接入,我建议放在依赖配置阶段一起做,而不是等代码生成完再补。因为 Claude Code 调用模型本身也需要通道,你可以在它的配置里指向 TaoToken 的 API 地址,这样生成过程和后续运行用的是同一套 Key 管理。具体配置在下一节展开。
3. 可复制配置:pom.xml、application.yml 与 TaoToken 接入片段
这一节给你三份可以直接落地的配置:Maven 的pom.xml、SpringBoot 的application.yml,以及 TaoToken 的接入配置。前两份是 Claude Code 生成项目的骨架,第三份是通道接入。
先看pom.xml。如果你让 Claude Code 按上面的契约生成,它产出的结构大致如下。我把它整理成可直接复制的版本,注意spring-boot-starter-parent的版本要和你的 Java 版本匹配,Java 17 对应 Spring Boot 3.x。
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.2.5</version> <relativePath/> </parent> <groupId>com.example</groupId> <artifactId>demo</artifactId> <version>0.0.1-SNAPSHOT</version> <name>demo</name> <description>SpringBoot scaffold generated by Claude Code</description> <properties> <java.version>17</java.version> <mybatis-plus.version>3.5.6</mybatis-plus.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>${mybatis-plus.version}</version> </dependency> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> </configuration> </plugin> </plugins> </build> </project>再看application.yml。这里把数据源、MyBatis-Plus、Thymeleaf 都配好,数据库连接信息单独放到application-dev.yml,方便切换环境。
server: port: 8080 spring: profiles: active: dev thymeleaf: cache: false prefix: classpath:/templates/ suffix: .html mybatis-plus: mapper-locations: classpath*:/mapper/**/*.xml configuration: map-underscore-to-camel-case: true log-impl: org.apache.ibatis.logging.stdout.StdOutImpl global-config: db-config: id-type: autoapplication-dev.yml:
spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/demo_db?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai username: root password: your_password接下来是 TaoToken 接入。TaoToken 提供统一的 API 通道,Claude Code 这类工具可以通过配置 Base URL 和 Key 指向它。API 地址是 https://taotoken.net/api ,注意这个地址不带 UTM 参数。配置时你需要三件套:Base URL、API Key、Model ID。Key 在控制台创建,地址是 https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite 。
如果你用的是 Claude Code 的配置文件方式,可以在项目或全局配置里写入类似结构(具体字段名以你所用版本为准):
{ "apiBaseUrl": "https://taotoken.net/api", "apiKey": "sk-你的TaoToken密钥", "model": "claude-sonnet-4-20250514" }如果你用的是 Codex 的auth.json结构,写法类似:
{ "base_url": "https://taotoken.net/api", "api_key": "sk-你的TaoToken密钥", "model_id": "claude-sonnet-4-20250514" }三件套缺一不可:Base URL 决定请求发到哪,Key 决定身份,Model ID 决定用哪个模型。少任何一个都会在请求阶段报错。配置完成后,Claude Code 的模型调用就走 TaoToken 通道了,生成 SpringBoot 项目的过程和通道接入是解耦的,你可以先配通道再生成,也可以先生成再配通道。
4. 启动验证:mvn spring-boot:run 与接口返回实测
配置齐了,让 Claude Code 按DESIGN.md执行生成。它会先创建一个实现计划,然后逐项执行,每完成一个功能单元就自己git commit一次。执行过程中它会用 Subagent 模式,每个任务派一个子代理,任务之间做审查。你不需要盯着每一步,但要在关键节点确认。
生成完成后,先别急着夸它。直接让它自己启动:
请在项目根目录执行 mvn spring-boot:run,把启动日志贴出来,如果有报错自己修复。这一步很关键。Claude Code 生成的代码大概率会有小问题:可能是某个 import 漏了,可能是 MyBatis-Plus 的 Mapper 没加@MapperScan,可能是数据库连接信息不对。让它自己跑、自己看日志、自己修,比你自己去 IDE 里找快得多。我实测下来,它通常能在两三轮内把项目拉起来。
如果你想手动验证,在项目根目录执行:
mvn spring-boot:runMaven 会先下载依赖,然后启动内嵌 Tomcat。看到类似下面的日志就说明起来了:
Started DemoApplication in 3.456 seconds (JVM running for 4.123) Tomcat started on port(s): 8080 (http)启动之前记得先在本地 MySQL 里建库,执行schema.sql初始化脚本。如果改了数据库密码,去application-dev.yml里同步改掉。
项目起来之后,验证接口。假设 Claude Code 生成了一个UserController,提供/api/user/list接口。用 curl 测一下:
curl -X GET http://localhost:8080/api/user/list如果返回统一的Result包装体,类似:
{ "code": 200, "message": "success", "data": [] }说明 Controller、Service、Mapper 三层都通了。再访问首页http://localhost:8080/,Thymeleaf 模板能正常渲染就说明前端层也没问题。
验证通过后,让 Claude Code 把代码推到远程仓库:
请把当前所有提交推送到远程 origin 的 main 分支。它会执行git push,你确认一下远程仓库能看到提交记录就行。到这里,一个完全由 Claude Code 操作完成、你一行 Java 代码没写的 SpringBoot 项目就跑起来了。整个过程我实测下来不到一小时,其中大部分时间花在前期聊需求和写CLAUDE.md上,真正生成和调试的时间反而不多。
5. 常见报错排查:401、local proxy failed、reading choices 与 OAuth
这一节把接入和运行过程中最容易撞上的几个报错列出来,对照着排。
401 Unauthorized。这个几乎都是 Key 的问题。要么 Key 没填、填错,要么 Key 对应的额度用完了。检查你的 TaoToken 配置里apiKey字段是否完整,注意不要有多余空格。如果用的是环境变量,确认变量名和代码里读的一致。401 不会告诉你具体哪里错,只能自己逐项核对三件套:Base URL、Key、Model ID。
local proxy failed / connection refused。这个报错通常出现在请求发不出去的时候。先确认apiBaseUrl写的是https://taotoken.net/api,不要多加斜杠或路径。然后确认本机网络能正常访问这个地址。如果你在配置里写了本地代理端口,检查那个端口是否真的在监听。这个报错和模型无关,纯粹是网络层没通。
Error reading choices / unexpected response format。这个报错说明请求发出去了、也收到响应了,但响应结构不是预期的 OpenAI 兼容格式。常见原因是 Model ID 写错了,或者 Base URL 指向了一个不兼容的端点。回到配置里核对 Model ID 是否和 TaoToken 控制台里列出的名称完全一致。另外确认你用的客户端版本支持当前的响应格式。
OAuth 相关报错。如果你用的是 Claude Code 的 OAuth 登录方式,而不是 API Key 方式,可能会遇到 token 过期或回调失败。这种情况建议直接切到 API Key 方式,用 TaoToken 的 Key 走apiBaseUrl配置,绕开 OAuth 流程。API Key 方式更稳定,也更容易排查。
Maven 依赖下载失败。这个和 TaoToken 无关,是 Maven 仓库的问题。检查settings.xml里的镜像配置,或者换一个网络环境重试。如果某个依赖版本不存在,Claude Code 生成的pom.xml里可能写了一个不存在的版本号,去 Maven Central 查一下真实版本改掉。
启动时报 datasource 相关错误。检查application-dev.yml里的数据库 URL、用户名、密码,确认 MySQL 服务在跑、库已创建、schema.sql已执行。如果用的是 MySQL 8,驱动类名必须是com.mysql.cj.jdbc.Driver,URL 里要带serverTimezone参数。
排错的核心思路是分层定位:先确认通道通不通(401、proxy failed),再确认响应格式对不对(reading choices),最后确认项目本身能不能跑(datasource、Maven)。一层层往下查,比盲目改代码有效得多。
6. 把通道和项目都管起来:TaoToken 接入与后续开发
项目跑起来只是开始。后续你要在这个脚手架上加功能,Claude Code 会继续用同一套通道调用模型。这时候统一 Key 管理的价值就体现出来了:你不需要在多个地方维护不同的 Key,也不用担心某个模型的额度突然用完导致工作中断。
TaoToken 的接入入口我放在这里,方便你按需取用。模型对话调试可以用 https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_content=models&utm_campaign=rewrite ,长期编码和 Agent 场景适合 Coding Plan,地址是 https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite 。API Key 在控制台创建:https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite 。接入文档在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite ,遇到配置问题先翻文档。
回到项目本身。这个由 Claude Code 生成的 SpringBoot 脚手架,后续开发时建议保持两个习惯。第一,每加一个新功能之前,先更新CLAUDE.md里的约束,比如新增了某个模块,把包结构补进去。第二,每个功能单元让 Claude Code 单独 commit,commit message 写清楚做了什么。这样当你发现某个功能方向不对时,可以精确回滚到出问题之前的那次提交,而不是把整个项目推倒重来。
还有一点关于上下文的经验:当你和 Claude Code 聊了很久、生成了很多文件之后,新开一个会话,让它先读CLAUDE.md和DESIGN.md再开始工作。这样它的上下文是干净的,不会被之前的无关对话干扰。我踩过的坑就是在一个超长会话里连续加了五六个功能,到后面它开始忘记早期的包结构约定,生成的代码放错了目录。后来改成每个功能新开会话、先读契约文件,问题就没了。
最后,如果你想让 Claude Code 直接跑起来,可以用 ClaudeCodeAnthropic 的接入方式,把 Base URL 指向 TaoToken 的 API 地址,Key 用控制台创建的,Model ID 填你需要的模型。三件套配好,它就能在命令行里自主完成从生成到提交的全流程。项目代码和通道配置是两回事,分开管理,互不干扰。