天天看點

spring2的AOP架構-AOP實戰

AOP筆記2-spring AOP API

Spring  AOP隻實作了針對方法調用的攔截及增強,在j2ee應用中,攔截到方法級的操作已經足夠。spring  AOP讓Spring支援聲明式事務。為了使用spring AOP,首先要了解它的API結構

AOP聯盟API

一套用于規範AOP實作的底層API,String的AOP架構也是直接以這些API為基礎建構的。

Aop包:定義了增強(Advice)接口和AOP運作時異常AspectException

Intercept包:攔截器包,規範了連接配接點(join point)及增強(advice)的類型

Instrument和reflect包:切面與應用子產品如何內建在一起

切入點(point cut):即要在哪裡切入代碼。

Spring使用Pointcut接口表示切入點,并預定義了幾個切入點實作類:

(1)NameMathMethodPointcut:方法名稱比對切入點,它的mappedname和  mappedNames屬性表示比對的方法名,名稱隻支援“*”通配符,代表0個或多個字元

(2)JdkPegexpMethodPointcut:正規表達式切入點,如果是JDK1.4以下版本,使用Perl5RegexpMethodPointcut,這時要導入jakarta-oro-xx.jar包。它的patternt和patterns表示比對方法名稱的正規表達式,excludePattern和excludePatterns表示要排除的方法名稱正規表達式。

(3)expression_r_r_rPointcut:描述式切入點接口,用表達語言來描述切入點,spring提供了一個實作類,即AspectJexpression_r_r_rPointcut,它的expression_r_r_r屬性表示要描述的切入點。使用這個類要用于AspectJ中的文法解析處理器,這時要引入aspectjweaver.jar包。

增強(advice):也就是要切入什麼代碼。

Spirng Aop增強類型是圍繞方法調用連接配接點展開的,提供了以下四種類型;

(1)MethodBeforAdvice:方法調用前增強接口。使用者要實作它的before()方法

(2)AfterReturningAdvice:傳回後增強接口。使用者要實作它的afterReturning()方法。

(3)ThrowsAdvice:異常增強接口。這是個辨別接口,但在實際應用中,使用者要學現afterThrowing()方法。

(4)MethodInterceptor:環繞增強接口。又稱攔截器,是個辨別接口,在實際應用中,使用者要學現它的invoke()方法。

引介(Introduction):在不更改源代碼的情況下,給一個類增加屬性、方法以及讓它實作其它接口或其它父類。spring使用引介攔截器IntroductionInterceptor定義引介,它的implementsInterface屬性用來指定要實作的某個接口,spring提供該接口的兩個實作:

(1)DelegatingIntroductionInterceptor:執行個體化時要引入接口實作作為參數

(2)DelegatePerTargetObjectDelegatingIntroductionInterceptor:實作化時要引入一個接口及實作類作為參數。

增強器(Advisor):一個切面的子產品化封裝(如把切入點和增強封裝為一個整體,它們是無法單獨使用的),簡稱切面。有以下兩大類:

(1)由切入點(point cut)及增強(advice)組合的切面。

(2)組合引介的切面

Spring Aop最底層的切面封裝是Advisor接口,其下面還有兩個接口IntroductionAdvisor(引介增強器)及PointcutAdvisor(切入點增強器),它們有幾下幾種實作:

(1)DefaultPointcutAdvisor:預設的切面封裝。它的advice及pointcut屬性分别指增強和切入點。

(2)NameMatchMethodPointcutAdvisor:方法比對切入點切面。不用專門定義切入點,隻要指定增強。它的mappedName屬性指定切入點比對的方法名稱,advice屬性指定增強。

(3)RegexpMethodPointcutAdvisor:正規表達式切入點切面。不用專門定義切入,隻要指定增強。它的advice屬性表示要包裝的增強,pattern和patterns屬性表示要設定的切入點

(4)AspectJexpression_r_r_rPointcutAdvisor:AspectJ表達式切入點切面。不要專門定義切入點,隻要指定增強。它的advice屬性表示要包裝的增強,expression_r_r_r表示要生成切入點的表達式。

(5)DefultIntroductionAdvisor:引介增強器(IntroductionInterceptor)的實作

代理工廠(ProxyFactory):spring AOP是基于代理實作的,代理工廠用來建立代理對象。Spring的AOP提供了以下幾個代理工廠實作。

 (1) ProxyFactoryBean:一般代理工廠

 (2) TransactionProxyFactoryBean:事務代理工廠

 (3) LocalStatelessSessionProxyFactoyBean:用于建立EJB代理的代理工廠

 (4) BeanNameAutoProxyCreator:根據名稱自動建立代理

 (5) DefaultAdvisorAutoProxyCreator:根據切面自動建立代理

AOP筆記3-spring AOP執行個體

假設有以下業務元件,我們使用AOP攔截它的兩個業務方法,在方法執行前加入使用者驗證子產品,在方法執行完成後,加入日志記錄子產品。

public interface Component{

        void business1();//業務方法1

        void business2();

}

public class ComonentImpl implements Component{

        public void business1(){

                System.out.println(“執行業務處理方法1”);

        }

        public void business2(){

                System.out.println(“執行業務處理方法2”);

在Spring使用AOP有三種方式:

(1) 基于API方式。這種方式加入了Spring AOP API,入侵性較強。

一、建立增強,即要加入的代碼

//實作spring提供的增強類

public class AdviceBean implements MethodBeforeAdvice,AfterReturningAdvice{

        //目标對象業務方法執行前要執行的代碼。

        public void befor(Method method,Object[]args,Object target)throws Throwable{

                validaterUser();//驗證使用者合法性

        public void afterReturning(Object return Value,Method method,Object[] args,

             Object target)throws Throwable{

               writeLogInfo();//寫入日志

        public void validateUser(){

                System.out.println(“使用者驗證通過!”);

        public void writeLogInfo(){

                System.out.println(“日志寫入成功!”);

二、建立切入點類,即要在哪裡加入增強,這裡直接使用spring提供的切入點實作類,如:NameMatchMethodPointcut

三、建立切面封裝類,包裝切入點和增強,這裡直接使用spring提供的實作類,如:

DefaultPointcutAdvisor

四、建立代理類,這裡直接使用spring提供的代理工廠類負責建立。

五、配置以上資源

<!—以下例子的類省略了包路徑,實際中要加入-->

<bean id="targetBean" class="...ComponentImpl"/>

<bean id="adviceBean" class="...AdviceBean"/>

<!--使用sping AOP API定義切入點  -->

<bean id="pointcutBean"

class="org.springframework.aop.support.NameMatchMethodPointcut">

     <property name="mappedName" value="business*"/>

</bean>

<!--使用sping AOP API定義切面,封裝切入點和增強-->

<bean id="aspectBean"

class="org.springframework.aop.support.DefaultPointcutAdvisor">

     <property name="advice" ref="adviceBean"/>

     <property name="pointcut" ref="pointcutBean"/>

<!--使用sping AOP API定義工廠,建立代理-->

<bean id="component" class="org.springframework.aop.framework.ProxyFactoryBean">

             <property name="target" ref="targetBean"/>

             <property name="interceptorNames" >

                     <list>

                             <value>aspectBean</value>

                     </list>

             </property>

六、測試

ApplicationContext context=new ClassPathXmlApplicationContext(aop.xml);

Component cp=(Component)context.getBean(“component”);

cp.business1();//測試aop運作結果

(2)基于Schema方式

。這種方式使用普通的java對象表示切入子產品,易于移植。它使用配置檔案定義增強、切入點、切面。這種方式需要AspectJ架構的支援,要在lib中加入aspectjweaver.jar包(spring-aop.jar包含了該包)

一、建立要切入的子產品

public class AspectBean{

二、使用配置檔案定義切入點、增強、切面

<!-- 定義代表切面的java對象-->

<bean id="aspectBean" class="….AspectBean"/>

<aop:config>

        <!-- 定義切面-->

        <aop:aspect id="aspectDemo" ref="aspectBean">

                <!--定義切入點-->

                <aop:pointcut id="somePointcut" expression_r_r_r=

                "execution(* com.acon.aop.domain.Component.business*(..))"/>

                <!--定義切入點上的增強-->

                        <aop:before pointcut-ref="somePointcut" method="validateUser"/>

                        <aop:after-returning pointcut-ref="somePointcut"

                              method="writeLogInfo"/>

                </aop:aspect>

</aop:config>

<!--定義元件-->

<bean id="component" class="com.acon.aop.domain.ComponentImpl"/>

三、測試(内容同使用上一節,略)

注意:

a.由于使用了<aop>元素,要修改此檔案聲明,即:

在<beans>中加入“xmlns:aop="http://www.springframework.org/schema/aop"”

并在”xsi:shemaLocation”中指定AOP配置的schema位址:

“http://www.springframework.org/schema/aop

http://www.springframework.org/schema/aop/spring-aop-2.0.xsd”

b. execution(* )”*”号後面是空格,否則出” Pointcut is not  well-formed: expecting”錯誤

(3)使用AspectJ注解支援

。基于注解需要jdk1.5支援,由于切面封裝子產品是POJO,這種方式不依賴Spring架構。這種方式要引入AspectJ架構相關包-aspectjweaver.jar,由于spring底層使用運作時位元組碼生成機制,還要相入asm-x.jar和asm-commons-x.jar等(這些包都包含在spring.aop.jar中了,在這裡說明,隻是告訴大家這些包是用來幹什麼用的)

一、定義切面

import org.aspectj.lang.annotation.Aspect;

import org.aspectj.lang.annotation.Pointcut;

import org.aspectj.lang.annotation.Before;

import org.aspectj.lang.annotation.After;

@Aspect

public class AspectAnnotationBean{

        //定義切入點

        @Pointcut(“execution(*com.acon.aop.domain.Component.business*(..))”)

        public void somePointcut(){}

        //在切入點上加入增強,”*”後有空格

        @Pointcut("execution(* com.acon.aop.domain.Component.business*(..))")

        @After(“somePointcut()”)

                System.out.println(“寫入日志成功!”);

二、配置切面

<!—定義切面子產品-->

<bean id=”aspectBean” class=”….AspectAnnotationBean”/>

<!—使用@AspectJ自動代理-->

<aop:aspectj-autoproxy/>

三、測試同上一節,略

繼續閱讀