SpringBoot2多執行緒無法注入問題
阿新 • • 發佈:2019-01-22
1、情況描述
使用springboot2多執行緒,執行緒類無法實現自動注入需要的bean,解決思路,通過工具類獲取需要的bean
如下
package com.ps.uzkefu.apps.ctilink.handler; import com.baomidou.mybatisplus.mapper.EntityWrapper; import com.ps.uzkefu.apps.callcenter.entity.CallRecord; import com.ps.uzkefu.apps.callcenter.service.CallRecordService; import com.ps.uzkefu.apps.ctilink.init.ApplicationContextProvider; import com.ps.uzkefu.apps.ctilink.ommodel.CallCdr; import com.ps.uzkefu.apps.ctilink.ommodel.Cdr; import com.ps.uzkefu.apps.ctilink.rediskey.CdrType; import com.ps.uzkefu.apps.ctilink.rediskey.EventType; import com.ps.uzkefu.apps.ctilink.rediskey.RedisKeyPrefix; import com.ps.uzkefu.apps.oms.account.entity.User; import com.ps.uzkefu.apps.oms.account.service.UserService; import com.ps.uzkefu.util.UUIDUtil; import com.ps.uzkefu.utils.PhoneModel; import com.ps.uzkefu.utils.PhoneUtils; import org.apache.commons.lang.StringUtils; import org.redisson.api.RBucket; import org.redisson.api.RedissonClient; import java.util.Date; import java.util.Objects; /** * Author:ZhuShangJin * Date:2018/6/26 */ public class CdrHandler implements Runnable { public Cdr cdr; //無法自動注入 public RedissonClient redissonClient; //無法自動注入 public UserService userService; //無法自動注入 public CallRecordService callRecordService; public CdrHandler() { //new的時候注入需要的bean this.redissonClient = ApplicationContextProvider.getBean(RedissonClient.class); this.userService = ApplicationContextProvider.getBean(UserService.class); this.callRecordService = ApplicationContextProvider.getBean(CallRecordService.class); } public RedissonClient getRedissonClient() { return redissonClient; } public void setRedissonClient(RedissonClient redissonClient) { this.redissonClient = redissonClient; } public Cdr getCdr() { return cdr; } public void setCdr(Cdr cdr) { this.cdr = cdr; } public UserService getUserService() { return userService; } public void setUserService(UserService userService) { this.userService = userService; } public CallRecordService getCallRecordService() { return callRecordService; } public void setCallRecordService(CallRecordService callRecordService) { this.callRecordService = callRecordService; } @Override public void run() { if (this.getCdr().getOuter() != null) { saveOuterCdr(); } else if (this.getCdr().getVisitor() != null) { saveVistorCdr(); } } private void saveOuterCdr() { // 外呼 通話結束 CallCdr callCdr = null; RBucket<CallCdr> bucket = redissonClient.getBucket(RedisKeyPrefix.CALL_OUTER_CDR + this.getCdr().getOuter().getId() + "_" + cdr.getCpn()); callCdr = bucket.get(); callCdr.setRedisKey(RedisKeyPrefix.CALL_OUTER_CDR + this.getCdr().getOuter().getId() + "_" + cdr.getCpn()); callCdr.setLastEvent(EventType.BYE); callCdr.setLastEventTime(new Date()); callCdr.setTalkLength(Integer.parseInt(this.getCdr().getDuration())); callCdr.setTrunkNum(this.getCdr().getTrunkNumber()); callCdr.setHangupTime(new Date()); callCdr.setRecord(this.getCdr().getRecording()); if (callCdr.getAnsweredTime() == null){ callCdr.setCallTime(callCdr.getHangupTime()); }else { long time = callCdr.getAnsweredTime().getTime() - callCdr.getRingLength()*1000; callCdr.setCallTime(new Date(time)); } //todo 儲存到資料庫 User user = userService.selectOne(new EntityWrapper<User>().eq("extension", callCdr.getExtensionNum() + "")); callCdr.setUserName(user.getUserName()); callCdr.setCorpCode(user.getCorpCode()); callCdr.setCreater(user.getId()); callCdr.setId(UUIDUtil.genUUID()); callCdr.setCreateTime(new Date()); PhoneModel phoneModel = PhoneUtils.getPhoneModel(callCdr.getCustomerPhone()); if (phoneModel != null) { callCdr.setCustomerCity(phoneModel.getCityName()); callCdr.setCustomerProvince(phoneModel.getProvinceName()); } callCdr.setCallId(System.currentTimeMillis() + "" + callCdr.getCallId()); bucket.set(callCdr); CallRecord callRecord = callCdr; boolean result = callRecordService.insert(callRecord); if (result) { bucket.delete(); } } private void saveVistorCdr() { CallCdr callCdr = null; RBucket<CallCdr> bucket = redissonClient.getBucket(RedisKeyPrefix.CALL_VISITOR_CDR + this.getCdr().getVisitor().getId() + "_" + cdr.getTrunkNumber()); callCdr = bucket.get(); callCdr.setRedisKey(RedisKeyPrefix.CALL_VISITOR_CDR + this.getCdr().getVisitor().getId() + "_" + cdr.getTrunkNumber()); callCdr.setRecord(this.getCdr().getRecording()); PhoneModel phoneModel = PhoneUtils.getPhoneModel(callCdr.getCustomerPhone()); if (phoneModel != null) { callCdr.setCustomerCity(phoneModel.getCityName()); callCdr.setCustomerProvince(phoneModel.getProvinceName()); } callCdr.setCallId(System.currentTimeMillis() + "" + callCdr.getCallId()); callCdr.setId(UUIDUtil.genUUID()); //來電 通話結束 外部電話 呼入 接入分機的童虎記錄 if (Objects.equals(CdrType.IN, this.getCdr().getType()) && this.getCdr().getCdpn().length() == 5) { callCdr.setExtensionNum(Integer.parseInt(this.getCdr().getCdpn())); User user = userService.selectOne(new EntityWrapper<User>().eq("extension", callCdr.getExtensionNum() + "")); callCdr.setUserName(user.getUserName()); callCdr.setCorpCode(user.getCorpCode()); callCdr.setCreater(user.getId()); if (Objects.equals(EventType.RING, callCdr.getLastEvent())) { if (StringUtils.isBlank(this.getCdr().getRecording())) { //使用者在坐席未接來電時 未接來電無錄音 掛機 int ringLength = (int) ((new Date().getTime() - callCdr.getLastEventTime().getTime()) / 1000); callCdr.setRingLength(ringLength); callCdr.setTalkLength(0); } else { //特殊情況 坐席接聽後立馬掛掉 callCdr.setTalkLength(Integer.parseInt(this.getCdr().getDuration())); callCdr.setRingLength(-1); callCdr.setLastEvent(CdrType.UNUSUAL); } } else { //正常情況 callCdr.setTalkLength(Integer.parseInt(this.getCdr().getDuration())); } } else if (Objects.equals(CdrType.IN, this.getCdr().getType()) && this.getCdr().getCdpn().length() != 5) { //客服沒接到 callCdr.setExtensionNum(0); callCdr.setUserName("未接到"); callCdr.setCorpCode(this.getCdr().getCdpn()); callCdr.setCreater("未接到"); callCdr.setTalkLength(0); int ringLength = (int) ((new Date().getTime() - callCdr.getCallTime().getTime())/1000); callCdr.setRingLength(ringLength); } callCdr.setCreateTime(new Date()); callCdr.setHangupTime(new Date()); bucket.set(callCdr); if (Objects.equals(CdrType.IN, this.getCdr().getType()) && this.getCdr().getCdpn().length() == 5 && Objects.equals(EventType.RING, callCdr.getLastEvent()) && StringUtils.isNotBlank(this.cdr.getRecording())) { }else if(Objects.equals(CdrType.UNUSUAL,callCdr.getLastEvent())){ }else { CallRecord callRecord = callCdr; boolean result = callRecordService.insert(callRecord); if (result) { bucket.delete(); } } } }
2、獲取bean的工具類
3、通過工具類的getBean方法即可獲取beanpackage com.ps.uzkefu.apps.ctilink.init; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; /** * Author:ZhuShangJin * Date:2018/7/3 */ @Component public class ApplicationContextProvider implements ApplicationContextAware { /** * 上下文物件例項 */ private static ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } /** * 獲取applicationContext * * @return */ public static ApplicationContext getApplicationContext() { return applicationContext; } /** * 通過name獲取 Bean. * * @param name * @return */ public static Object getBean(String name) { return getApplicationContext().getBean(name); } /** * 通過class獲取Bean. * * @param clazz * @param <T> * @return */ public static <T> T getBean(Class<T> clazz) { return getApplicationContext().getBean(clazz); } /** * 通過name,以及Clazz返回指定的Bean * * @param name * @param clazz * @param <T> * @return */ public static <T> T getBean(String name, Class<T> clazz) { return getApplicationContext().getBean(name, clazz); } }