SpringAI1.0的MCPServer自动暴露Tool

java 复制代码
@Configuration
public class ToolAutoRegistrar {

    @Autowired
    private ListableBeanFactory beanFactory;

    @Bean
    public ToolCallbackProvider toolCallbackProvider() {
        List<Object> toolBeans = beanFactory.getBeansWithAnnotation(Service.class)
                .values().stream()
                .filter(bean -> Arrays.stream(bean.getClass().getMethods())
                        .anyMatch(method -> method.isAnnotationPresent(Tool.class)))
                .collect(Collectors.toList());

        return MethodToolCallbackProvider.builder()
                .toolObjects(toolBeans.toArray())
                .build();
    }
}

这段代码会自动查找所有 @Service Bean 中包含 @Tool 注解的方法,然后注册进去。

更加健壮的代码

java 复制代码
package com.example.mcp.config;

import org.springframework.aop.framework.AopProxyUtils;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.ai.tool.MethodToolCallbackProvider;
import org.springframework.ai.tool.Tool;

import java.lang.reflect.Method;
import java.util.List;
import java.util.stream.Collectors;

@Configuration
public class ToolAutoRegistrar {

    @Bean
    public ToolCallbackProvider toolCallbackProvider(ListableBeanFactory beanFactory) {
        List<Object> toolBeans = beanFactory.getBeansOfType(Object.class)
                .values().stream()
                .filter(bean -> hasToolAnnotatedMethod(bean))
                .collect(Collectors.toList());

        return MethodToolCallbackProvider.builder()
                .toolObjects(toolBeans.toArray())
                .build();
    }

    private boolean hasToolAnnotatedMethod(Object bean) {
        Class<?> targetClass = AopProxyUtils.ultimateTargetClass(bean);
        for (Method method : targetClass.getDeclaredMethods()) {
            if (method.isAnnotationPresent(Tool.class)) {
                return true;
            }
        }
        return false;
    }
}
相关推荐
陆枫Larry4 分钟前
小程序 scroll-view 设置 padding 右侧不生效?用一层包裹解决
前端
晴殇i19 分钟前
CommonJS 与 ES6 模块引入的区别详解
前端·javascript·面试
Selicens21 分钟前
git批量删除本地多余分支
前端·git·后端
wuhen_n26 分钟前
KeepAlive:组件缓存实现深度解析
前端·javascript·vue.js
前端付豪27 分钟前
Nest 项目小实践之图书展示和搜索
前端·node.js·nestjs
wuhen_n28 分钟前
Vue Router与响应式系统的集成
前端·javascript·vue.js
青青家的小灰灰1 小时前
金三银四面试官最想听的 React 答案:虚拟 DOM、Hooks 陷阱与大型列表优化
前端·react.js·面试
HelloReader1 小时前
深入理解 Tauri 架构与应用体积优化实战指南
前端
lemon_yyds1 小时前
vue 2 升级vue3 : ref 和 v-model 命名为同名
前端·vue.js
codingWhat1 小时前
小程序里「嵌」H5:一套完整可落地的 WebView 集成方案
前端·uni-app·webview