近日在做业务上的短信推送和APP消息推送,通过调用别的模块的接口来实现,在springcloud中通过fegin进行调用。这里要说明的事情并不是如何开发推送功能,而是在调试过程中碰到的一些小问题。
我把消息推送之前的业务处理代码以及调用推送服务的代码都放在方法pushByAppAndShortMessage()中,然后把这个方法单独的放在crmservice里面。由于业务处理,pushByAppAndShortMessage中需要用到别的service,就不得不在crmservice中进行大量的autowired。代码如下:

  1. package cn.appliedata.operate.service;
  2. import java.util.List;
  3. import java.util.Map;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.scheduling.annotation.Async;
  6. import org.springframework.stereotype.Service;
  7.  
  8. import cn.appliedata.common.ResponseWrapper;
  9. import cn.appliedata.message.Message;
  10. import cn.appliedata.message.Message.Type;
  11. import cn.appliedata.model.account.UserAccount;
  12. import cn.appliedata.operate.bean.Supplieres;
  13. import cn.appliedata.operate.bean.crmFlow.SaveFeedbackDTO;
  14. import cn.appliedata.operate.enums.SupplierSuggestionEnum;
  15. import cn.appliedata.operate.feignClient.AccountFeignService;
  16. import cn.appliedata.operate.feignClient.MessageFeignService;
  17. import cn.appliedata.operate.feignClient.SmsCodeFeignService;
  18. import cn.appliedata.operate.mapper.crm.PartsDao;
  19. import cn.appliedata.operate.mapper.operate.OperateTaichiDao;
  20. import cn.appliedata.operate.util.ConstantUtil;
  21. import lombok.extern.slf4j.Slf4j;
  22. /**
  23. * @author :ayfei
  24. */
  25. @Service
  26. @Slf4j
  27. public class CrmService {
  28.  
  29. @Autowired
  30. private MessageFeignService messageFeignService;
  31. @Autowired
  32. private SmsCodeFeignService smsCodeFeignService;
  33. @Autowired
  34. private AccountFeignService accountFeignService;
  35. @Autowired
  36. private StocksiteService stocksiteService;
  37. @Autowired
  38. private PartsService partsService;
  39.  
  40. /*
  41. * 消息推送[APP、短信]
  42. */
  43. @Async
  44. public void pushByAppAndShortMessage(Integer i,Integer senderFlag,SaveFeedbackDTO saveFeedbackDTO){
  45. log.info("log推送1:索引index = "+i);
  46. Message message = new Message(); // 创建APP推送消息体
  47. message.setType(Type.ORDER); // 消息类型不能为空
  48. if(senderFlag == ConstantUtil.INTNUM1){ // 1 服务人员 发送,推送给 供应商
  49. log.info("log推送:推送给供应商");
  50. //有新增、有修改,获取供应商的 accountcode 和 手机号
  51. String type = "";
  52. String feedBackName = "";//异常反馈单号
  53. if(saveFeedbackDTO.getType() == ConstantUtil.INTNUM1){
  54. type = "新增";
  55. message.setContent("您有一条"+type+"异常反馈单待处理,请前往工具->运维反馈进行处理"); //内容不能为空
  56. }else if(saveFeedbackDTO.getType() == ConstantUtil.INTNUM2){
  57. type = "更新";
  58. Map<String,String> serviceWorkerMap = partsService.getServiceWorkerInfo(saveFeedbackDTO.getFeedbackId());
  59. feedBackName = serviceWorkerMap.get("feedBackName"); //当前的异常反馈单号
  60. message.setContent("您有一条"+type+"异常反馈单待处理,异常反馈单号:"+feedBackName+",请前往工具->运维反馈进行处理"); //内容不能为空
  61. }
  62. //根据供应商id获取责任人id和电话
  63. String ownerId = null;
  64. String ownerPhone = null;
  65. List<Supplieres> supplierSelect = stocksiteService.supplierSelect(null, null, saveFeedbackDTO.getSupplierId());
  66. if(supplierSelect == null || supplierSelect.get(0) == null){
  67. log.info("根据供应商id获取责任人信息为空");
  68. return;
  69. }else{
  70. ownerId = supplierSelect.get(0).getOwnerId();
  71. ownerPhone = supplierSelect.get(0).getNewSupplierCall();
  72. }
  73.  
  74. if(ownerPhone != null){
  75. try {
  76. //短信推送供应商
  77. String shortMessage = "您有一条"+type+"异常反馈单:"+feedBackName+"待处理,请登录APP前往工具->运维反馈进行处理。";
  78. //ResponseWrapper sendArbitrarilyMsg = smsCodeFeignService.sendArbitrarilyMsg(ownerPhone, "", shortMessage);//给服务人员发送短信
  79. ResponseWrapper sendArbitrarilyMsg = smsCodeFeignService.sendArbitrarilyMsg("18337117299", "", shortMessage);//给服务人员发送短信
  80. if(!sendArbitrarilyMsg.isSuccess()){
  81. log.info("异常反馈单号:"+feedBackName+"的消息短信推送供应商失败");//短信发送失败
  82. }
  83. } catch (Exception e) {
  84. log.info("异常反馈单号:"+feedBackName+"的消息短信推送供应商出现异常");
  85. }
  86.  
  87. try {
  88. //APP推送供应商 获取供应商账号的 accountcode
  89. ResponseWrapper<UserAccount> accountByMobile = accountFeignService.getAccountByMobile(ownerPhone);
  90. if(accountByMobile == null || accountByMobile.getObj() == null){
  91. log.info("获取远程供应商账号信息异常/返回信息为空");
  92. return;
  93. }
  94. message.setTo(accountByMobile.getObj().getAccountCode()); //
  95. message.setSubject(type+"异常反馈单信息"); //标题不能为空
  96. message.setSummary("您有一条"+type+"异常反馈单信息,注意查收");//消息摘要不能为空
  97. ResponseWrapper respon = messageFeignService.addMessage(message); //APP推送给供应商的账号
  98. if(!respon.isSuccess()){
  99. log.info("异常反馈单新增、修改信息,APP推送供应商失败");//APP失败
  100. }
  101. } catch (Exception e) {
  102. log.info("异常反馈单新增、修改信息,APP推送供应商出现异常");
  103. }
  104. }else{
  105. log.info("供应商电话为null!,无法推送");
  106. }
  107. }else if(senderFlag == ConstantUtil.INTNUM2){ //2 供应商 发送, 推送给 服务人员
  108. log.info("log推送:推送给服务人员");
  109. //只有修改功能,获取服务人员的accountcode 和 手机号
  110. String feedbackidStr = saveFeedbackDTO.getFeedbackId();
  111. Map<String,String> serviceWorkerMap = partsService.getServiceWorkerInfo(feedbackidStr);//根据异常反馈单id获取对应服务单对应的服务人员信息
  112. if(serviceWorkerMap == null){
  113. log.info("根据异常反馈单id:"+saveFeedbackDTO.getFeedbackId()+"获取到的服务人员信息对象为null");
  114. return;
  115. }
  116. String serviceWorkerMobile = serviceWorkerMap.get("mobile"); //服务人员电话
  117. String serviceWorkerId = serviceWorkerMap.get("id"); //服务人员id
  118. String serviceWorkerName = serviceWorkerMap.get("name"); //服务人员姓名
  119. String feedBackName = serviceWorkerMap.get("feedBackName"); //当前的异常反馈单号
  120. //获取服务人员账号的 accountcode
  121. try {
  122. ResponseWrapper<UserAccount> accountByMobile = accountFeignService.getAccountByMobile(serviceWorkerMobile);
  123. if(accountByMobile == null || accountByMobile.getObj() == null){
  124. log.info("获取远程供应商账号信息异常/返回信息为空");
  125. return;
  126. }
  127. message.setTo(accountByMobile.getObj().getAccountCode());
  128. message.setSubject("供应商反馈意见信息"); //标题不能为空
  129. message.setSummary("您有一条供应商反馈信息,请注意查收");//消息摘要不能为空
  130. message.setContent("异常反馈单号:"+feedBackName+",已由供应商填写反馈信息。供应商意见:"+
  131. SupplierSuggestionEnum.getNameStatic(saveFeedbackDTO.getSuggestion())
  132. +";供应商意见备注:"+saveFeedbackDTO.getSuggestionMemo()); //内容不能为空
  133. ResponseWrapper respon = messageFeignService.addMessage(message);//APP推送给服务人员的账号
  134. if(!respon.isSuccess()){
  135. log.info("异常反馈单号:"+feedBackName+"的信息变更,APP推送服务人员失败");//APP失败
  136. }
  137. } catch (Exception e) {
  138. log.info("异常反馈单号:"+feedBackName+"的信息变更,APP推送服务人员出现异常");//APP失败
  139. }
  140.  
  141. }
  142. }
  143.  
  144. }

然后再controller中进行调用crmservice的pushByAppAndShortMessage()方法的时候,出现如下异常:

  1. 2019-01-10 13:29:34,762 ERROR (FeignClientsHeadersTransfer.java:60)- headers复制出错!
  2. java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
  3. at org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes(RequestContextHolder.java:131)
  4. at cn.appliedata.feign.FeignClientsHeadersTransfer.lambda$requestInterceptor$0(FeignClientsHeadersTransfer.java:26)
  5. at feign.SynchronousMethodHandler.targetRequest(SynchronousMethodHandler.java:158)
  6. at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:88)
  7. at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:76)
  8. at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:103)
  9. at com.sun.proxy.$Proxy141.addMessage(Unknown Source)
  10. at cn.appliedata.operate.service.CrmService.pushByAppAndShortMessage(CrmService.java:97)
  11. at cn.appliedata.operate.service.CrmService$$FastClassBySpringCGLIB$$7d315874.invoke(<generated>)
  12. at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
  13. at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738)
  14. at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
  15. at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:85)
  16. at org.springframework.cloud.sleuth.instrument.async.TraceAsyncAspect.traceBackgroundThread(TraceAsyncAspect.java:69)
  17. at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  18. at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
  19. at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  20. at java.lang.reflect.Method.invoke(Method.java:498)
  21. at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:627)
  22. at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:616)
  23. at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)
  24. at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
  25. at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
  26. at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
  27. at org.springframework.aop.interceptor.AsyncExecutionInterceptor$1.call(AsyncExecutionInterceptor.java:115)
  28. at java.util.concurrent.FutureTask.run(FutureTask.java:266)
  29. at org.springframework.cloud.sleuth.instrument.async.SpanContinuingTraceRunnable.run(SpanContinuingTraceRunnable.java:52)
  30. at java.lang.Thread.run(Thread.java:748)
  31. 2019-01-10 13:29:34,763 INFO (AbstractApplicationContext.java:583)- Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@3b9a0944: startup date [Thu Jan 10 13:29:34 GMT+08:00 2019]; parent: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@66273da0
  32. 2019-01-10 13:29:34,786 INFO (AutowiredAnnotationBeanPostProcessor.java:155)- JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
  33. 2019-01-10 13:29:34,803 INFO (ChainedDynamicProperty.java:115)- Flipping property: service-message.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647
  34. 2019-01-10 13:29:34,804 INFO (ShutdownEnabledTimer.java:58)- Shutdown hook installed for: NFLoadBalancer-PingTimer-service-message
  35. 2019-01-10 13:29:34,805 INFO (BaseLoadBalancer.java:192)- Client: service-message instantiated a LoadBalancer: DynamicServerListLoadBalancer:{NFLoadBalancer:name=service-message,current list of Servers=[],Load balancer stats=Zone stats: {},Server stats: []}ServerList:null
  36. 2019-01-10 13:29:34,805 INFO (DynamicServerListLoadBalancer.java:222)- Using serverListUpdater PollingServerListUpdater
  37. 2019-01-10 13:29:34,806 INFO (DynamicServerListLoadBalancer.java:150)- DynamicServerListLoadBalancer for client service-message initialized: DynamicServerListLoadBalancer:{NFLoadBalancer:name=service-message,current list of Servers=[],Load balancer stats=Zone stats: {},Server stats: []}ServerList:org.springframework.cloud.netflix.ribbon.eureka.DomainExtractingServerList@6b044553
  38. 2019-01-10 13:29:34,878 ERROR (SimpleAsyncUncaughtExceptionHandler.java:37)- Unexpected error occurred invoking async method 'public void cn.appliedata.operate.service.CrmService.pushByAppAndShortMessage(java.lang.Integer,java.lang.Integer,cn.appliedata.operate.bean.crmFlow.SaveFeedbackDTO)'.
  39. java.lang.RuntimeException: com.netflix.client.ClientException: Load balancer does not have available server for client: service-message
  40. at org.springframework.cloud.netflix.feign.ribbon.LoadBalancerFeignClient.execute(LoadBalancerFeignClient.java:71)
  41. at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:97)
  42. at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:76)
  43. at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:103)
  44. at com.sun.proxy.$Proxy141.addMessage(Unknown Source)
  45. at cn.appliedata.operate.service.CrmService.pushByAppAndShortMessage(CrmService.java:97)
  46. at cn.appliedata.operate.service.CrmService$$FastClassBySpringCGLIB$$7d315874.invoke(<generated>)
  47. at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
  48. at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738)
  49. at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
  50. at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:85)
  51. at org.springframework.cloud.sleuth.instrument.async.TraceAsyncAspect.traceBackgroundThread(TraceAsyncAspect.java:69)
  52. at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  53. at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
  54. at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  55. at java.lang.reflect.Method.invoke(Method.java:498)
  56. at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:627)
  57. at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:616)
  58. at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)
  59. at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
  60. at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
  61. at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
  62. at org.springframework.aop.interceptor.AsyncExecutionInterceptor$1.call(AsyncExecutionInterceptor.java:115)
  63. at java.util.concurrent.FutureTask.run(FutureTask.java:266)
  64. at org.springframework.cloud.sleuth.instrument.async.SpanContinuingTraceRunnable.run(SpanContinuingTraceRunnable.java:52)
  65. at java.lang.Thread.run(Thread.java:748)
  66. Caused by: com.netflix.client.ClientException: Load balancer does not have available server for client: service-message
  67. at com.netflix.loadbalancer.LoadBalancerContext.getServerFromLoadBalancer(LoadBalancerContext.java:483)
  68. at com.netflix.loadbalancer.reactive.LoadBalancerCommand$1.call(LoadBalancerCommand.java:184)
  69. at com.netflix.loadbalancer.reactive.LoadBalancerCommand$1.call(LoadBalancerCommand.java:180)
  70. at rx.Observable.unsafeSubscribe(Observable.java:10151)
  71. at rx.internal.operators.OnSubscribeConcatMap.call(OnSubscribeConcatMap.java:94)
  72. at rx.internal.operators.OnSubscribeConcatMap.call(OnSubscribeConcatMap.java:42)
  73. at rx.Observable.unsafeSubscribe(Observable.java:10151)
  74. at rx.internal.operators.OperatorRetryWithPredicate$SourceSubscriber$1.call(OperatorRetryWithPredicate.java:127)
  75. at rx.internal.schedulers.TrampolineScheduler$InnerCurrentThreadScheduler.enqueue(TrampolineScheduler.java:73)
  76. at rx.internal.schedulers.TrampolineScheduler$InnerCurrentThreadScheduler.schedule(TrampolineScheduler.java:52)
  77. at rx.internal.operators.OperatorRetryWithPredicate$SourceSubscriber.onNext(OperatorRetryWithPredicate.java:79)
  78. at rx.internal.operators.OperatorRetryWithPredicate$SourceSubscriber.onNext(OperatorRetryWithPredicate.java:45)
  79. at rx.internal.util.ScalarSynchronousObservable$WeakSingleProducer.request(ScalarSynchronousObservable.java:276)
  80. at rx.Subscriber.setProducer(Subscriber.java:209)
  81. at rx.internal.util.ScalarSynchronousObservable$JustOnSubscribe.call(ScalarSynchronousObservable.java:138)
  82. at rx.internal.util.ScalarSynchronousObservable$JustOnSubscribe.call(ScalarSynchronousObservable.java:129)
  83. at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)
  84. at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
  85. at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)
  86. at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
  87. at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)
  88. at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
  89. at rx.Observable.subscribe(Observable.java:10247)
  90. at rx.Observable.subscribe(Observable.java:10214)
  91. at rx.observables.BlockingObservable.blockForSingle(BlockingObservable.java:444)
  92. at rx.observables.BlockingObservable.single(BlockingObservable.java:341)
  93. at com.netflix.client.AbstractLoadBalancerAwareClient.executeWithLoadBalancer(AbstractLoadBalancerAwareClient.java:112)
  94. at org.springframework.cloud.netflix.feign.ribbon.LoadBalancerFeignClient.execute(LoadBalancerFeignClient.java:63)
  95. ... 25 common frames omitted
  96. 2019-01-10 13:29:35,024 INFO (ChainedDynamicProperty.java:115) - Flipping property: service-sms-code.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647
  97. 2019-01-10 13:29:35,648 INFO (ChainedDynamicProperty.java:115)- Flipping property: service-account.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647

这篇文章给了一些思路:https://segmentfault.com/a/1190000014418250
大致意思就是,fegin底调用了访问了RequestContextHolder.currentRequestAttributes()导致,因此在service层方法里头调用该方法要慎重,为了避免出错,可以再封装一下。所以我认为是servvice层代用fegin导致的。于是决定把这个方法放到工具类代码中(结合以前遇到的utils中注入bean),
代码如下:然后再controller中调用工具类中此方法,得以实现。正常运行。

  1. package cn.appliedata.operate.util;
  2. import java.util.List;
  3. import java.util.Map;
  4. import javax.annotation.PostConstruct;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.scheduling.annotation.Async;
  7. import org.springframework.stereotype.Component;
  8. import cn.appliedata.common.ResponseWrapper;
  9. import cn.appliedata.message.Message;
  10. import cn.appliedata.message.Message.Type;
  11. import cn.appliedata.model.account.UserAccount;
  12. import cn.appliedata.operate.bean.Supplieres;
  13. import cn.appliedata.operate.bean.crmFlow.SaveFeedbackDTO;
  14. import cn.appliedata.operate.enums.SupplierSuggestionEnum;
  15. import cn.appliedata.operate.feignClient.AccountFeignService;
  16. import cn.appliedata.operate.feignClient.MessageFeignService;
  17. import cn.appliedata.operate.feignClient.SmsCodeFeignService;
  18. import cn.appliedata.operate.service.PartsService;
  19. import cn.appliedata.operate.service.StocksiteService;
  20. import lombok.extern.slf4j.Slf4j;
  21. /**
  22. * @author :ayfei
  23. * @createTime :2019年1月10日下午2:31:41
  24. * @description :
  25. */
  26. @Slf4j
  27. @Component
  28. public class PushByAppAndShortMessageUtil {
  29.  
  30. @Autowired
  31. private MessageFeignService messageFeignService;
  32. @Autowired
  33. private SmsCodeFeignService smsCodeFeignService;
  34. @Autowired
  35. private AccountFeignService accountFeignService;
  36. @Autowired
  37. private StocksiteService stocksiteService;
  38. @Autowired
  39. private PartsService partsService;
  40.  
  41. private static PushByAppAndShortMessageUtil utils ;
  42.  
  43. @PostConstruct //关键二 通过@PostConstruct 和 @PreDestroy 方法 实现初始化和销毁bean之前进行的操作
  44. public void init() {
  45. utils = this;
  46. utils.messageFeignService = this.messageFeignService; // 初使化时将已静态化的messageFeignService实例化
  47. utils.smsCodeFeignService = this.smsCodeFeignService;
  48. utils.accountFeignService = this.accountFeignService;
  49. utils.stocksiteService = this.stocksiteService;
  50. utils.partsService = this.partsService;
  51. }
  52.  
  53. /*
  54. * 消息推送[APP、短信]
  55. */
  56. @Async
  57. public static void pushByAppAndShortMessage(Integer i,Integer senderFlag,SaveFeedbackDTO saveFeedbackDTO){
  58. log.info("log推送1:索引index = "+i);
  59. Message message = new Message(); // 创建APP推送消息体
  60. message.setType(Type.ORDER); // 消息类型不能为空
  61. if(senderFlag == ConstantUtil.INTNUM1){ // 1 服务人员 发送,推送给 供应商
  62. log.info("log推送:推送给供应商");
  63. //有新增、有修改,获取供应商的 accountcode 和 手机号
  64. String type = "";
  65. String feedBackName = "";//异常反馈单号
  66. if(saveFeedbackDTO.getType() == ConstantUtil.INTNUM1){
  67. type = "新增";
  68. message.setContent("您有一条"+type+"异常反馈单待处理,请前往工具->运维反馈进行处理"); //内容不能为空
  69. }else if(saveFeedbackDTO.getType() == ConstantUtil.INTNUM2){
  70. type = "更新";
  71. Map<String,String> serviceWorkerMap = utils.partsService.getServiceWorkerInfo(saveFeedbackDTO.getFeedbackId());
  72. feedBackName = serviceWorkerMap.get("feedBackName"); //当前的异常反馈单号
  73. message.setContent("您有一条"+type+"异常反馈单待处理,异常反馈单号:"+feedBackName+",请前往工具->运维反馈进行处理"); //内容不能为空
  74. }
  75. //根据供应商id获取责任人id和电话
  76. String ownerId = null;
  77. String ownerPhone = null;
  78. List<Supplieres> supplierSelect = utils.stocksiteService.supplierSelect(null, null, saveFeedbackDTO.getSupplierId());
  79. if(supplierSelect == null || supplierSelect.get(0) == null){
  80. log.info("根据供应商id获取责任人信息为空");
  81. return;
  82. }else{
  83. ownerId = supplierSelect.get(0).getOwnerId();
  84. ownerPhone = supplierSelect.get(0).getNewSupplierCall();
  85. }
  86. if(ownerPhone != null){
  87. try {
  88. //短信推送供应商
  89. String shortMessage = "您有一条"+type+"异常反馈单:"+feedBackName+"待处理,请登录APP前往工具->运维反馈进行处理。";
  90. //ResponseWrapper sendArbitrarilyMsg = utils.sendArbitrarilyMsg(ownerPhone, "", shortMessage);//给服务人员发送短信
  91. ResponseWrapper sendArbitrarilyMsg = utils.smsCodeFeignService.sendArbitrarilyMsg("18337117299", "", shortMessage);//给服务人员发送短信
  92. if(!sendArbitrarilyMsg.isSuccess()){
  93. log.info("异常反馈单号:"+feedBackName+"的消息短信推送供应商失败");//短信发送失败
  94. }
  95. } catch (Exception e) {
  96. log.info("异常反馈单号:"+feedBackName+"的消息短信推送供应商出现异常");
  97. }
  98. try {
  99. //APP推送供应商 获取供应商账号的 accountcode
  100. ResponseWrapper<UserAccount> accountByMobile = utils.accountFeignService.getAccountByMobile(ownerPhone);
  101. if(accountByMobile == null || accountByMobile.getObj() == null){
  102. log.info("获取远程供应商账号信息异常/返回信息为空");
  103. return;
  104. }
  105. message.setTo(accountByMobile.getObj().getAccountCode()); //
  106. message.setSubject(type+"异常反馈单信息"); //标题不能为空
  107. message.setSummary("您有一条"+type+"异常反馈单信息,注意查收");//消息摘要不能为空
  108. ResponseWrapper respon = utils.messageFeignService.addMessage(message); //APP推送给供应商的账号
  109. if(!respon.isSuccess()){
  110. log.info("异常反馈单新增、修改信息,APP推送供应商失败");//APP失败
  111. }
  112. } catch (Exception e) {
  113. log.info("异常反馈单新增、修改信息,APP推送供应商出现异常");//APP异常
  114. }
  115. }else{
  116. log.info("供应商电话为null!,无法推送");
  117. }
  118. }else if(senderFlag == ConstantUtil.INTNUM2){ //2 供应商 发送, 推送给 服务人员
  119. log.info("log推送:推送给服务人员");
  120. //只有修改功能,获取服务人员的accountcode 和 手机号
  121. String feedbackidStr = saveFeedbackDTO.getFeedbackId();
  122. Map<String,String> serviceWorkerMap = utils.partsService.getServiceWorkerInfo(feedbackidStr);//根据异常反馈单id获取对应服务单对应的服务人员信息
  123. if(serviceWorkerMap == null){
  124. log.info("根据异常反馈单id:"+saveFeedbackDTO.getFeedbackId()+"获取到的服务人员信息对象为null");
  125. return;
  126. }
  127. String serviceWorkerMobile = serviceWorkerMap.get("mobile"); //服务人员电话
  128. String serviceWorkerId = serviceWorkerMap.get("id"); //服务人员id
  129. String serviceWorkerName = serviceWorkerMap.get("name"); //服务人员姓名
  130. String feedBackName = serviceWorkerMap.get("feedBackName"); //当前的异常反馈单号
  131. //获取服务人员账号的 accountcode
  132. try {
  133. ResponseWrapper<UserAccount> accountByMobile = utils.accountFeignService.getAccountByMobile(serviceWorkerMobile);
  134. if(accountByMobile == null || accountByMobile.getObj() == null){
  135. log.info("获取远程供应商账号信息异常/返回信息为空");
  136. return;
  137. }
  138. message.setTo(accountByMobile.getObj().getAccountCode());
  139. message.setSubject("供应商反馈意见信息"); //标题不能为空
  140. message.setSummary("您有一条供应商反馈信息,请注意查收");//消息摘要不能为空
  141. message.setContent("异常反馈单号:"+feedBackName+",已由供应商填写反馈信息。供应商意见:"+
  142. SupplierSuggestionEnum.getNameStatic(saveFeedbackDTO.getSuggestion())
  143. +";供应商意见备注:"+saveFeedbackDTO.getSuggestionMemo()); //内容不能为空
  144. ResponseWrapper respon = utils.messageFeignService.addMessage(message);//APP推送给服务人员的账号
  145. if(!respon.isSuccess()){
  146. log.info("异常反馈单号:"+feedBackName+"的信息变更,APP推送服务人员失败");//APP失败
  147. }
  148. } catch (Exception e) {
  149. log.info("异常反馈单号:"+feedBackName+"的信息变更,APP推送服务人员出现异常");//APP异常
  150. }
  151.  
  152. }
  153. }
  154.  
  155. }

===============================================

上述的这个方法,业务上属于消息推送,我决定让他异步执行。使用注解实现。但是一直没有生效,结合文章:
https://blog.csdn.net/qq_34545192/article/details/80484780,主要是因为第三点我没有做到!!!
在@SpringBootApplication启动类 添加注解@EnableAsync
异步方法使用注解@Async ,返回值为void或者Future
切记一点 ,异步方法和调用方法一定要**** 写在不同的类中 ****,如果写在一个类中,是没有效果的

为什么第三点会没有效果,那是因为Spring像@Transcation @Async等这些都是使用了动态代理,由Proxy$对象去调用被增强方法,重点来了:方法里想用增强方法(博主说的第三点)则需要得到当前的Proxy$对象 详情请看 ->Spring的 AopContext.currentProxy()方法

springcloud中servcie层调用fegin异常以及异步方法的实现的更多相关文章

  1. springCloud中的服务调用feign

    springCloud中的服务调用(要在调用端写) 前提进行了服务注册 流程: 1.在服务模块中添加依赖 <!--服务调用--> <dependency> <groupI ...

  2. C# 中 async/await 调用传统 Begin/End 异步方法

    最近在改进园子的图片上传程序,希望实现用户上传图片时同时将图片文件保存在三个地方:1)服务器本地硬盘:2)又拍云:3)阿里云OSS.并且在保存时使用异步操作. 对于异步保存到本地硬盘,只需用 Stea ...

  3. SpringCloud(5)---Feign服务调用

    SpringCloud(5)---Feign服务调用 上一篇写了通过Ribbon进行服务调用,这篇其它都一样,唯一不一样的就是通过Feign进行服务调用. 注册中心和商品微服务不变,和上篇博客一样,具 ...

  4. 非常全面的讲解SpringCloud中Zuul网关原理及其配置,看它就够了!

    Zuul是spring cloud中的微服务网关.网关:是一个网络整体系统中的前置门户入口.请求首先通过网关,进行路径的路由,定位到具体的服务节点上. Zuul是一个微服务网关,首先是一个微服务.也是 ...

  5. MVC003之调用BLL层方法(BLL层调用了WebService)

    项目又BLL类库,在类库中引用了webservice.在web层调用BLL的方法时 错误如下: 在 ServiceModel 客户端配置部分中,找不到引用协定“OAService.IntranetSe ...

  6. SpringCloud项目,接口调用返回http 500 - Internal Server Error的错误

    今天上班的时候,自己正在参与的Spring Cloud项目出现了问题,原本上周五还正常的项目突然所有接口调用都是返回http 500的错误. 项目的状态是在Eureka上可以看到对应微服务是在线状态, ...

  7. servlet层调用biz业务层出现浏览器 500错误,解决方法 dao数据访问层 数据库Util工具类都可能出错 通过新建一个测试类复制代码逐步测试查找出最终出错原因

    package com.swift.jztk.servlet; import java.io.IOException; import javax.servlet.ServletException; i ...

  8. mybatis中存储过程的调用

    dao层 // 调用存储过程 void callProcedureGrantEarnings(@Param("params") Map<String,Object> p ...

  9. SpringCloud 服务间互相调用 @FeignClient注解

    SpringCloud搭建各种微服务之后,服务间通常存在相互调用的需求,SpringCloud提供了@FeignClient 注解非常优雅的解决了这个问题 首先,保证几个服务都在一个Eureka中注册 ...

随机推荐

  1. UI面试题(1)

    1.请创建一个数组对象[@“ad”,@“bc”,@“sdf”,@“yu”],并且对该数组对象进行排序(使用冒泡排序); NSMutableArray *array = [NSMutableArraya ...

  2. html文档树形结构图

  3. viewstate的基本用法

    转自:http://www.cnblogs.com/ooip/p/4743536.html 在web窗体将控件属性设置为runat=server时,这个控件会被添加一个隐藏属性_ViewState,_ ...

  4. 树莓派 Learning 002 装机后的必要操作 --- 05 给树莓派搭建“x86 + pi”环境 -- 安装**32位运行库** -- 解决`E:未发现软件包 xxx` 问题

    树莓派 装机后的必要操作 - 给树莓派搭建"x86 + pi"环境 – 安装32位运行库 – 解决E:未发现软件包 xxx 问题 我的树莓派型号:Raspberry Pi 2 Mo ...

  5. Learning Python 002 print() 和 input()

    Python print() 和 input() print()函数 print()函数可以向终端中输入指定的内容. 输出当个字符串 .py文件中,输入下面的代码,并保存: print('hello ...

  6. cdce62005配置说明

    相关芯片手册可查阅:http://www.ti.com.cn/product/cn/cdce62005 需要使用的软件下载地址:http://www.ti.com.cn/cn/lit/sw/scac1 ...

  7. 学习笔记:首次进行JUnit+Ant构建自动的单元测试(一)

    指导博客:https://blog.csdn.net/Cceking/article/details/51692010 基于软件测试的需求,使用JUnit+Ant构建自动的单元测试. IDE:ecli ...

  8. elasticsearch 基本介绍

    1. Elasticsearch的适用场景: (1)类似百度百科的全文检索,高亮,搜索推荐(2)新闻类的搜索,用户行为日志(点击,浏览,收藏,评论)+社交网络数据(对某某新闻的相关看法),数据分析,给 ...

  9. 洛谷P2474 [SCOI2008]天平

    P2474 [SCOI2008]天平 题目背景 2008四川NOI省选 题目描述 你有n个砝码,均为1克,2克或者3克.你并不清楚每个砝码的重量,但你知道其中一些砝码重量的大小关系.你把其中两个砝码A ...

  10. centos 7.X关闭防火墙和selinux

    一.关闭防火墙 centos从7开始默认用的是firewalld,这个是基于iptables的,虽然有iptables的核心,但是iptables的服务是没安装的. 所以你只要停止firewalld服 ...