日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 前端技术 > javascript >内容正文

javascript

@transactional注解_为啥同一个类中普通方法调用Spring注解方法,注解会失效?看完你就明白,So easy!...

發(fā)布時(shí)間:2023/12/19 javascript 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 @transactional注解_为啥同一个类中普通方法调用Spring注解方法,注解会失效?看完你就明白,So easy!... 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Spring注解(如@Transactional、@Cacheable、@Async等),在使用不當(dāng)時(shí),很可能會(huì)失效。失效的情況有很多種,本文我們就來(lái)瞅瞅,為啥同一個(gè)類中普通方法調(diào)用Spring注解方法,注解會(huì)失效呢?

有一些同學(xué)可能不知道其中原由,別急,讓我來(lái)為大家揭曉答案。

聽(tīng)說(shuō)你很懂源碼?Spring讀懂了?還有這20道源碼面試題接得住嗎??zhuanlan.zhihu.com

Spring在掃描bean的時(shí)候,如果掃描到方法上有這些注解,那么spring會(huì)通過(guò)動(dòng)態(tài)代理模式,為這個(gè)bean動(dòng)態(tài)地生成一個(gè)代理類,在代理類中,會(huì)對(duì)有注解的這個(gè)方法,做一些增強(qiáng)處理,如給有@Transactional注解的方法開(kāi)啟transaction。

當(dāng)我們想要調(diào)用這個(gè)方法時(shí),實(shí)際上是先調(diào)用了代理對(duì)象中被增強(qiáng)的方法,然后在代理對(duì)象中,又會(huì)調(diào)用我們實(shí)際的目標(biāo)對(duì)象中的方法。在通過(guò)代理對(duì)象中轉(zhuǎn)的這一過(guò)程中,像上邊說(shuō)的開(kāi)啟和提交transaction就實(shí)現(xiàn)了。

實(shí)現(xiàn)機(jī)制我們大體知道了,下面我們用代碼來(lái)模擬演示一下。

假設(shè)我們訂單業(yè)務(wù)處理類中,有兩個(gè)方法:校驗(yàn)訂單參數(shù)方法verifyOrderParameters() 和 保存訂單方法saveOrder(),其中saveOrder方法上加了@Transactional注解,verifyOrderParameters方法內(nèi)會(huì)調(diào)用saveOrder方法。

OrderService

/*** 訂單業(yè)務(wù)層的接口定義*/ public interface OrderService {/*** 校驗(yàn)訂單參數(shù)*/void verifyOrderParameters();/*** 保存訂單*/void saveOrder(); }

OrderServiceImpl

/*** 訂單業(yè)務(wù)層的具體處理類*/ public class OrderServiceImpl implements OrderService{@Overridepublic void verifyOrderParameters() {System.out.println("校驗(yàn)訂單參數(shù)");// 調(diào)用保存訂單方法saveOrder();}@Override@Transactionalpublic void saveOrder() {System.out.println("保存訂單信息到DB");} }

我們用偽代碼來(lái)演示一下Spring動(dòng)態(tài)代理生成的代理類。

OrderServiceImplProxy

/*** 訂單業(yè)務(wù)層具體處理類的代理類*/ public class OrderServiceImplProxy implements OrderService{/*** 持有被代理的具體的目標(biāo)對(duì)象*/private OrderServiceImpl orderServiceImpl;public OrderServiceImplProxy(OrderServiceImpl orderServiceImpl) {this.orderServiceImpl = orderServiceImpl;}@Overridepublic void verifyOrderParameters() {orderServiceImpl.verifyOrderParameters();}@Overridepublic void saveOrder() {System.out.println("開(kāi)啟事務(wù)。。。");orderServiceImpl.saveOrder();System.out.println("提交事務(wù)。。。");} }

邊我們來(lái)看下客戶端調(diào)用saveOrder方法和verifyOrderParameters方法,輸出結(jié)果都是什么樣的。

public class Client {public static void main(String[] args) {// 創(chuàng)建一個(gè)訂單業(yè)務(wù)的真實(shí)處理對(duì)象OrderServiceImpl orderServiceImpl = new OrderServiceImpl();// 創(chuàng)建一個(gè)代理對(duì)象OrderServiceImplProxy orderServiceImplProxy = new OrderServiceImplProxy(orderServiceImpl);// 執(zhí)行代理對(duì)象的校驗(yàn)訂單方法orderServiceImplProxy.verifyOrderParameters();System.out.println("--------------------------------------------");// 執(zhí)行代理對(duì)象的保存訂單方法orderServiceImplProxy.saveOrder();} }

執(zhí)行main方法后,得到下邊的輸出:

校驗(yàn)訂單參數(shù)
保存訂單信息到DB
--------------------------------------------
開(kāi)啟事務(wù)。。。
保存訂單信息到DB
提交事務(wù)。。。

通過(guò)這個(gè)演示代碼,想必同學(xué)們已經(jīng)了解了吧,普通方法verifyOrderParameters內(nèi)調(diào)用注解方法saveOrder時(shí),其實(shí)調(diào)用的是原目標(biāo)對(duì)象(orderServiceImpl)的saveOrder方法,沒(méi)有走代理對(duì)象(orderServiceImplProxy)中被增強(qiáng)的saveOrder方法,所以就不會(huì)產(chǎn)生效果啦。

動(dòng)態(tài)代理是實(shí)現(xiàn)Spring AOP的一個(gè)重要手段,所以大家以后再用注解以及切面時(shí),一定要注意這個(gè)坑噢。

作者:曉呆同學(xué)
原文鏈接:https://blog.csdn.net/daidaineteasy/article/details/105981724

總結(jié)

以上是生活随笔為你收集整理的@transactional注解_为啥同一个类中普通方法调用Spring注解方法,注解会失效?看完你就明白,So easy!...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。