springboot项目中通过applicationContext.getBeansOfType(class)获取某一接口的所有实现类,并通过枚举完成策略模式,替代if/else,使代码更加优雅易于扩展

下面是项目demo结构,如图

ApiEnum枚举制定接口信息

public enum ApiEnum { 
    API_01("api01.xml","接口01"),    
    API_02("api02.xml","接口02");    
    private String value;    
    private String desc;    
    public String getValue() {
        return value;    
    public String getDesc() {
        return desc;    
    ApiEnum(String value, String desc) {
        this.value = value;        
    this.desc = desc;    

ApiFactory 获取接口实现bean,并存储到 ConcurrentHashMap,通过枚举获取对应的实现bean

@Component
public class ApiFactory {
    @Autowired    
    ApplicationContext applicationContext;    
    Map<String, ApiService> beans = new ConcurrentHashMap<>();   
    @Bean("operations")    
    public Map<String, ApiService> operations() {
        Map<String, ApiService> map = applicationContext.getBeansOfType(ApiService.class);        
        for (ApiService api : map.values()) {
            beans.put(api.op().getValue(), api);       
        return beans;    
     public ApiService getApi(ApiEnum apiEnum) {
        return beans.get(apiEnum.getValue());    

定义接口ApiService

public interface ApiService {
    ApiEnum op();    
    Object invoke(Object obj);

接口实现 TestApiService01、TestApiService02

@Service
public class TestApiService01 implements ApiService {
    @Override    
    public ApiEnum op() {
        return ApiEnum.API_01;    
    @Override    
    public Object invoke(Object obj) {
        return "执行api接口01";    
@Service
public class TestApiService02 implements ApiService {
    @Override    
    public ApiEnum op() {
        return ApiEnum.API_02;    
    @Override    
    public Object invoke(Object obj) {
        return "执行api接口02";    

定义controller

@RestController
public class TestApiController {
    @Autowired    
    ApiFactory factory;   
    @RequestMapping("/")    
    public String index() {
        Object invoke = factory.getApi(ApiEnum.API_02).invoke(null);        
        return (String) invoke;    

最后启动项目,访问127.0.0.1:8080测试即可看到对应接口返回

@SpringBootApplication
public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);