国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

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

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

服務器之家 - 編程語言 - Java教程 - 解決SpringBoot項目使用多線程處理任務時無法通過@Autowired注入bean問題

解決SpringBoot項目使用多線程處理任務時無法通過@Autowired注入bean問題

2021-05-29 12:27Bug開發工程師 Java教程

這篇文章主要介紹了SpringBoot項目使用多線程處理任務時無法通過@Autowired注入bean問題的解決方法,需要的朋友可以參考下

最近在做一個“溫濕度控制”的項目,項目要求通過用戶設定的溫濕度數值和實時采集到的數值進行比對分析,因為數據的對比與分析是一個通過前端頁面控制的定時任務,經理要求在用戶開啟定時任務時,單獨開啟一個線程進行數據的對比分析,并將采集到的溫濕度數值存入數據庫中的歷史數據表,按照我們正常的邏輯應該是用戶在請求開啟定時任務時,前端頁面通過調用后端接口,創建一個新的線程來執行定時任務,然后在線程類中使用 @autowired 注解注入保存歷史數據的service層,在線程類中調用service層保存歷史數據的方法實現溫濕度數據的保存,這時就出現了一個很尷尬的問題,在新開啟的線程中使用 @autowired 注解無法注入需要的bean(即:保存歷史數據的service層),程序一直在報 nullpointerexception

這是controller層,方法 startexperiment 和 stopexperiment 分別是開始定時任務和停止定時任務的方法,getdata方法不屬于本次討論范圍,不用管

?
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
package com.backstage.controller;
import com.alibaba.fastjson.jsonobject;
import com.backstage.entity.jsonresponse;
import com.backstage.entity.threshold;
import com.backstage.service.mainpageservice;
import org.springframework.beans.factory.annotation.autowired;
import org.springframework.web.bind.annotation.requestmapping;
import org.springframework.web.bind.annotation.restcontroller;
import javax.servlet.http.httpservletrequest;
/**
 * @projectname:
 * @package: com.backstage.controller
 * @classname: mainpagecontroller
 * @description: 主頁面相關操作控制器
 * @author: wangzhilong
 * @createdate: 2018/8/29 9:49
 * @version: 1.0
 */
@restcontroller
@requestmapping("/main")
public class mainpagecontroller {
 @autowired
 private mainpageservice mainpageservice;
 /**
  * 開始實驗
  *
  * @param threshold
  */
 @requestmapping("/startexperiment")
 public jsonresponse startexperiment(httpservletrequest request, threshold threshold) {
  return mainpageservice.startexperiment(request, threshold);
 }
 /**
  * 停止實驗
  */
 @requestmapping("/stopexperiment")
 public jsonresponse stopexperiment() {
  return mainpageservice.stopexperiment();
 }
 /**
  * 獲取實時數據
  *
  * @return
  */
 @requestmapping("/getdata")
 public jsonobject getdata() {
  return null;
 }
}

 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
26
27
28
29
30
31
32
package com.backstage.service;
import com.alibaba.fastjson.jsonobject;
import com.backstage.entity.jsonresponse;
import com.backstage.entity.threshold;
import javax.servlet.http.httpservletrequest;
/**
 * @projectname:
 * @package: com.backstage.service
 * @classname: mainpageservice
 * @description: 主頁面相關操作業務層接口
 * @author: wangzhilong
 * @createdate: 2018/8/29 9:51
 * @version: 1.0
 */
public interface mainpageservice {
 /**
  * 開始實驗
  *
  * @param threshold
  */
 jsonresponse startexperiment(httpservletrequest request, threshold threshold);
 /**
  * 停止實驗
  */
 jsonresponse stopexperiment();
 /**
  * 獲取實時數據
  *
  * @return
  */
 jsonobject getdata();
}

 

 service 層實現類代碼,關于springboot項目使用多線程進行業務處理不屬于本章節的討論范圍,如有需要,請留言,我會在看到留言后第一時間更新相關技術文章,由于這里刪除了一些與本章節無關的代碼,如果復制到開發工具內有報錯問題,麻煩大家提醒我一下,以便修改,非常感謝

?
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
package com.backstage.service.impl;
import com.alibaba.fastjson.jsonobject;
import com.backstage.entity.*;
import com.backstage.monitor.timingmonitoring;
import com.backstage.service.*;
import org.springframework.beans.factory.annotation.autowired;
import org.springframework.context.annotation.bean;
import org.springframework.scheduling.trigger;
import org.springframework.scheduling.triggercontext;
import org.springframework.scheduling.concurrent.threadpooltaskscheduler;
import org.springframework.scheduling.support.crontrigger;
import org.springframework.stereotype.service;
import javax.servlet.http.httpservletrequest;
import java.text.simpledateformat;
import java.util.date;
import java.util.list;
import java.util.concurrent.scheduledfuture;
/**
 * @projectname:
 * @package: com.backstage.service.impl
 * @classname: mainpageserviceimpl
 * @description: 主頁面相關操作業務層實現類
 * @author: wangzhilong
 * @createdate: 2018/8/29 9:51
 * @version: 1.0
 */
@service
public class mainpageserviceimpl implements mainpageservice {
 @autowired
 private threadpooltaskscheduler threadpooltaskscheduler;
 private scheduledfuture<?> future2;
 @bean
 public threadpooltaskscheduler threadpooltaskscheduler() {
  return new threadpooltaskscheduler();
 }
 /**
  * 開始實驗
  *
  * @param threshold
  */
 @override
 public jsonresponse startexperiment(httpservletrequest request, threshold threshold) {
  timingmonitoring timingmonitoring = new timingmonitoring();
  timingmonitoring.setthreshold(threshold, list, experiment.getid(), experimentdata.getid());
  future2 = threadpooltaskscheduler.schedule(new timingmonitoring(), new trigger() {
   @override
   public date nextexecutiontime(triggercontext triggercontext) {
    //設置定時任務的執行時間為3秒鐘執行一次
    return new crontrigger("0/10 * * * * ?").nextexecutiontime(triggercontext);
   }
  });
  return new jsonresponse(0,"開始實驗!");
 }
 /**
  * 停止實驗
  */
 @override
 public jsonresponse stopexperiment() {
  if (future2 != null) {
   experimentservice.upd(gettime());
   future2.cancel(true);
  }
  return new jsonresponse(0,"結束實驗!");
 }
 /**
  * 獲取實時數據
  *
  * @return
  */
 @override
 public jsonobject getdata() {
  return null;
 }
 protected string gettime() {
  simpledateformat format = new simpledateformat("yyyy-mm-dd hh:mm:ss");
  return format.format(new date());
 }
}

重點,線程類代碼,大家注意看,我在代碼最開始使用了spring的 @autowired 注解注入需要的service,可在調用service中的add方法時,程序報空指針異常,一直認為是add方法或者sql語句有問題,找了一上午,也沒發現任何問題,后來單獨調用這個add方法是可以正常插入數據的,唯獨在這個線程類中調用時報錯,感覺和線程有莫大的關系,百度一搜,還真找到了,原來,在線程中為了線程安全,是防注入的,沒辦法,要用到這個類啊。只能從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
package com.backstage.monitor;
import com.backstage.entity.detaileddata;
import com.backstage.entity.threshold;
import com.backstage.entity.valvevalue;
import com.backstage.service.detaileddataservice;
import java.text.simpledateformat;
import java.util.date;
import java.util.list;
/**
 * @projectname:
 * @package: com.backstage.monitor
 * @classname: timingmonitoring
 * @description: 定時監測溫(濕)度 數據
 * @author: wangzhilong
 * @createdate: 2018/8/29 10:11
 * @version: 1.0
 */
public class timingmonitoring implements runnable{
 //歷史數據業務層接口
 @autowired
 public detaileddataservice detaileddataservice;
 private threshold threshold;   //閾值實體類
 private list<valvevalue> settingdata; //設定的溫濕度數據
 private integer id;      //實驗記錄id
 private integer dataid;     //歷史數據主表id
 
 public void setthreshold(threshold threshold, list<valvevalue> settingdata, integer id, integer dataid) {
  this.threshold = threshold;
  this.settingdata = settingdata;
  this.id = id;
  this.dataid = dataid;
 }
 @override
 public void run() {
  //模擬從plc獲取到的數據
  string data = "001,50.5,002,37,003,45.6,004,40,005,55.2,006,58";
  if (data == null || data.trim() == "") {
   return; //若獲取到的數據為空,則直接停止該方法的執行
  }
  double temperature = 0.0; //溫度
  double humidity = 0.0//濕度
  integer type = null;    //數據類型,1是溫度,2是濕度
  //解析數據,并將數據保存到歷史數據數據庫
  string[] str = data.split(",");
  simpledateformat format = new simpledateformat("yyyy-mm-dd hh:mm:ss:ss");
  for (int i = 0; i < str.length; i++) {
   if (i == 1 || i == 5 || i == 9) { //溫度
    type = 1;
    temperature += double.parsedouble(str[i]);
    //system.out.println("溫度" + i + " -》 " + str[i-1] + ":" + str[i]);
    detaileddataservice.add(new detaileddata(null, type, double.parsedouble(str[i]), format.format(new date()), str[i - 1], dataid));
   }
   if (i == 3 || i == 7 || i == 11) { //濕度
    type = 2;
    humidity += double.parsedouble(str[i]);
    //system.out.println("濕度" + i + " -》 " + str[i-1] + ":" + str[i]);
    detaileddataservice.add(new detaileddata(null, type, double.parsedouble(str[i]), format.format(new date()), str[i - 1], dataid));
   }
  }
 }
 /**
  * 獲取當前時間,精確到毫秒
  * @return
  */
 protected string gettime() {
  simpledateformat format = new simpledateformat("yyyy-mm-dd hh:mm:ss:ss");
  return format.format(new date());
 }
}

獲取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
package com.backstage.config;
import org.springframework.beans.beansexception;
import org.springframework.context.applicationcontext;
import org.springframework.context.applicationcontextaware;
import org.springframework.stereotype.component;
/**
 * @projectname:
 * @package: com.backstage.config
 * @classname: applicationcontextprovider
 * @description: 獲取bean對象的工具類
 * @author: wangzhilong
 * @createdate: 2018/8/31 13:26
 * @version: 1.0
 */
/**
 * 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);
 }
}

這樣呢,就可以在線程類中寫一個無參的構造方法,在構造方法中,通過調用工具類中的 getbean() 方法就可以拿到實例了,程序在調用這個線程類時,會自動調用其無參的構造方法,在構造方法中我們將需要的bean對象注入,然后就可以正常使用了,下邊是線程類修改后的代碼,由于別的地方沒有改動,所以這里只給大家改動的代碼,省得大家看到一大堆代碼頭疼。

?
1
2
3
4
public timingmonitoring() {
  //new的時候注入需要的bean
  this.detaileddataservice = applicationcontextprovider.getbean(detaileddataservice.class);
 }

總結

以上所述是小編給大家介紹的springboot項目使用多線程處理任務時無法通過@autowired注入bean 問題,希望對大家有所幫助,如果大家有任何疑問歡迎給我留言,小編會及時回復大家的!

原文鏈接:https://www.cnblogs.com/xiaolong1996/archive/2018/09/01/9571645.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产精品久久久久久久福利院 | 亚洲欧美aa| 天天噜天天干 | 亚洲精彩视频 | 精品一区二区在线观看 | 色视频网| 国产精品久久久久久久久久久免费看 | 色婷婷综合久久久中字幕精品久久 | 成人小视频在线观看 | 亚洲国产精品久久久久婷婷老年 | 夜夜爽99久久国产综合精品女不卡 | 久久视频在线 | 黄色一级大片在线免费看产 | 欧美日韩中文字幕 | 91成人小视频| 亚洲精品偷拍自拍 | 操av在线 | 涩涩视频观看 | 国产欧美精品一区二区色综合 | 亚洲自拍偷拍一区 | 青青草免费在线 | 亚洲啪啪网站 | 黄色精品网站 | 国产精品美女久久久久aⅴ国产馆 | 国产一级一级特黄女人精品毛片 | 欧美一区| 中文字幕一区二区三区乱码在线 | 国产精品99久久久久久宅男 | 中文字幕亚洲一区二区三区 | 日韩欧美视频在线 | 91在线影院 | 中文字幕亚洲一区二区三区 | 亚洲精品成a人 | 久在线 | 国产精品女同一区二区久久夜 | 日日夜夜国产 | 欧美a级成人淫片免费看 | 美女一级| h片观看| 日韩国产免费观看 | 日韩精品免费在线视频 |