1. 程式人生 > >AOP之5種增強方法應用範例

AOP之5種增強方法應用範例

         Spring AOP 提供了 5 種類型的通知,它們分別是 Before Advice(前置通知)、After Returning Advice(後置通知)、Interception Around Advice(周圍通知)、Throws Advice(異常通知)和 Introduction Advice(引介通知)。下面分別進行介紹。

1、前置通知(前置增強)

       前置通知顧名思意,該通知織入在方法呼叫之前。我們可以通過Spring 的MethodBeforeAdvice 介面實現。MethodBeforeAdvice 只提供方法before(),該方法無返回值,方法接受呼叫方法,方法引數和目標物件這3個引數。這裡需要注意的是,雖然before()方法得到了呼叫方法的引數,這裡值得注意的是方法引數可以進行更改!

建立一個工人介面類:

/**  
*功能 工人介面類
*作者 林炳文([email protected] 部落格:http://blog.csdn.net/evankaka)  
*時間 2015.4.22 
*/
package com.mucfc.advice;
public interface Worker {
	void getTool(String tool);
	void digSomething(String type);
	void initWork();

}

工人實現類:
/**  
*功能 工人實現類
*作者 林炳文([email protected] 部落格:http://blog.csdn.net/evankaka)  
*時間 2015.4.22 
*/
package com.mucfc.advice;

import javax.management.RuntimeErrorException;

public class DigWorker implements Worker{

	@Override
	public void getTool(String tool) {
     System.out.println("---------------呼叫方法--------------");	
     System.out.println("領取工具:"+tool);	
    // throw new RuntimeException("執行異常");
	}

	@Override
	public void digSomething(String type) {
	     System.out.println("---------------呼叫方法--------------");	
		 System.out.println("開始賣力挖取:"+type);	
		
	}

	@Override
	public void initWork() {
		System.out.println("生成一個DigWorker例項");			
	}
	

}

3、建立前置增強的方法:

/**  
*功能 前置增強方法
*作者 林炳文([email protected] 部落格:http://blog.csdn.net/evankaka)  
*時間 2015.4.22 
*/
package com.mucfc.advice;
import java.lang.reflect.Method;

import org.springframework.aop.MethodBeforeAdvice;
public class WearingBeforeAdvice implements MethodBeforeAdvice{


	public void before(Method arg0, Object[] arg1, Object arg2)
			throws Throwable {
		String thing=(String)arg1[0];
		System.out.println("--------------進行前置增強---------------");
		System.out.println("得到"+thing+"之前先穿上工作服!!");
	}

}

4、將增強方法織入到相應的地方
    //1、不使用xml配置例項化
    Worker target=new DigWorker();    
    BeforeAdvice advice=new WearingBeforeAdvice();
    //Spring提供的代理工廠
    ProxyFactory pFactory=new ProxyFactory();
    //設定代理目標,預設使用Cglib動態代理
    pFactory.setTarget(target);
    
    //為代理目標新增前置增強,這裡會為目標的每個方法都增加增強
    pFactory.addAdvice(advice);
    //生成代理例項
    Worker proxy=(Worker)pFactory.getProxy();
    proxy.getTool("鑽機");
    proxy.digSomething("煤炭");

結果:在工人實現類的兩個方法呼叫之前都進行了前置增強


介面代理預設是使用JDK動態代理,如要使用CGLIB動態程式碼,在加上:

    //指定做優化,又將使用cglib動態
    pFactory.setOptimize(true);

若要使用JDK動態代理,加上:

    //指定對介面進行代理,通過JDK動態代理
    pFactory.setInterfaces(target.getClass().getInterfaces());
二、後置增強

後置通知(After returning advice):在某連線點正常完成後執行的通知:例如,一個方法沒有丟擲任何異常,正常返回。

1、增強方法代理

/**  
*功能 後置增強方法
*作者 林炳文([email protected] 部落格:http://blog.csdn.net/evankaka)  
*時間 2015.4.22 
*/
package com.mucfc.advice;
import java.lang.reflect.Method;
import org.springframework.aop.AfterReturningAdvice;
public class WeaningAfterAdvice implements AfterReturningAdvice{

	@Override
	public void afterReturning(Object arg0, Method arg1, Object[] arg2,
			Object arg3) throws Throwable {
		System.out.println("--------------進行後置增強---------------");
		System.out.println("工作結束,請先脫掉工作服");
	}

}
工人還是上面的工人,其它方法不變。

2、我們在進行增強配置時,可以直接使用API函式,但是這樣比較複雜,下面我們來用XML註解配置的方法來同時實現前置和後後置增強

在src資料夾下新建 一個XML檔案,取名為beans.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:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans  
                http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
        http://www.springframework.org/schema/context  
        http://www.springframework.org/schema/context/spring-context-3.0.xsd">

然後就是下面的配置如下:
        <!-- 要進行增強的目標 -->
	<bean id="target" class="com.mucfc.advice.DigWorker" init-method="initWork"/>    
        
	<!-- 前置增強的方法 -->
	<bean id="beforeAdvice" class="com.mucfc.advice.WearingBeforeAdvice" />
	<!-- 後置增強的方法 -->
	<bean id="afterAdvice" class="com.mucfc.advice.WeaningAfterAdvice" />
	
	<!--同時設定前置增強和後置增強方法  -->
	<bean id="worker1" class="org.springframework.aop.framework.ProxyFactoryBean"
		p:proxyInterfaces="com.mucfc.advice.Worker" p:interceptorNames="beforeAdvice,afterAdvice"
		p:target-ref="target" lazy-init="true"/>
這裡 p:interceptorNames="beforeAdvice,afterAdvice"表示同時加入了前置和後置增強。

lazy-init="true"表示能要用的時候才初始化這個例項

3、呼叫

   //2、下面使用Spring的xml配置例項化
   ApplicationContext ctx=new ClassPathXmlApplicationContext("beans.xml");
   //worker1帶前置和後置增強
   Worker worker1=(Worker)ctx.getBean("worker1");
   System.out.println("worker1進入工作:");
   worker1.getTool("鋤頭");
結果如下:


在呼叫方法之前都進行了前置和後置增強,注意,這裡會為工人類的所有方法都織入增強!

三、環繞增強

環繞通知(Around Advice):包圍一個連線點的通知,如方法呼叫。這是最強大的一種通知型別。環繞通知可以在方法呼叫前後完成自定義的行為。它也會選擇是否繼續執行連線點或直接返回它自己的返回值或丟擲異常來結束執行。


1、新增增強方法類:

/**  
*功能 環繞增強方法
*作者 林炳文([email protected] 部落格:http://blog.csdn.net/evankaka)  
*時間 2015.4.22 
*/
package com.mucfc.advice;
import java.lang.reflect.Method;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;;
public  class WearingInterceptor implements MethodInterceptor{

	@Override
	public Object invoke(MethodInvocation arg0) throws Throwable {
		Object[] args=arg0.getArguments();//目標方法入參
		String toolname=(String)args[0];
		System.out.println("--------------環繞增強開始---------------");
		System.out.println("得到"+toolname+"之前先穿上工作服");
		Object object=arg0.proceed();
		System.out.println("工作結束,請先脫掉工作服");
		System.out.println("--------------環繞增強結束---------------");
;				return object;
	}


}
2、然後還是在beans.xml中配置:
        <!-- 環繞增強的方法 -->
	<bean id="aroundAdvice" class="com.mucfc.advice.WearingInterceptor" />	
	<!--設定環繞增強方法  -->
	<bean id="worker2" class="org.springframework.aop.framework.ProxyFactoryBean"
		p:proxyInterfaces="com.mucfc.advice.Worker" p:interceptorNames="aroundAdvice"
		p:target-ref="target" lazy-init="true"/>

3、使用
   //work2帶環繞增強
   Worker worker2=(Worker)ctx.getBean("worker2");
   System.out.println("worker2進入工作:");
   worker2.getTool("鑽機");

結果:

三、異常丟擲增強

異常通知(After throwing advice):在方法丟擲異常退出時執行的通知。

1、將前置增強方法中的工人實現 類的方法增個, throw new RuntimeException("執行異常");

	@Override
	public void getTool(String tool) {
     System.out.println("---------------呼叫方法--------------");	
     System.out.println("領取工具:"+tool);	
     throw new RuntimeException("執行異常");
	}

2、處理異常丟擲的類
/**  
*功能 異常丟擲增強類
*作者 林炳文([email protected] 部落格:http://blog.csdn.net/evankaka)  
*時間 2015.4.22 
*/
package com.mucfc.advice;
import java.lang.reflect.Method;

import org.springframework.aop.ThrowsAdvice;

public class WeaningThrowAdvice implements ThrowsAdvice {
	public void afterThrowing(Method method, Object[] args, Object target,
			Exception ex) throws Throwable {
    System.out.println("--------------------");
    System.out.println("method:"+method.getName());
    System.out.println("丟擲異常"+ex.getMessage());
    System.out.println("成功回滾事務");
	}

}

3、XML配置
	<!-- 異常丟擲增強的方法  -->
	<bean id="thorwAdvice" class="com.mucfc.advice.WeaningThrowAdvice" />
		
	<!--設定異常丟擲增強方法  proxyTargetClass="true",使用CgLib代理-->
		<bean id="worker3" class="org.springframework.aop.framework.ProxyFactoryBean"
		p:interceptorNames="thorwAdvice"
		p:target-ref="target" 
		p:proxyTargetClass="true"/>

4、使用
   //work3帶環繞增強
  Worker worker3=(Worker)ctx.getBean("worker3");
   System.out.println("worker3進入工作:");
   worker3.getTool("錘子");

注意,由於這裡給方法強制丟擲了異常,所以要執行上面的程式碼,記得要把前面的增強方法測試的程式碼都給去掉,只留下以下程式碼:

五、引介增強

引介增強是一種比較特殊的增強型別,它不是在目標方法周圍織入增強,而是為目標類建立新的方法和屬性,所以引介增強的連線點是類級別的,而非方法級別的。通過引介增強,我們可以為目標類新增一個介面的實現,即原來目標類未實現某個介面,通過引介增強可以為目標類建立實現該介面的代理。一般用得比較 少,這裡就不寫程式碼了

相關推薦

AOP5增強方法應用範例

         Spring AOP 提供了 5 種類型的通知,它們分別是 Before Advice(前置通知)、After Returning Advice(後置通知)、Interception Around Advice(周圍通知)、Throws Advice(異常通

ASP.NET5全域性變數!頁面間傳值方法!

之一: 1. 使用QueryString變數   QueryString是一種非常簡單的傳值方式,他可以將傳送的值顯示在瀏覽器的位址列中。如果是傳遞一個或多個安全性要求不高或是結構簡單的數值時,可以使用這個方法。但是對於傳遞陣列或物件的話,就不能用這個方法了。下面是一個例子:   a.aspx的C#程式

Mybatis逆向工程實現方法

ntb roo obj tar ges detail 是否 href rip 1.逆向工程之原始方法 (1)下載兩個jar包:mysql-connector-java(6.x版本及以上的和5.x版本有所區別,主要是驅動和時區;詳情參見:https://blog.csdn.n

Java多執行緒迴圈列印ABC的5實現方法

https://blog.csdn.net/weixin_39723337/article/details/80352783   題目:3個執行緒迴圈列印ABC,其中A列印3次,B列印2次,C列印1次,迴圈列印2輪一.Synchronized同步法思路:使用synchronized、wait、n

軟體成本估算快速功能點方法應用示例

1、需求示意 專案背景:某開發方為政府部門甲新開發一OA系統,以支援其網上辦公、文件流轉等電子政務需求。開發方需根據初步需求確定專案預算。本專案預算期需求較明確,開發方瞭解各功能的重用情況,並確定採用JAVA開發,無特殊質量要求,團隊為其他行業開發過此類系統。 主要功能:……收文管理

關鍵詞優化快速上首頁的5優化方法

關鍵詞快速上首頁是每個seo優化人員所想的,也是每一個企業所夢寐以求的。但是seo優化本身卻又是一個漫長枯燥的過程,這裡不考慮作弊,因為終究不能長久,除非做短平快的錢。那麼我們如何快速上首頁呢?junseo針對非巨頭網站為大家做一下總結。1.關鍵詞定位,即網站定位這非常關鍵,

馳騁工作流引擎JFlow與activiti的對比5基本控制流模式的對比

前言 為了更好的說明activiti 與jflow的兩款工作流引擎的特點與區別,我們按照如下幾個方面做一次全面的、客觀的對比。       首先activiti是國外的一款開源的工作流程引擎,在國際上影響比較深遠與廣泛,解決了BPM領域的很多

C-index/C-statistic 計算的5不同方法及比較

前言 宣告: 所有計算基於R軟體,如果有人問其他軟體如何實現,請自行Google。 評價一個預測模型的表現可以從三方面來度量: 區分能力(discrimination): 指的是模型區分有病/沒病,死亡/活著等結局的預測能力。簡單舉個例子,比如說,現有100個人,50個有病

Java多執行緒任務超時結束的5實現方法

public class AwaitTermination {static class Task implements Runnable{public String name;private int time;public Task(String s,int t) {name=s;time=t;}public

1畫素表格(1px表格)的5製作方法

在轉載CSS覺問題及解決辦法時看到的這樣定義表格邊框的方法,如果用表格的border="1"屬性定義,實際顯示的寬度要比1px粗。所以我直到現在都是定義table的left和top邊框,然後定義td的right和bottom邊框,這樣也用css定義了一個表格的邊框。沒想到還

面試官讓用5python方法實現字串反轉?對不起我有16

導讀:最近身邊有個朋友,因為經受不住年薪30W+的誘惑,立志轉行成為一名程式設計師。在自學程式設計一個月以後,假裝自己是學生哥,信心滿滿地和應屆畢業生一起參加了校招。然而,進行了十幾次面試,統統折戟沉沙。 學習Python中有不明白推薦加入交流群 號:960410

區塊鏈專案中的5賺錢方法,你get了嗎?

區塊鏈專案的主要特點是去中心化。去中心化的關鍵條件是區塊鏈系統活躍成員的數量。為吸引和留住新的社群成員,專案提出的經濟模式不僅允許通過常規的採礦和貿易賺錢,還有以下多種賺錢方法。一、賞金運動賞金運動是專

WordPress忘記密碼的5解決方法

無意中忘記wordpress的密碼了,恰巧在後臺又沒來得及設定郵件,只好四處苦尋解決辦法,還好總算找到了…… 1. WordPress內建的找加密碼方法 如果你的admin帳戶的電子郵件地址是正確的, 那就根據普通的找回密碼步驟, 在Wordpress的登入頁點選”忘記密

Spring學習(5):SpringAOP的5增強型別

前言 Spring使用增強類定義橫切邏輯,同時由於Spring只支援方法連線點,增強類還包括在方法的哪一點加入橫切程式碼的方位資訊,所以增強既包含橫切邏輯,又包含部分連線點資訊。使用增強前,最好能理解動態代理的知識。本文分別採用繼承介面和使用配置檔案來實現增強

NSTimer的5建立方法異同

NSTimer在IOS開發中會經常用到,現在將基本用法總結如下: 一、建立timer:有5種初始化方法 1.+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti invocation:(NSInvocation *

web開發 Tomcat啟動報錯 5解決方法 Server Tomcat v8.0 Server at localhost failed to start . 五綜合解決方法

Eclipse 中Tomcat 啟動報錯 Eclipse的提示視窗  Server Tomcat v8.0 Server at localhost failed to start . 日誌輸出中報   Failed to destroy end point associa

快速排序的5優化方法

1、快速排序的基本思想:    快速排序使用分治的思想,通過一趟排序將待排序列分割成兩部分,其中一部分記錄的關鍵字均比另一部分記錄的關鍵字小。之後分別對這兩部分記錄繼續進行排序,遞迴地以達到整個序列有序的目的。 2、快速排序的三個步驟: (1)選擇基準:在待排序列中

資料結構與演算法查詢方法

本節的內容: 什麼是列表查詢; 順序查詢(線性查詢); 二分查詢; 順序查詢與二分查詢比較; 執行時間; 增速問題 一:什麼是查詢 查詢:在一些資料元素中,通過一定的方法找出與給定的關鍵詞相同的資料元素的過程。 二:順序查詢(線性查詢)

應用程式中替換Linux中Glibc的malloc的5方法

打算優化系統的記憶體分配,接管glibc提供的記憶體管理,但是整個工程的程式碼量很大,使用malloc、realloc、calloc和free的地方到處都是,如果自己寫好的介面需要重新命名所有的呼叫,先不說工作量,部分沒有許可權檢視程式碼的.a檔案就搞不定了。所以需要替換掉系統的malloc,保證原

5建立型模式:簡單工廠和工廠方法模式

以下為簡單工廠模式 簡單工廠模式解釋:         簡單工廠模式(Simple Factory Pattern)屬於類的創新型模式,又叫靜態工廠方法模式(Static FactoryMethod Pattern),是通過專門定義一個類來負責建立其他類的例項,被建立的例項通常都具有共同的父類。 簡單工廠