You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot中能否通过注解调用方法?自定义注解实现咨询

实现基于自定义注解的方法调用

完全可以通过自定义注解+Spring的Bean扫描来实现你的需求,下面是具体的实现步骤:

1. 自定义方法注解

先定义一个运行时可见的方法注解,用来标识方法的唯一标识:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomAnnotation {
    String value(); // 用来存储方法的标识字符串
}

2. 标记目标方法

在类A中用自定义注解标记需要被调用的方法,同时把类A交给Spring管理(比如添加@Component注解):

import org.springframework.stereotype.Component;

@Component
public class A {
    @CustomAnnotation("m1")
    public void method1() {
        System.out.println("调用了method1");
    }

    @CustomAnnotation("m2")
    public void method2() {
        System.out.println("调用了method2");
    }
}

3. 构建方法映射器

写一个Spring组件,在应用启动时扫描所有被Spring管理的Bean,收集带有@CustomAnnotation的方法,把注解标识和对应的方法、Bean实例存入Map,方便后续调用:

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

@Component
public class MethodInvoker implements ApplicationContextAware {
    // key: 注解的标识字符串,value: 存储Bean实例和对应的Method
    private final Map<String, MethodHolder> methodMap = new HashMap<>();

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        // 扫描所有Spring管理的Bean
        String[] beanNames = applicationContext.getBeanDefinitionNames();
        for (String beanName : beanNames) {
            Object bean = applicationContext.getBean(beanName);
            Class<?> beanClass = bean.getClass();
            // 遍历Bean的所有方法
            for (Method method : beanClass.getDeclaredMethods()) {
                // 判断方法是否带有自定义注解
                if (method.isAnnotationPresent(CustomAnnotation.class)) {
                    CustomAnnotation annotation = method.getAnnotation(CustomAnnotation.class);
                    String identifier = annotation.value();
                    // 把方法和Bean实例存入Map
                    methodMap.put(identifier, new MethodHolder(bean, method));
                }
            }
        }
    }

    // 对外提供的调用方法
    public void invoke(String identifier) throws Exception {
        MethodHolder holder = methodMap.get(identifier);
        if (holder == null) {
            throw new IllegalArgumentException("找不到标识为" + identifier + "的方法");
        }
        // 反射调用方法(示例为无参方法,有参场景可扩展参数传递逻辑)
        holder.method.invoke(holder.bean);
    }

    // 内部类,用来存储Bean实例和Method
    private static class MethodHolder {
        Object bean;
        Method method;

        MethodHolder(Object bean, Method method) {
            this.bean = bean;
            this.method = method;
        }
    }
}

4. 在类B中调用方法

直接注入MethodInvoker,通过标识字符串调用对应方法:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class B {
    @Autowired
    private MethodInvoker methodInvoker;

    public void callTargetMethod() {
        String identifier = "m2";
        try {
            methodInvoker.invoke(identifier);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

扩展说明

  • 如果需要调用带参数的方法,可以给invoke方法添加参数列表,反射调用时传入method.invoke(holder.bean, args)即可
  • 可以给自定义注解添加更多属性(比如方法描述、权限控制规则等),扩展功能边界
  • 注意重复标识的问题,扫描时可判断是否已有相同标识,根据业务需求选择抛出异常或覆盖旧数据

内容的提问来源于stack exchange,提问作者count_campeador

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 07:42:44