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

Spring Boot如何收集自定义注解标注的类并获取其实例?

该需求完全可实现,两种方案可以分别借助Spring提供的类路径扫描API、Spring上下文查询API实现,具体实现方式如下:

方案1:扫描注解类并手动实例化

使用Spring提供的ClassPathScanningCandidateComponentProvider类实现自定义类扫描,不需要依赖Spring托管实例,自行反射创建对象。

实现代码(MyAnnotationService.java中)

import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.beans.factory.config.BeanDefinition;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

public class MyAnnotationService {

    public void scanAndInstantiate() throws Exception {
        // 初始化扫描器,false表示不使用Spring默认的@Component等注解过滤规则
        ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
        // 添加自定义注解过滤规则,只扫描带@MyAnnotation的类
        scanner.addIncludeFilter(new AnnotationTypeFilter(MyAnnotation.class));
        
        // 指定要扫描的基础包,可配置为你项目的根包,比如"com.my.project"
        Set<BeanDefinition> candidateComponents = scanner.findCandidateComponents("com.my.project");
        
        List<Object> instances = new ArrayList<>();
        for (BeanDefinition bd : candidateComponents) {
            // 拿到类全限定名,反射实例化
            Class<?> clazz = Class.forName(bd.getBeanClassName());
            Object instance = clazz.getDeclaredConstructor().newInstance();
            instances.add(instance);
            // 后续可以自行收集注解的name属性,组装成你需要的结构
        }
    }
}

注意事项

  • 该方式创建的实例不归Spring容器管理,类内部的@Autowired、@Value等Spring注解不会自动生效,仅适合无Spring依赖的简单类使用。

方案2:从Spring容器直接获取托管的注解实例

这是业务中实现策略模式最常用的方案,所有标注@MyAnnotation的类需要先添加@Component(或@Service等Spring组件注解)交给Spring托管,之后直接从上下文批量查询即可。

实现代码(MyAnnotationService.java中)

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.AnnotationUtils;
import javax.annotation.PostConstruct;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class MyAnnotationService {

    @Autowired
    private ApplicationContext applicationContext;

    private Map<String, Object> strategyMap;

    @PostConstruct
    public void initStrategyMap() {
        // 从容器中拿到所有带@MyAnnotation注解的Bean实例
        Map<String, Object> annotationBeans = applicationContext.getBeansWithAnnotation(MyAnnotation.class);
        // 组装成key为注解name属性、value为实例的Map
        strategyMap = annotationBeans.values().stream()
                .collect(Collectors.toMap(
                        bean -> AnnotationUtils.findAnnotation(bean.getClass(), MyAnnotation.class).name(),
                        bean -> bean
                ));
    }

    // 后续业务方法可以直接根据name从strategyMap中拿对应实例使用
    public Object getStrategy(String name) {
        return strategyMap.get(name);
    }
}

注意事项

  • 必须给所有@MyAnnotation标注的实现类加上@Component等Spring组件注解,否则Spring不会托管该类,无法被扫描到。
  • 该方式拿到的实例已经完成了所有Spring依赖注入,完全符合业务开发的使用要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 09:54:05