使用AspectJ和Spring簡化了AOP

我最近開始研究面向方面的編程(AOP),至少可以說使我興奮。 當然我很熟悉它,因為我看到它在Spring中用于事務管理,但是我從未深入研究它。 在本文中,我想展示通過AspectJ可以快速掌握AOP和Spring。 本文中的材料基于Ramnivas Laddad出色的AOP書《 AspectJ in Action》 。

AOP不是一種語言,而是一種軟件工程方法。 像任何方法一樣,它具有不同的實現,并且AspectJ當前是最豐富,最完整的。 由于AspectJ和AspectWerkz合并,現在可以使用注釋創建方面。

開發人員編寫代碼的原因是為了提供某種功能。 對于這種討論,功能性的種類并不重要:有些人可能想提供業務功能,另一些人可能出于研究目的編寫代碼,而另一些人則純粹出于樂趣。 關鍵是任何信息系統都有其核心動機,即它想要提供的關鍵功能。 例如,我最近編寫了PODAM ,這是一個測試工具,其最終目標是自動填充POJO / JavaBean屬性。

每個信息系統也需要正交服務(AOP稱之為橫切關注點); 例如日志記錄,安全性,審核,異常管理等。 盡管信息系統可以分為不同的功能(AOP定義了連接點),但全面需要正交服務。 例如,如果要記錄每個公共方法執行所花的時間,則每個公共方法應具有以下偽代碼:

public void someBusinessMethod() {long start = System.currentTimeInMilliseconds();doTheBusinessFunctionality();long end = System.currentTimeInMilliseconds();log.debug("The execution of someBusinessMethod took " + (end - start) + " milliseconds");}

在上述方法中,核心功能僅由someBusinessMethod()標識,而其他所有功能僅是記錄活動。 最好有以下內容:

//Some external magic happens before the invocation of this method to take the start time
public void someBusinessMethod() {doTheBusinessFunctionality(); }
//Some external magic happens after the invocation of this method to take the end time and logs how long the execution took.

開發人員通常需要整個應用程序中的日志記錄,安全性等,而不是單一方法。 AOP允許開發人員通過在外部某個地方(稱為“方面”)定義行為以應用于匹配某種模式的所有代碼(AOP實際上允許更廣泛的功能集,例如添加接口,實例變量,方法,等等,只舉一個例子)。 然后,通過AOP所謂的Weaver,將這種授權的行為添加到最終執行代碼中。

可以通過多種方式實現:編織可以在源級別,二進制級別和加載時間進行。 您可以將編織器視為C和C ++中的鏈接器。 源和庫鏈接在一起以創建可執行文件; 編織者將Java代碼和方面結合在一起,以創建授權的行為。

Spring通過圍繞必須豐富其行為的代碼創建一個AOP代理來實現這種授權行為。 以下代碼顯示了一個基于AspectJ的非常簡單的示例; 該示例圍繞使用某些身份驗證服務執行簡單方法。

身份驗證服務看起來非常簡單(關鍵不是功能的實現方式,而是可用的身份驗證服務):

/*** */
package uk.co.jemos.aop;/*** A simple authenticator service.* * @author mtedone* */
public class Authenticator {public void authenticate() {System.out.println("Authenticated");}}Now let's have a look at the business logic:/*** */
package uk.co.jemos.aop;/*** A simple service which delivers messages* @author mtedone* */
public class MessageCommunicator {public void deliver(String message) {System.out.println(message);}public void deliver(String person, String message) {System.out.println(person + ", " + message);}}

我們希望在調用MessageCommunicator的任何業務方法之前先調用Authenticator。 使用AspectJ注釋語法,我們用純Java編寫Aspect:

package uk.co.jemos.aop;import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;@Aspect
public class SecurityAspect {    private Authenticator authenticator = new Authenticator();@Pointcut("execution(* uk.co.jemos.aop.MessageCommunicator.deliver(..))")public void secureAccess() {};@Before("secureAccess()")public void secure() {System.out.println("Checking and authenticating user...");authenticator.authenticate();}}

上面的代碼更加有趣。 一個方面用@Aspect注釋標記。 切入點是我們代碼中的一個關注點,我們希望我們的Aspect可以加入其中。語法

@Pointcut(“ execution(* uk.co.jemos.aop.MessageCommunicator.deliver(..))”)public void secureAccess(){};

意思是:“定義一個名為secureAccess的切入點,該切入點適用于MessageCommunicator類中的所有傳遞方法,而不管該方法的返回類型如何”。 接下來的內容被稱為建議,這是AOP增強班級行為的地方:

@Before("secureAccess()")
public void secure() {System.out.println("Checking and authenticating user...");authenticator.authenticate();}

上面的代碼說:“在對secureAccess()切入點進行任何匹配之前,將代碼應用到塊中”。 以上所有內容都是純Java,盡管注釋屬于AspectJ運行時。 為了在Spring中使用上述方面,我定義了一個Spring上下文文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"><aop:aspectj-autoproxy /><bean id="messageCommunicator" /><bean id="securityAspect" /></beans>

XML元素:<aop:aspectj-autoproxy />指示Spring圍繞各個方面創建代理。 現在,當我從客戶端使用MessageCommunicator時:

/**
* @param args
*/
public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:aop-appContext.xml");MessageCommunicator communicator = ctx.getBean("messageCommunicator",MessageCommunicator.class);communicator.deliver("Hello World");communicator.deliver("Marco", "Hello World");
}

我得到以下輸出:

信息:從類路徑資源[aop-appContext.xml]加載XML bean定義2011年5月15日11:51:41
org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO:在org.springframework.beans.factory.support.DefaultListableBeanFactory@21b64e6a中預先實例化單例:定義bean [org.springframework.aop.config.internalAutoProxyCreator,messageCommunicator,securityAspect]; 工廠層次結構的根檢查和認證用戶…認證的Hello World 正在檢查和認證用戶…已認證Marco,Hello World

通過允許我們將外部組件中的橫切關注點外部化,然后在需要時將其編織到我們的代碼中,AOP大大改變了我們思考軟件工程的方式,這允許編寫更簡潔,更可維護的代碼,并且實現不受限制。 另外,如果我們通過使它們可重用而謹慎地編寫我們的方面,我們可以快速地建立一個通用,可重用方面的庫,以注入的方式為我們的代碼添加功能。

采用AOP顯然存在弊端,主要是開發人員熟悉該技術所需的學習曲線。 如上面的示例所示,AspectJ定義了自己的語言和語法); @Before注釋只是一種可能性:建議可以在對象之前,之后,周圍使用; 此外,定義切入點的語法不是Java,而是類似腳本的語法。 AspectJ方面還具有關鍵字和本機對象,以捕獲他們建議的連接點的上下文,并且需要學習此語法。 但是,通過學習這項新穎而令人興奮的技術所需的額外努力,潛在的收益將大大增加。

參考: Marco Tedone博客中的 JCG合作伙伴 Marco Tedone 使用AspectJ和Spring簡化了AOP 。


翻譯自: https://www.javacodegeeks.com/2012/04/aop-made-easy-with-aspectj-and-spring.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/373192.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/373192.shtml
英文地址,請注明出處:http://en.pswp.cn/news/373192.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

第一沖刺階段 工作總結 04

1、昨天我繼續我的任務&#xff0c;連接數據庫。 2、今天打算繼續做數據庫的連接。 3、遇到的問題&#xff1a;昨天在數據庫連接時&#xff0c;老是連接不上&#xff0c;顯示錯誤&#xff0c;所以今天打算接著弄。轉載于:https://www.cnblogs.com/zz0906/p/5422510.html

windows2012同步linux時間,Windows server2012時間同步NTP配置

遇到經常服務器時間無法同步&#xff0c;可以自己建立一臺時間同步服務器&#xff0c;NTP配置如下&#xff1a;一、服務端配置 (Ntp服務器&#xff0c;客戶端將根據這臺服務器的時間進行同步)1、微軟鍵R鍵&#xff0c;進入“運行”&#xff0c;輸入“regedit”,進入注冊表2、 H…

反差萌

反差萌 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 0 Accepted Submission(s): 0 Problem Description有2N個人&#xff0c;每人有個萌值Mi(1<i<2N)。 要求將他們分為N對&#xff0c;使得反差值之和…

Java EE 6示例– Galleria第2部分

您可能在最后一篇Java EE 6 Galleria示例帖子中關注了我。 第一個是基本介紹。 第二個是關于在最新的GlassFish上運行它。 有人提到RedHat&#xff0c;我們應該研究將這個示例從GlassFish中移除。 很好;&#xff09;感謝您的好主意。 這正是我們今天要做的。 我將把Galleria示例…

suggest

http://lovebeyond.iteye.com/blog/941633轉載于:https://www.cnblogs.com/sunxun/p/5421251.html

linux的tar命令壓縮26g文件,linux如何使用tar命令大包壓縮進文件

linux如何使用tar命令大包壓縮進文件發布時間&#xff1a;2020-05-29 12:30:14來源&#xff1a;億速云閱讀&#xff1a;206作者&#xff1a;Leah本篇文章主要介紹linux中使用tar命令大包壓縮進文件的方法。內容比較詳細&#xff0c;文章包含了命令的使用示例&#xff0c;希望大…

與reCAPTCHA的Spring集成

有時我們只需要CAPTCHA &#xff0c;這是一個可悲的事實。 今天&#xff0c;我們將學習如何與reCAPTCHA集成。 因為主題本身并不是特別有趣和高級&#xff0c;所以我們將通過使用Spring Integration處理低級細節來過度設計&#xff08;&#xff1f;&#xff09;。 Google決定使…

《機器學習基石》---感知機算法

1 推導感知機模型 基本思想是&#xff0c;把特征的線性加權值作為一個分數&#xff0c;根據這個分數與一個門限值的關系來進行分類&#xff1a; 我們加一個特征x0等于1&#xff0c;門限值就可以放到w里面去&#xff0c;得到更簡單的形式&#xff1a; 這就是感知機模型&#xff…

未知錯誤:1000正在終止線程

若在try{} catch{}的catch 塊中加入 catch (Exception ex) { Response.Write(ex.Message); Response.End(); } 則捕獲異常后&#xff0c;提示未知錯誤&#xff1a;1000正在終止線程 轉載于:https://www.cnblogs.com/dennysong/p/5422567.…

分叉并加入Java 7 – JSR 166并發實用程序

Java 7最有趣的改進之一是對并發的更好支持。 使用JSR 166并發實用程序&#xff0c;我們可以對并發進行一些非常有用的改進。 在我看來&#xff0c;fork-join庫在軟件工程中具有很高的實際應用潛力。 Fork and join為算法提供了非常簡單的編程模型&#xff0c;可以將其實現為遞…

linux內核源碼代碼量,Linux內核源代碼數量已經超過1000萬行

Linux版本2.6.27更新后,人們發現,這一內核的源代碼數量已經超過了1000萬行.當然,這些行數僅僅是計算機統計出來的行數,包括空白行,為了代碼的可讀性增加的注釋等,當然Linux和所有的長期項目一樣,隨著時間的推移,舊的代碼 會被丟棄和更換,但總體規模來說,Linux的內核在不斷增強,…

Python之路【第八篇】:堡壘機實例以及數據庫操作

Python之路【第八篇】&#xff1a;堡壘機實例以及數據庫操作 堡壘機前戲 開發堡壘機之前&#xff0c;先來學習Python的paramiko模塊&#xff0c;該模塊機遇SSH用于連接遠程服務器并執行相關操作 SSHClient 用于連接遠程服務器并執行基本命令 基于用戶名密碼連接&#xff1a; 12…

關于typedef的使用方法

在計算機編程語言中用來為復雜的聲明定義簡單的別名。與宏定義有些差異。它本身是一種存儲類的keyword&#xff0c;與auto、extern、mutable、static、register等keyword不能出如今同一個表達式中。typedef聲明&#xff0c;簡稱typedef&#xff0c;為現有類型創建一個新的名字&…

ADF BC:創建綁定到業務組件的UI表

在此示例中&#xff0c;我們將展示如何創建綁定到業務組件的簡單UI表&#xff08;af&#xff1a;table&#xff09;。 我再次嘗試使用簡單的標準在網上進行搜索&#xff1a; “如何創建綁定到業務組件ADF 11g的af&#xff1a;table” 我必須承認我沒有得到我想要的答案。 信息…

linux驅動程序混合架構,嵌入式系統最小驅動框架(類似linux驅動程序架構)(示例代碼)...

2010年就打算把linux里的驅動框架核心代碼摳出來的&#xff0c;但是由于懶而且linux代碼量大&#xff0c;一直下不了手。最近調試的intel curie里驅動架構也類似linux&#xff0c;代碼就少多了&#xff0c;由于工作需要不得不梳理一下這一堆代碼&#xff0c;今天花了一下午&…

MyBaits 錯誤分析

錯誤原因&#xff1a;在DAO的映射文件中&#xff0c;在映射標簽中的type類型寫成DAO類了&#xff0c;應該寫成javaBean轉載于:https://www.cnblogs.com/shuaiandjun/p/5428847.html

超越JUnit –測試框架的替代方案

JUnit是事實上的Java單元測試框架&#xff0c;但是可能有一些新的&#xff08;不是那么新的&#xff09;框架可以用于Web開發。 在采用之前可能要問自己的問題&#xff1a; 它們是否快速&#xff0c;容易開發&#xff0c;因此成本低廉&#xff1f; 他們運行快并因此鼓勵采用嗎…

tensorflow mnist read_data_sets fails

下載處理mnist數據時出現如下錯誤 VisibleDeprecationWarning: converting an array with ndim > 0 to an index will result in an error in the future 解決方法&#xff1a; 在input_data.py文件中return numpy.frombuffer(bytestream.read(4), dtypedt) 后添加[0] retur…

斑馬打印機linux驅動安裝教程,linux-Zebra軟件包的基本安裝與配置

Zebra是一個路由軟件包&#xff0c;提供基于TCP/IP路由服務&#xff0c;支持RIPv1, RIPv2, RIPng, OSPFv2, OSPFv3, BGP- 4,和 BGP-4等眾多路由協議。Zebra還支持BGP特性路由反射器(Route Reflector)。除了傳統的 IPv4路由協議&#xff0c;Zebra也支持IPv6路由協議。如果運行的…

iOS 改變App狀態欄顏色為白色

默認狀態欄為黑色&#xff0c;對于某些App不是很美觀&#xff0c;變成白色很簡單&#xff0c;只需要兩個步驟。 1.在Info.plist中添加新項目&#xff0c;View controller-based status bar appearance&#xff0c;Boolean值為No. 2.在AppDelegate的- (BOOL)application:(UIAppl…