日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當(dāng)前位置:首頁(yè) > 科技  > 軟件

@Async注解失效的九種場(chǎng)景

來(lái)源: 責(zé)編: 時(shí)間:2024-05-08 09:23:37 180觀看
導(dǎo)讀前言最近有粉絲問(wèn)了我一個(gè)問(wèn)題:他在項(xiàng)目某個(gè)方法使用@Async注解,但是該方法還是同步執(zhí)行了,異步不起作用,到底是什么原因呢?偽代碼如下:@Slf4j@Servicepublic class UserService { @Async public void async(String v

前言

最近有粉絲問(wèn)了我一個(gè)問(wèn)題:他在項(xiàng)目某個(gè)方法使用@Async注解,但是該方法還是同步執(zhí)行了,異步不起作用,到底是什么原因呢?89728資訊網(wǎng)——每日最新資訊28at.com

偽代碼如下:89728資訊網(wǎng)——每日最新資訊28at.com

@Slf4j@Servicepublic class UserService {    @Async    public void async(String value) {        log.info("async:" + value);    }}

這個(gè)問(wèn)題還是比較有意思的,今天這篇文章總結(jié)了@Async注解失效的9種場(chǎng)景,希望對(duì)你會(huì)有所幫助。89728資訊網(wǎng)——每日最新資訊28at.com

圖片圖片89728資訊網(wǎng)——每日最新資訊28at.com

1 未使用@EnableAsync注解

在Spring中要開(kāi)啟@Async注解異步的功能,需要在項(xiàng)目的啟動(dòng)類,或者配置類上,使用@EnableAsync注解。89728資訊網(wǎng)——每日最新資訊28at.com

例如:89728資訊網(wǎng)——每日最新資訊28at.com

@EnableAsync@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})public class Application {    public static void main(String[] args) {        SpringApplication.run(Application.class, args);    }}

@EnableAsync注解相當(dāng)于一個(gè)開(kāi)關(guān),控制是否開(kāi)啟@Async注解異步的功能,默認(rèn)是關(guān)閉的。89728資訊網(wǎng)——每日最新資訊28at.com

如果在項(xiàng)目的啟動(dòng)類上沒(méi)使用@EnableAsync注解,則@Async注解異步的功能不生效。89728資訊網(wǎng)——每日最新資訊28at.com

2 內(nèi)部方法調(diào)用

我們?cè)谌粘i_(kāi)發(fā)中,經(jīng)常需要在一個(gè)方法中調(diào)用另外一個(gè)方法,例如:89728資訊網(wǎng)——每日最新資訊28at.com

@Slf4j@Servicepublic class UserService {    public void test() {        async("test");    }    @Async    public void async(String value) {        log.info("async:{}", value);    }}

這個(gè)示例中,在UserService類中的test()方法中調(diào)用了async()方法。89728資訊網(wǎng)——每日最新資訊28at.com

如果在controller中@Autowired了UserService類的對(duì)象,調(diào)用了它的test()方法,則async()異步的功能會(huì)失效。89728資訊網(wǎng)——每日最新資訊28at.com

我們知道Spring通過(guò)@Async注解實(shí)現(xiàn)異步的功能,底層其實(shí)是通過(guò)Spring的AOP實(shí)現(xiàn)的,也就是說(shuō)它需要通過(guò)JDK動(dòng)態(tài)代理或者cglib,生成代理對(duì)象。89728資訊網(wǎng)——每日最新資訊28at.com

異步的功能,是在代理對(duì)象中增加的,我們必須調(diào)用代理對(duì)象的test()方法才行。89728資訊網(wǎng)——每日最新資訊28at.com

而在類中直接進(jìn)行方法的內(nèi)部調(diào)用,在test()方法中調(diào)用async()方法,調(diào)用的是該類原對(duì)象的async方法,相當(dāng)于調(diào)用了this.async()方法,而并非UserService代理類的async()方法。89728資訊網(wǎng)——每日最新資訊28at.com

因此,像這種內(nèi)部方法調(diào)用,@Async注解的異步功能會(huì)失效。89728資訊網(wǎng)——每日最新資訊28at.com

3 方法非public

在Java中有4種權(quán)限修飾符89728資訊網(wǎng)——每日最新資訊28at.com

  • public:所有類都可以訪問(wèn)。
  • private:只能同一個(gè)類訪問(wèn)。
  • protected:同一個(gè)類,同一個(gè)包下的其他類,不同包下的子類可以訪問(wèn)。
  • 默認(rèn)修飾符:同一個(gè)類,同一個(gè)包下的其他類可以訪問(wèn)。

在實(shí)際工作中,我們使用頻率最高的可能是public和private了。89728資訊網(wǎng)——每日最新資訊28at.com

如果我在定義Service類中的某個(gè)方法時(shí),有時(shí)把權(quán)限修飾符定義錯(cuò)了,例如:89728資訊網(wǎng)——每日最新資訊28at.com

@Slf4j@Servicepublic class UserService {    @Async    private void async(String value) {        log.info("async:{}", value);    }}

這個(gè)例子中將UserService類的async()方法的權(quán)限修飾符定義成了private的,這樣@Async注解也會(huì)失效。89728資訊網(wǎng)——每日最新資訊28at.com

因?yàn)閜rivate修飾的方法,只能在UserService類的對(duì)象中使用。89728資訊網(wǎng)——每日最新資訊28at.com

而@Async注解的異步功能,需要使用Spring的AOP生成UserService類的代理對(duì)象,該代理對(duì)象沒(méi)法訪問(wèn)UserService類的private方法,因此會(huì)出現(xiàn)@Async注解失效的問(wèn)題。89728資訊網(wǎng)——每日最新資訊28at.com

4 方法返回值錯(cuò)誤

我們?cè)趯懸粋€(gè)新的方法時(shí),經(jīng)常需要定義方法的返回值。89728資訊網(wǎng)——每日最新資訊28at.com

返回值可以是void、int、String、User等等,但如果返回值定義錯(cuò)誤,也可能會(huì)導(dǎo)致@Async注解的異步功能失效。89728資訊網(wǎng)——每日最新資訊28at.com

例如:89728資訊網(wǎng)——每日最新資訊28at.com

@Servicepublic class UserService {    @Async    public String async(String value) {        log.info("async:{}", value);        return value;    }}

UserService類的async方法的返回值是String,這種情況竟然會(huì)導(dǎo)致@Async注解的異步功能失效。89728資訊網(wǎng)——每日最新資訊28at.com

在AsyncExecutionInterceptor類的invoke()方法,會(huì)調(diào)用它的父類AsyncExecutionAspectSupport中的doSubmit方法,該方法時(shí)異步功能的核心代碼,如下:89728資訊網(wǎng)——每日最新資訊28at.com

圖片圖片89728資訊網(wǎng)——每日最新資訊28at.com

從圖中看出,@Async注解的異步方法的返回值,要么是Future,要么是null。89728資訊網(wǎng)——每日最新資訊28at.com

因此,在實(shí)際項(xiàng)目中,如果想要使用@Async注解的異步功能,相關(guān)方法的返回值必須是void或者Future。89728資訊網(wǎng)——每日最新資訊28at.com

5 方法用static修飾了

有時(shí)候,我們的方法會(huì)使用static修飾,這樣在調(diào)用的地方,可以直接使用類名.方法名,訪問(wèn)該方法了。89728資訊網(wǎng)——每日最新資訊28at.com

但如果在@Async方法上加了static修飾符,例如:89728資訊網(wǎng)——每日最新資訊28at.com

@Slf4j@Servicepublic class UserService {    @Async    public static void async(String value) {        log.info("async:{}", value);    }}

這時(shí)@Async的異步功能會(huì)失效,因?yàn)檫@種情況idea會(huì)直接報(bào)錯(cuò):Methods annotated with '@Async' must be overridable 。89728資訊網(wǎng)——每日最新資訊28at.com

使用@Async注解聲明的方法,必須是能被重寫的,很顯然static修飾的方法,是類的靜態(tài)方法,是不允許被重寫的。89728資訊網(wǎng)——每日最新資訊28at.com

因此這種情況下,@Async注解的異步功能會(huì)失效。89728資訊網(wǎng)——每日最新資訊28at.com

6 方法用final修飾

在Java種final關(guān)鍵字,是一個(gè)非常特別的存在。89728資訊網(wǎng)——每日最新資訊28at.com

用final修飾的類,沒(méi)法被繼承。89728資訊網(wǎng)——每日最新資訊28at.com

用final修飾的方法,沒(méi)法被重寫。89728資訊網(wǎng)——每日最新資訊28at.com

用final修飾的變量,沒(méi)法被修改。89728資訊網(wǎng)——每日最新資訊28at.com

如果final使用不當(dāng),也會(huì)導(dǎo)致@Async注解的異步功能失效,例如:89728資訊網(wǎng)——每日最新資訊28at.com

@Slf4j@Servicepublic class UserService {    public void test() {        async("test");    }    @Async    public  final void async(String value) {        log.info("async:{}", value);    }}

這種情況下idea也會(huì)直接報(bào)錯(cuò):Methods annotated with '@Async' must be overridable 。89728資訊網(wǎng)——每日最新資訊28at.com

因?yàn)槭褂胒inal關(guān)鍵字修飾的方法,是沒(méi)法被子類重寫的。89728資訊網(wǎng)——每日最新資訊28at.com

因此這種情況下,@Async注解的異步功能會(huì)失效。89728資訊網(wǎng)——每日最新資訊28at.com

7 業(yè)務(wù)類沒(méi)加@Service注解

有時(shí)候,我們?cè)谛录覵ervice類時(shí),會(huì)忘了加@Service注解,例如:89728資訊網(wǎng)——每日最新資訊28at.com

@Slf4j//@Servicepublic class UserService {    @Async    public void async(String value) {        log.info("async:{}", value);    }}@Servicepublic class TestService {   @Autowired   private UserService userService;    public void test() {        userService.async("test");    }}

這種情況下,@Async注解異步的功能也不會(huì)生效。因?yàn)閁serService類沒(méi)有使用@Service、@Component或者@Controller等注解聲明,該類不會(huì)被Spring管理,因此也就無(wú)法使用Spring的異步功能。89728資訊網(wǎng)——每日最新資訊28at.com

8 自己new的對(duì)象

在項(xiàng)目中,我們經(jīng)常需要new一個(gè)對(duì)象,然后對(duì)他賦值,或者調(diào)用它的方法。89728資訊網(wǎng)——每日最新資訊28at.com

但如果new了一個(gè)Service類的對(duì)象,可能會(huì)出現(xiàn)一些意想不到的問(wèn)題,例如:89728資訊網(wǎng)——每日最新資訊28at.com

@Slf4j@Servicepublic class UserService {    @Async    public void async(String value) {        log.info("async:{}", value);    }}@Servicepublic class TestService {    public void test() {        UserService userService = new UserService();        userService.async("test");    }}

在TestService類的test()方法中,new了一個(gè)UserService類的對(duì)象,然后調(diào)用該對(duì)象的async()方法。89728資訊網(wǎng)——每日最新資訊28at.com

很顯然這種情況下,async()方法只能同步執(zhí)行,沒(méi)法異步執(zhí)行。89728資訊網(wǎng)——每日最新資訊28at.com

因?yàn)樵陧?xiàng)目中,我們自己new的對(duì)象,不會(huì)被Spring管理,因此也就無(wú)法使用Spring的異步功能。89728資訊網(wǎng)——每日最新資訊28at.com

不過(guò)我們可以通過(guò)BeanPostProcessor類,將創(chuàng)建的對(duì)象手動(dòng)注入到Spring容器中。89728資訊網(wǎng)——每日最新資訊28at.com

9 Spring無(wú)法掃描異步類

我們?cè)赟pring項(xiàng)目中可以使用@ComponentScan注解指定項(xiàng)目中掃描的包路徑,例如:89728資訊網(wǎng)——每日最新資訊28at.com

@ComponentScan({"com.susan.demo.service1"})@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})public class Application {    public static void main(String[] args) {        SpringApplication.run(Application.class, args);    }}

項(xiàng)目中com.susan.demo.service1這個(gè)路徑是不存在的,會(huì)導(dǎo)致@Async注解異步的功能失效。89728資訊網(wǎng)——每日最新資訊28at.com

同時(shí)如果@ComponentScan注解定義的路徑,沒(méi)有包含你新加的Servcie類的路徑,@Async注解異步的功能也會(huì)失效。89728資訊網(wǎng)——每日最新資訊28at.com

好了,今天的文章內(nèi)容先到這里。89728資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-87270-0.html@Async注解失效的九種場(chǎng)景

聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com

上一篇: 從輸入 Url 到頁(yè)面渲染的不同階段給出優(yōu)化建議

下一篇: 京東:今年 618 大促活動(dòng) 5 月 31 日現(xiàn)貨開(kāi)售

標(biāo)簽:
  • 熱門焦點(diǎn)
Top 主站蜘蛛池模板: 苏尼特左旗| 横山县| 平乐县| 进贤县| 阿拉善右旗| 阿拉善盟| 霞浦县| 固安县| 汉川市| 阿合奇县| 沛县| 枣强县| 肃宁县| 淳安县| 大港区| 泰州市| 昌平区| 南丹县| 大埔县| 浪卡子县| 西乌| 寿宁县| 龙井市| 梅州市| 芒康县| 盱眙县| 泾阳县| 黄梅县| 阿尔山市| 清苑县| 化德县| 西乌珠穆沁旗| 桃江县| 河间市| 龙川县| 万荣县| 威宁| 禹州市| 泉州市| 高碑店市| 中超|