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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring事务“套路”面试

發布時間:2024/4/11 javascript 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring事务“套路”面试 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

回復”666“獲取公眾號專屬資料

記一次“帶套路”的面試

//接口 interface?Service?{void?doNeedTx();void?doNotneedTx(); }//目標類,實現接口 class?ServiceImpl?implements?Service?{@Transactional@Overridepublic?void?doNeedTx()?{System.out.println("execute?doNeedTx?in?ServiceImpl");}//no?annotation?here@Overridepublic?void?doNotneedTx()?{this.doNeedTx();} }//代理類,也要實現相同的接口 class?ProxyByJdkDynamic?implements?Service?{//包含目標對象private?Service?target;public?ProxyByJdkDynamic(Service?target)?{this.target?=?target;}//目標類中此方法帶注解,進行特殊處理@Overridepublic?void?doNeedTx()?{//開啟事務System.out.println("->?create?Tx?here?in?Proxy");//調用目標對象的方法,該方法已在事務中了target.doNeedTx();//提交事務System.out.println("<-?commit?Tx?here?in?Proxy");}//目標類中此方法沒有注解,只做簡單的調用@Overridepublic?void?doNotneedTx()?{//直接調用目標對象方法target.doNotneedTx();} }

//是否是JDK動態代理 System.out.println("isJdkDynamicProxy?=>?"?+?AopUtils.isJdkDynamicProxy(exampleService)); //是否是CGLIB代理 System.out.println("isCglibProxy?=>?"?+?AopUtils.isCglibProxy(exampleService)); //代理類的類型 System.out.println("proxyClass?=>?"?+?exampleService.getClass()); //代理類的父類的類型 System.out.println("parentClass?=>?"?+?exampleService.getClass().getSuperclass()); //代理類的父類實現的接口 System.out.println("parentClass's?interfaces?=>?"?+?Arrays.asList(exampleService.getClass().getSuperclass().getInterfaces())); //代理類實現的接口 System.out.println("proxyClass's?interfaces?=>?"?+?Arrays.asList(exampleService.getClass().getInterfaces())); //代理對象 System.out.println("proxy?=>?"?+?exampleService); //目標對象 System.out.println("target?=>?"?+?AopProxyUtils.getSingletonTarget(exampleService)); //代理對象和目標對象是不是同一個 System.out.println("proxy?==?target?=>?"?+?(exampleService?==?AopProxyUtils.getSingletonTarget(exampleService))); //目標類的類型 System.out.println("targetClass?=>?"?+?AopProxyUtils.getSingletonTarget(exampleService).getClass()); //目標類實現的接口 System.out.println("targetClass's?interfaces?=>?"?+?Arrays.asList(AopProxyUtils.getSingletonTarget(exampleService).getClass().getInterfaces()));System.out.println("----------------------------------------------------");//自己模擬的動態代理的測試 Service?target?=?new?ServiceImpl(); ProxyByJdkDynamic?proxy?=?new?ProxyByJdkDynamic(target); proxy.doNeedTx(); System.out.println("-------"); proxy.doNotneedTx(); System.out.println("-------");

以下是輸出結果:

//是JDK動態代理 isJdkDynamicProxy?=>?true //不是CGLIB代理 isCglibProxy?=>?false //代理類的類型,帶$的 proxyClass?=>?class?com.sun.proxy.$Proxy82 //代理類的父類 parentClass?=>?class?java.lang.reflect.Proxy 代理類的父類實現的接口 parentClass's?interfaces?=>?[interface?java.io.Serializable] //代理類實現的接口,包含了目標類的接口IExampleService,還有其它的 proxyClass's?interfaces?=>?[interface?org.eop.sb.example.service.IExampleService, interface?org.springframework.aop.SpringProxy, interface?org.springframework.aop.framework.Advised, interface?org.springframework.core.DecoratingProxy] //代理對象 proxy?=>?org.eop.sb.example.service.impl.ExampleServiceImpl@54561bc9 //目標對象 target?=>?org.eop.sb.example.service.impl.ExampleServiceImpl@54561bc9 //代理對象和目標對象輸出的都是@54561bc9,還真有點懵逼 //進行測試后發現,其實不是同一個,只是toString()的問題 proxy?==?target?=>?false //目標類,我們自己寫的 targetClass?=>?class?org.eop.sb.example.service.impl.ExampleServiceImpl //目標類實現的接口,我們自己寫的 targetClass's?interfaces?=>?[interface?org.eop.sb.example.service.IExampleService] ---------------------------------------------------- //帶注解的方法調用,有事務的開啟和提交 ->?create?Tx?here?in?Proxy execute?doNeedTx?in?ServiceImpl <-?commit?Tx?here?in?Proxy ------- //沒有注解的方法調用,是沒有事務的 execute?doNeedTx?in?ServiceImpl -------

class?Target?{@Transactionalpublic?void?doNeedTx()?{System.out.println("execute?doNeedTx?in?Target");}//no?annotation?herepublic?void?doNotneedTx()?{this.doNeedTx();} }class?ProxyByCGLIB?extends?Target?{private?Target?target;public?ProxyByCGLIB(Target?target)?{this.target?=?target;}@Overridepublic?void?doNeedTx()?{System.out.println("->?create?Tx?in?Proxy");target.doNeedTx();System.out.println("<-?commit?Tx?in?Proxy");}@Overridepublic?void?doNotneedTx()?{target.doNotneedTx();} }

//不是JDK動態代理 isJdkDynamicProxy?=>?false //是CGLIB代理 isCglibProxy?=>?true //生成的代理類的類型,帶$$的 proxyClass?=>?class?org.eop.sb.example.service.impl.ExampleServiceImpl$$EnhancerBySpringCGLIB$$5320b86e //代理類的父類,就是目標類 parentClass?=>?class?org.eop.sb.example.service.impl.ExampleServiceImpl //父類實現的接口,就是我們自己寫的接口 parentClass's?interfaces?=>?[interface?org.eop.sb.example.service.IExampleService] /**代理類實現的接口,并不包含目標類的接口*/ proxyClass's?interfaces?=>?[interface?org.springframework.aop.SpringProxy, interface?org.springframework.aop.framework.Advised, interface?org.springframework.cglib.proxy.Factory] //代理對象 proxy?=>?org.eop.sb.example.service.impl.ExampleServiceImpl@1b2702b1 //目標對象 target?=>?org.eop.sb.example.service.impl.ExampleServiceImpl@1b2702b1 //代理對象和目標對象不是同一個 proxy?==?target?=>?false //目標類,我們自己寫的類 targetClass?=>?class?org.eop.sb.example.service.impl.ExampleServiceImpl //目標類實現的接口 targetClass's?interfaces?=>?[interface?org.eop.sb.example.service.IExampleService]

由于采用的是相同的測試代碼,所以目標類是實現了接口的,不過這并不影響使用CGLIB來生成代理。可見,代理類確實繼承了目標類以保持和目標類的類型兼容,對外接口相同。注:只要是以代理方式實現的聲明式事務,無論是JDK動態代理,還是CGLIB直接寫字節碼生成代理,都只有public方法上的事務注解才起作用。而且必須在代理類外部調用才行,如果直接在目標類里面調用,事務照樣不起作用。

后記

想知道更多?描下面的二維碼關注我


加技術群入口(備注:Tech):

免費星球入口:

免費資料入口:后臺回復“666”

朕已閱?

超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生

總結

以上是生活随笔為你收集整理的Spring事务“套路”面试的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。