關(guān)于spring?aop兩種代理混用的問(wèn)題
spring aop兩種代理混用問(wèn)題
工作繁忙,但是遇到問(wèn)題還是要總結(jié)積累下來(lái),今天項(xiàng)目中出現(xiàn)了代理混用的問(wèn)題,解決之后記錄一下對(duì)兩種代理方式的學(xué)習(xí)理解。
一、首先復(fù)習(xí)一下兩種代理
JDK動(dòng)態(tài)代理 和 cglib代理
1、如果目標(biāo)對(duì)象實(shí)現(xiàn)了接口,默認(rèn)情況下會(huì)采用JDK的動(dòng)態(tài)代理實(shí)現(xiàn)AOP
2、如果目標(biāo)對(duì)象實(shí)現(xiàn)了接口,可以強(qiáng)制使用CGLIB實(shí)現(xiàn)AOP
3、如果目標(biāo)對(duì)象沒(méi)有實(shí)現(xiàn)了接口,必須采用CGLIB庫(kù),spring會(huì)自動(dòng)在JDK動(dòng)態(tài)代理和CGLIB之間轉(zhuǎn)換
Spring AOP的原理是 JDK 動(dòng)態(tài)代理和CGLIB字節(jié)碼增強(qiáng)技術(shù),前者需要被代理類(lèi)實(shí)現(xiàn)相應(yīng)接口,也只有接口中的方法可以被JDK動(dòng)態(tài)代理技術(shù)所處理;后者實(shí)際上是生成一個(gè)子類(lèi),來(lái)覆蓋被代理類(lèi),那么父類(lèi)的final方法就不能代理,因?yàn)楦割?lèi)的final方法不能被子類(lèi)所覆蓋。一般而言Spring默認(rèn)優(yōu)先使用JDK動(dòng)態(tài)代理技術(shù),只有在被代理類(lèi)沒(méi)有實(shí)現(xiàn)接口時(shí),才會(huì)選擇使用CGLIB技術(shù)來(lái)實(shí)現(xiàn)AOP。
但是也提供了配置參數(shù)來(lái)強(qiáng)制選擇使用 CGLIB 技術(shù),如下:
<aop:config proxy-target-class="true" />
proxy-target-class="true" 表示強(qiáng)制使用 CGLIB 技術(shù)來(lái)實(shí)現(xiàn)AOP,因?yàn)镃GLIB是生成子類(lèi)也就是代理類(lèi)來(lái)實(shí)現(xiàn)的,所以proxy-target-class,表示是否代理目標(biāo)類(lèi)。<aop:config /> 就會(huì)由spring來(lái)選擇,spring優(yōu)先使用JDK動(dòng)態(tài)代理來(lái)實(shí)現(xiàn)AOP。
二、我們項(xiàng)目是spring-boot項(xiàng)目
默認(rèn)即為proxy-target-class="true",service實(shí)現(xiàn)類(lèi)使用@service注解后都是使用CGLIB代理。
我遇到問(wèn)題是,service某個(gè)方法添加@Async注解使該方法可異步調(diào)用,然后原有從spring容器中獲取Bean對(duì)象的方法運(yùn)行時(shí)就報(bào)錯(cuò)了,原來(lái)這個(gè)service實(shí)現(xiàn)類(lèi)就不在使用CGLIB而是直接使用JDK動(dòng)態(tài)代理。時(shí)間緊迫,具體原因后續(xù)再次分析,今天的記錄就先到這里。
spring的aop和代理模式理解
Spring的AOP:即面向切面編程,其代碼實(shí)質(zhì),即代理模式的應(yīng)用。
代理模式代碼的主要特點(diǎn)是
不改變?cè)蓄?lèi)的前提下,在原有類(lèi)某些方法執(zhí)行前后,插入任意代碼。所以代理模式需要寫(xiě)新的類(lèi)對(duì)原有的類(lèi)進(jìn)行包裝。
代理模式目前實(shí)現(xiàn)的方式有三種
- 靜態(tài)代理:需要增強(qiáng)原有類(lèi)的哪個(gè)方法,就需要對(duì)在代理類(lèi)中包裝哪個(gè)方法。個(gè)人理解,從功能上來(lái)說(shuō),原有類(lèi)和代理類(lèi)不一定要實(shí)現(xiàn)共同接口,但是為了賦予代理和和被代理類(lèi)之間的邏輯關(guān)系,增加程序的可讀性,可理解性,邏輯性,增加代理對(duì)象和被代理對(duì)象之間的關(guān)系,以更加符合面向?qū)ο缶幊淌撬季S,而應(yīng)該實(shí)現(xiàn)共同接口。
- 動(dòng)態(tài)代理:使用反射機(jī)制,方法和對(duì)象都是傳入的變量,就可以經(jīng)過(guò)傳入的對(duì)象和方法而動(dòng)態(tài)調(diào)用被代理對(duì)象的任何方法,jdk中提供了實(shí)現(xiàn)此動(dòng)態(tài)代理的api,被代理類(lèi)必須實(shí)現(xiàn)接口
- Cglib代理:返回對(duì)象是代理對(duì)象的子類(lèi),不需要代理對(duì)象實(shí)現(xiàn)接口。當(dāng)調(diào)用原對(duì)象方法時(shí),實(shí)際上調(diào)用的是代理子類(lèi)的方法。
Aop的最大意義是
在不改變?cè)瓉?lái)代碼的前提下,也不對(duì)源代碼做任何協(xié)議接口要求。而實(shí)現(xiàn)了類(lèi)似插件的方式,來(lái)修改源代碼,給源代碼插入新的執(zhí)行代碼。
Struts2中的攔截器,spring中的賴(lài)加載都是用代理模式實(shí)現(xiàn)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- Spring中AOP概念與兩種動(dòng)態(tài)代理模式原理詳解
- 解決spring AOP中自身方法調(diào)用無(wú)法應(yīng)用代理的問(wèn)題
- 帶你了解如何使用Spring基于ProxyFactoryBean創(chuàng)建AOP代理
- Spring-AOP @AspectJ進(jìn)階之如何綁定代理對(duì)象
- Spring aop 如何通過(guò)獲取代理對(duì)象實(shí)現(xiàn)事務(wù)切換
- Spring-AOP自動(dòng)創(chuàng)建代理之BeanNameAutoProxyCreator實(shí)例
- Spring AOP 與代理的概念與使用
相關(guān)文章
詳解Java設(shè)計(jì)模式編程中的訪問(wèn)者模式
這篇文章主要介紹了Java設(shè)計(jì)模式編程中的訪問(wèn)者模式,訪問(wèn)者模式的合理利用可以避免項(xiàng)目中出現(xiàn)大量重復(fù)的代碼,需要的朋友可以參考下2016-02-02
使用Java讀取Excel文件數(shù)據(jù)的方法詳解
通過(guò)編程方式讀取Excel數(shù)據(jù)能實(shí)現(xiàn)數(shù)據(jù)導(dǎo)入、批量處理、數(shù)據(jù)比對(duì)和更新等任務(wù)的自動(dòng)化,本文為大家介紹了三種Java讀取Excel文件數(shù)據(jù)的方法,需要的可以參考下2024-01-01
Java AOP實(shí)現(xiàn)自定義滑動(dòng)窗口限流器方法詳解
這篇文章主要介紹了Java AOP實(shí)現(xiàn)自定義滑動(dòng)窗口限流器方法,其中滑動(dòng)窗口算法彌補(bǔ)了計(jì)數(shù)器算法的不足,滑動(dòng)窗口算法把間隔時(shí)間劃分成更小的粒度,當(dāng)更小粒度的時(shí)間間隔過(guò)去后,把過(guò)去的間隔請(qǐng)求數(shù)減掉,再補(bǔ)充一個(gè)空的時(shí)間間隔,需要的朋友可以參考下2022-07-07
SpringBoot前后端接口對(duì)接常見(jiàn)錯(cuò)誤小結(jié)
SpringBoot前后端接口對(duì)接工作時(shí),經(jīng)常遇到請(qǐng)求500,400等問(wèn)題,本文主要介紹了SpringBoot前后端接口對(duì)接常見(jiàn)錯(cuò)誤小結(jié),感興趣的可以了解一下2022-01-01
spring mvc 組合mybatis框架實(shí)例詳解
本項(xiàng)目采用 maven 結(jié)構(gòu),主要演示了 spring mvc + mybatis,controller 獲取數(shù)據(jù)后以json 格式返回?cái)?shù)據(jù)。對(duì)spring mvc 組合mybatis的方法感興趣的朋友可以參考下本文2018-01-01
Spring Boot利用Java Mail實(shí)現(xiàn)郵件發(fā)送
這篇文章主要為大家詳細(xì)介紹了Spring Boot利用Java Mail實(shí)現(xiàn)郵件發(fā)送,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-02-02
java項(xiàng)目導(dǎo)出為.exe執(zhí)行文件的方法步驟
最近做了個(gè)項(xiàng)目,想要轉(zhuǎn)換成可執(zhí)行文件,那么java項(xiàng)目如何導(dǎo)出為.exe執(zhí)行文件,本文就介紹一下,主要使用jar2exe軟件,感興趣的可以了解一下2021-05-05

