之前做个几个大模型的应用,都是使用Python语言,后来有一个项目使用了Java,并使用了Spring AI框架。随着Spring AI不断地完善,最近它发布了1.0正式版,意味着它已经能很好的作为企业级生产环境的使用。对于Java开发者来说真是一个福音,其功能已经能满足基于大模型开发企业级应用。借着这次机会,给大家分享一下Spring AI框架。
注意:由于框架不同版本改造会有些使用的不同,因此本次系列中使用基本框架是 Spring AI-1.0.0,JDK版本使用的是19,Spring-AI-Alibaba-1.0.0.3-SNAPSHOT。
代码参考: https://github.com/forever1986/springai-study
前几章基本上对Spring AI Alibaba的基本使用,包括模型、提示词、聊天记忆等讲了一遍,可以看到基本上使用方式与Spring AI差异不大,这一章讲一下Spring AI Alibaba-基于Nacos的MCP,这是一个基于企业级生产环境实践总结出来的应用框架。
1 基于Nacos的MCP
Spring AI Alibaba MCP 结合 Nacos 服务注册中心,为企业级智能体应用提供了强大的基础架构支持。这一组合解决方案主要围绕三条核心技术线展开,实现了从服务注册、工具代理到服务发现的完整闭环,为企业级 AI 应用部署提供了坚实基础。

Nacos3中提供了新的MCP列表功能,其中有三类MCP服务可以注册到Nacos:
- 第一类:已有的API服务,通过声明自动转化为 MCP 服务,配合 Higress 的协议转换能力,实现 0 代码改造成 MCP 服务协议
- 第二类:已经构建好的或其他供应商提供的 MCP 服务,可以导入到 Nacos 中,进行其描述、工具列表、工具 Schema 等内容的动态修改和维护
- 第三类:新构建的 MCP 服务注册, 配合 Spring AI Alibaba应用框架或者Nacos-MCP 的 sdk,能够做到像微服务一样自动注册到 Nacos 中进行统一的管理和维护
前两类都是Nacos3本身支持的功能,这里主要是讲Spring AI Alibaba。因此本次演示的是第三类,使用Spring AI Alibaba框架注册服务到Nacos,并通过Spring AI Alibaba框架获得及发现MCP服务。
2 MCP 服务注册到 Nacos
参考lesson25子模块中ali-mcp-server子模块
示例说明:本实例创建一个MCP的server,里面有一个查询天气的工具,然后将MCP服务(基于sse模式)注册到Nacos上面,本次使用Nacos3.0.2版本
2.1 前提准备
1)安装并启动nacos3.0.2

2)申请高德开放平台的API KEY

2.2 代码
1)新建lesson25子模块
2)在lesson25子模块下,新建ali-mcp-server子模块,其pom引入如下:
<dependencies>
<!-- MCP Nacos 注册 -->
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-starter-nacos-mcp-server</artifactId>
</dependency>
<!-- MCP Server (webflux) -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-server-webflux</artifactId>
</dependency>
</dependencies>
3)新建application.properties配置文件
server.port=9005
spring.application.name=mcp-nacos-registry-example
spring.ai.dashscope.api-key=你的阿里百炼API KEY
spring.ai.dashscope.chat.options.model=qwen-plus
## NacosMcpProperties nacos的配置
spring.ai.alibaba.mcp.nacos.namespace=public
spring.ai.alibaba.mcp.nacos.server-addr=localhost:8848
spring.ai.alibaba.mcp.nacos.username=nacos
spring.ai.alibaba.mcp.nacos.password=nacos
## McpServerProperties MCP的配置
spring.ai.mcp.server.name=webflux-mcp-server
spring.ai.mcp.server.version=1.0.0
spring.ai.mcp.server.type=ASYNC
## NacosMcpRegistryProperties MCP注册到nacos的配置
spring.ai.alibaba.mcp.nacos.registry.enabled=true
spring.ai.alibaba.mcp.nacos.registry.service-group=mcp-server
spring.ai.alibaba.mcp.nacos.registry.service-name=webflux-mcp-server
4)配置RestTemplateConfig类:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
5)新增天气查询服务WeatherService:
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Service
public class WeatherService {
@Autowired
private RestTemplate restTemplate;
private static final String adcode = "adcode";
@Tool(description = "获取中国城市的天气情况")
public String getWeatherForecastByCity(@ToolParam(description = "城市名称") String city) {
// 获取城市的adcode
String result = restTemplate.getForObject("https://restapi.amap.com/v3/geocode/geo?address="+city+"&key=ef3cbaef8f0965c6205f56e0ff00ceb4", String.class);
// 这里为了方便简单处理一下字符串获取adcode,正式的话需要解析json格式
int startIndex = result.indexOf(adcode);
String code = result.substring(startIndex+adcode.length()+3,result.indexOf(",",startIndex)-1);
// 通过城市的adcode,进行获取天气预报
result = restTemplate.getForObject("https://restapi.amap.com/v3/weather/weatherInfo?extensions=all&key=ef3cbaef8f0965c6205f56e0ff00ceb4&city="+code, String.class);
return result;
}
}
6)新建启动类Lesson25ServerApplication,注册工具:
import com.demo.lesson25.server.service.WeatherService;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.ai.tool.method.MethodToolCallbackProvider;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class Lesson25ServerApplication {
public static void main(String[] args) {
SpringApplication.run(Lesson25ServerApplication.class, args);
}
@Bean
public ToolCallbackProvider weatherTools(WeatherService weatherService) {
return MethodToolCallbackProvider.builder().toolObjects(weatherService).build();
}
}
2.3 演示
1)启动项目后,在nacos控制台的MCP服务列表可以看到注册的MCP服务

2)点击详情,可以看看详情

3)查看服务列表,可以看到服务已经注册到nacos

4)点击详情可以看到服务地址

3 Client 结合 Nacos 实现 MCP 集群发现
参考lesson25子模块中ali-mcp-client子模块
示例说明,本实例创建一个MCP的client,通过Nacos方式,将上面注册的工具通过sse模式拉取到本地,并访问测试
3.1 代码实现
1)在lesson25子模块下,新建ali-mcp-client子模块,其pom引入如下:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-starter-nacos-mcp-client</artifactId>
</dependency>
<!-- 引入的是mcp-client -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-client-webflux</artifactId>
</dependency>
</dependencies>
2)创建application.properties配置文件
server.port=9006
spring.application.name=mcp-nacos-client-example
spring.ai.dashscope.api-key=你的阿里百炼API KEY
spring.ai.dashscope.chat.options.model=qwen-plus
## NacosMcpProperties nacos的配置
spring.ai.alibaba.mcp.nacos.namespace=public
spring.ai.alibaba.mcp.nacos.server-addr=localhost:8848
spring.ai.alibaba.mcp.nacos.username=nacos
spring.ai.alibaba.mcp.nacos.password=nacos
## NacosMcpSseClientProperties MCP客户端配置通过nacos获取的MCP server
spring.ai.alibaba.mcp.nacos.client.enabled=true
spring.ai.alibaba.mcp.nacos.client.sse.connections.server1.service-name=webflux-mcp-server
spring.ai.alibaba.mcp.nacos.client.sse.connections.server1.version=1.0.0
## McpClientCommonProperties MCP客户端配置的配置
spring.ai.mcp.client.enabled=true
spring.ai.mcp.client.name=mcp-client-webflux
spring.ai.mcp.client.version=1.0.0
spring.ai.mcp.client.type=ASYNC
3)配置ClientController 演示类:
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ClientController {
private final ChatClient chatClient;
public ClientController(ChatClient.Builder chatClientBuilder, @Qualifier("loadbalancedMcpAsyncToolCallbacks") ToolCallbackProvider tools) {
this.chatClient = chatClientBuilder
.defaultToolCallbacks(tools.getToolCallbacks())
.build();
}
@GetMapping("/ai/generate")
public String generate(@RequestParam(value = "message", defaultValue = "请问北京市目前天气预报?") String message) {
return this.chatClient.prompt()
.user(message)
.call().content();
}
}
说明:工具的获取,Spring AI Alibaba分为同步和异步
1)同步方式:
- 通过@Qualifier(“loadbalancedSyncMcpToolCallbacks”) ToolCallbackProvider tools参数注册;
- 通过@Autowired private List loadbalancedMcpSyncClients;变量注册
2)异步方式:
- 通过@Qualifier(“loadbalancedMcpAsyncToolCallbacks”) ToolCallbackProvider tools参数注册;
- 通过@Autowired private List loadbalancedMcpAsyncClients;变量注册
4)启动类Lesson25ClientApplication :
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Lesson25ClientApplication {
public static void main(String[] args) {
SpringApplication.run(Lesson25ClientApplication.class, args);
}
}
3.2 演示
http://localhost:9006/ai/generate

结语:本章通过一个基于Nacos的MCP服务端和MCP客户端,演示了Spring AI Alibaba-基于Nacos的MCP实现方法,当然Spring AI Alibaba-基于Nacos的MCP是一种企业级的应用模式,详情可以参考官方文档,它并不止提供本章内容,比如远程其它MCP服务也可以通过Nacos注册等等。这里就不多累述。
Spring AI系列上一章:《Spring AI 系列之三十 - Spring AI Alibaba-其它模型》
Spring AI系列下一章:《Spring AI 系列之三十二 - Spring AI Alibaba-Graph框架之入门》
569





