一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - 解決SpringBoot2多線程無法注入的問題

解決SpringBoot2多線程無法注入的問題

2020-08-27 00:03NemoHero Java教程

這篇文章主要介紹了解決SpringBoot2多線程無法注入的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧

1、情況描述

使用springboot2多線程,線程類無法實現自動注入需要的bean,解決思路,通過工具類獲取需要的bean

如下

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
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的工具類

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package 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);
 }
}

3、通過工具類的getBean方法即可獲取bean

補充知識:關于Spring/SpringBoot在靜態工具類中注入Service的解決方案

前言今天博主將為大家分享:關于Spring/SpringBoot在靜態工具類中注入Service的解決方案!不喜勿噴,如有異議歡迎討論!

最近遇到了需要在工具類中注入Service,由于工具類中方法一般都是靜態的,所以要求該屬性也要是靜態的(Service)。但是由于Spring/SpringBoot正常情況下不能支持注入靜態屬性(會報空指針異常)。主要原因在于:Spring的依賴注入實際上是依賴于Set方法進行注入值的,Spring是基于對象層面的依賴注入,而靜態屬性/靜態變量實際上是屬于類的。

解決方案:

給當前的工具類加上@Component,使其成為一個bean對象

聲明一個靜態的屬性(加上注解@Autowired),一個非靜態的屬性。

聲明一個返回值為void并且不能拋出異常的方法,在其中將非靜態屬性賦值給靜態屬性。該方法上加上注解@PostConstruct

這樣就將service的值注入了進來。示例代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/**
*
*@Description: 關于Spring/SpringBoot在靜態工具類中注入Service的解決方案
*@ClassName: XXUtils.java
*@author ChenYongJia
*@Date 2019年6月26日 晚上21:20
*/
 
@Component
public class XXUtils {
 
@Autowired
private SpecialLogSevice sevice;
 
private static SpecialLogSevice specialLogSevice;
 
@PostConstruct
public void init() {
 specialLogSevice = sevice;
}
 
//下面的內容就省略了,需要調用specialLogSevice打點就行了
 
}

在上述代碼中@PostConstruct是Java EE5規范之后,Servlet新增的兩個影響servlet聲明周期的注解之一,另外一個是@PreConstruct。這兩個都可以用來修飾一個非靜態的返回值為void的方法,并且該方法不能拋出異常。

被@PostConstruct注解修飾的方法會在服務器加載Servlet的時候運行,并且只會被服務器調用一次,類似于Servlet中的init方法。被該注解修飾的方法會在構造器執行之后,init方法執行之前執行。Spring中允許開發者在受理的Bean中去使用它,當IOC容器被實例化管理當前bean時,被該注解修飾的方法會執行,完成一些初始化的工作。

被PreConstruct注解修飾的方法會在服務器卸載Servlet的時候運行,類似于Servlet中的destroy方法。被該注解修飾的方法會在destroy方法執行之后,Servlet徹底卸載之前執行。

到這里:關于Spring/SpringBoot在靜態工具類中注入Service的解決方案!分享完畢了,快去試試吧!希望大家多多支持服務器之家!

原文鏈接:https://blog.csdn.net/zsj777/article/details/80965081

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 男生和女生艹逼 | 欧美三级做爰全过程 | 麻豆在线md0087免费 | 精品综合久久久久久97超人 | 青青热久免费精品视频网站 | 538精品视频 | 丰腴尤物贵妇浪荡小说 | 高清免费毛片 | 好吊妞乱淫 | 美女mm131爽爽爽久久 | 精品女同同性视频很黄很色 | 精品国产一区二区三区在线观看 | 国产卡一卡二卡三乱码手机 | 亚洲 欧美 日韩 国产 视频 | 国色天香社区在线 | 激情视频在线播放 | 日本在线一区 | 青青成人福利国产在线视频 | 翁熄性放纵交换300章 | 亚洲国产欧美在线人成aaaa20 | 久久精品嫩草影院免费看 | 亚洲成人网页 | www一区| 特黄特黄一级高清免费大片 | 亚洲国产日韩欧美一区二区三区 | 美女大鸡鸡 | 白丝女榨干蹂躏我 | 91免费永久国产在线观看 | 四虎库 | 国产亚洲精品自在线亚洲情侣 | 亚洲日韩精品欧美一区二区一 | 国产人妖ts在线视频网 | 深夜网站在线观看 | 国产精品第 | 亚洲福利电影一区二区? | 91婷婷射 | 国产成人精品视频一区二区不卡 | ts视频在线观看 | chinese壮直男gay老年人 | 亚洲春色综合另类网蜜桃 | 闺蜜调教我做她的脚奴 |