如何 return 从 Java 中的 Callable Future 函数映射

How to return Map from Callable Future function in Java

在我的 spring 引导程序中,我尝试使用 Callable Future 函数进行多处理。更准确地说,在 loop 内部,我打开了多个线程并从函数中接收了 Map 列表。之后我打印我收到的结果。不幸的是,它给出了错误 Method threw 'java.util.concurrent.ExecutionException' exception。内部详细消息 NullPointerException。我尝试了多种方法,其中 none 有效。

public class MyCallable implements Callable<List<Map<String, Object>>> {

    @Autowired
    @Qualifier("jdbcMaster")
    JdbcTemplate jdbcTemplate;

    private String SQL_QUERY;

    public MyCallable(){
    }

    public MyCallable(String SQL_QUERY){
        this.SQL_QUERY = SQL_QUERY;
    }

    @Override
    public List<Map<String, Object>> call() throws Exception {
        List<Map<String, Object>> ph_list = jdbcTemplate.queryForList(SQL_QUERY);
        return ph_list;
    }
}

        Integer listSize = regionFilials.size();
        ExecutorService service = Executors.newFixedThreadPool(listSize);
        List<Future<List<Map<String, Object>>>> resultList = new ArrayList<>();

        for (int i=0; i<listSize; i++){
            filialId = "'" + regionFilials.get(i) + "'";
            SQL_RESULT = SQL_SPECIAL_INCOME.replace("?", filialId);

            MyCallable myCallable  = new MyCallable(SQL_RESULT);
            Future<List<Map<String, Object>>> result = service.submit(myCallable);
            resultList.add(result);
        }

       for (Future<List<Map<String, Object>>> futures : resultList){

           try {
               if (futures.isDone()) {
                   try {
                       System.out.println("Name: " + futures.get(20, TimeUnit.SECONDS));
                   } catch (TimeoutException e) {
                       e.printStackTrace();
                   }
               }

           } catch (InterruptedException e) {
               e.printStackTrace();
           } catch (ExecutionException e) {
               e.getCause();
           }

       }

当我尝试用普通方法得到 SQL_RESULT select 语句的结果时,它给出了正确的结果。问题不在于 SQL。我想我是不是错误地捕捉到了未来的结果,还是以错误的方式实现了可调用的未来。

据我所知,MyCallable 没有注释,而且它没有被 Spring 实例化,所以这意味着 jdbcTemplate 依赖项不会被自动注入。请检查调试 - 它应该为空。 我推荐以下选项之一:

  1. 将 JdbcTemplate 依赖项添加到创建可调用文件的 class。在 MyCallable 的构造函数中设置 JdbcTemplate 或为 JdbcTemplate 创建一个 setter 并手动设置它。
  2. 保持原样,只需确保将 @Component 注释和 @Scope 设置为 MyCallable 的原型。然后你可以使用 context.getBean(MyCallable.class) 来实例化 MyCallable 并注入 JDBCTemplate。

我会推荐第一种方法,因为在 MyCallable 中没有太多意义作为 bean - 它不会注入任何地方,所以第二种方法不常见并且使代码不那么干净。