?
Dokumen ini menggunakan Manual laman web PHP Cina Lepaskan
在創(chuàng)建了AOP代理之后,你能夠使用org.springframework.aop.framework.Advised
接口對它們進行管理。
任何AOP代理都能夠被轉(zhuǎn)型為這個接口,不論它實現(xiàn)了哪些其它接口。這個接口包括下面的方法:
Advisor[] getAdvisors(); void addAdvice(Advice advice) throws AopConfigException; void addAdvice(int pos, Advice advice) throws AopConfigException; void addAdvisor(Advisor advisor) throws AopConfigException; void addAdvisor(int pos, Advisor advisor) throws AopConfigException; int indexOf(Advisor advisor); boolean removeAdvisor(Advisor advisor) throws AopConfigException; void removeAdvisor(int index) throws AopConfigException; boolean replaceAdvisor(Advisor a, Advisor b) throws AopConfigException; boolean isFrozen();
getAdvisors()
方法將為每個已經(jīng)被加入工廠的通知器,攔截器或者其它通知類型返回一個通知器。如果你曾經(jīng)添加一個通知器,那么所返回的通知器將是你加入的對象。
如果你曾經(jīng)加入一個攔截器或者其它通知類型,Spring將把它們包裝在一個通知器里,后者使用一個永遠返回true的切入點。因此如果你曾經(jīng)加入一個MethodInterceptor
,
返回的通知器將是一個DefaultPointcutAdvisor
,它可以返回你加入的MethodInterceptor
和一個匹配所有類和方法的切入點。
addAdvisor()
方法可以用來添加任何通知器。通常保存切入點和通知的通知器是DefaultPointcutAdvisor
,它可以用于任何通知或切入點(但不包括引入類型)。
缺省情況下,你可以加入或移除通知器或者攔截器甚至當(dāng)代理已經(jīng)被創(chuàng)建之后。唯一的限制是無法加入或者移除一個引入通知器,因為工廠中獲得的已有代理不能顯示接口的改變(你可以通過從工廠里獲取一個新的代理來避免這個問題)。
下面是一個簡單的例子,它把一個AOP代理轉(zhuǎn)型為Advised
接口,檢查并操作它的通知:
Advised advised = (Advised) myObject; Advisor[] advisors = advised.getAdvisors(); int oldAdvisorCount = advisors.length; System.out.println(oldAdvisorCount + " advisors"); // Add an advice like an interceptor without a pointcut // Will match all proxied methods // Can use for interceptors, before, after returning or throws advice advised.addAdvice(new DebugInterceptor()); // Add selective advice using a pointcut advised.addAdvisor(new DefaultPointcutAdvisor(mySpecialPointcut, myAdvice)); assertEquals("Added two advisors", oldAdvisorCount + 2, advised.getAdvisors().length);
在一個實際運行的系統(tǒng)里,修改一個業(yè)務(wù)對象上的通知是否明智是個問題,雖然無疑在某些情況下這樣做是合理的。然而這在開發(fā)中是很有用的: 例如,在測試的時候。對于希望測試的方法調(diào)用,有時我發(fā)現(xiàn)把測試代碼加入到一個攔截器或者其它通知里是非常有用的。 (例如,通知可以與目標(biāo)方法存在于同一個事務(wù)里,在把事務(wù)標(biāo)記為回滾之前可以用SQL來檢查數(shù)據(jù)庫是否被正確的更新了。)
依賴于你怎樣創(chuàng)建代理,你通常可以設(shè)置一個
frozen
標(biāo)志,在這種情況下
Advised
的isFrozen()
方法將返回true,任何增加或者移除通知的修改都會導(dǎo)致一個AopConfigException
異常。
在某些情況下這種凍結(jié)被通知對象狀態(tài)的能力是很有用的:例如,防止調(diào)用代碼來移除一個進行安全檢查的攔截器。在Spring 1.1中它也被用來允許激進優(yōu)化,如果已經(jīng)知道不需要運行時對通知進行修改的話。