日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

spring aop代码的增强

發(fā)布時間:2025/7/14 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 spring aop代码的增强 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

這篇博客,主要會分析spring aop是如何實現(xiàn)代碼增強(qiáng)的。

從上一篇博客 我們大概知道,spring能在不改變代碼的前提下,往一個方法的之前和之后添加代碼。

想下,java中有哪種技術(shù)可以幫我們實現(xiàn)動態(tài)修改代碼呢?就是jdk的動態(tài)代理。關(guān)于動態(tài)代理可以看下這篇博客jdk動態(tài)代理與cglib動態(tài)代理實現(xiàn)原理

大體我們先知道,jdk動態(tài)代理和cglib的動態(tài)代理都可以在運行時修改源碼。兩者之間的基本區(qū)別之一是,jdk動態(tài)代理需要被代理的類實現(xiàn)接口,cglib不需要。

然后我們開始分析spring是如何使用動態(tài)代理的。

回到spring調(diào)用鏈的圖,spring 對于aop的增強(qiáng)是在創(chuàng)建bean時,通過BeanPostProcessor機(jī)制來實現(xiàn)的。在spring初始化之后類后,會有一次對類增強(qiáng)的機(jī)會。就是在AbstractAutoProxyCreator里。

AbstractAutoProxyCreator.postProcessAfterInitialization

public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {if (bean != null) {Object cacheKey = getCacheKey(bean.getClass(), beanName);if (!this.earlyProxyReferences.contains(cacheKey)) {return wrapIfNecessary(bean, beanName, cacheKey);}}return bean; }

這里就是檢查下該類是否已經(jīng)暴露過了(可能已經(jīng)創(chuàng)建了,比如A依賴B時,創(chuàng)建A時候,就會先去創(chuàng)建B。當(dāng)真正需要創(chuàng)建B時,就沒必要再代理一次已經(jīng)代理過的對象)

wrapIfNecessary

真正創(chuàng)建代理對象的地方就在wrapIfNecessary


依舊我們先來看最關(guān)鍵的一步,createProxy

protected Object createProxy(Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {if (this.beanFactory instanceof ConfigurableListableBeanFactory) {AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);}ProxyFactory proxyFactory = new ProxyFactory();proxyFactory.copyFrom(this);if (!proxyFactory.isProxyTargetClass()) {if (shouldProxyTargetClass(beanClass, beanName)) {proxyFactory.setProxyTargetClass(true);}else {evaluateProxyInterfaces(beanClass, proxyFactory);}}Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);for (Advisor advisor : advisors) {proxyFactory.addAdvisor(advisor);}proxyFactory.setTargetSource(targetSource);customizeProxyFactory(proxyFactory);proxyFactory.setFrozen(this.freezeProxy);if (advisorsPreFiltered()) {proxyFactory.setPreFiltered(true);}//獲取代理對象return proxyFactory.getProxy(getProxyClassLoader()); }

createProxy也很長,依舊我們只關(guān)心最重要的也就是最后一行,proxyFactory.getProxy

整理了一個流程圖



大概說明下:
1)代理對象的創(chuàng)建最終委托給AopProxy生成
2)AopProxy的創(chuàng)建交由AopProxyFactory工廠
3)AopProxyFactory的默認(rèn)實現(xiàn)是DefaultAopProxyFactory

AopProxyFactory.createAopProxy

那么我們先來看看AopProxy究竟是如何創(chuàng)建的。


我們首先可以看出,最后生成的AopProxy底層實現(xiàn)要么是cglib的,要么是jdk。再然后,我們分析下,什么時候使用jdk動態(tài)代理,什么時候使用cglib的。

1)配置了optimize。由于 cglib的動態(tài)代理創(chuàng)建類比較慢,但是執(zhí)行代碼比較快,jdk動態(tài)代理相反,創(chuàng)建比較快,執(zhí)行比較慢。如果配置了optimize=true,那么目標(biāo)類實現(xiàn)了接口就使用jdk代理,否則就用cglib。默認(rèn)是false。
2)proxyTargetClass 是否強(qiáng)制使用cglib實現(xiàn)代理。默認(rèn)是false
3)沒有可代理的接口

代理對象的生成

到了這里,我們繼續(xù)分析AopProxy如何生成代理對象(這里以jdk動態(tài)代理來分析)



看到Proxy.newProxyInstance就非常熟悉了,jdk的動態(tài)代理。

總結(jié)及待續(xù)

這篇博客大致分析了下,spring是如何創(chuàng)建代理對象的。jdk及cglib代理方式的選擇。以及大概看了下jdk代理對象的創(chuàng)建。

當(dāng)然還是留了很多問題,首先就是wrapIfNecessary里的各種緩存究竟是干啥用的,再然后就是jdk代理里,非常核心的InvocationHandler.invoke方法是如何實現(xiàn)的。再然后,我們常說的,切面,通知這些概念在源碼層究竟對應(yīng)著啥。這些問題會再下一篇博客介紹。

總結(jié)

以上是生活随笔為你收集整理的spring aop代码的增强的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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