今天在干活时碰到了一个问题:Requested bean is currently in creation: Is there an unresolvable circular reference,也就是循环注入/依赖的问题,这里做一下记录,方便还没有解决相同问题的同行做个参考。
我的问题是因为多个服务层在注入时,出现了循环注入的情况,导致启动项目报错,具体的错误 就不帐号出来了。。直接说解决方案。
网上有好多说更改注入方式,将构造器注入改为手动注入之类 的,但这种解决方案感觉 不太适合我,,想了想,既然出现了循环注入的情况 ,那就将其它中的一环打断就好了。。。。
我的解决方案是直接从Spring容器中拿到我须要的Bean,代码如下:
工具类:
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
* @author ckinghan
* @title: SpringContextUtil
* @projectName platform
* @description: 获取springcontext中的bean
* @date 2019/10/1811:23
*/
@Component
public class SpringContextUtil implements ApplicationContextAware {
public static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext context) throws BeansException {
SpringContextUtil.context = context;
}
/**
* 获取容器中的实例
* @param clazz 根据class获取Spring容器中对应的Bean类
*/
public static <T> T getBean( Class<T> clazz){
return context.getBean(clazz);
}
public static ApplicationContext getContext(){
return context;
}
}
使用范例:
/**
* @Created with IDEA
* @author:ckinghan
* @description: 消息中间件退款重试任务处理
* @Date:2019年10月18日14:32:56
*/
@Slf4j
@Service
public class MqRefundServiceImpl implements MqRefundService {
@Override
public Boolean decode(byte[] msg) {
String mqMsg = new String(msg);
try {
RefundDetailsEntity refundDetailsEntity = JSON.parseObject(mqMsg,RefundDetailsEntity .class);
//获取支付通道,主要获取退款回调url api_key mch_id 退款证书地址
RemoteOperatorService operatorService = SpringContextUtil.getBean(RemoteOperatorService.class);
R<OperatorPayChannel> payResult = operatorService.getPayChannelByUuid(refundDetailsEntity.getPayUuid(),SecurityConstants.FROM_IN);
if(ObjectUtil.isNull(payResult.getData())){
throw new Exception("获取退款通道信息失败") ;
}
OperatorPayChannel payChannel = payResult.getData();
KeyStore keyStore = KeyStore.getInstance("PKCS12");
FileInputStream instream = null;
String mchId = null;
switch (refundDetailsEntity.getPayChannel()){
case 0:
instream = new FileInputStream(payChannel.getRefundCertUrl());
mchId = payChannel.getMchId();
break;
case 1:
instream = new FileInputStream(payChannel.getWxAppRefundCertUrl());
mchId = payChannel.getWxAppMchId();
break;
default:
log.error("退款重试任务执行失败,未设置除微信之外的其它退款通道");
return true;
}
try {
keyStore.load(instream,mchId.trim().toCharArray());
} finally {
instream.close();
}
SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore,mchId.trim().toCharArray()).build();
AsyncService asyncService = SpringContextUtil.getBean(AsyncService.class);
asyncService.startWXRefund(refundDetailsEntity,payChannel,sslcontext);
}catch (Exception e){
e.printStackTrace();
log.error("重新发起退款计划失败,退款数据为:{},具体原因:{}",mqMsg,e.getMessage());
//如果失败,则直接将订单置为手动订单
}
return null;
}
}
结果完美解决我问题。。。如果此文章观点、思路或描述错误,请各位指出,以免误导它人。