javascript
Spring AOP 的底层实现
實例代碼 demo code
- 創建一個配置類去掃描包,開啟 AspectJ 的自動代理支持
- 新建接口和接口實現類
- 創建一個切面
- 創建啟動類
- 啟動 main() 方法,可以看到輸出的內容,所有 aop 的功能有啟用
對代碼進行 debug,分析如何創建 bean 對象,并對 bean 對象進行增強
-
對 main() 方法進行 debug,執行完成這一行代碼,已經創建出一個被增強的 bean 對象,而不是下面一行才創建增強 bean 對象,這個創建出的 beanName 為 demoDaoImpl
-
來到 refresh() 方法
-
來到 refresh() 方法中的 finishBeanFactoryInitialization(beanFactory) 方法,這個方法對 bean 進行實例化和初始化操作
-
來到 finishBeanFactoryInitialization() 方法中 preInstantiateSingletons() 方法,開始著手實例化 bean 對象
-
來到 preInstantiateSingletons() 方法,打上斷點,指定 beanName.equals(“demoDaoImpl”),可以看到想要注冊的 bean
-
debug 代碼往下執行,來到 getBean(beanName) 方法
-
debug 繼續往下執行,來到 doGetBean(beanName) 方法,在 spring 中一般 do 開頭的方法才是真正做事的方法
-
最開始創建 bean 對象的時候,通過 getSingleton() 獲取的 sharedInstance 為 null,所有執行到 if(sharedInstance != null) 對應的 else 邏輯里面
-
來到 else 邏輯里面的 createBean() 方法,非常核心的方法,debug 進去看
-
在 createBean() 方法中跳到 doCreateBeanBean 方法中,do 開頭的方法要開始真正創建 bean 對象了
-
doCreateBean() 方法中調用 addSingletonFactory() 方法,這個邏輯是判斷當前對象是否持有 InstantiationAwareBeanPostProcessor,如果有的話通過它的 getEarlyBeanReference() 方法獲取對象引用,然后將其放到三級緩存中
-
bean 填充 populateBean(),bean 初始化 initializeBean()
- populateBean() 通過 InstantiationAwareBeanPostProcessor.postProcessProperties() 方法對 bean 屬性進行填充,@Autowired 注入屬性就在這里實現
- initializeBean() 初始化 bean,通過各種的 BeanPostProcessor 對 bean 進行后置處理
- 后置處理器的前置處理
- 后置處理器的后置處理,bean 代理增強就是通過后置處理完成的
- 可以看到有個后置處理器 AnnotationAwareAspectJAutoProxyCreator,這個處理器就是一個 BeanPostProcessor
- AbstractAutoProxyCreator 對 postProcessAfterInitialization() 方法進行重寫,wrapIfNecessary() 方法,對 bean 對象進行代理增強
- 來到 wrapIfNecessary() 方法,查看 bean 有哪些地方需要增強,如果有增強的地方,就對其進行增強,通過 createProxy() 方法,創建代理對象返回
- 來到 createProxy() 方法,真正創建代理的方法就是 getProxy()
- getProxy() 執行前調用 createAopProxy() 創建 AopProxyFactory,委托 AopProxyFactory 去創建代理對象
- 進到 createAopProxy() 方法,先調用 getAopProxyFactory() 獲取到 AopProxyFactory 對象,再調用 createAopProxy() 方法
- createAopProxy() 有個默認的實現類 DefaultAopProxyFactory,該類的默認實現,判斷是通過 Jdk 動態代理 還是 Cglib 代理,到這一步確定返回的代理的類型,確定代理的類型之后,可以根據返回的對象調用 getProxy() 方法,生成代理對象
- Cglib 和 JdkDynamic 通過生成 class 文件對增強的目標進行增強,實現邏輯是 jdk 部分的源碼,之后具體分析,需要留意:
- JdkDynamic 通過 Proxy 生成的 .class 文件,默認 extends Proxy,所以接口進行代理,要通過 JdkDynamic
- Cglib 通過對目標類 extends 的方法繼承重寫增強,所以類的增強一定要通過 Cglib 的方式,因為 java 的規定就是單繼承、多實現
生成字節碼(.class)文件文件之后如何進行調用 ?
- CglibAopProxy
- 代理對象調用方法的時候會到 intercept() 方法
- 拿到所有的 aop advice:List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
- 實例化一個 CglibMethodInvocation(其實就是 ReflectiveMethodInvocation 對象) 對象調用 proceed() 方法:retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
- proceed() 方法中遞歸調用會得到 MethodInterceptor 對象,調用 invoke() 方法,各種攔截器起作用,進行方法的攔截處理:return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
- JdkDynamicAopProxy
- 代理對象調用方法的時候會到 invoke(),操作和 Cglib 基本一樣
- 獲取 aop advice:List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
- 實例化 MethodInvocation 對象,調用 proceed() 方法:MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
- 遞歸調用 Joinpoint.proceed() 方法,同樣也是 ReflectiveMethodInvocation 實現類的 proceed() 方法,各種攔截器起作用,進行方法的攔截處理:return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
- 上面兩個方法中的 MethodInterceptor.invoke() 方法調用,其中就包括事物的 TransactionInterceptor,事物的實現就是由該攔截器處理,invoke() 方法調用 invokeWithinTransaction() 方法真正處理事物
Aop 創建代理對象流程總結
AbstractApplicationContext.refresh(); 容器刷新
->
AbstractApplicationContext.finishBeanFactoryInitialization(beanFactory); 完成bean工廠的初始化
->
beanFactory.preInstantiateSingletons(); 初始化非懶加載的 bea 實例
->
DefaultListableBeanFactory.getBean(beanName); 創建bean
->
AbstractBeanFactory.getBean(String name); 創建 bean
->
AbstractBeanFactory.doGetBean(String name, @Nullable Class requiredType, @Nullable
Object[] args, boolean typeCheckOnly); 創建 bean
->
createBean(beanName, mbd, args); 創建 bean
->
Object beanInstance = doCreateBean(beanName, mbdToUse, args); 創建 bean
->
exposedObject = initializeBean(beanName, exposedObject, mbd); 初始化 bean
->
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); 獲取所有的 BeanPostProcessor (AnnotationAwareAspectJAutoProxyCreator > AspectJAwareAdvisorAutoProxyCreator > AbstractAdvisorAutoProxyCreator > AbstractAutoProxyCreator 這個類是 BeanPostProcessor 的實現類,是后置處理器實現代理對象增強的關鍵點)
->
Object current = processor.postProcessAfterInitialization(result, beanName); 調用所有的 BeanPostProcessor,來到 wrapIfNecessary() 方法
->
AbstractAutoProxyCreator.wrapIfNecessary(bean, beanName, cacheKey); 如果 bean 需要增強,就進行增強
->
Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new
SingletonTargetSource(bean)); 創建代理對象
->
proxyFactory.getProxy(getProxyClassLoader()); 獲取代理對象 classLoader
->
createAopProxy().getProxy(classLoader); 判斷代理增強的類型
->
Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this); 生成代理對象
總結
以上是生活随笔為你收集整理的Spring AOP 的底层实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: little-endian java_L
- 下一篇: URL长链转短链