SpringBoot项目中根据类型获取对应QueryEngine实现类的正确方法
你的工厂注册方案逻辑是通顺的,本身是可行的,不过在SpringBoot环境下可以利用Spring容器的特性实现更简洁的方案,不需要手动维护工厂的注册逻辑。
首先明确现有代码的问题
你当前直接使用@Autowired注入QueryEngine会启动报错,因为Spring容器中存在多个该接口的实现类,无法确定要注入哪个实例。
最优实现方案(Spring原生支持)
Spring原生支持注入指定接口的所有实现到Map结构中,key为Bean的名称,value为对应实现类的实例,完全不需要自己写工厂类:
- 给每个查询引擎实现类指定对应名称的Bean
// BigQueryEngine 对应参数传入的BigQuery @Component("BigQuery") public class BigQueryEngine implements QueryEngine { @Override public void runQuery(String query) { // BigQuery查询逻辑 } } // MSSQLEngine 对应参数传入的MSSQL @Component("MSSQL") public class MSSQLEngine implements QueryEngine { @Override public void runQuery(String query) { // MSSQL查询逻辑 } } // PrestoEngine 对应参数传入的Presto @Component("Presto") public class PrestoEngine implements QueryEngine { @Override public void runQuery(String query) { // Presto查询逻辑 } }
- 改造你的服务类,直接注入所有实现的Map
@Service public class QueryService { // Spring会自动填充该Map,key为上面指定的Bean名称,value为对应实例 @Autowired private Map<String, QueryEngine> queryEngineMap; public void runQuery(String query, String engineType) { QueryEngine targetEngine = queryEngineMap.get(engineType); if (targetEngine == null) { throw new IllegalArgumentException("不支持的查询引擎类型:" + engineType); } targetEngine.runQuery(query); } }
原有工厂方案的修正
如果你坚持要用自己写的工厂类,只需要修正代码中的变量名错误,再加上自动注册逻辑即可:
- 修正工厂类的变量名
public class QueryEngineFactory { private static final Map<String, QueryEngine> schedulers = new HashMap<>(); public static void register(String schedulerName, QueryEngine scheduler){ if(schedulerName!=null && scheduler!=null){ schedulers.put(schedulerName, scheduler); } } public static QueryEngine getScheduler(String schedulerName){ if(schedulers.containsKey(schedulerName)){ return schedulers.get(schedulerName); } return null; } }
- 每个实现类初始化时自动注册
@Component public class BigQueryEngine implements QueryEngine, InitializingBean { @Override public void runQuery(String query) { // 实现逻辑 } @Override public void afterPropertiesSet() throws Exception { QueryEngineFactory.register("BigQuery", this); } }
其余实现类按照同样逻辑添加注册代码即可。
内容的提问来源于stack exchange,提问作者Marcin_S
相关产品推荐
相关产品推荐

