<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    零雨其蒙's Blog

    做優秀的程序員
    隨筆 - 59, 文章 - 13, 評論 - 58, 引用 - 0
    數據加載中……

    Spring中的AOP

    Spring 中的 AOP

    創建時間: 2007127 星期六

    ????????????????? ?零雨其蒙原創,轉載請注明

    一、概述

    (一)基本概念

    1 、什么是AOP

    ??? 面向方面編程。所謂方面即是指日志、權限、異常處理、事務處理等。

    2 AOP3個關鍵概念

    ?? 1 )切入點( Pointcut ): Pointcut Join Point 的集合, Join Point 就是需要注入 Adivce 的位置,也就是需要插入日志輸出代碼、事務處理代碼等“方面”( Aspect ,也就是 AOP 中的 A )代碼的地方。

    ??? 比如我現在要寫一個存錢的方法: saving ()

    ??? 通常情況下我就得在這個 saving ()方法前后寫些事務代碼

    ??? 如:

    ?

    ????????? logger.log(Level.INFO,”start”);

    Saving();

    ???????????????????????? logger.log(Level.INFO,”end”);

    ??????

    ???????? 對于事務代碼而言, saving ()方法的前后就都是 Join Point 了。在 Spring 中它對應 config.xml 中設定的方法,這個方法就是類( class )中需要進行某方面處理的方法( method )。

    ?????? ? 2 )通知( Advice ): 就是指 Join Point 對應的代碼(方法)。比如日志輸出這個方面,指的就是日志輸出的代碼或方法了。在 Spring 中,它對應類( class )。

    ??????? 3 Advisor Poincut Advice 的配置器,它包括 Pointcut Advice ,是將 Advice 注入程序中 Pointcut 位置的代碼。在 Sping 中,它對應 config.xml 中的配置段 <bean id=logAdvisor class=”org.springframework.aop.support.RegexpMethodPointcutAdvisor”>

    ? <bean id=”logAdvisor” class=”org.springframework.aop.support.RegexpMetho

    dPointcutAdvisor”>

    ??? //advice 屬性對應的當然就是輸出日志的類,也就是 對應的那個bean

    ??? <property name=”advice”>

    ???????? <ref bean=”log”/>

    ??? </property>

    ?? //patterns 屬性指出指定要代理的方法,使用的是正則表達式

    ??? <property name=”patterns”>

    ???????? <value>.*doAuditing.*</value>

    ??? </property>

    </bean>

    ?

    (二)框架圖

    ?

    創建代理的兩種方法

    ProxyFactoryBean

    動態代理

    ?

    Spring4 Advice

    Interception Around

    Before

    After Returning

    Throw

    ?

    兩種代理方式

    Java 動態代理

    CGLIB 代理

    ?

    (三)何時使用什么

    ? 1 、創建代理的兩種方法中首選動態代理。

    1 種:針對某個類進行配置。可以指定某個類中所有方法都調用方面,也可以指定某個類中的某個方法,此時由于用到正則表達式,于是需要引入 jakarta-oro-2.0.8.jar 包。

    2 種:針對某個方法進行配置。

    ? 2 Spring4Advice

    ????? 1 種:在需要調用方面的方法前后都調用處理方面的代碼

    ????? 2 種:在需要調用方面的方法之前調用處理方面的代碼

    3 種:在需要調用方面的方法之后都調用處理方面的代碼

    4 種:在需要調用方面的方法發生異常時調用處理方面的代碼

    3 、兩種代理方式首選第1種。

    ????????? 1 種:面向接口,必須先定義接口,這是好的習慣,應該提倡

    ????????? 2 種:當沒有接口的時候,可以使用這種方法。需引入 cglib-nodep-2.1_3,jar 包。

    二、詳細

    (一)、創建AOP代理的兩種方法:

    1 、用ProxyFactoryBean創建AOP代理

    ?? (需要指明代理目標類)

    1 )代理目標類的所有方法

    <?xml version="1.0" encoding="UTF-8"?>

    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"

    ?"http://www.springframework.org/dtd/spring-beans.dtd">

    <beans>

    // 下面 interceptorNames 屬性(property)中的value值就是這個beanid,其主要對應的是寫入日志的那個類,也就是Spring AOP概念中的Advice(通知)。

    <bean id="log" class="com.gc.action.LogAround"/>

    // 要輸出日志的那個類(因為這種方法必須要指明代理目標類)

    <bean id="timeBook" class="com.gc.action. timeBook "/>

    // 下面開始定義代理類,也就是ProxyFactoryBean,這是Spring自帶的類,這也是Spring AOP中的Advisor

    <bean id=”logProxy” class=”org.springframework.aop.framework.ProxyFactor

    yBean ”>

    ?// 第一個屬性,是指明要代理的類的接口,因為這個例子中使用的是Java動態代理機制來實現AOP的,因此必須指明接口

    ??? <property name=”proxyInterfaces”>

    ??????? <value>com.gc.impl.TimeBookInterface</value>

    ??? </property>

    // 這個屬性是指明代理目標(target)類,也就是 定義的那個類

    ?? ?<property name=”target”>

    ??????? <ref bean=”timeBook”/>

    ??? </property>

    [U1] ? // 這個屬性是用來指明插入哪個Advice,此處使用list,應該表示這個類不只是可以調用這一個log

    ??? <property name=”interceptorNames”>

    ???????? <list>

    ???? ?????????<value>log</value> // 這個值(log)對應 中定義的那個idlogbean

    ???????? </list>

    ??? </property>

    [U2] ? </bean>

    </beans>

    2 )代理目標類的指定方法

    <?xml version="1.0" encoding="UTF-8"?>

    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"

    ?"http://www.springframework.org/dtd/spring-beans.dtd">

    <beans>

    <bean id="log" class="com.gc.action.LogAround"/>

    <bean id="timeBook" class="com.gc.action. timeBook "/>

    // 在上一段配置文件中添加了下面這個bean,用來指明要輸出日志的指定方法(上一個例子是所有方法都輸出日志)

    <bean id=”logAdvisor” class=”org.springframework.aop.support.RegexpMetho

    dPointcutAdvisor”>

    ??? //advice 屬性對應的當然就是輸出日志的類,也就是 對應的那個bean

    ??? <property name=”advice”>

    ???????? <ref bean=”log”/>

    ??? </property>

    ?? //patterns 屬性指出指定要代理的方法,使用的是正則表達式

    ??? <property name=”patterns”>

    ??? ?????<value>.*doAuditing.*</value>

    ??? </property>

    </bean>

    <bean id=”logProxy” class=”org.springframework.aop.framework.ProxyFactor

    yBean ”>

    ??? <property name=”proxyInterfaces”>

    ??????? <value>com.gc.impl.TimeBookInterface</value>

    ??? </property>

    ??? <property name=”target”>

    ??????? <ref bean=”timeBook”/>

    ??? </property>

    ??? <property name=”interceptorNames”>

    ???????? <list>

    ????????????? <value>log</value>

    ???????? </list>

    ??? </property>

    </bean>

    </beans>

    ?

    2 、用DefaultAdvisorAutoProxyCreator創建自動代理

    ?? (好處:不用指明代理目標類,如果一個大項目中有很多類也不必一個一個設置 AOP 代理)

    <?xml version="1.0" encoding="UTF-8"?>

    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"

    ?"http://www.springframework.org/dtd/spring-beans.dtd">

    <beans>

    <bean id="log" class="com.gc.action.Log Aop "/>

    <bean id="timeBook" class="com.gc.action. timeBook "/>

    // 使用DefaultAdvisorAutoProxyCreator(紅色代碼)替代ProxyFactoryBean(綠色代碼),因為綠色代碼的作用是為具體的類(即所謂代理目標類)設置advice

    <bean id=”autoProxyCreator” class=”org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator”>

    <bean id=”logAdvisor [U3] ? ” class=”org.springframework.aop.support.RegexpMetho

    dPointcutAdvisor”>

    ? ?? <property name=”advice”>

    ???????? <ref bean=”log”/>

    ??? </property>

    ? ?? <property name=”patterns”>

    ?????? ??<value>.*doAuditing.*</value> [U4] ?

    ??? </property>

    </bean>

    /*<bean id=”logProxy” class=”org.springframework.aop.framework.ProxyFactor

    yBean”>

    ??? <property name=”proxyInterfaces”>

    ??????? <value>com.gc.impl.TimeBookInterface</value>

    ??? </property>

    ??? <property name=”target”>

    ??????? <ref bean=”timeBook”/>

    ??? </property>

    ??? <property name=”interceptorNames”>

    ???????? <list>

    ????????????? <value>log</value>

    ???????? </list>

    ??? </property>

    </bean>*/

    </beans>

    ?

    3 、總結

    實際上, DefaultAdvisorAutoProxyCreator ProxyFactoryBean 就是兩種代理類,前者是自動的將 Advisor 和目標類聯系起來,后者是通過指定的方式,將目標類和 Advisor 組合起來。

    advisor ,對應的就是 org.springframework.aop.support.RegexpMethodPointcutAdvisor ,通過正則表達式來匹配類中的方法(設定 Pointcut )。

    (二)Spring四種通知(Advice)形式

    1 Interception Around通知

    ?????? 1 )負責輸出日志的類

    import org.aopalliance.intercept.MethodInterceptor;

    import org.aopalliance.intercept.MethodInvocation;

    import org.apache.log4j.Level;

    import org.apache.log4j.Logger;

    ?

    public class LogAround implements MethodInterceptor{

    ????? private Logger logger = Logger.getLogger(this.getClass().getName());

    ???

    ??? public Objectinvoke(MethodInvocation methodInvocation) throws Throwable {

    ?????????? logger.log(Level.INFO, methodInvocation.getArguments()[0] + " 開始審核數據....");?

    ??????? try {

    ????????? Object result = methodInvocation.proceed();

    ????????? return result;

    ??????? }

    ??????? finally {

    ???????????????? logger.log(Level.INFO, methodInvocation.getArguments()[0] + " 審核數據結束....");

    ??????? }???????

    ?? }

    }?????

    ? 2 )配置文件

    <?xml version="1.0" encoding="UTF-8"?>

    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"

    ?"http://www.springframework.org/dtd/spring-beans.dtd">

    <beans>

    <bean id="log" class="com.gc.action.Log Aop "/>

    <bean id="timeBook" class="com.gc.action. timeBook "/>

    <bean id=”logProxy” class=”org.springframework.aop.framework.ProxyFactor

    yBean”>

    ??? <property name=”proxyInterfaces”>

    ??????? <value>com.gc.impl.TimeBookInterface</value>

    ??? </property>

    ??? <property name=”target”>

    ??????? <ref bean=”timeBook”/>

    ??? </property>

    ??? <property name=”interceptorNames”>

    ???????? <list>

    ????????????? <value>log</value>

    ???????? </list>

    ??? </property>

    </bean>

    </beans>

    ?

    ?

    2 Before通知

    1 )負責輸出日志的類

    import java.lang.reflect.Method;

    ?

    import org.apache.log4j.Level;

    import org.apache.log4j.Logger;

    import org.springframework.aop.MethodBeforeAdvice;

    ?

    public class LogBefore implements MethodBeforeAdvice {

    ?????? private Logger logger = Logger.getLogger(this.getClass().getName());

    ???

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

    ????????????? logger.log(Level.INFO, args[0] + " 開始審核數據 ....");

    ?? }

    }

    2 )配置文件

    ???? 與第 1 種方法相同。

    3 After Returning通知

    1 )負責輸出日志的類

    import java.lang.reflect.Method;

    ?

    import org.apache.log4j.Level;

    import org.apache.log4j.Logger;

    import org.springframework.aop.AfterReturningAdvice;

    ?

    public class LogAfterReturning implements AfterReturningAdvice {

    ?????? private Logger logger = Logger.getLogger(this.getClass().getName());

    ???

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

    ????????????? logger.log(Level.INFO, args[0] + " 開始審核數據 ....");

    ?? }

    }

    2 )配置文件

    ???? 與第 1 種方法相同。

    4 Throw通知

    1 )負責輸出日志的類

    import java.lang.reflect.Method;

    ?

    import org.apache.log4j.Level;

    import org.apache.log4j.Logger;

    import org.springframework.aop.ThrowsAdvice;

    ?

    public class LogThrow implements ThrowsAdvice {

    ?????? private Logger logger = Logger.getLogger(this.getClass().getName());

    ???

    ??? public void afterThrowing(Method method, Object[] args, Object target,Throwable subclass) throws Throwable {

    ????????????? logger.log(Level.INFO, args[0] + " 開始審核數據 ....");

    ?? }

    }

    2 )配置文件

    ???? 與第 1 種方法相同。

    5 、測試程序

    ?? 1 )使用自動代理

    public class TestHelloWorld {

    ?????? public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException {

    ????????????? ApplicationContext actx=new FileSystemXmlApplicationContext("config.xml");

    ????????????? TimeBookInterface timeBookProxy = (TimeBookInterface)actx.getBean("timeBook");

    ????????????? timeBookProxy.doAuditing(" 張三 ");

    ?? 2 )不使用自動代理

    public class TestHelloWorld {

    ?????? public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException {

    ????????????? ApplicationContext actx=new FileSystemXmlApplicationContext("config.xml");

    ????????????? TimeBookInterface timeBookProxy = (TimeBookInterface)actx.getBean("logProxy");

    ????????????? timeBookProxy.doAuditing(" 張三 ");

    使用自動代理,則直接調用該類的名字( timeBook ),否則調用相應的代理 bean logProxy )。因為第 1 種方法中根本就沒有對應的代理 bean ,只有一個 Spring 的自動代理類

    ?

    (三)Spring兩種代理方式

    1 Java動態代理

    1 )配制文件(不使用自動代理)

    <?xml version="1.0" encoding="UTF-8"?>

    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"

    ?"http://www.springframework.org/dtd/spring-beans.dtd">

    <beans>

    <bean id="log" class="com.gc.action.Log Aop "/>

    <bean id="timeBook" class="com.gc.action. timeBook "/>

    <bean id=”logProxy” class=”org.springframework.aop.framework.ProxyFactor

    yBean”>

    ??? <property name=”proxyInterfaces”>

    ??????? <value>com.gc.impl.TimeBookInterface</value>

    ??? </property>

    ??? <property name=”target”>

    ??????? <ref bean=”timeBook”/>

    ??? </property>

    ??? <property name=”interceptorNames”>

    ???????? <list>

    ????????????? <value>log</value>

    ???????? </list>

    ??? </property>

    </bean>

    </beans>

    ?

    2 )測試程序

    public class TestHelloWorld {

    ?????? public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException {

    ????????????? ApplicationContext actx=new FileSystemXmlApplicationContext("config.xml");

    ????????????? TimeBookInterface timeBookProxy = (TimeBookInterface)actx.getBean("logProxy");

    ????????????? timeBookProxy.doAuditing(" 張三 ");

    ?

    2 CGLIB代理

    1 )配制文件(不使用自動代理)

    <?xml version="1.0" encoding="UTF-8"?>

    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"

    ?"http://www.springframework.org/dtd/spring-beans.dtd">

    <beans>

    <bean id="log" class="com.gc.action.Log Aop "/>

    <bean id="timeBook" class="com.gc.action. timeBook "/>

    <bean id=”logProxy” class=”org.springframework.aop.framework.ProxyFactor

    yBean”>

    // 增加如下屬性,就表示使用的是CGLIB代理(對目標類直接代理)

    ??? <property name=”proxyTargetClass”>

    ??????? <value>true</value>

    ??? </property>

    ?? /* 然后去掉下面的屬性,也就是說此種方法不需要面向接口,或不需要指出接口

    <property name=”proxyInterfaces”>

    ??????? <value>com.gc.impl.TimeBookInterface</value>

    ??? </property>*/

    ??? <property name=”target”>

    ??????? <ref bean=”timeBook”/>

    ??? </property>

    ??? <property name=”interceptorNames”>

    ???????? <list>

    ??????????? ??<value>log</value>

    ???????? </list>

    ??? </property>

    </bean>

    </beans>

    ?

    2 )測試程序

    public class TestHelloWorld {

    ?????? public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException {

    ????????????? ApplicationContext actx=new FileSystemXmlApplicationContext("config.xml");

    ????????????? TimeBookInterface timeBookProxy = (TimeBookInterface)actx.getBean("logProxy");

    ????????????? timeBookProxy.doAuditing(" 張三 ");

    ?

    ?


    ?[U1] Join Point

    ?[U2] Advice

    ?[U3] 這個名字自己可以隨便起

    ?[U4] 如果想對類的所有方法都有效,就要寫成 .*.*

    posted on 2007-01-31 17:10 零雨其蒙 閱讀(1807) 評論(1)  編輯  收藏 所屬分類: 學習筆記

    評論

    # re: Spring中的AOP  回復  更多評論   

    最近也在學習Spring,強烈支持,多多交流哦!
    2007-02-01 00:33 | 施偉
    主站蜘蛛池模板: 亚洲人成777在线播放| 精品国产免费观看久久久| 三年片在线观看免费西瓜视频| 国产精品亚洲专一区二区三区| 亚洲色偷偷偷综合网| 久久精品国产99国产精品亚洲| 亚洲国产av美女网站| 亚洲午夜电影在线观看高清 | 日韩欧毛片免费视频| 精品国产sm捆绑最大网免费站| 99re在线这里只有精品免费| 亚洲偷自拍拍综合网| 亚洲国产成人VA在线观看| 亚洲国产精品成人一区| 亚洲男人第一无码aⅴ网站| 亚洲精品国产V片在线观看| 久久久久亚洲AV成人网| 久久亚洲中文字幕精品一区四| 91麻豆国产自产在线观看亚洲| 亚洲综合日韩久久成人AV| 亚洲色偷拍另类无码专区| 国产亚洲精品a在线观看app| 亚洲av日韩综合一区在线观看| 亚洲乱亚洲乱淫久久| 亚洲高清免费在线观看| 亚洲天堂2016| 亚洲av成人中文无码专区| 亚洲a无码综合a国产av中文| jyzzjyzz国产免费观看| 精品国产一区二区三区免费| 久久A级毛片免费观看| 欧洲黑大粗无码免费| 国产91在线免费| 国精无码欧精品亚洲一区| 亚洲综合视频在线观看| 亚洲熟妇AV乱码在线观看| 野花视频在线官网免费1| 国产中文字幕在线免费观看| 131美女爱做免费毛片| 免费无码黄网站在线观看| 久久亚洲AV无码西西人体|