今天給大家介紹一下Spring AOP為什么會失效。文章的內(nèi)容小編覺得不錯,現(xiàn)在給大家分享一下,覺得有需要的朋友可以了解一下,希望對大家有所幫助,下面跟著小編的思路一起來閱讀吧。
創(chuàng)新互聯(lián)建站長期為成百上千客戶提供的網(wǎng)站建設(shè)服務(wù),團隊從業(yè)經(jīng)驗10年,關(guān)注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺,與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為瓜州企業(yè)提供專業(yè)的成都網(wǎng)站制作、成都做網(wǎng)站,瓜州網(wǎng)站改版等技術(shù)服務(wù)。擁有十余年豐富建站經(jīng)驗和眾多成功案例,為您定制開發(fā)。
怎么理解AOP代理。
Spring AOP是基于代理的。
在編寫自己的方面或使用Spring Framework提供的任何基于Spring AOP的方面之前,掌握最后一條語句的實際含義是至關(guān)重要的。
首先考慮這樣一個場景,其中您有一個普通的、未代理的、沒有什么特別的、直接的對象引用,如下面的代碼片段所示。
public class SimplePojo implements Pojo {
public void foo() {
// this next method invocation is a direct call on the
'this' reference this.bar();
}
public void bar() { // some logic...
}
}
如果在對象引用上調(diào)用方法,則會直接在該對象引用上調(diào)用該方法,如下所示。
public class Main {
public static void main(String[] args) {
Pojo pojo = new SimplePojo();
// this is a direct method call on the 'pojo' reference pojo.foo();
}
}
當(dāng)客戶端代碼擁有的引用是代理時,情況略有變化。
請考慮以下圖表和代碼片段。
public class Main {
public static void main(String[] args) {
ProxyFactory factory = new ProxyFactory(new
SimplePojo());
factory.addInterface(Pojo.class);
factory.addAdvice(new RetryAdvice());
Pojo pojo = (Pojo) factory.getProxy();
// this is a method call on the proxy! pojo.foo();
}
}
這里要理解的關(guān)鍵是main(..)中的客戶端代碼。
主類的具有對代理的引用。
這意味著對該對象引用的方法調(diào)用將是對代理的調(diào)用,因此代理將能夠委托給與該特定方法調(diào)用相關(guān)的所有攔截器(通知)。
然而,一旦調(diào)用最終到達目標(biāo)對象(本例中為SimplePojo引用),它可能對自身進行的任何方法調(diào)用(如this.bar()或this.foo())都將針對this引用而不是代理調(diào)用。
這具有重要的意義。
這意味著自調(diào)用不會導(dǎo)致與方法調(diào)用相關(guān)聯(lián)的通知有機會執(zhí)行。
好的,那么我們該怎么做呢?
最好的方法(這里松散地使用術(shù)語“最佳”)是重構(gòu)您的代碼,這樣就不會發(fā)生自調(diào)用。
當(dāng)然,這確實需要您做一些工作,但這是最好的、侵入性最小的方法。
下一種方法絕對是可怕的,我?guī)缀醪辉钢赋鲞@一點,正是因為它太可怕了。
你可以(窒息!)。
通過執(zhí)行以下操作,將類中的邏輯完全綁定到Spring AOP:
public class SimplePojo implements Pojo {
public void foo() {
// this works, but... gah! ((Pojo) AopContext.currentProxy()).bar();
}
public void bar() {
// some logic...
}
}
這完全將您的代碼耦合到Spring AOP,并且它使類本身意識到它是在AOP上下文中使用的,這與AOP背道而馳。
創(chuàng)建代理時還需要一些額外的配置:
public class Main {
public static void main(String[] args) {
ProxyFactory factory = new ProxyFactory
(new SimplePojo());
factory.adddInterface(Pojo.class);
factory.addAdvice(new RetryAdvice());
factory.setExposeProxy(true);
Pojo pojo = (Pojo) factory.getProxy();
// this is a method call on the proxy! pojo.foo();
}
}
最后,必須注意的是,AspectJ沒有這個自調(diào)用問題,因為它不是一個基于代理的AOP框架。
除了使用
有關(guān)Spring的AOP API的完整細(xì)節(jié),請參閱下一章。
在這里,我們想重點介紹使用@AspectJ方面自動創(chuàng)建代理的能力。
類org.springframework.aop.aspectj.annotation.AspectJProxyFactory可用于創(chuàng)建由一個或多個@AspectJ方面建議的目標(biāo)對象的代理。
這個類的基本用法非常簡單,如下所示。
有關(guān)完整信息,請參閱Javadoc。
// create a factory that can generate a proxy for the given target object
AspectJProxyFactory factory = new AspectJProxyFactory(targetObject);
// add an aspect, the class must be an @AspectJ aspect
// you can call this as many times as you need with different aspects
factory.addAspect(SecurityManager.class);
// you can also add existing aspect instances, the type of the object supplied must be an @AspectJ aspect
factory.addAspect(usageTracker);
// now get the proxy object...
MyInterfaceType proxy = factory.getProxy();
在Spring應(yīng)用程序中使用AspectJ。
到目前為止,我們在本章中介紹的所有內(nèi)容都是純Spring AOP。
在這一節(jié)中,如果您的需求超出了Spring AOP單獨提供的功能,我們將看看如何使用AspectJ編譯器/編織器來替代Spring AOP,或者除了Spring AOP之外使用AspectJ編譯器/編織器。
Spring附帶了一個小的AspectJ方面庫,它在您的發(fā)行版中作為Spring-aspects.jar獨立提供;您需要將其添加到類路徑中才能使用其中的方面。
以上就是Spring AOP為什么會失效的全部內(nèi)容了,更多與Spring AOP為什么會失效相關(guān)的內(nèi)容可以搜索創(chuàng)新互聯(lián)之前的文章或者瀏覽下面的文章進行學(xué)習(xí)哈!相信小編會給大家增添更多知識,希望大家能夠支持一下創(chuàng)新互聯(lián)!