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;
    }
}
相关推荐
阿猫的故乡10 分钟前
Vue过渡动画从入门到装X:淡入淡出、滑动、列表动画、第三方库全搞定
前端·javascript·vue.js
IManiy25 分钟前
总结之Vibe Coding前端骨架
前端
JS菌32 分钟前
AI Agent 沙箱双层防护体系:从权限过滤到内核隔离的完整实现
前端·人工智能·后端
Aphasia31142 分钟前
从输入URL到页面展示全流程
前端·面试
我叫黑大帅1 小时前
前端如何竖屏固定视口背景
前端·javascript·面试
abcy0712131 小时前
python pandas csv异步后台清洗前端优先返回成功信息
前端·python·pandas
IT_陈寒2 小时前
Vite这个坑我帮你踩了,动态导入居然这样才生效
前端·人工智能·后端
swipe2 小时前
Mem0 x Agent 实战系列:分层记忆 + 三路召回,搭建真正可用的长期记忆层
前端·javascript·面试
鹤鸣的日常2 小时前
前端运行时动态环境变量方案
前端·react.js·docker·前端框架·vue·gitlab
Lee川2 小时前
Event Loop 面试通关:从原理到口述再到实战
前端·面试