Java AOP
AOP知識整理
AOP(Aspect-Oriented Programming):面向切面的編程。OOP(Object-Oriented Programming)面向對象的編程。對于OOP我們已經再熟悉不過了,對于AOP,可能我們會覺得是一種新特性,其實AOP是對OOP的一種補充,OOP面向的是縱向編程,繼承、封裝、多態是其三大特性,而AOP是面向橫向的編程。
面向切面編程(AOP)通過提供另外一種思考程序結構的途經來彌補面向對象編程(OOP)的不足。在OOP中模塊化的關鍵單元是類(classes),而在AOP中模塊化的單元則是切面。切面能對關注點進行模塊化,例如橫切多個類型和對象的事務管理。
AOP框架是spring的一個重要組成部分。但是Spring IoC容器并不依賴于AOP,這意味著你有權利選擇是否使用AOP,AOP做為Spring IoC容器的一個補充,使它成為一個強大的中間件解決方案。
AOP在Spring Framework中的作用
1.AOP概念:
學習AOP,當然得先了解一下其眾多的概念性術語:
通知類型:
環繞通知是最常用的通知類型。和AspectJ一樣,Spring提供所有類型的通知,我們推薦你使用盡可能簡單的通知類型來實現需要的功能。例如,如果你只是需要一個方法的返回值來更新緩存,最好使用后置通知而不是環繞通知,盡管環繞通知也能完成同樣的事情。用最合適的通知類型可以使得編程模型變得簡單,并且能夠避免很多潛在的錯誤。比如,你不需要在JoinPoint上
調用用于環繞通知的proceed()方法,就不會有調用的問題。
在這里,基于@AspectJ的AOP我就不多寫了,因為我更青睞于Spring中使用ProxyFactoryBean創建AOP代理。
2.使用ProxyFactoryBean創建AOP代理:
在Spring里創建一個AOP代理的基本方法是使用org.springframework.aop.framework.ProxyFactoryBean。 這個類對應用的切入點和通知提供了完整的控制能力(包括它們的應用順序)。像其它的FactoryBean實現一樣,ProxyFactoryBean引入了一個間接層。如果你定義一個名為foo的ProxyFactoryBean, 引用foo的對象看到的將不是ProxyFactoryBean實例本身,而是一個ProxyFactoryBean實現里getObject() 方法所創建的對象。 這個方法將創建一個AOP代理,它包裝了一個目標對象。
ProxyFactoryBean類本身也是一個JavaBean,其屬性主要有如下用途:
一些主要屬性從org.springframework.aop.framework.ProxyConfig里繼承下來(這個類是Spring里所有AOP代理工廠的父類)。這些主要屬性包括:
ProxyFactoryBean中需要說明的其它屬性包括:
這里的名字是當前工廠中bean的名字,包括父工廠中bean的名字。這里你不能使用bean的引用因為這會導致ProxyFactoryBean忽略通知的單例設置。
你可以把一個攔截器的名字加上一個星號作為后綴(*)。這將導致這個應用程序里所有名字以星號之前部分開頭的通知器都被應用。
單例:工廠是否應該返回同一個對象,不論方法getObject()被調用的多頻繁。 多個FactoryBean實現都提供了這個方法。缺省值是true。 如果你希望使用有狀態的通知--例如,有狀態的mixin--可以把單例屬性的值設置為false來使用原型通知。
3.基于JDK和CGLIB的代理:
如果一個需要被代理的目標對象的類(后面將簡單地稱它為目標類)沒有實現任何接口,那么一個基于CGLIB的代理將被創建。 這是最簡單的場景,因為JDK代理是基于接口的,沒有接口意味著沒有使用JDK進行代理的可能.
如果ProxyFactoryBean的proxyTargetClass屬性被設為true,那么一個基于CGLIB的代理將創建。 這樣的規定是有意義的,遵循了最小驚訝法則(保證了設定的一致性)。甚至當ProxyFactoryBean的proxyInterfaces屬性被設置為一個或者多個全限定接口名, 而proxyTargetClass屬性被設置為true仍然將實際使用基于CGLIB的代理。
如果ProxyFactoryBean的proxyInterfaces屬性被設置為一個或者多個全限定接口名,一個基于JDK的代理將被創建。 被創建的代理將實現所有在proxyInterfaces屬性里被說明的接口; 如果目標類實現了全部在proxyInterfaces屬性里說明的接口以及一些額外接口,返回的代理將只實現說明的接口而不會實現那些額外接口。
如果ProxyFactoryBean的proxyInterfaces屬性沒有被設置, 但是目標類實現了一個(或者更多)接口,那么ProxyFactoryBean將自動檢測到這個目標類已經實現了至少一個接口, 一個基于JDK的代理將被創建。被實際代理的接口將是目標類所實現的全部接口; 實際上,這和在proxyInterfaces屬性中列出目標類實現的每個接口的情況是一樣的。 然而,這將顯著地減少工作量以及輸入錯誤的可能性。
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
新聞熱點
疑難解答