日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring面向方面的编程

發(fā)布時(shí)間:2023/12/3 javascript 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring面向方面的编程 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

介紹

在理想的面向?qū)ο笙到y(tǒng)中,我們希望將每個(gè)對(duì)象設(shè)計(jì)為執(zhí)行一項(xiàng)特定任務(wù)。 但是,除了執(zhí)行其主要任務(wù)外,對(duì)象還執(zhí)行被動(dòng)任務(wù),例如日志記錄,事務(wù),安全性,緩存等。這些被動(dòng)活動(dòng)是必需的,但不是業(yè)務(wù)邏輯的一部分,被稱為“ 跨切問題 ”。

(橫切關(guān)注點(diǎn)==系統(tǒng)中常用的功能)

橫切關(guān)注點(diǎn)與業(yè)務(wù)邏輯分開可能是編寫精心設(shè)計(jì)的解耦代碼的重要一步。 讓我們思考一下解決交叉切割問題的方法

遺產(chǎn)

繼承立即在腦海中彈出,我們可以繼承通用功能并在對(duì)象中使用它。 但是繼承通用功能需要我們?cè)O(shè)計(jì)一個(gè)基類。 如果我們?cè)诙鄠€(gè)地方重用該類,那么以后修改類可能會(huì)很困難。

繼承==以后很難修改(非彈性代碼)

代表團(tuán)

委派是處理交叉切割問題的更好方法。 記住組成要重于繼承,(授權(quán)和組成要共同關(guān)注)。 但是,那么我們將不得不在許多地方進(jìn)行調(diào)用以委托對(duì)象,從而使其變得繁瑣。

委派==繁瑣

面向方面的編程

這是否意味著我們要喝湯了。 相反,這給我們提供了第三種也是最好的方法,即面向方面的編程。 AOP避免了繼承的脆弱性和委派的繁瑣性。 AOP在相互交叉的關(guān)注點(diǎn)領(lǐng)域大放異彩

什么是AOP?

AOP允許我們將橫切關(guān)注點(diǎn)模塊化到稱為Aspects的特殊對(duì)象中,從而創(chuàng)建更清晰和分離的代碼。 有了適當(dāng)?shù)姆矫?#xff0c;對(duì)象就不必?fù)?dān)心執(zhí)行被動(dòng)橫切問題,因?yàn)锳OP會(huì)處理所有這些問題。

與AOP有關(guān)的術(shù)語

像任何成功的技術(shù)一樣,AOP也帶有自己的術(shù)語和術(shù)語集。 讓我們先看一下那些,然后再進(jìn)行更深入的了解AOP的工作。

  • 關(guān)注 –這些是基于其功能模塊化的系統(tǒng)的一部分。 有兩種類型的關(guān)注點(diǎn)。 1.核心關(guān)注點(diǎn)2.跨領(lǐng)域關(guān)注點(diǎn)。 核心關(guān)注點(diǎn)與系統(tǒng)的業(yè)務(wù)邏輯相關(guān),即系統(tǒng)執(zhí)行的主動(dòng)任務(wù),例如生成工資單,獲取員工記錄,進(jìn)行銀行轉(zhuǎn)賬等。跨部門關(guān)注點(diǎn)是執(zhí)行主動(dòng)任務(wù)(例如日志記錄,緩存)所需的被動(dòng)任務(wù)等等
  • 連接點(diǎn)–連接點(diǎn)是執(zhí)行流程中的一點(diǎn),其中發(fā)生了一些動(dòng)作,并且有可能應(yīng)用Aspect(跨領(lǐng)域關(guān)注點(diǎn))。 連接點(diǎn)可以是調(diào)用方法,引發(fā)異常或?qū)ο鬆顟B(tài)改變。
  • 建議 – AOP中的每個(gè)方面都有其目的,即它必須完成的工作。 該作業(yè)必須在連接點(diǎn)處應(yīng)用。 方面的工作或目的稱為建議。 除了定義方面的工作之外,建議還定義方面執(zhí)行工作的時(shí)間。 應(yīng)該在核心任務(wù)完成執(zhí)行之前或之后應(yīng)用作業(yè),還是在兩者之前和之后應(yīng)用作業(yè)。
  • 切入點(diǎn) –系統(tǒng)中可以有許多連接點(diǎn),但是并非所有方面都由Aspect建議。 Aspect從Pointcut獲得幫助,以選擇要在其中編織建議的Joinpoint。
  • 方面 –建議和切入點(diǎn)定義了方面。 正如我們看到的,建議定義了方面的工作以及何時(shí)執(zhí)行。 雖然Pointcut定義了方面編織建議的位置。 因此,工作的內(nèi)容,時(shí)間和地點(diǎn)定義了方面。
  • 目標(biāo) –目標(biāo)是被建議的對(duì)象。 (核心關(guān)注)。 在AOP的幫助下,該對(duì)象可以自由地執(zhí)行其主要任務(wù),而不必?fù)?dān)心交叉問題。
  • 代理 –將建議應(yīng)用于目標(biāo)對(duì)象時(shí),將創(chuàng)建一個(gè)代理對(duì)象。 AOP容器創(chuàng)建并管理對(duì)象的生命周期,程序員無需擔(dān)心它們。
  • 編織 –編織是將Advice或Aspect應(yīng)用于目標(biāo)對(duì)象以創(chuàng)建代理對(duì)象的過程。 編織可以在編譯時(shí)或類加載時(shí)或在運(yùn)行時(shí)完成。 通常,Spring AOP在運(yùn)行時(shí)將方面編織到目標(biāo)對(duì)象中。
  • 那是要消化的一長串術(shù)語。 在繼續(xù)之前,請(qǐng)花點(diǎn)時(shí)間了解它們。

    咨詢類型

    沉迷于示例之前的最后一篇文章是學(xué)習(xí)建議的類型。 主要有4種建議。

  • 建議之前 –在Joinpoint開始執(zhí)行之前應(yīng)用建議之前。 通過實(shí)現(xiàn)org.springframework.aop.MethodBeforeAdvice接口來創(chuàng)建BeforeAdvice。 要實(shí)現(xiàn)的方法是公共無效(方法m,對(duì)象args [],對(duì)象目標(biāo))拋出Throwable
  • 返回建議之后–在Joinpoint完成執(zhí)行之后應(yīng)用建議之后。 AfterReturningAdvice是通過實(shí)現(xiàn)org.springframework.aop.AfterReturningAdvice接口創(chuàng)建的。 ThingableReturning(Method m,Object args [],Object target)拋出后 ,要實(shí)現(xiàn)的方法是公共無效
  • 引發(fā)建議 –當(dāng)Joinpoint在執(zhí)行過程中引發(fā)異常時(shí),將應(yīng)用引發(fā)建議。
  • 圍繞建議 –此建議圍繞Joinpoint執(zhí)行,并在Joinpoint執(zhí)行之前和之后執(zhí)行。 這甚至可以用來控制Joinpoint的調(diào)用。
  • 我們將嘗試在SpringAOP的幫助下開發(fā)一個(gè)簡(jiǎn)單的緩存。 緩存具有三個(gè)主要的核心問題。

    核心關(guān)注點(diǎn)

  • 將對(duì)象保存在緩存中。
  • 從緩存返回對(duì)象。
  • 從緩存中刪除對(duì)象。
  • 現(xiàn)在,除了這些核心問題之外,緩存框架還有其他被動(dòng)任務(wù)。 這些被動(dòng)任務(wù)構(gòu)成了交叉問題。

    橫切關(guān)注點(diǎn)

  • 達(dá)到其大小限制時(shí)重新調(diào)整緩存大小。 (LRU)實(shí)施。
  • 鎖定對(duì)象以防止在讀取對(duì)象時(shí)將其刪除。
  • 鎖定高速緩存以防止在調(diào)整大小時(shí)阻止和讀取/寫入/刪除高速緩存。
  • 編碼所有這些橫切關(guān)注點(diǎn)可能是耗時(shí)且乏味的,因此讓我們簡(jiǎn)化示例,當(dāng)緩存已滿時(shí),我們將僅實(shí)現(xiàn)調(diào)整大小邏輯。 因此,在完成示例之后,我們將擁有一個(gè)可以放置,獲取和刪除對(duì)象的緩存。 例如,緩存的最大大小已設(shè)置為10。 一旦高速緩存存儲(chǔ)了10個(gè)對(duì)象,則對(duì)高速緩存的任何添加都將導(dǎo)致通過刪除第一個(gè)對(duì)象來刪除(重新調(diào)整大小)高速緩存。 調(diào)整大小的操作由使用Spring AOP創(chuàng)建的Aspect控制。 這是示例中要遵循的步驟

    可以從SVN此處下載示例代碼: https : //www.assembla.com/code/weblog4j/subversion/nodes/31/SpringDemos/trunk

  • 依賴關(guān)系 – AOP是spring的核心功能,因此要使Spring AOP正常運(yùn)行,我們需要的是核心spring jar,因此在您的POM中添加以下依賴關(guān)系。 <dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-beans</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring.version}</version></dependency>
  • 核心緩存對(duì)象。 package com.aranin.spring.aop;import java.util.Date; import java.util.LinkedHashMap; import java.util.Map;public class MyCache {private LinkedHashMap<String, Object> cacheMap = new LinkedHashMap<String, Object>();private LinkedHashMap<String, Date> timeStampMap = new LinkedHashMap<String, Date>();/*** defines the max size of hashmap*/private long maxsize = 10; //should come from properties file or some configuration/*** how long the object should be stored before it is evicted from cache*/private long objectLifeTime = 10000;private boolean lock = false;public LinkedHashMap<String, Object> getCacheMap() {return cacheMap;}public void setCacheMap(LinkedHashMap<String, Object> cacheMap) {this.cacheMap = cacheMap;}public LinkedHashMap<String, Date> getTimeStampMap() {return timeStampMap;}public void setTimeStampMap(LinkedHashMap<String, Date> timeStampMap) {this.timeStampMap = timeStampMap;}public long getMaxsize() {return maxsize;}public void setMaxsize(long maxsize) {this.maxsize = maxsize;}public long getObjectLifeTime() {return objectLifeTime;}public void setObjectLifeTime(long objectLifeTime) {this.objectLifeTime = objectLifeTime;}public boolean isLock() {return lock;}public void setLock(boolean lock) {this.lock = lock;}/*** This method is used to retrive the object from cache* @param key* @return*/public Object get(String key){return this.getCacheMap().get(key);}/*** this method is used for putting an object in cache* @param key* @param object*/public void put(String key, Object object){//get the curr dateDate date = new Date(System.currentTimeMillis());//set object in cacheMapthis.getCacheMap().put(key,object);//put timestamp in cachethis.getTimeStampMap().put(key, date);}public void delete(String key){this.getCacheMap().remove(key);this.getTimeStampMap().remove(key);}public void clearAll(){this.setCacheMap(new LinkedHashMap<String, Object>());this.setTimeStampMap(new LinkedHashMap<String, Date>());}/*** remove last 2 entries* not worried about object life time* this is just an example*/public void resize(){System.out.println("inside resize");long size = this.getCacheMap().size();System.out.println("size + " + size);if(size == this.getMaxsize()){System.out.println("max size has reached");Map.Entry<String, Date> firstEntry = this.getTimeStampMap().entrySet().iterator().next();System.out.println("removing : " + firstEntry.getKey() + " value : " + firstEntry.getValue());this.timeStampMap.remove(firstEntry.getKey());Map.Entry<String, Object> firstCEntry = this.getCacheMap().entrySet().iterator().next();System.out.println("removing : " + firstCEntry.getKey() + " value : " + firstCEntry.getValue());this.cacheMap.remove(firstCEntry.getKey());}System.out.println("leaving resize with size : " + this.getCacheMap().size());} }

    這個(gè)課沒什么好說的。 有兩個(gè)LinkedHashMaps,一個(gè)用于存儲(chǔ)對(duì)象,另一個(gè)用于存儲(chǔ)將對(duì)象推入緩存時(shí)的時(shí)間戳。 最大大小設(shè)置為10,并且具有g(shù)et,put和delete方法。 還有一個(gè)調(diào)整大小的方法,Aspect將調(diào)用此方法,稍后我們將進(jìn)行檢查。

  • 調(diào)整建議 package com.aranin.spring.aop;import org.springframework.aop.MethodBeforeAdvice;import java.lang.reflect.Method;public class ResizeAdvice implements MethodBeforeAdvice {@Overridepublic void before(Method method, Object[] args, Object target) throws Throwable {System.out.println("invoking " + method.getName() + " on " + target.getClass() + " Object");if(method.getName().equals("put")){System.out.println("before invoking " + method.getName());((MyCache)target).resize();}} }

    如您所見,這是建議之前的一種方法。 類實(shí)現(xiàn)MethodBeforeAdvice接口,該接口包含單個(gè)方法before()。 如果您檢查該方法,則在我們調(diào)用put方法時(shí),將檢查rezise方法是否被調(diào)用。

  • Spring上下文springaopdemo.xml <?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:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.1.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-3.1.xsd"><bean id="resizeAdvice" class="com.aranin.spring.aop.ResizeAdvice" /><bean id="myCache" class="com.aranin.spring.aop.MyCache" /><bean id="myAOPCache"class="org.springframework.aop.framework.ProxyFactoryBean"><property name="target" ref="myCache" /><property name="interceptorNames"><list><value>resizeAdvice</value></list></property></bean> </beans>

    如果您注意到上述xml文件,則MyCache和ResizeAdvice都已注冊(cè)為spring bean。 文件中的主要bean是myAOPCache。 這是spring aop在核心類上應(yīng)用建議后創(chuàng)建的代理對(duì)象。 代理對(duì)象由ProxyFactoryBean類創(chuàng)建。 我們將myCache對(duì)象的引用傳遞給代理對(duì)象,并注冊(cè)所有將應(yīng)用于代理類的建議。

  • 最后,讓我們檢查Client,這將有助于我們運(yùn)行此演示。 package com.aranin.spring.aop;import org.springframework.context.ApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext;public class MyCacheClient {public static void main(String[] args){ApplicationContext springcontext = new FileSystemXmlApplicationContext("D:/samayik/SpringDemos/src/main/resources/springaopdemo.xml");MyCache myCache = (MyCache)springcontext.getBean("myAOPCache");myCache.put("1", "1");myCache.put("2", "2");myCache.put("3", "3");myCache.put("4", "4");myCache.put("5", "5");myCache.put("6", "6");myCache.put("7", "7");myCache.put("8", "8");myCache.put("9", "9");myCache.put("10", "10");System.out.println((String)myCache.get("1"));System.out.println((String)myCache.get("2"));System.out.println((String)myCache.get("10"));myCache.put("11", "11");System.out.println((String)myCache.get("1"));System.out.println((String)myCache.get("2"));System.out.println((String)myCache.get("10"));System.out.println((String)myCache.get("11"));}}

    在該類中,我們啟動(dòng)spring容器并加載spingaopdemo.xml中存在的bean。 我們?cè)诰彺嬷型扑?0個(gè)對(duì)象,當(dāng)我們嘗試推送第11個(gè)對(duì)象時(shí),第一個(gè)對(duì)象被刪除并插入第11個(gè)對(duì)象。 輸出很大,所以我沒有發(fā)布輸出。 上課并檢查輸出是否令您滿意。

  • 摘要

    在這篇文章中,我們學(xué)習(xí)了如何使用面向方面的編程更好地處理交叉問題。 AOP是一個(gè)強(qiáng)大的概念,它使我們可以編寫更清晰和更分離的代碼。 AOP不提供任何新內(nèi)容。 它所做的只是將業(yè)務(wù)邏輯與系統(tǒng)必須執(zhí)行的其他普通任務(wù)分離。 它可以重用實(shí)現(xiàn)系統(tǒng)范圍內(nèi)交叉關(guān)注點(diǎn)的代碼。 我們還學(xué)習(xí)了與AOP相關(guān)的各種術(shù)語。 最后但并非最不重要的一點(diǎn)是,我們看到了一個(gè)簡(jiǎn)單的示例,在該示例中,我們使用Spring AOP創(chuàng)建了一個(gè)簡(jiǎn)單的方法前建議,并將其應(yīng)用于管理緩存系統(tǒng)。

    注意

    您可以自由使用和分發(fā)此代碼中開發(fā)的緩存系統(tǒng)。 盡管不建議在生產(chǎn)系統(tǒng)中使用它。

    一如既往,我一直希望這篇文章作為集體學(xué)習(xí)的啟動(dòng)平臺(tái),隨意發(fā)表一兩個(gè)關(guān)于您對(duì)AOP的看法以及如何計(jì)劃在代碼中使用它的評(píng)論。 祝您閱讀愉快。

    參考: Weblog4j博客上來自我們JCG合作伙伴 Niraj Singh的Spring面向方面編程 。

    翻譯自: https://www.javacodegeeks.com/2013/10/aspect-oriented-programming-with-spring-2.html

    總結(jié)

    以上是生活随笔為你收集整理的Spring面向方面的编程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。