近日在做业务上的短信推送和APP消息推送,通过调用别的模块的接口来实现,在springcloud中通过fegin进行调用。这里要说明的事情并不是如何开发推送功能,而是在调试过程中碰到的一些小问题。
我把消息推送之前的业务处理代码以及调用推送服务的代码都放在方法pushByAppAndShortMessage()中,然后把这个方法单独的放在crmservice里面。由于业务处理,pushByAppAndShortMessage中需要用到别的service,就不得不在crmservice中进行大量的autowired。代码如下:
package cn.appliedata.operate.service; import java.util.List; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import cn.appliedata.common.ResponseWrapper; import cn.appliedata.message.Message; import cn.appliedata.message.Message.Type; import cn.appliedata.model.account.UserAccount; import cn.appliedata.operate.bean.Supplieres; import cn.appliedata.operate.bean.crmFlow.SaveFeedbackDTO; import cn.appliedata.operate.enums.SupplierSuggestionEnum; import cn.appliedata.operate.feignClient.AccountFeignService; import cn.appliedata.operate.feignClient.MessageFeignService; import cn.appliedata.operate.feignClient.SmsCodeFeignService; import cn.appliedata.operate.mapper.crm.PartsDao; import cn.appliedata.operate.mapper.operate.OperateTaichiDao; import cn.appliedata.operate.util.ConstantUtil; import lombok.extern.slf4j.Slf4j; /** * @author :ayfei */ @Service @Slf4j public class CrmService { @Autowired private MessageFeignService messageFeignService; @Autowired private SmsCodeFeignService smsCodeFeignService; @Autowired private AccountFeignService accountFeignService; @Autowired private StocksiteService stocksiteService; @Autowired private PartsService partsService; /* * 消息推送[APP、短信] */ @Async public void pushByAppAndShortMessage(Integer i,Integer senderFlag,SaveFeedbackDTO saveFeedbackDTO){ log.info("log推送1:索引index = "+i); Message message = new Message(); // 创建APP推送消息体 message.setType(Type.ORDER); // 消息类型不能为空 if(senderFlag == ConstantUtil.INTNUM1){ // 1 服务人员 发送,推送给 供应商 log.info("log推送:推送给供应商"); //有新增、有修改,获取供应商的 accountcode 和 手机号 String type = ""; String feedBackName = "";//异常反馈单号 if(saveFeedbackDTO.getType() == ConstantUtil.INTNUM1){ type = "新增"; message.setContent("您有一条"+type+"异常反馈单待处理,请前往工具->运维反馈进行处理"); //内容不能为空 }else if(saveFeedbackDTO.getType() == ConstantUtil.INTNUM2){ type = "更新"; Map<String,String> serviceWorkerMap = partsService.getServiceWorkerInfo(saveFeedbackDTO.getFeedbackId()); feedBackName = serviceWorkerMap.get("feedBackName"); //当前的异常反馈单号 message.setContent("您有一条"+type+"异常反馈单待处理,异常反馈单号:"+feedBackName+",请前往工具->运维反馈进行处理"); //内容不能为空 } //根据供应商id获取责任人id和电话 String ownerId = null; String ownerPhone = null; List<Supplieres> supplierSelect = stocksiteService.supplierSelect(null, null, saveFeedbackDTO.getSupplierId()); if(supplierSelect == null || supplierSelect.get(0) == null){ log.info("根据供应商id获取责任人信息为空"); return; }else{ ownerId = supplierSelect.get(0).getOwnerId(); ownerPhone = supplierSelect.get(0).getNewSupplierCall(); } if(ownerPhone != null){ try { //短信推送供应商 String shortMessage = "您有一条"+type+"异常反馈单:"+feedBackName+"待处理,请登录APP前往工具->运维反馈进行处理。"; //ResponseWrapper sendArbitrarilyMsg = smsCodeFeignService.sendArbitrarilyMsg(ownerPhone, "", shortMessage);//给服务人员发送短信 ResponseWrapper sendArbitrarilyMsg = smsCodeFeignService.sendArbitrarilyMsg("18337117299", "", shortMessage);//给服务人员发送短信 if(!sendArbitrarilyMsg.isSuccess()){ log.info("异常反馈单号:"+feedBackName+"的消息短信推送供应商失败");//短信发送失败 } } catch (Exception e) { log.info("异常反馈单号:"+feedBackName+"的消息短信推送供应商出现异常"); } try { //APP推送供应商 获取供应商账号的 accountcode ResponseWrapper<UserAccount> accountByMobile = accountFeignService.getAccountByMobile(ownerPhone); if(accountByMobile == null || accountByMobile.getObj() == null){ log.info("获取远程供应商账号信息异常/返回信息为空"); return; } message.setTo(accountByMobile.getObj().getAccountCode()); // message.setSubject(type+"异常反馈单信息"); //标题不能为空 message.setSummary("您有一条"+type+"异常反馈单信息,注意查收");//消息摘要不能为空 ResponseWrapper respon = messageFeignService.addMessage(message); //APP推送给供应商的账号 if(!respon.isSuccess()){ log.info("异常反馈单新增、修改信息,APP推送供应商失败");//APP失败 } } catch (Exception e) { log.info("异常反馈单新增、修改信息,APP推送供应商出现异常"); } }else{ log.info("供应商电话为null!,无法推送"); } }else if(senderFlag == ConstantUtil.INTNUM2){ //2 供应商 发送, 推送给 服务人员 log.info("log推送:推送给服务人员"); //只有修改功能,获取服务人员的accountcode 和 手机号 String feedbackidStr = saveFeedbackDTO.getFeedbackId(); Map<String,String> serviceWorkerMap = partsService.getServiceWorkerInfo(feedbackidStr);//根据异常反馈单id获取对应服务单对应的服务人员信息 if(serviceWorkerMap == null){ log.info("根据异常反馈单id:"+saveFeedbackDTO.getFeedbackId()+"获取到的服务人员信息对象为null"); return; } String serviceWorkerMobile = serviceWorkerMap.get("mobile"); //服务人员电话 String serviceWorkerId = serviceWorkerMap.get("id"); //服务人员id String serviceWorkerName = serviceWorkerMap.get("name"); //服务人员姓名 String feedBackName = serviceWorkerMap.get("feedBackName"); //当前的异常反馈单号 //获取服务人员账号的 accountcode try { ResponseWrapper<UserAccount> accountByMobile = accountFeignService.getAccountByMobile(serviceWorkerMobile); if(accountByMobile == null || accountByMobile.getObj() == null){ log.info("获取远程供应商账号信息异常/返回信息为空"); return; } message.setTo(accountByMobile.getObj().getAccountCode()); message.setSubject("供应商反馈意见信息"); //标题不能为空 message.setSummary("您有一条供应商反馈信息,请注意查收");//消息摘要不能为空 message.setContent("异常反馈单号:"+feedBackName+",已由供应商填写反馈信息。供应商意见:"+ SupplierSuggestionEnum.getNameStatic(saveFeedbackDTO.getSuggestion()) +";供应商意见备注:"+saveFeedbackDTO.getSuggestionMemo()); //内容不能为空 ResponseWrapper respon = messageFeignService.addMessage(message);//APP推送给服务人员的账号 if(!respon.isSuccess()){ log.info("异常反馈单号:"+feedBackName+"的信息变更,APP推送服务人员失败");//APP失败 } } catch (Exception e) { log.info("异常反馈单号:"+feedBackName+"的信息变更,APP推送服务人员出现异常");//APP失败 } } } }
然后再controller中进行调用crmservice的pushByAppAndShortMessage()方法的时候,出现如下异常:
2019-01-10 13:29:34,762 ERROR (FeignClientsHeadersTransfer.java:60)- headers复制出错! 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. at org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes(RequestContextHolder.java:131) at cn.appliedata.feign.FeignClientsHeadersTransfer.lambda$requestInterceptor$0(FeignClientsHeadersTransfer.java:26) at feign.SynchronousMethodHandler.targetRequest(SynchronousMethodHandler.java:158) at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:88) at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:76) at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:103) at com.sun.proxy.$Proxy141.addMessage(Unknown Source) at cn.appliedata.operate.service.CrmService.pushByAppAndShortMessage(CrmService.java:97) at cn.appliedata.operate.service.CrmService$$FastClassBySpringCGLIB$$7d315874.invoke(<generated>) at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:85) at org.springframework.cloud.sleuth.instrument.async.TraceAsyncAspect.traceBackgroundThread(TraceAsyncAspect.java:69) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:627) at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:616) at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.aop.interceptor.AsyncExecutionInterceptor$1.call(AsyncExecutionInterceptor.java:115) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at org.springframework.cloud.sleuth.instrument.async.SpanContinuingTraceRunnable.run(SpanContinuingTraceRunnable.java:52) at java.lang.Thread.run(Thread.java:748) 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 2019-01-10 13:29:34,786 INFO (AutowiredAnnotationBeanPostProcessor.java:155)- JSR-330 'javax.inject.Inject' annotation found and supported for autowiring 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 2019-01-10 13:29:34,804 INFO (ShutdownEnabledTimer.java:58)- Shutdown hook installed for: NFLoadBalancer-PingTimer-service-message 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 2019-01-10 13:29:34,805 INFO (DynamicServerListLoadBalancer.java:222)- Using serverListUpdater PollingServerListUpdater 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 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)'. java.lang.RuntimeException: com.netflix.client.ClientException: Load balancer does not have available server for client: service-message at org.springframework.cloud.netflix.feign.ribbon.LoadBalancerFeignClient.execute(LoadBalancerFeignClient.java:71) at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:97) at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:76) at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:103) at com.sun.proxy.$Proxy141.addMessage(Unknown Source) at cn.appliedata.operate.service.CrmService.pushByAppAndShortMessage(CrmService.java:97) at cn.appliedata.operate.service.CrmService$$FastClassBySpringCGLIB$$7d315874.invoke(<generated>) at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:85) at org.springframework.cloud.sleuth.instrument.async.TraceAsyncAspect.traceBackgroundThread(TraceAsyncAspect.java:69) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:627) at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:616) at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.aop.interceptor.AsyncExecutionInterceptor$1.call(AsyncExecutionInterceptor.java:115) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at org.springframework.cloud.sleuth.instrument.async.SpanContinuingTraceRunnable.run(SpanContinuingTraceRunnable.java:52) at java.lang.Thread.run(Thread.java:748) Caused by: com.netflix.client.ClientException: Load balancer does not have available server for client: service-message at com.netflix.loadbalancer.LoadBalancerContext.getServerFromLoadBalancer(LoadBalancerContext.java:483) at com.netflix.loadbalancer.reactive.LoadBalancerCommand$1.call(LoadBalancerCommand.java:184) at com.netflix.loadbalancer.reactive.LoadBalancerCommand$1.call(LoadBalancerCommand.java:180) at rx.Observable.unsafeSubscribe(Observable.java:10151) at rx.internal.operators.OnSubscribeConcatMap.call(OnSubscribeConcatMap.java:94) at rx.internal.operators.OnSubscribeConcatMap.call(OnSubscribeConcatMap.java:42) at rx.Observable.unsafeSubscribe(Observable.java:10151) at rx.internal.operators.OperatorRetryWithPredicate$SourceSubscriber$1.call(OperatorRetryWithPredicate.java:127) at rx.internal.schedulers.TrampolineScheduler$InnerCurrentThreadScheduler.enqueue(TrampolineScheduler.java:73) at rx.internal.schedulers.TrampolineScheduler$InnerCurrentThreadScheduler.schedule(TrampolineScheduler.java:52) at rx.internal.operators.OperatorRetryWithPredicate$SourceSubscriber.onNext(OperatorRetryWithPredicate.java:79) at rx.internal.operators.OperatorRetryWithPredicate$SourceSubscriber.onNext(OperatorRetryWithPredicate.java:45) at rx.internal.util.ScalarSynchronousObservable$WeakSingleProducer.request(ScalarSynchronousObservable.java:276) at rx.Subscriber.setProducer(Subscriber.java:209) at rx.internal.util.ScalarSynchronousObservable$JustOnSubscribe.call(ScalarSynchronousObservable.java:138) at rx.internal.util.ScalarSynchronousObservable$JustOnSubscribe.call(ScalarSynchronousObservable.java:129) at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48) at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30) at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48) at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30) at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48) at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30) at rx.Observable.subscribe(Observable.java:10247) at rx.Observable.subscribe(Observable.java:10214) at rx.observables.BlockingObservable.blockForSingle(BlockingObservable.java:444) at rx.observables.BlockingObservable.single(BlockingObservable.java:341) at com.netflix.client.AbstractLoadBalancerAwareClient.executeWithLoadBalancer(AbstractLoadBalancerAwareClient.java:112) at org.springframework.cloud.netflix.feign.ribbon.LoadBalancerFeignClient.execute(LoadBalancerFeignClient.java:63) ... 25 common frames omitted 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 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中调用工具类中此方法,得以实现。正常运行。
package cn.appliedata.operate.util; import java.util.List; import java.util.Map; import javax.annotation.PostConstruct; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; import cn.appliedata.common.ResponseWrapper; import cn.appliedata.message.Message; import cn.appliedata.message.Message.Type; import cn.appliedata.model.account.UserAccount; import cn.appliedata.operate.bean.Supplieres; import cn.appliedata.operate.bean.crmFlow.SaveFeedbackDTO; import cn.appliedata.operate.enums.SupplierSuggestionEnum; import cn.appliedata.operate.feignClient.AccountFeignService; import cn.appliedata.operate.feignClient.MessageFeignService; import cn.appliedata.operate.feignClient.SmsCodeFeignService; import cn.appliedata.operate.service.PartsService; import cn.appliedata.operate.service.StocksiteService; import lombok.extern.slf4j.Slf4j; /** * @author :ayfei * @createTime :2019年1月10日下午2:31:41 * @description : */ @Slf4j @Component public class PushByAppAndShortMessageUtil { @Autowired private MessageFeignService messageFeignService; @Autowired private SmsCodeFeignService smsCodeFeignService; @Autowired private AccountFeignService accountFeignService; @Autowired private StocksiteService stocksiteService; @Autowired private PartsService partsService; private static PushByAppAndShortMessageUtil utils ; @PostConstruct //关键二 通过@PostConstruct 和 @PreDestroy 方法 实现初始化和销毁bean之前进行的操作 public void init() { utils = this; utils.messageFeignService = this.messageFeignService; // 初使化时将已静态化的messageFeignService实例化 utils.smsCodeFeignService = this.smsCodeFeignService; utils.accountFeignService = this.accountFeignService; utils.stocksiteService = this.stocksiteService; utils.partsService = this.partsService; } /* * 消息推送[APP、短信] */ @Async public static void pushByAppAndShortMessage(Integer i,Integer senderFlag,SaveFeedbackDTO saveFeedbackDTO){ log.info("log推送1:索引index = "+i); Message message = new Message(); // 创建APP推送消息体 message.setType(Type.ORDER); // 消息类型不能为空 if(senderFlag == ConstantUtil.INTNUM1){ // 1 服务人员 发送,推送给 供应商 log.info("log推送:推送给供应商"); //有新增、有修改,获取供应商的 accountcode 和 手机号 String type = ""; String feedBackName = "";//异常反馈单号 if(saveFeedbackDTO.getType() == ConstantUtil.INTNUM1){ type = "新增"; message.setContent("您有一条"+type+"异常反馈单待处理,请前往工具->运维反馈进行处理"); //内容不能为空 }else if(saveFeedbackDTO.getType() == ConstantUtil.INTNUM2){ type = "更新"; Map<String,String> serviceWorkerMap = utils.partsService.getServiceWorkerInfo(saveFeedbackDTO.getFeedbackId()); feedBackName = serviceWorkerMap.get("feedBackName"); //当前的异常反馈单号 message.setContent("您有一条"+type+"异常反馈单待处理,异常反馈单号:"+feedBackName+",请前往工具->运维反馈进行处理"); //内容不能为空 } //根据供应商id获取责任人id和电话 String ownerId = null; String ownerPhone = null; List<Supplieres> supplierSelect = utils.stocksiteService.supplierSelect(null, null, saveFeedbackDTO.getSupplierId()); if(supplierSelect == null || supplierSelect.get(0) == null){ log.info("根据供应商id获取责任人信息为空"); return; }else{ ownerId = supplierSelect.get(0).getOwnerId(); ownerPhone = supplierSelect.get(0).getNewSupplierCall(); } if(ownerPhone != null){ try { //短信推送供应商 String shortMessage = "您有一条"+type+"异常反馈单:"+feedBackName+"待处理,请登录APP前往工具->运维反馈进行处理。"; //ResponseWrapper sendArbitrarilyMsg = utils.sendArbitrarilyMsg(ownerPhone, "", shortMessage);//给服务人员发送短信 ResponseWrapper sendArbitrarilyMsg = utils.smsCodeFeignService.sendArbitrarilyMsg("18337117299", "", shortMessage);//给服务人员发送短信 if(!sendArbitrarilyMsg.isSuccess()){ log.info("异常反馈单号:"+feedBackName+"的消息短信推送供应商失败");//短信发送失败 } } catch (Exception e) { log.info("异常反馈单号:"+feedBackName+"的消息短信推送供应商出现异常"); } try { //APP推送供应商 获取供应商账号的 accountcode ResponseWrapper<UserAccount> accountByMobile = utils.accountFeignService.getAccountByMobile(ownerPhone); if(accountByMobile == null || accountByMobile.getObj() == null){ log.info("获取远程供应商账号信息异常/返回信息为空"); return; } message.setTo(accountByMobile.getObj().getAccountCode()); // message.setSubject(type+"异常反馈单信息"); //标题不能为空 message.setSummary("您有一条"+type+"异常反馈单信息,注意查收");//消息摘要不能为空 ResponseWrapper respon = utils.messageFeignService.addMessage(message); //APP推送给供应商的账号 if(!respon.isSuccess()){ log.info("异常反馈单新增、修改信息,APP推送供应商失败");//APP失败 } } catch (Exception e) { log.info("异常反馈单新增、修改信息,APP推送供应商出现异常");//APP异常 } }else{ log.info("供应商电话为null!,无法推送"); } }else if(senderFlag == ConstantUtil.INTNUM2){ //2 供应商 发送, 推送给 服务人员 log.info("log推送:推送给服务人员"); //只有修改功能,获取服务人员的accountcode 和 手机号 String feedbackidStr = saveFeedbackDTO.getFeedbackId(); Map<String,String> serviceWorkerMap = utils.partsService.getServiceWorkerInfo(feedbackidStr);//根据异常反馈单id获取对应服务单对应的服务人员信息 if(serviceWorkerMap == null){ log.info("根据异常反馈单id:"+saveFeedbackDTO.getFeedbackId()+"获取到的服务人员信息对象为null"); return; } String serviceWorkerMobile = serviceWorkerMap.get("mobile"); //服务人员电话 String serviceWorkerId = serviceWorkerMap.get("id"); //服务人员id String serviceWorkerName = serviceWorkerMap.get("name"); //服务人员姓名 String feedBackName = serviceWorkerMap.get("feedBackName"); //当前的异常反馈单号 //获取服务人员账号的 accountcode try { ResponseWrapper<UserAccount> accountByMobile = utils.accountFeignService.getAccountByMobile(serviceWorkerMobile); if(accountByMobile == null || accountByMobile.getObj() == null){ log.info("获取远程供应商账号信息异常/返回信息为空"); return; } message.setTo(accountByMobile.getObj().getAccountCode()); message.setSubject("供应商反馈意见信息"); //标题不能为空 message.setSummary("您有一条供应商反馈信息,请注意查收");//消息摘要不能为空 message.setContent("异常反馈单号:"+feedBackName+",已由供应商填写反馈信息。供应商意见:"+ SupplierSuggestionEnum.getNameStatic(saveFeedbackDTO.getSuggestion()) +";供应商意见备注:"+saveFeedbackDTO.getSuggestionMemo()); //内容不能为空 ResponseWrapper respon = utils.messageFeignService.addMessage(message);//APP推送给服务人员的账号 if(!respon.isSuccess()){ log.info("异常反馈单号:"+feedBackName+"的信息变更,APP推送服务人员失败");//APP失败 } } catch (Exception e) { log.info("异常反馈单号:"+feedBackName+"的信息变更,APP推送服务人员出现异常");//APP异常 } } } }
===============================================
上述的这个方法,业务上属于消息推送,我决定让他异步执行。使用注解实现。但是一直没有生效,结合文章:
https://blog.****.net/qq_34545192/article/details/80484780,主要是因为第三点我没有做到!!!
在@SpringBootApplication启动类 添加注解@EnableAsync
异步方法使用注解@Async ,返回值为void或者Future
切记一点 ,异步方法和调用方法一定要**** 写在不同的类中 ****,如果写在一个类中,是没有效果的
为什么第三点会没有效果,那是因为Spring像@Transcation @Async等这些都是使用了动态代理,由Proxy$对象去调用被增强方法,重点来了:方法里想用增强方法(博主说的第三点)则需要得到当前的Proxy$对象 详情请看 ->Spring的 AopContext.currentProxy()方法