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

Spring Boot @Service注入下的泛型反向查找实现方案

优雅匹配AbstractBurninator子类与对应DoesThings实现(无需Map)

针对你的场景,这里提供两种无需手动维护Map的优雅实现方式,都是利用Spring的依赖注入特性和Java多态来解决匹配问题:


方案一:增强接口,显式声明支持类型(推荐)

通过给DoesThings接口添加一个判断方法,让每个实现类自行声明支持的AbstractBurninator子类类型,逻辑直观且无反射依赖。

1. 修改DoesThings接口

新增supports方法用于匹配类型:

public interface DoesThings<B extends AbstractBurninator> {
    void doAllTheThings(B burninator, String payload);
    
    // 新增:判断当前实现是否支持指定Burninator类型
    boolean supports(Class<? extends AbstractBurninator> burninatorClass);
}

2. 实现子类的supports方法

每个DoesThings实现类明确声明自己支持的Burninator子类:

@Service
public class FizzThingDoer implements DoesThings<FizzBurninator> {
    @Override
    public void doAllTheThings(FizzBurninator burninator, String payload) {
        // Fizz相关业务逻辑
    }

    @Override
    public boolean supports(Class<? extends AbstractBurninator> burninatorClass) {
        return FizzBurninator.class.equals(burninatorClass);
    }
}

@Service
public class BuzzThingDoer implements DoesThings<BuzzBurninator> {
    @Override
    public void doAllTheThings(BuzzBurninator burninator, String payload) {
        // Buzz相关业务逻辑
    }

    @Override
    public boolean supports(Class<? extends AbstractBurninator> burninatorClass) {
        return BuzzBurninator.class.equals(burninatorClass);
    }
}

3. 在BurninationService中匹配调用

通过流遍历找到匹配的实现类:

@Service
public class BurninationService {
    @Autowired
    private List<DoesThings<? extends AbstractBurninator>> thingDoers;

    public void hahaha(Whistlefeather wf) {
        AbstractBurninator burninator = inferSomehow();
        
        // 找到匹配的DoesThings实现
        DoesThings<? super AbstractBurninator> matchingDoer = thingDoers.stream()
                .filter(doer -> doer.supports(burninator.getClass()))
                .findFirst()
                .orElseThrow(() -> new IllegalArgumentException("无匹配的DoesThings实现:" + burninator.getClass().getSimpleName()));
        
        // 类型转换后调用方法(@SuppressWarnings消除泛型转换警告)
        @SuppressWarnings("unchecked")
        DoesThings<AbstractBurninator> typedDoer = (DoesThings<AbstractBurninator>) matchingDoer;
        typedDoer.doAllTheThings(burninator, "业务载荷");
    }
}

方案二:利用Spring工具类解析泛型类型

如果不想修改原有接口,可以通过Spring的GenericTypeResolver工具类,反射解析DoesThings实现类的泛型参数类型,实现自动匹配。

1. 保持原有接口和实现类不变

无需修改DoesThings接口,实现类正常编写即可:

@Service
public class FoobazThingDoer implements DoesThings<FoobazBurninator> {
    @Override
    public void doAllTheThings(FoobazBurninator burninator, String payload) {
        // Foobaz相关业务逻辑
    }
}

2. 在BurninationService中通过泛型解析匹配

import org.springframework.core.GenericTypeResolver;

@Service
public class BurninationService {
    @Autowired
    private List<DoesThings<? extends AbstractBurninator>> thingDoers;

    public void hahaha(Whistlefeather wf) {
        AbstractBurninator burninator = inferSomehow();
        Class<? extends AbstractBurninator> burninatorClass = burninator.getClass();
        
        // 解析泛型参数并匹配
        DoesThings<? super AbstractBurninator> matchingDoer = thingDoers.stream()
                .filter(doer -> {
                    // 获取当前DoesThings实现对应的泛型参数类型
                    Class<?> genericType = GenericTypeResolver.resolveTypeArgument(doer.getClass(), DoesThings.class);
                    return burninatorClass.equals(genericType);
                })
                .findFirst()
                .orElseThrow(() -> new IllegalArgumentException("无匹配的DoesThings实现:" + burninatorClass.getSimpleName()));
        
        // 类型转换后调用方法
        @SuppressWarnings("unchecked")
        DoesThings<AbstractBurninator> typedDoer = (DoesThings<AbstractBurninator>) matchingDoer;
        typedDoer.doAllTheThings(burninator, "业务载荷");
    }
}

方案对比

维度方案一(显式声明)方案二(泛型解析)
代码可读性高(逻辑直观)中(依赖反射逻辑)
可维护性高(新增实现只需重写supports)中(需确保泛型声明规范)
依赖无额外依赖依赖Spring核心工具类
灵活性高(可支持多类型匹配)中(仅匹配显式声明的泛型类型)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 03:01:00