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

5 篇文章 1 订阅
4 篇文章 0 订阅

      在实际开发中,有些业务场景我们不能使用注解@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());
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

门主冬七

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值