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