<?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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd" default-autowire="byName" default-lazy-init="true"> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <!-- the transactional semantics... --> <tx:attributes> <!-- all methods starting with 'get' are read-only --> <tx:method name="get*" read-only="true"/> <tx:method name="find*" read-only="true"/> <!-- other methods use the default transaction settings (see below) --> <tx:method name="*"/> </tx:attributes> </tx:advice> <aop:config> <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.becom.XXXX.service..*(..))"/> <aop:aspect id="aspectForService" ref="catTransactionAspectForService"> <aop:pointcut id="webserviceService" expression="execution(* com.becom.XXXX.service..*(..))" /> <aop:around pointcut-ref="webserviceService" method="doAround" /> </aop:aspect> </aop:config> <bean id="catTransactionAspectForService" class="com.becom.dkyd.webapp.util.CatTransactionAspect"> <property name="transactionType" value="SERVICE"></property> </bean> </beans>
一 .面向切面編程(AOP)的基礎概念:java
以一個普通的java方法來舉例node
public 返回類型 方法名(參數列表){ ——>環繞通知 方法前處理代碼 ——> 前置通知 try{ 方法具體實現(方法體)……. 方法後處理代碼 ——> 後置通知 }Catch(異常類型 e){ 異常處理…… ——> 例外通知 }finally{ 最後處理代理…… ——> 最終通知 } }
a. 橫切關注點:如上面5個通知的位置,在java對象中,能夠這些具備相似共同處理邏輯的位置加入如權限驗證、事物處理、日誌記錄等處理邏輯的對象稱爲橫切關注點,面向對象編程(OOP)的關注點是縱向將現實世界的事物抽象成編程的對象模型。而面向切面編程(AOP)的關注點是橫向的,它將編程對象模型中擁有相似處理邏輯的地方抽象出來造成切面,而編程對象中的處理邏輯就是橫切關注點。web
b. 切面(Aspect):將橫切關注點抽象就造成切面,與類相似,兩者關注點不一樣,類是事物特性的抽象,切面是橫切關注點的抽象。spring
c. 鏈接點(Joinpoint):被攔截到的點,在Spring中指方法,由於spring只支持方法類型的鏈接點,即被攔截的方法。如上面例子的方法。數據庫
d. 切入點(Pointcut):指對鏈接點進行攔截的定義,是鏈接點的集合,即一系列被攔截方法的集合。express
e. 通知(Advice):指攔截到鏈接點以後要作的事情,即攔截以後的邏輯處理。一般的權限驗證、事物處理、日誌記錄等操做就是在通知中定義和完成的。編程
f. 目標對象(Target):代理的目標對象,即被攔截的對象。如上面例子中方法所在的對象。app
g. 織入(Weave):指將切面應用到目標對象,並致使代理對象建立的過程。webapp
h. 引入(Introduction):在不修改代碼的前提下,引入能夠在運行期爲類動態的添加一些方法和字段。代理
二.配置
1. Spring中支持面向切面編程(AOP)的依賴包:
Spring解壓後目錄中的以下3個包:
lib/aspectj/aspectjweaver.jar
lib/aspectj/aspectjrt.jar
lib/cglib/cglib-nodep-2.1-3.jar
2. 在spring中使用面向切面編程(AOP)時,須要在spring配置文件中引入aop的命名空間,即添加以下的配置:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd" default-autowire="byName" default-lazy-init="true">
注意:Spring2.5之後提供兩種AOP方法,即基於xml配置文件方式和基於java註解方式。
A.若要使用註解方式的aop,須要在spring配置文件中添加以下的對象註解方式aop的支持:
<aop:aspectj-autoProxy/>
Spring經過BeanWrapper類封裝一個javabean的行爲,能夠設置和獲取其屬性值,如:
BeanWrapper 包裝類對象 = BeanWrapperImpl(new 被包裝類()); 包裝類對象.setPropertyValue(「屬性名」,」屬性值」);
經過這種方法就能夠給被包裝類設置屬性。
(1).在spring配置文件中加入對註解方法的aop支持。
(2).定義切面:和建立普通類相似,在類前加上」@Aspect」註解,代表該類是一個切面。
(3).在切面中加入切入點:
切入點就是被攔截對象方法的集合,一般切入點定義在切面中某個對切入點進行處理的方法上。使用」@Pointcut」註解,語法以下:
@Pointcut(「execution(* com.test.service..*.*(..))」) public void anyMethod(){//方法名爲切入點名 切入點處理 }
語法參數詳解:
a. 第一個」*」:表示被攔截的方法是任意的返回類型。 b. com.test.service:這裏是舉一個簡單的例子,表示要被攔截的包名,即被攔截的包。 c.被攔截包名後面的兩個」..」:表示被攔截包下面的子包也遞歸進行攔截,即被攔截的子包。 d. 」..」以後的」*」:表示被攔截包及其子包下面的全部類,即被攔截的類。 e. 最後一個」*」:表示被攔截類中的全部方法,即被攔截的方法。 f. 」(..)」:表示被攔截的方法接收任意的參數,即被攔截的參數。 注意:切入點定義語法能夠支持通配符,可是必定要嚴格遵循語法規則。如: @Pointcut(「execution(*com.test.service..*.add*(..))」) 表示對com.test.service包及其子包下全部的類中以」add」開頭的方法進行攔截。
(4).在切面中添加通知:
Spring中通知位置請參看下面的小例子。
」@Before」註解:聲明前置通知。
「@AfterRutruning」註解:聲明後置通知。
「@After」註解:聲明最終通知。
「@AfterThrowing」註解:聲明例外通知。
「@Around」註解:聲明環繞通知。
一個定義通知的例子以下:
@Before(「anyMethod()(切面中聲明的切入點名)」) public void doAccessCheck(){ …… }
注意:環繞通知和其餘4種通知的稍有不一樣,環繞通知的定義方式比較特別,環繞通知在整個方法調用先後都會起做用,所以必須使用鏈接點對象告訴鏈接點在環繞通知處理以後繼續其邏輯處理。其定義方式以下:
@Around(切入點名) public Object doBasicProfiling(ProcedingJoinPoint pjp) throws Throwable{ …… return pjp.proceed();//該句是告訴鏈接點繼續執行其餘的操做 }
(1).獲取輸入參數:
@Before(「切入點名 && args(輸入參數名)」) public void doSomething(String 輸入參數名){……}
(2).獲取返回結果:
@AfterReturning(Pointcut=」切入點名」,returning=」返回結果名」) public void dosomething(String 結果名){……}
B. 基於XML方式的面向切面編程(AOP)開發:
(1).定義切面類,在切面類中添加通知。
(2).將切面類想普通java類同樣在spring配置文件中配置。
(3).在spring配置文件中添加AOP配置以下:
<aop:config> <!--配置切面--> <aop:aspect id=」切面id」 ref=」spring配置文件中切面類的id」> <!--配置切入點--> <aop:pointcut id=」切入點id」 expression=」execution(* com.test.service..*.*(..))」/> <!--配置通知--> <aop:before pointcut-ref=」切入點id」 method=」切面類中相應的處理方法」/> <aop:after ……/> …… </aop:aspect> </aop:config>
三. Spring的事務處理(Spring的聲明式事務處理):
事務簡單來講是指數據庫中的一條最基本的操做,關於事務的詳細講解之後會在數據庫相關總結中具體說明。Spring的面向切面編程(AOP)一個最重要的應用是事務管理,Spring2.5之後版本的事務管理支持基於註解的方式和基於XML文件的方式兩種:
(1).基於註解方式的事務管理:
a. 在spring配置文件中添加事務管理的命名空間以下:
xmlns:ts=http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
b. 在spring配置文件中配置事務管理器以下:
<bean id=」txManager」 class=」org.springframework.jdbc.datasource.DataSourceTransactionManager」> <property name=」dataSource」 ref=」spring中配置的數據源bean的id」/> </bean>
c. 在spring配置文件中添加支持註解方式的事務配置項以下:
<tx:annotation-driventransaction-managertx:annotation-driventransaction-manager=」txManager(spring中配置的事務管理器bean的id)」/>
d. 使用基於註解的事務管理:
在Spring所管理的JavaEE工程中,須要使用事務的業務邏輯地方加上「@Transactional」註解。
(2).基於XML文件方式的事務管理:
a. 在spring配置文件中配置事務管理器以下:
<bean id=」txManager」 class=」org.springframework.jdbc.datasource.DataSourceTransactionManager」> <property name=」dataSource」 ref=」spring中配置的數據源bean的id」/> </bean>
b. 在spring配置文件中添加事物管理的切面以下:
<aop:config> <!--配置事務切入點--> <aop:pointcut id=」transactionPointcut」 Expression=」execution(* com.test.service..*.*(..))」/> <!--配置事務通知--> <aop:advisor advice-ref=」txAdvice」 pointcut-ref=」transactionPointcut」/> </aop:config>
c.在spring配置文件中爲事務通知添加事物處理特性以下:
<tx:advice id=」txAdvice」 transactionManager=」txManager」> <tx:attributes> <!--這裏舉例將以get開頭的查詢方法設置爲只讀,不支持事務--> <tx:method name=」get*」 read-only=」true」 propagation=」NOT_SUPPORTED」/> <!--其餘的方法設置爲spring默認的事物行爲--> <tx:method name=」*」/> </tx:attributes> </tx:advice>