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;
    }
}
相关推荐
鱼鱼块1 分钟前
《从零开始掌握CSS盒模型:结构、计算与最佳实践》
前端
子醉2 分钟前
html5 input[type=date]如何让日期中的年/月/日改成英文
前端·html·html5
Data_Adventure3 分钟前
从前端到 Java 后端:一份详细转型路线指南
前端·后端
神秘的猪头8 分钟前
CSS 盒子模型详解:从 `box-sizing` 理解布局本质
前端·javascript
UIUV11 分钟前
CSS学习笔记:深入理解盒子模型与 box-sizing
前端·css·前端框架
远山枫谷14 分钟前
vue3通信组件学习小记
前端·vue.js
jump68017 分钟前
width height min-width min-height. 100%. 100vw 100vh的区别
前端
F_Director18 分钟前
Webpack性能优化的理论和实践
前端·webpack·性能优化
自由日记21 分钟前
css文档流
前端·css·html
2501_9387994224 分钟前
CSS Container Queries:基于父容器的响应式设计
前端·css