【java】Spring开发中不能使用IOC的情况

xiaoxiao2021-02-28  8

      在实际开发中,有些业务场景我们不能使用注解@Autowire、@Resource、@Inject等自动注入Bean。在多线程的环境下,我们调用Bean的方法来处理我们的业务数据,但是需要处理的数据资源都是单独的,主要针对需要处理的数据资源属于Bean的成员变量,例如:

@Component("withdrawKHQueryResultExecutor") public class OnlineWithdrawKHQueryResultExecutor implements Callable<String>{ private ErrorTask errorTask; @Resource private IOnlineWithdrawQueryService onlineWithdrawQueryService; @Resource private IMerchInfoService merchInfoService; @Resource private OnlineWithdrawHandler onlineWithdrawHandler; @Override public String call() throws Exception { String txnId = errorTask.getTxnId(); String finalSts = errorTask.getFinalStatus(); BillBizSimple simple = onlineWithdrawQueryService.queryBillBizSimle(txnId); MerchInfo merchInfo = merchInfoService.selectByMerchId(simple.getMerchId()); if(FilnalStatusEnum.C_FIRST_POST_FAIL.getValue().equals(finalSts)){ onlineWithdrawHandler.handleFirstPostingFail(simple,merchInfo,errorTask); } return "执行成功!"; } public ErrorTask getErrorTask() { return errorTask; } public void setErrorTask(ErrorTask errorTask) { this.errorTask = errorTask; } } 对于我们来说,errorTask就是需要我们传入的资源,再来看调用的方法代码:

@Component("withdrawKHQueryResultJob") public class WithdrawKHQueryResultJob { private static final Logger logger = Logger.getLogger(WithdrawKHQueryResultJob.class); private static final int FIXED_THREAD_POOL_NUM = 5; private static ExecutorService threadPool = Executors.newFixedThreadPool(FIXED_THREAD_POOL_NUM); private static List<String> finalStsList; @Resource private IErrorTaskService errorTaskService; @Resource private OnlineWithdrawKHQueryResultExecutor withdrawKHQueryResultExecutor; @Override public void runJob(String batchDate) throws Exception { try{ // 计算5分钟之前的时间 Date modTime = DateUtil.getTimeByMinute(-5); // 查询条件 ErrorTaskExampleExt example = new ErrorTaskExampleExt(); example.createCriteria() .andFinalStatusIn(finalStsList) .andModifyTimeGreaterThanOrEqualTo(modTime); // 总记录数 int totalRecords = errorTaskService.countByExample(example); logger.info(getJobId()+"本次执行总记录数:" + totalRecords); final CompletionService<String> completionService = new ExecutorCompletionService<String>(threadPool); Pager pager = new Pager(totalRecords, Constant.QUERY_DBDATE_PAGE_SIZE); if(pager.getTotal() > 0){ for (int page = 1,n=pager.getPages(); page <= n; page++) { example.setStart((page-1)*pager.getPageSize()); example.setLimit(pager.getPageSize()); List<ZbErrorTask> handleList= errorTaskService.selectByExampleByPage(example); if (!CollectionUtils.isEmpty(handleList)) { for (int i = 0, m = handleList.size(); i < m; i++) { ZbErrorTask errorTask = handleList.get(i); withdrawKHQueryResultExecutor.setErrorTask(errorTask); Future<String> future = completionService.submit(withdrawKHQueryResultExecutor); } } } } }catch(Exception e){ e.printStackTrace(); } } static{ finalStsList = new ArrayList<String>(); finalStsList.add(FilnalStatusEnum.C_FIRST_POST_FAIL.getValue()); } } 我们把withdrawKHQueryResultExecutor当做参数进行了执行,这样多线程执行就会出问题,我们知道 spring bean 的作用域,

一般常用的有singleton、prototype看来本例中我们的bean需要使用prototype作用域来处理了。我们获取Spring Bean的方式也需要调整下,目前利用了Spring的IOC来注入,那我们还有另外一个方式来获取Bean,那就是我们需要自己来写一个工具类,需要实现Spring的ApplicationContextAware接口,关于用法网上的讲解很多,自行解决,下面看工具类的代码:

public class SpringContextUtil implements ApplicationContextAware { @Autowired private static ApplicationContext context; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { SpringContextUtil.context=applicationContext; } public static <T> T getBean(String name, Class<T> requiredType){ return context.getBean(name, requiredType); } public static Object getBean(String name){ return context.getBean(name); } public static <T> Object getBean(Class<T> requiredType){ return context.getBean(requiredType); } public static ApplicationContext getContext() { return context; } public static void setContext(ApplicationContext context) { SpringContextUtil.context = context; } } 这样我们就开始调整程序了,最终的代码程序如下:

@Scope("prototype") @Component("withdrawKHQueryResultExecutor") public class OnlineWithdrawKHQueryResultExecutor implements Callable<String>{ private ErrorTask errorTask; @Resource private IOnlineWithdrawQueryService onlineWithdrawQueryService; @Resource private IMerchInfoService merchInfoService; @Resource private OnlineWithdrawHandler onlineWithdrawHandler; @Override public String call() throws Exception { String txnId = errorTask.getTxnId(); String finalSts = errorTask.getFinalStatus(); BillBizSimple simple = onlineWithdrawQueryService.queryBillBizSimle(txnId); MerchInfo merchInfo = merchInfoService.selectByMerchId(simple.getMerchId()); if(FilnalStatusEnum.C_FIRST_POST_FAIL.getValue().equals(finalSts)){ onlineWithdrawHandler.handleFirstPostingFail(simple,merchInfo,errorOrderTask); } return "执行成功!"; } public ErrorTask getErrorTask() { return errorTask; } public void setErrorTask(ErrorTask errorTask) { this.errorTask = errorTask; } } @Component("withdrawKHQueryResultJob") public class WithdrawKHQueryResultJob { private static final Logger logger = Logger.getLogger(WithdrawKHQueryResultJob.class); private static final int FIXED_THREAD_POOL_NUM = 5; private static ExecutorService threadPool = Executors.newFixedThreadPool(FIXED_THREAD_POOL_NUM); private static List<String> finalStsList; @Resource private IErrorTaskService errorTaskService; @Override public void runJob(String batchDate) throws Exception { try{ // 计算5分钟之前的时间 Date modTime = DateUtil.getTimeByMinute(-5); // 查询条件 ErrorTaskExampleExt example = new ErrorTaskExampleExt(); example.createCriteria() .andFinalStatusIn(finalStsList) .andModifyTimeGreaterThanOrEqualTo(modTime); // 总记录数 int totalRecords = errorTaskService.countByExample(example); logger.info(getJobId()+"本次执行总记录数:" + totalRecords); final CompletionService<String> completionService = new ExecutorCompletionService<String>(threadPool); Pager pager = new Pager(totalRecords, Constant.QUERY_DBDATE_PAGE_SIZE); if(pager.getTotal() > 0){ for (int page = 1,n=pager.getPages(); page <= n; page++) { example.setStart((page-1)*pager.getPageSize()); example.setLimit(pager.getPageSize()); List<ZbErrorTask> handleList= errorTaskService.selectByExampleByPage(example); if (!CollectionUtils.isEmpty(handleList)) { for (int i = 0, m = handleList.size(); i < m; i++) { ZbErrorOrderTask errorOrderTask = handleList.get(i); OnlineWithdrawKHQueryResultExecutor withdrawKHQueryResultExecutor = (OnlineWithdrawKHQueryResultExecutor) SpringContextUtil.getBean("withdrawKHQueryResultExecutor"); withdrawKHQueryResultExecutor.setErrorOrderTask(errorOrderTask); Future<String> future = completionService.submit(withdrawKHQueryResultExecutor); } } } } }catch(Exception e){ e.printStackTrace(); } } static{ finalStsList = new ArrayList<String>(); finalStsList.add(FilnalStatusEnum.C_FIRST_POST_FAIL.getValue()); } }

转载请注明原文地址: https://www.6miu.com/read-2450107.html

最新回复(0)