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);    
    }
}