1. 概述

我们在使用代码加载系统工具类时,如下使用下面代码,如果我需要增加工具类时这个代码需要做修改,因此我希望当增加工具类时,能自动加载这些类。

 @Bean
 public ToolCallbackProvider toolProvider(McpService mcpService) {
        return MethodToolCallbackProvider.builder()
                .toolObjects(mcpService)
                .build();
    }

2. 动态加载类的实现

2.1 EnableTool

这个注解作用于需要动态加载的工具类上。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface EnableTool {

}

2.2 ToolScannerRegistrar

这个类用于加载有 EnableTool 注解的类,并将其加入到 spring容器。

public class ToolScannerRegistrar implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(registry);
        scanner.addIncludeFilter(new AnnotationTypeFilter(EnableTool.class));

        // 获取配置的包路径,如果没有配置则使用启动类所在的包
        AnnotationAttributes attributes = AnnotationAttributes.fromMap(
                importingClassMetadata.getAnnotationAttributes(EnableToolScan.class.getName()));
        String[] basePackages = attributes.getStringArray("basePackages");

        if (basePackages.length == 0) {
            basePackages = new String[]{ClassUtils.getPackageName(importingClassMetadata.getClassName())};
        }

        scanner.scan(basePackages);
    }
}

2.3 增加类扫描注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(ToolScannerRegistrar.class)
public @interface EnableToolScan {
    String[] basePackages() default {};
}

2.4 实现类扫描,并返回 ToolCallbackProvider对象

这个方法的作用是从容器中获取EnableTool 的对象实例。
然后使用 MethodToolCallbackProvider.Builder 都这些对象的 spring 容器实例,进行初始化。

@Configuration
public class ToolAutoConfiguration {

    @Autowired
    private ApplicationContext applicationContext;

    @Bean
    public ToolCallbackProvider toolProvider() {
        MethodToolCallbackProvider.Builder builder = MethodToolCallbackProvider.builder();

        // 获取所有带有@EnableTool注解的bean
        Map<String, Object> toolBeans = applicationContext.getBeansWithAnnotation(EnableTool.class);

        Object[] toolObjects = new Object[toolBeans.size()];
        int i = 0;
        for(Map.Entry<String, Object> ent : toolBeans.entrySet()){
            toolObjects[i] = ent.getValue();
            i++;
        }

        builder.toolObjects(toolObjects);

        return builder.build();
    }
}

2.5 在主启动类增加注解

@EnableToolScan(basePackages = "com.redxun.mcpmvc.service")
public class McpmvcApplication {

2.6注意我们在编写工具类的使用时,可以不用加 @Service注解

代码实现案例

@EnableTool
public class McpService2 {

    @Tool(description = "查询某个地区的天气")
    public static String getTianqiByArea(String area) {
        return area +"天气为:" + FortuneTeller.getRandomWeather();
    }
}

posted on 2025-08-31 23:22  自由港  阅读(36)  评论(0)    收藏  举报