與AspectJ的靜態(tài)代理不同信粮,Spring AOP使用的動態(tài)代理搀菩,所謂的動態(tài)代理就是說AOP框架不會去修改字節(jié)碼缕题,而是在內(nèi)存中臨時為方法生成一個AOP對象摄狱,這個AOP對象包含了目標(biāo)對象的全部方法,并且在特定的切點(diǎn)做了增強(qiáng)處理摇肌,并回調(diào)原對象的方法擂红。
Spring AOP中的動態(tài)代理主要有兩種方式,JDK動態(tài)代理和CGLIB動態(tài)代理。JDK動態(tài)代理通過反射來接收被代理的類昵骤,并且要求被代理的類必須實(shí)現(xiàn)一個接口树碱。JDK動態(tài)代理的核心是InvocationHandler接口和Proxy類。
如果目標(biāo)類沒有實(shí)現(xiàn)接口变秦,那么Spring AOP會選擇使用CGLIB來動態(tài)代理目標(biāo)類成榜。CGLIB(Code Generation Library),是一個代碼生成的類庫蹦玫,可以在運(yùn)行時動態(tài)的生成某個類的子類赎婚,注意,CGLIB是通過繼承的方式做的動態(tài)代理樱溉,因此如果某個類被標(biāo)記為final挣输,那么它是無法使用CGLIB做動態(tài)代理的。
<aop:aspectj-autoproxy proxy-target-class="true" ></aop:aspectj-autoproxy> 設(shè)置spring aop代理的方式 福贞。當(dāng)proxy-target-class="true"時就是cglib代理模式(類代理) 撩嚼,當(dāng)proxy-target-class="true"時就是jdk的代理模式(接口代理)
@EnableAspectJAutoProxy(proxyTargetClass = true)(注解的方式)
可以強(qiáng)制的將spring aop代理模式寫成cglib的代理模式(類代理)
踩坑點(diǎn):Spring AOP不支持代理類內(nèi)部方法調(diào)用的攔截,比如類中a方法調(diào)用b方法挖帘,切面攔截b方法會失敗的
AspectJ在編譯時就增強(qiáng)了目標(biāo)對象完丽,Spring AOP的動態(tài)代理則是在每次運(yùn)行時動態(tài)的增強(qiáng),生成AOP代理對象肠套,區(qū)別在于生成AOP代理對象的時機(jī)不同舰涌,相對來說AspectJ的靜態(tài)代理方式具有更好的性能猖任,但是AspectJ需要特定的編譯器進(jìn)行處理你稚,而Spring AOP則無需特定的編譯器處理