悟道子
2023-12-19 11:40:43
记一次SpringMVC异步请求@Async失效问题
1、问题背景
项目是SpringMVC老项目,网站部分表单提交时间卡慢,4s左右,分段日志时间定为发现其中有3s多是花在了调用发送邮件微服务上,而这段逻辑是异步调用,也就是说异步调用@Async失效。
2、问题分析
(1)、代码中已引入task相关配置
xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd
<task:annotation-driven executor="asyncExecutor" scheduler="scheduler"/> <!-- 支持 @Async 注解 --> <task:executor id="asyncExecutor" pool-size="100-10000" queue-capacity="10"/>
<!-- 自动扫描的包名 --> <context:component-scan base-package="com.gstarcad"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" /> </context:component-scan>
(2)、异步方法和调用类也没有在一个方法中,最后发现注解扫描时,出现了重复实例化,加载两个xml存在覆盖问题,@Async就失效了。
在app-resource.xml中扫描了一次,如上配置
加载app-mvc.xml时又扫了整个包
<context:component-scan base-package="com.gstarcad.website"/>
调整为
<context:component-scan base-package="com.gstarcad.website" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" /> </context:component-scan>
异步调用生效。
<context:component-scan> 有个属性use-default-filters它的默认值为true,会扫描指定包下的全部的标有@Component的类,并注册成bean。Use-default-filter此时为true那么会对base-package包或者子包下的所有的进行Java类进行扫描,并把@Component的类的java类注册成bean,所以还是不能避免异步方法所在类被重复扫描。
如果需要指定一些包扫描,一些包不扫描,则需要修改Use-dafault-filter的默认值。
Use-dafault-filters=”false”的情况下:<context:exclude-filter>指定的不扫描,<context:include-filter>指定的扫描。
3、结论
避免@Async失效
(1)、异步方法和调用类不能在同一个方法中;
(2)、注解扫描时,要注意过滤,避免重复实例化,覆盖问题。
评论
最近浏览
wx123456wx LV2
7月14日
浙江螃蟹 LV7
7月10日
214liujianchen LV4
6月17日
小鱼aaaaaA
6月8日
暂无贡献等级
jun LV12
5月9日
AaronDjc LV3
2024年10月5日
youwuzuichen LV11
2024年9月14日
Ckxlnd LV13
2024年8月5日
zdmxjxj LV11
2024年7月20日
CrystalQ LV8
2024年7月16日




