天天看點

bboss aop攔截器使用簡介

bboss aop攔截器使用簡介,本文适用于最新的bboss版本,下載下傳方法參考: http://yin-bp.iteye.com/blog/1080824

1.概述

bboss aop/ioc架構支援給元件配置一到多個攔截器,攔截器執行的順序為類似堆棧的先入後出的模式,before方法按順序執行(先入),其他方法采用逆序方式執行(後出,先執行最後一個攔截器的其他方法,最後執行第一個攔截器的其他方法)。

這裡需要補充說明一下,聲明式事務攔截器是bboss内置的一個攔截器,事務攔截器作為元件的所有攔截器中最後一個攔截器執行,同樣遵循上面的先入後出原則。

2.攔截器接口

package com.frameworkset.proxy;
import java.lang.reflect.Method;
public interface Interceptor {
    public void before(Method method,Object[] args) throws Throwable;
    public void after(Method method,Object[] args) throws Throwable;
    public void afterThrowing(Method method,Object[] args,Throwable throwable) throws Throwable;
    
    public void afterFinally(Method method,Object[] args) throws Throwable;
}      

Interceptor 接口定義了四個接口方法:

before-在方法執行之前執行,如果抛出異常,就會終止方法繼續執行,同時将異常傳遞到應用層。

after-在方法執行之後執行,如果抛出異常,就會終止後續其他方法執行,同時将異常傳遞到應用層。

afterThrowing-當方法執行過程中抛出異常時執行,如果抛出異常,就會終止後續其他方法執行,同時将異常傳遞到應用層。

afterFinally-在方法finally後執行,如果抛出異常,就會終止後續其他方法執行,同時将異常傳遞到應用層。

是以在實作自己的Interceptor 時,一定要注意異常的處理,因為攔截器方法的異常會影響元件方法的執行流程。

3.一個具體的攔截器

package org.frameworkset.spi.properties.interceptor;

import java.lang.reflect.Method;

import com.frameworkset.proxy.Interceptor;
public class InterceptorImpl implements Interceptor {
	private A a;
	public void after(Method method, Object[] args) throws Throwable {
		System.out.println("Insterceptor.after(" + method.getName() + ", Object[] args)=" + args[0]);

	}

	public void afterFinally(Method method, Object[] args) throws Throwable {
		System.out.println("Insterceptor.afterFinally(" + method.getName() + ", Object[] args)=" + args[0]);
	}

	public void afterThrowing(Method method, Object[] args, Throwable throwable)
			throws Throwable {
		System.out.println("Insterceptor.afterThrowing(" + method.getName() + ", Object[] args, Throwable throwable)=" + args[0]);

	}

	public void before(Method method, Object[] args) throws Throwable {
		System.out.println("Insterceptor.before(" + method.getName() + ", Object[] args)=" + args[0]);


	}
}      

攔截器InterceptorImpl 中定義了一個全局變量:

private A a;

我們可以對攔截器應用依賴注入(ioc)機制來注入其他業務元件和屬性,也就是說攔截器元件本身也是以元件的方式來管理,ioc的所有機制都可以應用于攔截器xml配置節點interceptor,下面具體介紹配置xml元素-interceptor的用法。

4.攔截器配置xml元素-interceptor

interceptor元素作為元件定義元素property的内置元素使用,用來配置元件的aop攔截器。interceptor元素内置method元素,用來配置元件中需要被該攔截器攔截的具體方法,如果沒有配置method元素,則對應的攔截器将攔截元件中所有的方法。如果元件配置了多個攔截器,每個攔截器都可以配置自己需要攔截的具體方法。

下面是一個配置執行個體:

<properties>
	<property name="test.interceptorbean" singlable="true" class="org.frameworkset.spi.properties.interceptor.A">
		<interceptor class="org.frameworkset.spi.properties.interceptor.InterceptorImpl"			
			f:a="attr:test.bean"
		/>		
	</property>
	
	<property name="test.interceptorbeanmethod" singlable="true" class="org.frameworkset.spi.properties.interceptor.A">
		<interceptor class="org.frameworkset.spi.properties.interceptor.InterceptorImpl"			
			f:a="attr:test.bean"
		>
			<method name="test">
				<param type="java.lang.String"/>
			</method>			
		</interceptor>		
	</property>
	
	<property name="test.bean" singlable="true" class="org.frameworkset.spi.properties.interceptor.A">
	</property>
</properties>      

說明:

情形一

<interceptor class="org.frameworkset.spi.properties.interceptor.InterceptorImpl"

f:a="attr:test.bean"

/>

這種配置攔截所有方法,同時我們為攔截器中的屬性a注入了另外一個元件執行個體。

情形二

>

<method name="test">

<param type="java.lang.String"/>

</method>

</interceptor>

這裡通過method元素指定了攔截器需要攔截的元件方法,可以配置多個:

<method name="test">

</method>

如果是具體的方法就需要指定方法的參數,如果是采用pattern(正規表達式)則無需指定方法參數,例如:

<method pattern="test.*"/>//表示攔截所有以test開頭的方法,這裡遵循标準的java正規表達式文法

<method pattern="*"/>//表示攔截所有方法,這裡遵循标準的java正規表達式文法

情形三

如果有多個攔截器,請按順序配置即可:

<interceptor class="org.frameworkset.spi.properties.interceptor.PermissioncheckInterceptorImpl"			
			f:a="attr:test.bean"
		/>
<interceptor class="org.frameworkset.spi.properties.interceptor.LogInterceptorImpl"			
			f:a="attr:test.bean"
		/>      

5.内置的聲明式事務攔截器配置需要攔截的事務方法配置示例

借助transactions元素和method來進行聲明式事務方法配置。transactions和interceptor元素不一樣,當transactions中沒有配置method時,事務攔截器不會攔截元件的任何方法;而在transactions元素中method方法可以通過txtype屬性指定方法需要開啟的事務類型,并且在method元素中還可以通過rollbackexceptions和exception元素結合配置需要復原事務的異常資訊。下面是transactions的配置執行個體:

<property id="tx.a" singlable="true" class="org.frameworkset.spi.transaction.A1" >
		<!--  
			在下面的節點對元件的業務方法事務進行定義
			隻要将需要進行事務控制的方法配置在transactions中即可
		-->
		<transactions>
			<!-- 
				定義需要進行事務控制的方法
				屬性說明:
				name-方法名稱,可以是一個正規表達式,正規表達式的文法請參考jakarta-oro的相關文檔,如果使用
				正規表達式的情況時,則方法中聲明的方法參數将被忽略,但是復原異常有效。
				pattern-方法名稱的正規表達式比對模式,模式比對的順序受配置位置的影響,如果配置在後面或者中間,
						那麼會先執行之前的方法比對,如果比對上了就不會對該模式方法進行比對了,否則執行比對操作。
						如果比對上特定的方法名稱,那麼這個方法就是需要進行事務控制的方法
						例如:模式testInt.*比對接口中以testInt開頭的任何方法
				txtype-需要控制的事務類型,取值範圍:
				NEW_TRANSACTION,
				REQUIRED_TRANSACTION,
				MAYBE_TRANSACTION,
				NO_TRANSACTION
				RW_TRANSACTION
			-->
			<method name="testTXInvoke" txtype="NEW_TRANSACTION">
				<param type="java.lang.String"/>
			</method>			
			<method name="testTXInvoke" txtype="REQUIRED_TRANSACTION"/>			
			<method name="testTXInvokeWithReturn" txtype="REQUIRED_TRANSACTION"/>			
			<method name="testTXInvokeWithException" txtype="MAYBE_TRANSACTION"/>				
			<method name="testSameName" txtype="NO_TRANSACTION"/>			
			<method name="testSameName1">
				<param type="java.lang.String"/>
			</method>
			<!-- 			    
					定義使事務復原的異常,如果沒有明确聲明需要復原事務的異常,那麼當有異常發生時,
					事務管理架構将自動復原目前事務
					class-異常的完整類路徑
					type-是否檢測類型異常的子類控制辨別,
					IMPLEMENTS隻檢測異常類本身,忽略異常類的子類;
					INSTANCEOF檢查異常類本省及其所有子類					
				-->
			<method name="testTXWithSpecialExceptions">
				<rollbackexceptions>
					<exception class="org.frameworkset.spi.transaction.RollbackInstanceofException" 
					type="INSTANCEOF"/>
					<exception class="org.frameworkset.spi.transaction.Exception1" 
					type="IMPLEMENTS"/>
				</rollbackexceptions>
				<param type="java.lang.String"/>
			</method>			
			<method name="testTXWithInstanceofExceptions">
				<rollbackexceptions>
					<exception class="org.frameworkset.spi.transaction.RollbackInstanceofException" 
					type="INSTANCEOF"/>
				</rollbackexceptions>
				<param type="java.lang.String"/>
			</method>			
			<method name="testTXWithImplementsofExceptions">
				<rollbackexceptions>
					<exception class="org.frameworkset.spi.transaction.RollbackInstanceofException" 
					type="IMPLEMENTS"/>
				</rollbackexceptions>
				<param type="java.lang.String"/>
			</method>
			<!-- 
					
					如果涉及的方法名稱是一個正規表達式的比對模式,則無需配置方法參數 
					如果指定的方法沒有參數則無需指定參數
					注意參數出現的位置順序和實際方法定義的參數順序保持一緻
					模式為* 表示比對所有的方法
				-->				
			<!-- 
				通過模式方法進行聲明式事務控制,同時聲明了需要復原事務的異常
				pattern【testPatternTX[1-9.]*】表示以testPatternTX開頭的所有方法
			 -->			 
			<!--<method pattern="testPatternTX[1-9.]*">
				<rollbackexceptions>
					<exception class="org.frameworkset.spi.transaction.RollbackInstanceofException" 
					type="IMPLEMENTS"/>
				</rollbackexceptions>
				<param type="java.lang.String"/>
			</method>-->			 
			<!--	通過模式方法進行聲明式事務控制
				pattern【testPatternTX[1-9.]*】表示以testPatternTX開頭的所有方法		
				 -->	
			<method pattern="testPatternTX[1-9.]*"/>				
							
			<!-- 
				系統級别的異常java.lang.NullPointException,導緻事務復原
			 -->
			<method name="testSystemException">	
				<rollbackexceptions>
					<exception class="org.frameworkset.spi.transaction.RollbackInstanceofException" 
					type="IMPLEMENTS"/>
				</rollbackexceptions>
			</method>
		</transactions>
	</property>      

說明:transactions和interceptor元素一起使用,這時transactions将會作為最後一個攔截器執行。

ok,bboss的所有攔截器機制和示例就介紹到此。