使用Spring AspectJ和Maven進行面向方面的編程

Spring框架附帶AOP支持。 實際上,如Spring參考文檔中所述 ,

Spring的關鍵組件之一是AOP框架。 盡管Spring IoC容器不依賴于AOP,這意味著您不需要使用AOP,但AOP是對Spring IoC的補充,以提供功能強大的中間件解決方案。 AOP在Spring框架中用于…

  • …提供聲明性企業服務,尤其是代替EJB聲明性服務。 此類服務中最重要的是聲明式事務管理。 ?
  • …允許用戶實現自定義方面,并通過AOP補充其對OOP的使用。

盡管如此,與完整的AOP實現(例如AspectJ)相比, Spring AOP框架還是有某些限制。 人們在使用Spring AOP框架時遇到的最常見問題源于以下事實: Spring AOP是“基于代理的”。 換句話說,當將bean用作依賴項并且應通過特定方面建議其方法時,IoC容器將注入“方面感知” bean代理,而不是bean本身。 為了對用戶透明地對代理bean實例執行方法調用,以便在將調用委派給實際的“代理” bean之前和/或之后執行方面邏輯。

此外, Spring AOP框架使用JDK動態代理或CGLIB創建給定目標對象的代理。 第一個只能為接口創建代理,而第二個可以代理具體類,但有一定的限制。 特別是,如Spring參考文檔中所述 ,

如果要代理的目標對象實現至少一個接口,則將使用JDK動態代理。 目標類型實現的所有接口都將被代理。 如果目標對象未實現任何接口,則將創建CGLIB代理。

總而言之,在使用Spring AOP框架時,您應該牢記兩個重要事項:

  1. 如果您的“代理” bean實現了至少一個接口,則只能將代理bean強制轉換為該接口。 如果嘗試將其強制轉換為“代理” bean類,則應期望在運行時引發ClassCastException。 盡管如此, Spring AOP框架提供了強制CGLIB代理的選項,但有上述限制(請參閱Spring參考文檔的相關章節)
  2. 方面不適用于術中呼叫。 這意味著代理無法攔截來自相同“代理” bean的另一個方法的方法的調用

我們建議克服以上問題的方法是使用AspectJ編織。 換句話說,將方面邏輯直接注入到目標類中,并消除了代理所有方法的必要性。 有三種方法可以注入AspectJ方面所隱含的指令:

  1. 編譯時間編織–通過AspectJ編譯器編譯目標源或方面類
  2. 編譯后編織–向已編譯的類注入方面指令
  3. 加載時間編織–在類加載期間向字節碼注入方面指令

可以使用上述任何方法。 在本教程中,我們將介紹如何在Spring和Maven中使用AspectJ編譯時編織。 我們將實現最小的“問候” Spring服務和相關的“問候” AspectJ方面。 Spring服務方法調用將被AspectJ方面攔截。 AspectJ方面將使用其自己的“問候”消息來豐富Spring服務的“問候”消息。 AspectJ方面的“問候”消息將從Spring容器中注入,只是為了展示如何將Spring依賴項注入到AspectJ方面。

已經為其bean服務實現了方面的Spring用戶可以透明地切換到AspectJ ,這意味著由于Spring AOP框架使用AspectJ切入點表達語言的子集而無需編寫任何特殊代碼,并且@AspectJ Spring方面完全符合AspectJ的編織要求。 。

我們首選的開發環境是Eclipse ,因此,必須先安裝具有Maven支持的Eclipse 。 用于Eclipse的Maven插件的安裝不在本教程的討論范圍內,因此將不予討論。 但是,您將需要以下組件:

  1. 從這里蝕
  2. 從這里開始 ,Eclipse的Maven插件

在本教程中,我們將使用Eclipse Galileo,“ m2eclipse” Maven Integration for Eclipse插件版本0.10.0,Spring版本3.0.1,aspectjrt版本1.6.7和Aspectj-maven-plugin版本1.3。

讓我們開始,

  1. 創建一個新的Maven項目,轉到File? 項目? Maven? Maven項目
  2. 在向導的“選擇項目名稱和位置”頁面中,確保未選中“創建簡單項目(跳過原型選擇)”選項,單擊“下一步”以繼續使用默認值
  3. 在向導的“選擇原型”頁面中,在“目錄”下拉列表中選擇“ Nexus Indexer”,并在刷新原型選擇區域后,從“ org.codehaus.mojo”中選擇“ webapp-jee5”原型。原型”。 您可以使用“過濾器”文本框來縮小搜索結果范圍。 點擊“下一步”繼續
  4. 在向導的“輸入工件ID”頁面中,您可以定義項目的名稱和主程序包。 我們將“ Group Id”變量設置為“ com.javacodegeeks”,將“ Artifact Id”變量設置為“ aspectjspring”。 前面提到的選擇組成了主項目包“ com.javacodegeeks.aspectjspring”和項目名“ aspectjspring”。 點擊“完成”退出向導并創建您的項目

讓我們回顧一下有關Maven Web項目結構的一些事情

  1. / src / main / java文件夾包含應用程序動態內容的源文件
  2. / src / test / java文件夾包含用于單元測試的所有源文件
  3. / src / main / webapp文件夾包含用于創建有效的Web應用程序的基本文件,例如“ web.xml”
  4. / target文件夾包含已編譯和打包的可交付成果
  5. “ pom.xml”是項目對象模型(POM)文件。 包含所有項目相關配置的單個文件。

為了在運行時正確使用Spring ,我們必須向Web應用程序提供所有必需的庫。 打開“ pom.xml”的圖形編輯器并執行以下更改:

  1. 在POM編輯器的“概述”頁面上的“屬性”部分中找到并執行以下更改:
  • 創建一個名稱為org.springframework.version且值為3.0.1.RELEASE的新屬性
    • 根據您的Java運行時環境的版本,創建一個名稱為maven.compiler.source的新屬性,并賦值為value,我們將使用1.6
      • 根據您的Java運行時環境的版本創建一個名稱為maven.compiler.target的新屬性,并將其值設置為value,我們將使用1.6
        • 導航到POM編輯器的“ Dependencies”頁面,并創建以下依賴關系(您應在該頁面的“ Dependency Details”部分的“ GroupId”,“ Artifact Id”和“ Version”字段中進行填充):
          • 組ID: org.springframework工件ID: spring-web版本: $ {org.springframework.version}
            • ID:org.aspectj工件ID:aspectjrt版本:1.6.7
            1. 導航到POM編輯器的“插件”頁面,并創建以下插件(您應在該頁面的“插件詳細信息”部分的“ GroupId”,“工件ID”和“版本”字段中進行填充):
              • 組ID: org.codehaus.mojo工件ID: aspectj-maven-plugin版本: 1.3
              1. 在POM編輯器的“插件”頁面上,選擇新創建的插件(從“插件”部分中),并將其綁定到編譯執行目標。 為此,請找到“執行”部分并創建一個新的執行。 在“執行詳細信息”部分,創建一個新目標并將其命名為“ compile
              2. 新創建的插件需要進行最后的配置更改。 為了使AspectJ編譯器正確地編織方面類,我們必須定義所使用的Java運行時環境版本。 我們需要編輯“ pom.xml”文件來執行更改。 選擇POM編輯器的“ pom.xml”頁面,找到新創建的插件,并如下進行更改:
              3. <plugin><groupId>org.codehaus.mojo</groupId><artifactId>aspectj-maven-plugin</artifactId><version>1.3</version><configuration><source>${maven.compiler.source}</source><target>${maven.compiler.target}</target></configuration><executions><execution><goals><goal>compile</goal></goals></execution></executions>
                </plugin>
              4. 最后,如下所示更改“ maven-compiler-plugin”:
              5. <plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>2.0.2</version><configuration><source>${maven.compiler.source}</source><target>${maven.compiler.target}</target></configuration>
                </plugin>

                如您所見, Maven以聲明方式管理庫依賴關系。 創建本地存儲庫(默認情況下,位于{user_home} /。m2文件夾下),所有必需的庫都從公共存儲庫下載并放置在該庫中。 此外,庫內的依賴關系會自動解決和處理。

                下一步是為Web應用程序提供掛鉤,以便在啟動時加載Spring上下文。

                在/ src / main / webapp / WEB-INF下找到“ web.xml”文件,并添加以下內容:

                為了在啟動時加載Spring上下文,

                <listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
                </listener>

                現在讓我們創建將驅動Spring容器的applicationContext.xml文件。 在/ src / main / webapp / WEB-INF目錄下創建文件。 下面是一個示例“ applicationContext.xml”

                <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"xmlns:task="http://www.springframework.org/schema/task"xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsdhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsdhttp://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsdhttp://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd"><context:component-scan base-package="com.javacodegeeks.aspectjspring" /><bean class="com.javacodegeeks.aspectjspring.aspects.GreetingAspect" factory-method="aspectOf"><property name="message" value="Hello from Greeting Aspect"/></bean></beans>

                這里要注意的事情:

                1. 將context:component-scan元素的base-package屬性更改為項目的基本包,以便掃描Spring組件
                2. 僅當我們要向它們注入依賴項時,才必須在“ applicationContext.xml”中定義我們的方面
                3. AspectJ表示術語“方面關聯”。 它定義了如何管理方面狀態。 支持以下狀態關聯:
                • 每個JVM –構造和使用一個共享的方面實例(默認)
                • 每個對象–每個建議對象的方面都有其自己的狀態
                • 每個控制流–方面在每個特定控制流中都有自己的狀態
                  所有AspectJ方面類都具有“ hasAspect()”和“ aspectOf()”靜態方法。 這些方法由AspectJ編譯器/加載時間編織器隱式生成。 因此,對于默認的方面狀態,可以使用“ aspectOf()”方法來檢索一個方面的實例

                現在讓我們創建“問候” Spring服務和相關的“問候” AspectJ方面。 在主程序包下創建一個名為“服務”的子程序包,并將“ GreetingService”類放在此處。 下面是一個示例“問候”服務:

                package com.javacodegeeks.aspectjspring.services;import org.springframework.stereotype.Service;@Service("greetingService")
                public class GreetingService {public String sayHello() {return "Hello from Greeting Service";}}

                在主包下創建一個名為“ aspects”的子包,并將“ GreetingAspect”類放在此處。 下面是一個示例“問候”方面:

                package com.javacodegeeks.aspectjspring.aspects;import org.aspectj.lang.ProceedingJoinPoint;
                import org.aspectj.lang.annotation.Around;
                import org.aspectj.lang.annotation.Aspect;@Aspect
                public class GreetingAspect {private String message;public void setMessage(String message) {this.message = message;}@Around("execution(* com.javacodegeeks.aspectjspring.services.GreetingService.*(..))")public Object advice(ProceedingJoinPoint pjp) throws Throwable {String serviceGreeting = (String) pjp.proceed();return message + " and " + serviceGreeting;}}

                最后,在/ src / main / webapp文件夾下找到項目的主網頁“ index.jsp”,并進行如下更改:

                <%@ page language="java" import="org.springframework.web.context.WebApplicationContext, org.springframework.web.context.support.WebApplicationContextUtils, com.javacodegeeks.aspectjspring.services.GreetingService"%>
                <%@page contentType="text/html" pageEncoding="UTF-8"%>
                <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd"><% 
                WebApplicationContext webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
                GreetingService greetingService = (GreetingService) webApplicationContext.getBean("greetingService");
                %>
                <html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>JSP Page</title></head><body><h1>Test service invoked and greets you by saying : <%=greetingService.sayHello()%></h1></body>
                </html>

                這里要注意的事情:

                1. 頁面加載后,我們檢索Spring Web應用程序上下文,并查找“問候”服務。 我們要做的就是調用“ sayHello()”方法,從我們的方面和服務中查看合并的問候消息

                要構建應用程序,請右鍵單擊您的項目? 運行為? Maven包

                要部署Web應用程序,只需將“ .war”文件從“ target”目錄復制到Apache – Tomcat “ webapps”文件夾

                午餐應用程序將您的瀏覽器指向以下地址

                http:// localhost:8080 / {application_name} /

                如果一切順利,您應該會看到顯示以下內容的主網頁:

                “測試服務被調用并打招呼:“ Greeting Aspect向您問好,Greeting Service向您問好”

                您可以從這里下載項目

                希望你喜歡

                賈斯汀

                相關文章 :

                • GWT 2 Spring 3 JPA 2 Hibernate 3.5教程
                • GWT Spring和Hibernate進入數據網格世界
                • Spring3 RESTful Web服務
                • GWT 2 Spring 3 JPA 2 Hibernate 3.5教程– Eclipse和Maven 2展示
                • 帶有Spring和Maven教程的JAX–WS

                翻譯自: https://www.javacodegeeks.com/2010/07/aspect-oriented-programming-with-spring.html

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

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

              相關文章

              hadoop5--mapreduce設計模式

              運行結果附圖 本節課程主要內容為學習MapReduc設計模式&#xff0c;并編寫java程序對日志文件進行處理。 課本上介紹的MapReduce的設計模式主要包含:計數(Counting),分類(Classification),過濾處理(Filtering),排序(Sorting),去重計數(Distinct Counting),相關計數(Cross-Corre…

              ES5中新增的Array方法詳細說明

              http://www.zhangxinxu.com/wordpress/2013/04/es5%E6%96%B0%E5%A2%9E%E6%95%B0%E7%BB%84%E6%96%B9%E6%B3%95/轉載于:https://www.cnblogs.com/lmw425317/p/5339539.html

              jqGrid,REST,AJAX和Spring MVC集成

              兩年多以前&#xff0c;我寫了一篇關于兩個如何在Struts2中實現優雅的CRUD的文章。 實際上&#xff0c;我必須就該主題寫兩篇文章&#xff0c;因為該主題如此廣泛。 今天&#xff0c;我采用了一套更為流行的&#xff0c;完善的框架和庫&#xff0c;采用了更為輕量級的現代方法。…

              Java-馬士兵設計模式學習筆記-代理模式--動態代理 修改成可以代理任意接口

              一、概述 1.目標&#xff1a;把Proxy修改成可以代理任意接口及其任意方法 2.思路&#xff1a; (1)代理任意接口&#xff1a;把接口類型作為參數傳給Proxy的newProxyInstance(Class interfze) (2)代理任意方法&#xff1a;用interfze.getMethods()取出所有方法&#xff0c;拼接實…

              PTA習題

              PTA習題 PTA浙大版《C語言程序設計&#xff08;第3版&#xff09;》 題目集5-6 水仙花數是指一個N位正整數&#xff08;N≥3&#xff09;&#xff0c;它的每個位上的數字的N次冪之和等于它本身。 本題要求編寫兩個函數&#xff0c;一個判斷給定整數是否水仙花數&#xff0c;…

              acdream 1409 Musical 狀壓DP

              鏈接&#xff1a;http://acdream.info/problem?pid1409 題意&#xff1a;整個國家有n座城市&#xff0c;每座城市有三種粉絲。 第一種一周看一場音樂劇&#xff0c;挑選的音樂劇是已經在周圍城市播放上演過的次數最多的音樂劇中的隨機一個。 另外一種每天看一場音樂劇&#xf…

              真正的模塊化Web應用程序:為什么沒有開發標準?

              OSGI &#xff0c; SpringSource &#xff0c; Jboss模塊 &#xff0c;J2EE和清單永遠不會結束。所有這些技術都向他們的最終用戶/開發人員保證了相同的東西&#xff0c;或多或少是Java模塊化Web應用程序&#xff08;&#xff1f;&#xff09;。 但是&#xff0c;我們當中有多少…

              C語言5-7習題

              本題要求實現一個函數&#xff0c;用下列公式求cos(x)的近似值&#xff0c;精確到最后一項的絕對值小于e&#xff1a; #include <stdio.h> #include <math.h>double funcos( double e, double x );int main() { double e, x;scanf("%lf %lf", &…

              JDBC批處理executeBatch

              JDBC運行SQL聲明&#xff0c;有兩個處理接口&#xff0c;一PreparedStatement,Statement,一般程序JDBC有多少仍然比較PreparedStatement 只要運行批處理&#xff0c;PreparedStatement少一點Statement ps conn.prepareStatement(sql); for(int i 0;i<10;i){ ps.setString(…

              BC div2補題以及 復習模除 逆元__BestCoder Round #78 (div.2)

              第一題沒話說 智商欠費 加老柴輔導終于過了 需要在意的是數據范圍為2的63次方-1 三個數相加肯定爆了 四邊形的定義  任意邊小于其余三邊之和 換句話說就是  最長邊小于其余三邊之和 這樣的話問題轉化為 最長邊依次減其余三邊的結果是否小于等于0 還有一點是題目出現0邊 即最…

              習題6-1 分類統計字符個數 (15 分)

              本題要求實現一個函數&#xff0c;統計給定字符串中英文字母、空格或回車、數字字符和其他字符的個數。 函數接口定義&#xff1a; void StringCount( char s[] );其中 char s[] 是用戶傳入的字符串。函數StringCount須在一行內按照 letter 英文字母個數, blank 空格或回車…

              Servlet 3.0異步處理可將服務器吞吐量提高十倍

              Servlet是Java中處理服務器端邏輯的主要組件&#xff0c;新的3.0規范引入了一些非常有趣的功能&#xff0c;其中異步處理是最重要的功能之一。 可以利用異步處理來開發高度可伸縮的Web應用程序。 使用此功能可以有效地構建Web 2.0站點和AJAX應用程序。 我們的JCG合作伙伴之一To…

              使用secureCRT連接VMware-Ubuntukylin虛擬機

              使用SecureCRT連接VMware時總是提醒主機拒絕連接。這時可以使用sudo apt-get install openssh-server openssh-client&#xff0c;在主機上安裝ssh. 安裝成功后&#xff0c;可以連接到主機了。 如果顯示遠程主機拒絕連接。則可以使用如下方法。 VMware里面裝的是Ubuntukylin版本…

              加載音頻Audio

              var cameraAudio new Audio(); cameraAudio.src camera.wav;// 設置音頻對象的屬性,預加載視頻 var options_audio { preload : auto } for(var key in options_audio){ if(options_audio.hasOwnProperty(key) && (key in cameraAudio)){ cameraAudio[key] opti…

              習題6-2 使用函數求特殊a串數列和 (20 分)

              給定兩個均不超過9的正整數a和n&#xff0c;要求編寫函數求aaaaaa?aa?a&#xff08;n個a&#xff09;之和。 int fn( int a, int n ); int SumA( int a, int n );其中函數fn須返回的是n個a組成的數字&#xff1b;SumA返回要求的和。 我的代碼&#xff1a; int fn( int a, i…

              Java中可怕的雙重檢查鎖定成語

              本文討論的問題不是新問題&#xff0c;但即使是經驗豐富的開發人員也仍然很棘手。 單例模式是常見的編程習慣。 但是&#xff0c;當與多個線程一起使用時&#xff0c;必須進行某種類型的同步&#xff0c;以免破壞代碼。 Khangaonkar報告中的 JCG合作伙伴Manoj Khangaonkar在一篇…

              國內有哪些好的刷題網站?

              http://www.zhihu.com/question/25574458 Luau Lawrence&#xff0c;Data Mining 弱雞 / PhDNTU 溫夢強、石一帆、知乎用戶 等人贊同 - Welcome To PKU JudgeOnline 北京大學的Online Judge。POJ上面的題目有點老了&#xff0c;但好處是做的人多&#xff0c;經典算法題多&…

              IE版本判斷

              我們常常會在網頁的HTML里面看到形如[if lte IE 9]……[endif]的代碼&#xff0c;表示的是限定某些瀏覽器版本才能執行的語句&#xff0c;那么這些判斷語句的規則是什么呢&#xff1f;請看下文&#xff1a; <!--[if !IE]><!--> 除IE外都可識別 <!--<![endif]…

              Js 流程控制

              流程控制 順序、分支、循環 順序結構 代碼一行一行從上往下執行并解析 分支結構 if語句 switch語句 if語句 單分支 if(條件表達式){ //語句塊 } 含義&#xff1a;當條件表達式為真的時候就執行里面的語句塊 示例&#xff1a; 雙分支&#xff1a; if(條件表達式){ //語句塊1 }el…

              習題6-3 使用函數輸出指定范圍內的完數 (20 分)

              本題要求實現一個計算整數因子和的簡單函數&#xff0c;并利用其實現另一個函數&#xff0c;輸出兩正整數m和n&#xff08;0<m≤n≤10000&#xff09;之間的所有完數。所謂完數就是該數恰好等于除自身外的因子之和。例如&#xff1a;6123&#xff0c;其中1、2、3為6的因子。…