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的所有攔截器機制和示例就介紹到此。