javascript
Spring Aop 组件概述
AOP(Aspect-Oriented Programming) 面向切面編程, 這種編程模型是在 OOP(Object-Oriented Programming) 的基礎(chǔ)上誕生的一種編程模型, 我們可以簡(jiǎn)單的將其理解為: 在程序中具有公共特性的某些類/某些方法上進(jìn)行攔截, 在方法執(zhí)行的前面/后面/執(zhí)行結(jié)果返回后 增加執(zhí)行一些方法 (PS: 對(duì), 就這么簡(jiǎn)單, 最起碼 Spring 中是這樣的); 在 Spring 中主要通過(guò)了CGLib|動(dòng)態(tài)代理來(lái)實(shí)現(xiàn) -> CGLib(通過(guò)實(shí)現(xiàn)一個(gè)子類來(lái)控制對(duì)原始類的方法調(diào)用) 與 Proxy(創(chuàng)建一個(gè) Proxy 類, 內(nèi)部通過(guò)反射來(lái)調(diào)用原始類) 來(lái)實(shí)現(xiàn) <-- 這兩個(gè)實(shí)現(xiàn)類都可以通過(guò) HSDB 來(lái)獲取! , 對(duì)于 aop 主要有以下組件
Pointcut: 這個(gè)類位于 “org.springframework.aop” 包中, 它的主要作用還是定義切面的匹配點(diǎn), 在 Spring Aop 中匹配的點(diǎn)主要是 class 與 method 這兩個(gè)方面, 分別為 ClassFilter 與 MethodFilter
// 由 ClassFilter 與 MethodMatcher 組成的 pointcut public interface Pointcut {// 類過(guò)濾器, 可以知道哪些類需要攔截ClassFilter getClassFilter();// 方法匹配器, 可以知道哪些方法需要攔截MethodMatcher getMethodMatcher();// 匹配所有對(duì)象的 PointcutPointcut TRUE = TruePointcut.INSTANCE; }上面的接口中定義了 Pointcut 的主要方法, 從中我們可以看出, Pointcut 的匹配主要是根據(jù) class 與 method 來(lái)進(jìn)行匹配的; 在 Spring 中主要有以下幾類:
@Transactional 標(biāo)簽來(lái)確定方法是否匹配; 而 AspectJExpressionPointcut 其實(shí)就是 AspectJ
包中的工具類來(lái)進(jìn)行匹配
Advice: 建議忠告, 勸告, 通知, 這其實(shí)最開(kāi)始是 aopalliance 包中的一個(gè)空接口, 接口的存在主要是為了標(biāo)示對(duì)應(yīng)類為 Advice; 而在Spring Aop 中 Advice 其實(shí)表示的是在 Pointcut 點(diǎn)上應(yīng)該執(zhí)行的方法, 而這個(gè)方法可以在 Pointcut 的前面/后面/包裹 Pointcut/Pointcut拋出異常時(shí)/整個(gè) Pointcut 執(zhí)行成功返回時(shí)執(zhí)行 <- 有時(shí)語(yǔ)言不能完全解釋代碼所想表達(dá)的意思, 那我們直接來(lái)看代碼吧!
- Advice: 其主要分成兩類: 普通advice 與 Interceptor/MethodInterceptor,
- 通常Spring是將被AspectJ 標(biāo)注的方法解析成各種 Advice(BeforeAdvice, AfterAdvice, ThrowingAdvice, AfterReturingAdvice 或 AspectJMethodBeforeAdvice, AspectJAfterAdvice,
AspectJAfterReturningAdvice, AspectJAfterThrowingAdvice, AspectJAroundAdvice)
上面的 Advice 類別概述, 而又有以下說(shuō)明:
Advisor 其實(shí)它就是 Pointcut 與 Advice 的組合, Advice 是執(zhí)行的方法, 而要知道方法何時(shí)執(zhí)行, 則 Advice 必需與 Pointcut 組合在一起, 這就誕生了 Advisor 這個(gè)類(PS: 你可以嘗試這樣理解 -> Advice表示建議,Pointcut表示建議的地點(diǎn), Advisor表示建議者, 建議的者擁有建議的功能, 并且知道在哪兒建議 <- 純屬于歪歪), 主要有以下幾個(gè)類:
AspectJAfterReturningAdvice, AspectJAfterThrowingAdvice,
AspectJAroundAdvice, Pointcut 則是AspectJExpressionPointcut), 對(duì)于這個(gè)類的解析是在
ConfigBeanDefinitionParser
ReflectiveAspectJAdvisorFactory 來(lái)解析生成的(與之對(duì)應(yīng)的 Advice 是
AspectJMethodBeforeAdvice, AspectJAfterAdvice,
AspectJAfterReturningAdvice, AspectJAfterThrowingAdvice,
AspectJAroundAdvice, Pointcut 則是AspectJExpressionPointcut), 解析的步驟是:
AnnotationAwareAspectJAutoProxyCreator.findCandidateAdvisors() ->
BeanFactoryAspectJAdvisorsBuilder.buildAspectJAdvisors() ->
ReflectiveAspectJAdvisorFactory.getAdvisors() ->
ReflectiveAspectJAdvisorFactory.getAdvisor() 最終生成了
InstantiationModelAwarePointcutAdvisorImpl (當(dāng)然包括里面的 Pointcut 與 advice
也都是由 ReflectiveAspectJAdvisorFactory 解析生成的)
AnnotationTransactionAttributeSource, TransactionInterceptor
組合起來(lái)進(jìn)行事務(wù)的操作(PS: AnnotationTransactionAttributeSource 主要是解析方法上的
@Transactional注解, TransactionInterceptor 是個(gè) MethodInterceptor,
是正真操作事務(wù)的地方, 而B(niǎo)eanFactoryTransactionAttributeSourceAdvisor其實(shí)起著組合它們的作用); 與之相似的還有 BeanFactoryCacheOperationSourceAdvisor
Advised: 已經(jīng)被建議的對(duì)象(主要是代理生成的對(duì)象與AdvisedSupport), 其中蘊(yùn)含了:
// 這個(gè) Advised 接口的實(shí)現(xiàn)著主要是代理生成的對(duì)象與AdvisedSupport (Advised的支持器) public interface Advised extends TargetClassAware {// 這個(gè) frozen 決定是否 AdvisedSupport 里面配置的信息是否改變boolean isFrozen();// 是否代理指定的類, 而不是一些 Interfaceboolean isProxyTargetClass();// 返回代理的接口Class<?>[] getProxiedInterfaces();// 判斷這個(gè)接口是否是被代理的接口boolean isInterfaceProxied(Class<?> intf);// 設(shè)置代理的目標(biāo)對(duì)象void setTargetSource(TargetSource targetSource);// 獲取代理的對(duì)象TargetSource getTargetSource();// 判斷是否需要將 代理的對(duì)象暴露到 ThreadLocal中, 而獲取對(duì)應(yīng)的代理對(duì)象則通過(guò) AopContext 獲取void setExposeProxy(boolean exposeProxy);// 返回是否應(yīng)該暴露 代理對(duì)象boolean isExposeProxy();// 設(shè)置 Advisor 是否已經(jīng)在前面過(guò)濾過(guò)是否匹配 Pointcut (極少用到)void setPreFiltered(boolean preFiltered);// 獲取 Advisor 是否已經(jīng)在前面過(guò)濾過(guò)是否匹配 Pointcut (極少用到)boolean isPreFiltered();// 獲取所有的 AdvisorAdvisor[] getAdvisors();// 增加 Advisor 到鏈表的最后void addAdvisor(Advisor advisor) throws AopConfigException;// 在指定位置增加 Advisorvoid addAdvisor(int pos, Advisor advisor) throws AopConfigException;// 刪除指定的 Advisorboolean removeAdvisor(Advisor advisor);// 刪除指定位置的 Advisorvoid removeAdvisor(int index) throws AopConfigException;// 返回 Advisor 所在位置de indexint indexOf(Advisor advisor);// 將指定的兩個(gè) Advisor 進(jìn)行替換boolean replaceAdvisor(Advisor a, Advisor b) throws AopConfigException;// 增加 Advice <- 這個(gè)Advice將會(huì)包裹成 DefaultPointcutAdvisorvoid addAdvice(Advice advice) throws AopConfigException;// 在指定 index 增加 Advice <- 這個(gè)Advice將會(huì)包裹成 DefaultPointcutAdvisorvoid addAdvice(int pos, Advice advice) throws AopConfigException;// 刪除給定的 Adviceboolean removeAdvice(Advice advice);// 獲取 Advice 的索引位置int indexOf(Advice advice);// 將 ProxyConfig 通過(guò) String 形式返回String toProxyConfigString(); }其實(shí)它主要完成的是以下幾點(diǎn):
1. Proxy代理的Interface 2. 代理的對(duì)象 TargetSource 3. 包裹這個(gè) Advised 的Advisor, 以及對(duì)它的增刪 4. 對(duì) Advice 的增刪 而其主要的實(shí)現(xiàn)者是:1. AdvisedSupport: 這個(gè)類內(nèi)部是 List<Advisor>, Advisor[], interfaces, DefaultAdvisorChainFactory(判斷 Advisor 是否適合當(dāng)前的方法), targetSource 2. ProxyCreatorSupport: 這個(gè)類繼承 AdvisedSupport, 但是在這個(gè)類中主要還是通過(guò) AopProxyFactory 來(lái)完成代理對(duì)象的創(chuàng)建, 見(jiàn) ProxyCreatorSupport.createAopProxy() 3. ProxyFactory: 這個(gè)類通過(guò)構(gòu)造函數(shù)中的 proxyInterface/interceptor/targetSource 來(lái)創(chuàng)建代理對(duì)象(這個(gè)類是編程式 AOP 中最常用的對(duì)象) 4. ProxyFactoryBean: 這個(gè)類是基于 FactoryBean 的 Proxy創(chuàng)建形式, 其通過(guò)代理的 Interface, targetSource 與指定的 interceptorNames 來(lái)創(chuàng)建對(duì)應(yīng)的AopProxy, 最后生成對(duì)應(yīng)的代理對(duì)象 5. AspectJProxyFactory: 將一個(gè)被 @AspectJ 注解標(biāo)示的類丟入其中, 變創(chuàng)建了對(duì)應(yīng)的代理對(duì)象 (這個(gè)類現(xiàn)在已經(jīng)很少用了, 關(guān)于如何使用, 可以看這里(http://elim.iteye.com/blog/2397922))TargetSource: 這個(gè)類的概念其實(shí)是動(dòng)態(tài)代理作用的對(duì)象, 在 Spring 中又可以分為:
1. HotSwappableTargetSource: 進(jìn)行線程安全的熱切換到對(duì)另外一個(gè)對(duì)象實(shí)施動(dòng)態(tài)代理操作 2. AbstractPoolingTargetSource: 每次進(jìn)行生成動(dòng)態(tài)代理對(duì)象時(shí)都返回一個(gè)新的對(duì)象 3. ThreadLocalTargetSource: 為每個(gè)進(jìn)行請(qǐng)求的線程維護(hù)一個(gè)對(duì)象的 TargetSource 4. SingletonTargetSource: 最普遍最基本的單例 TargetSource, 在 Spring 中生成動(dòng)態(tài)代理對(duì)象, 一般都是用這個(gè) TargetSourceAdvisorChainFactory: 這個(gè)接口主要定義了從 Advised中獲取 Advisor 并判斷其是否與 對(duì)應(yīng)的 Method 相匹配, 最終返回的是MethodInterceptor; 其中對(duì) Advisor 轉(zhuǎn)化成 MethodInterceptor 的工作都是交由 DefaultAdvisorAdapterRegistry 來(lái)完成, 下面就是其主邏輯:
// 獲取匹配 targetClass 與 method 的所有切面的通知 @Override public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Advised config, Method method, Class<?> targetClass) {// This is somewhat tricky... We have to process introductions first,// but we need to preserve order in the ultimate list.List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length); // PS: 這里 config.getAdvisors 獲取的是 advisors 是數(shù)組Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());boolean hasIntroductions = hasMatchingIntroductions(config, actualClass); // 判斷是有 IntroductionAdvisor 匹配到// 下面這個(gè)適配器將通知 [Advice] 包裝成攔截器 [MethodInterceptor]; 而 DefaultAdvisorAdapterRegistry則是適配器的默認(rèn)實(shí)現(xiàn)AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();for (Advisor advisor : config.getAdvisors()) { // 獲取所有的 Advisorif (advisor instanceof PointcutAdvisor) { // advisor 是 PointcutAdvisor 的子類// Add it conditionally.PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;// 判斷此切面 [advisor] 是否匹配 targetClass (PS: 這里是類級(jí)別的匹配)if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {/** 通過(guò)對(duì)適配器將通知 [Advice] 包裝成 MethodInterceptor, 這里為什么是個(gè)數(shù)組? 因?yàn)橐粋€(gè)通知類* 可能同時(shí)實(shí)現(xiàn)了前置通知[MethodBeforeAdvice], 后置通知[AfterReturingAdvice], 異常通知接口[ThrowsAdvice]* 環(huán)繞通知 [MethodInterceptor], 這里會(huì)將每個(gè)通知統(tǒng)一包裝成 MethodInterceptor*/MethodInterceptor[] interceptors = registry.getInterceptors(advisor);MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();// 是否匹配 targetClass 類的 method 方法 (PS: 這里是方法級(jí)別的匹配)if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {if (mm.isRuntime()) { // 看了對(duì)應(yīng)的所有實(shí)現(xiàn)類, 只有 ControlFlowPointcut 與 AspectJExpressionPointcut 有可能 返回 true// Creating a new object instance in the getInterceptors() method// isn't a problem as we normally cache created chains.// 如果需要在運(yùn)行時(shí)動(dòng)態(tài)攔截方法的執(zhí)行則創(chuàng)建一個(gè)簡(jiǎn)單的對(duì)象封裝相關(guān)的數(shù)據(jù), 它將延時(shí)// 到方法執(zhí)行的時(shí)候驗(yàn)證要不要執(zhí)行此通知for (MethodInterceptor interceptor : interceptors) {interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm)); // 里面裝的是 Advise 與 MethodMatcher}}else {interceptorList.addAll(Arrays.asList(interceptors));}}}}else if (advisor instanceof IntroductionAdvisor) { // 這里是 IntroductionAdvisor// 如果是引入切面的話則判斷它是否適用于目標(biāo)類, Spring 中默認(rèn)的引入切面實(shí)現(xiàn)是 DefaultIntroductionAdvisor 類// 默認(rèn)的引入通知是 DelegatingIntroductionInterceptor 它實(shí)現(xiàn)了 MethodInterceptor 接口sIntroductionAdvisor ia = (IntroductionAdvisor) advisor;if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {Interceptor[] interceptors = registry.getInterceptors(advisor);interceptorList.addAll(Arrays.asList(interceptors));}}else {Interceptor[] interceptors = registry.getInterceptors(advisor);interceptorList.addAll(Arrays.asList(interceptors));}}return interceptorList; }DefaultAdvisorAdapterRegistry: 這里類里面存在著 MethodBeforeAdviceAdapter, AfterReturningAdviceAdapter, ThrowsAdviceAdapter 。 這三個(gè)類是將 Advice適配成MethodInterceptor 的適配類; 而其本身具有兩個(gè)重要的功能:
AopProxyFactory: 這個(gè)接口中定義了根據(jù) AdvisedSupport 中配置的信息來(lái)生成合適的AopProxy (主要分為 基于Java 動(dòng)態(tài)代理的 JdkDynamicAopProxy 與基于 Cglib 的ObjenesisCglibAopProxy), 主邏輯如下:
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {// 啟用了 優(yōu)化配置(原因就是 cglib 的性能比 JDK Proxy 要好) || 啟用了直接代理目標(biāo)類模式 || 沒(méi)有指定要代理的接口(除了 接口SpringProxy)if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {Class<?> targetClass = config.getTargetClass();if (targetClass == null) {throw new AopConfigException("TargetSource cannot determine target class: " +"Either an interface or a target is required for proxy creation.");}// 代理的對(duì)象是否是接口 或 targetClass 是否是 java.lang.reflect.Proxy 的子類if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) { return new JdkDynamicAopProxy(config);}// 創(chuàng)建 cglib 代理的工廠對(duì)象return new ObjenesisCglibAopProxy(config);}else {// 返回創(chuàng)建 JDK 代理的工廠對(duì)象return new JdkDynamicAopProxy(config);} }PS: 這里補(bǔ)充個(gè)知識(shí)點(diǎn) Cglib 生成代理類的速度比 Proxy 生成的慢(幾乎到10倍數(shù)), 但其執(zhí)行速度是 Proxy 的 10倍 (可能基于不同版本的 jar 包測(cè)出的數(shù)據(jù)會(huì)稍有不同),而在我們?nèi)粘J褂弥?JdkDynamicAopProxy 是最常使用的, 下面直接看一下其執(zhí)行的主邏輯
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {MethodInvocation invocation;Object oldProxy = null;boolean setProxyContext = false;// 目標(biāo)對(duì)象的包裝類, 通過(guò) AdvisedSupport的setTarget方法設(shè)置的會(huì)自動(dòng)封閉成 TargetSource 的實(shí)現(xiàn) SingletonTargetSourceTargetSource targetSource = this.advised.targetSource;Class<?> targetClass = null;Object target = null;try {// 被代理的接口中沒(méi)有定義 equals 方法且目前方法是 equals 方法, 則調(diào)用 equals 方法比較兩代對(duì)象所代理的接口if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {// The target does not implement the equals(Object) method itself.// 如果目標(biāo)對(duì)象沒(méi)有實(shí)現(xiàn) object 類的基礎(chǔ)方法 euqalsreturn equals(args[0]);}// hashCode 方法的處理else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {// The target does not implement the hashCode() method itself.// 如果目標(biāo)對(duì)象沒(méi)有實(shí)現(xiàn) object 類的基礎(chǔ)方法 hashCodereturn hashCode();}// 如果調(diào)用的方法是 DecoratingProxy聲明的else if (method.getDeclaringClass() == DecoratingProxy.class) {// There is only getDecoratedClass() declared -> dispatch to proxy config.return AopProxyUtils.ultimateTargetClass(this.advised);}/*** Class類的 isAssignableFrom(Class cls) 方法:* 自身類.class.isAssignableFrom(自身類或子類.class) 返回 true** 對(duì) Advised 接口或者子接口中的方法的調(diào)用不經(jīng)過(guò)任何攔截器, 直接委托給Advised 對(duì)象中的方法* (此 if 塊 的目的是實(shí)現(xiàn)將 advised 對(duì)象引入代理對(duì)象), this.advised.opaque 默認(rèn)情況下是 false(它只是一個(gè)開(kāi)關(guān)* 選項(xiàng), 控制代理對(duì)象是否可以操作 advised)*/else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&method.getDeclaringClass().isAssignableFrom(Advised.class)) {// Service invocations on ProxyConfig with the proxy config...// 調(diào)用 advised 的method 方法return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);}Object retVal;// 當(dāng)目標(biāo)對(duì)象內(nèi)部的自我調(diào)用無(wú)法實(shí)施切面中的增強(qiáng)則需要增強(qiáng)則需要通過(guò)此屬性暴露代理if (this.advised.exposeProxy) {// 把當(dāng)前代理對(duì)象放到 AopContext 中(其內(nèi)部使用 ThreadLocal 存著), 并返回上下文中原來(lái)的代理對(duì)象, 并且保留之前暴露設(shè)置的代理// Make invocation available if necessary.oldProxy = AopContext.setCurrentProxy(proxy);setProxyContext = true;}// May be null. Get as late as possible to minimize the time we "own" the target,// in case it comes from a pool.// 得到目標(biāo)對(duì)象target = targetSource.getTarget();if (target != null) {targetClass = target.getClass();}// 獲取當(dāng)前方法的攔截器鏈// Get the interception chain for this method.List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);// Check whether we have any advice. If we don't, we can fallback on direct// reflective invocation of the target, and avoid creating a MethodInvocation.// 檢測(cè)是否含有 MethodInterceptorif (chain.isEmpty()) {// 沒(méi)有任何攔截器需要執(zhí)行則直接執(zhí)行目標(biāo)對(duì)象方法// We can skip creating a MethodInvocation: just invoke the target directly// Note that the final invoker must be an InvokerInterceptor so we know it does// nothing but a reflective operation on the target, and no hot swapping or fancy proxying.Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);}else {/*** 如果有攔截器的設(shè)定, 那么需要調(diào)用攔截器之后才調(diào)用目標(biāo)對(duì)象的相應(yīng)方法* 通過(guò) 構(gòu)造一個(gè) ReflectiveMethodInvocation 來(lái)實(shí)現(xiàn), 下面會(huì)看* 這個(gè) ReflectiveMethodInvocation 類的具體實(shí)現(xiàn)*/// We need to create a method invocation...invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);// Proceed to the joinpoint through the interceptor chain.// 執(zhí)行攔截器鏈retVal = invocation.proceed();}// Massage return value if necessary.Class<?> returnType = method.getReturnType();// 處理返回目標(biāo)對(duì)象本身的情況, 也許某些方法是返回this引用, 此時(shí)需要返回代理對(duì)象而不是目標(biāo)對(duì)象if (retVal != null && retVal == target &&returnType != Object.class && returnType.isInstance(proxy) &&!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {// Special case: it returned "this" and the return type of the method// is type-compatible. Note that we can't help if the target sets// a reference to itself in another returned object.retVal = proxy;}else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) { // 從這里我們可以發(fā)現(xiàn), 攔截器的返回值若設(shè)定的不是 null, 但是 你主動(dòng)設(shè)置為 null, 則將會(huì)報(bào)出異常throw new AopInvocationException("Null return value from advice does not match primitive return type for: " + method);}return retVal;}finally {if (target != null && !targetSource.isStatic()) {// Must have come from TargetSource.// 如果此 targetSource 不是一個(gè)靜態(tài)的 targetSource, 那么釋放此 target, 默認(rèn)的 SingletonTargetSource.isStatic 方法是 true 的targetSource.releaseTarget(target);}if (setProxyContext) {// Restore old proxy.// 還原之前的代理對(duì)象AopContext.setCurrentProxy(oldProxy);}} }MethodInvocation 是進(jìn)行 invoke 對(duì)應(yīng)方法/MethodInterceptor的類, 其主要分成用于 Proxy 的 ReflectiveMethodInvocation, 與用于 Cglib 的 CglibMethodInvocation; ReflectiveMethodInvocation 其實(shí)就是遞歸的調(diào)用 MethodInterceptor, 當(dāng)沒(méi)有 MethodInterceptor可以調(diào)用時(shí), 則執(zhí)行對(duì)應(yīng)的切面點(diǎn)的方法, 如下:
/*** 實(shí)現(xiàn)前置增強(qiáng)在目標(biāo)方法前調(diào)用, 后置增強(qiáng)在目標(biāo)方法后調(diào)用*/ @Override public Object proceed() throws Throwable {// 執(zhí)行完所有增強(qiáng)執(zhí)行切點(diǎn)方法// currentInterceptorIndex 默認(rèn)等于 -1 的, 它記錄著當(dāng)前執(zhí)行到了哪個(gè)攔截器// interceptorsAndDynamicMethodMatchers 代表著匹配了的 MethodInterceptor// We start with an index of -1 and increment early.if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {// 如果所有的 攔截器都執(zhí)行完了的話, 則調(diào)用 invokeJoinPoint 方法去執(zhí)行目標(biāo)對(duì)象的目標(biāo)方法 (反射)return invokeJoinpoint();}// 得到當(dāng)前要執(zhí)行的攔截器(攔截器是順序執(zhí)行的 )Object interceptorOrInterceptionAdvice =this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);// 下面判斷當(dāng)前攔截器是不是一個(gè)動(dòng)態(tài)攔截器if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) { // 其實(shí)在 Spring 中 主要的實(shí)現(xiàn)類是 AspectJExpressionPointcut// 動(dòng)態(tài) 匹配 方法 攔截// Evaluate dynamic method matcher here: static part will already have// been evaluated and found to match.InterceptorAndDynamicMethodMatcher dm =(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;// 這里調(diào)用 MethodMatcher 類中帶3個(gè)參數(shù)的 matches 方法if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {// 匹配目標(biāo)類的目標(biāo)方法后執(zhí)行攔截器return dm.interceptor.invoke(this);}else {// 遞歸調(diào)用, 下一個(gè)攔截器或目標(biāo)類的方法// Dynamic matching failed.// Skip this interceptor and invoke the next in the chain.return proceed();}}else {// 將 this作為參數(shù)(MehtodInvocation)傳遞以保證當(dāng)前實(shí)例中調(diào)用鏈的執(zhí)行// It's an interceptor, so we just invoke it: The pointcut will have// been evaluated statically before this object was constructed.return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);} }AbstractAutoProxyCreator: 這個(gè)類是聲明式 Aop 編程中非常重要的一個(gè)角色, 我們可以從以下幾點(diǎn)來(lái)解析它:
1. AbstractAutoProxyCreator繼承了 ProxyProcessorSupport, 所以它具有了ProxyConfig中動(dòng)態(tài)代理應(yīng)該具有的配置屬性 2. AbstractAutoProxyCreator 實(shí)現(xiàn)了 SmartInstantiationAwareBeanPostProcessor(包括實(shí)例化的前后置函數(shù), 初始化的前后置函數(shù)) 并進(jìn)行了實(shí)現(xiàn) 3. 實(shí)現(xiàn)了 創(chuàng)建代理類的主方法 createProxy 方法 4. 定義了抽象方法 getAdvicesAndAdvisorsForBean(獲取 Bean對(duì)應(yīng)的 Advisor) AbstractAutoProxyCreator 中等于是構(gòu)建了創(chuàng)建 Aop 對(duì)象的主邏輯, 而其子類 AbstractAdvisorAutoProxyCreator 實(shí)現(xiàn)了getAdvicesAndAdvisorsForBean 方法, 并且通過(guò)工具類 BeanFactoryAdvisorRetrievalHelper(PS: 它的方法findAdvisorBeans中實(shí)現(xiàn)類獲取容器中所有 Advisor 的方法) 來(lái)獲取其對(duì)應(yīng)的 Advisor;AbstractAutoProxyCreator 的子類中主要有以下幾個(gè):
1. AspectJAwareAdvisorAutoProxyCreator: 通過(guò)解析 aop 命名空間的配置信息時(shí)生成的 AdvisorAutoProxyCreator, 主要通過(guò)ConfigBeanDefinitionParser.parse() -> ConfigBeanDefinitionParser.configureAutoProxyCreator() -> AopNamespaceUtils.registerAspectJAutoProxyCreatorIfNecessary() -> AopNamespaceUtils.registerAspectJAutoProxyCreatorIfNecessary(); 與之對(duì)應(yīng)的 Pointcut 是AspectJExpressionPointcut, Advisor 是 AspectJPointcutAdvisor, Advice 則是 AspectJAfterAdvice, AspectJAfterReturningAdvice, AspectJAfterThrowingAdvice, AspectJAroundAdvice 2. AnnotationAwareAspectJAutoProxyCreator: 這是基于 @AspectJ注解生成的 切面類的一個(gè) AbstractAutoProxyCreator, 解析額工作交給了 AspectJAutoProxyBeanDefinitionParser, 步驟如下AspectJAutoProxyBeanDefinitionParser.parse() -> AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary() -> AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary() 3. DefaultAdvisorAutoProxyCreator: 這個(gè)類也是 AbstractAutoProxyCreator的子類, 它帥選作用的類時(shí)主要是根據(jù)其中的 advisorBeanNamePrefix(類名前綴)配置進(jìn)行判斷 4. BeanNameAutoProxyCreator: 通過(guò)類的名字來(lái)判斷是否作用(正則匹配)本篇主要介紹了 Spring-Aop 中的主要構(gòu)建, 并進(jìn)行相應(yīng)的說(shuō)明, 單純的講 aop 這個(gè)概念其實(shí)不復(fù)雜, 而在 Spring 中, 主要表現(xiàn)在如下幾點(diǎn):
https://www.jianshu.com/p/de624a4190c6
總結(jié)
以上是生活随笔為你收集整理的Spring Aop 组件概述的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 产品经理装逼词汇大全
- 下一篇: WeCity未来城市2.0白皮书