如何从Java中的可调用未来函数中返回Map?

问题描述 投票:0回答:1

在我的春季引导程序中,我试图使用 可调用的未来 多处理的功能。更准确地说,Inside 我打开了多个线程,并从函数中接收到地图列表。之后,我打印了我收到的结果。不幸的是,它给出的错误是 Method threw 'java.util.concurrent.ExecutionException' exception. 内部详细留言 NullPointerException. 我尝试了多种方法,但都没有用。

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选择语句的结果时,它给出了正确的结果。问题不在于SQL。我想是我捕捉未来结果的方式不正确,还是实现可调用未来的方式不正确。

java spring-boot future callable
1个回答
1
投票

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.