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

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

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

    Chan Chen Coding...

    Spring AOP

    Spring AOP 簡單理解

    AOP技術即(面向切面編程)技術是在面向對象編程基礎上的發展,AOP技術是對所有對象或一類對象編程。核心是在不增加代碼的基礎上,還增加了新的功能。AOP編程在開發框架本身用的比較多,而實際項目中,用的比較少。它是將分散在各個業務邏輯代碼中的相同代碼抽取出來形成一個獨立的模塊。

    1、定義AOP術語

    (1)切面(aspect):要實現的交叉功能,是系統模塊化的一個切面或領域。

    (2)通知(advice):切面的具體實現,包含五類通知。

    (3)連接點(jointpoint):應用程序執行過程中插入切面的地點。

    (4)切點(cutpoint):定義通知應該應用哪些連接點。

    (5)引入(introduction):為類添加新方法和屬性。

    (6)目標對象(target):通知邏輯的織入目標類。

    (7)代理(proxy):將通知應用到目標對象后創建的對象,應用系統的其他部分不用為了支持代理對象而改變

    (8)織入(weaving):將切面應用到目標對象從而創建一個新代理對象的過程。

     

    2、AOP原理和實例

    (1)基礎接口和類的實現:

    package com.jasson.aop;

    public interface TestServiceInter1 {

        public void sayHello();
    }


    package com.jasson.aop;

    public interface TestServiceInter2 {

        public void sayBye();
        
        public void sayHi();
    }

    (2)實現類如下:
    package com.jasson.aop;

    public class TestService implements TestServiceInter1,TestServiceInter2 {

        public void sayHello() {
            System.out.println("sayHello() method ");
        }

        public void sayBye() {
            System.out.println("sayBye() method");
        }
        
        public void sayHi() {
            System.out.println("sayHi() method");
        }
    }

    (1)前置通知:要求在每個方法調用前進行日志記錄,則用的前置通知,定義如下:

    package com.jasson.aop;

    import java.lang.reflect.Method;

    import org.springframework.aop.MethodBeforeAdvice;

    public class MyMethodBeforeAdvice implements MethodBeforeAdvice {

        /**
         * method: 方法名
         * args: 輸入參數
         * target: 目標對象
         
    */
        public void before(Method method, Object[] args, Object target)
                throws Throwable {
            System.out.println("前置通知調用 記錄日志"+method.getName());
        }
    }

    配置文件如下:

     

    <?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:context="http://www.springframework.org/schema/context"
            xmlns:tx="http://www.springframework.org/schema/tx"
            xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
                    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
                    >
    <!-- 配置被代理的對象,即目標對象 -->
    <bean id="testService" class="com.jasson.aop.TestService" />
    <!-- 配置前置通知 -->
    <bean id="myMethodBeforeAdvice" class="com.jasson.aop.MyMethodBeforeAdvice" />
    <!-- 配置代理對象 -->
    <bean id="proxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean">
        <!-- 代理接口集 -->
        <property name="proxyInterfaces">
            <list>
                <value>com.jasson.aop.TestServiceInter1</value>
                <value>com.jasson.aop.TestServiceInter2</value>
            </list>
        </property>
        <!-- 把通知織入到代理對象  -->
        <property name="interceptorNames">
            <!-- 相當于包MyMethodBeforeAdvice前置通知和代理對象關聯,我們也
            可以把通知看出攔截器,struts2核心攔截器 -->
            <list>
                <value>myMethodBeforeAdvice</value>
            </list>
        </property>
        <!-- 配置被代理對象,即目標對象 -->
        <property name="target" ref="testService"/>
    </bean>
    </beans>
     

    package com.jasson.aop;

    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;

    public class App1 {

        /**
         * 
    @param args
         
    */
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            ApplicationContext ac=new ClassPathXmlApplicationContext("com/jasson/aop/beans.xml");
            TestServiceInter1 ts=(TestServiceInter1) ac.getBean("proxyFactoryBean");
            ts.sayHello();
            System.out.println("*******************************************");
            ((TestServiceInter2)ts).sayBye();
            System.out.println("*******************************************");
            ((TestServiceInter2)ts).sayHi();
        }
    } 

     執行結果如下:

    31-May-2012 18:19:53 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
    INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@c8f6f8: defining beans [testService,myMethodBeforeAdvice,
    myAfterReturningAdvice,myMethodInterceptor,myThrowsAdvice,proxyFactoryBean]; root of factory hierarchy
    前置通知調用 記錄日志sayHello
    sayHello() method 
    *******************************************
    前置通知調用 記錄日志sayBye
    sayBye() method
    *******************************************
    前置通知調用 記錄日志sayHi
    sayHi() method

    (2)后置通知:要求在調用每個方法后執行的功能,例如在調用每個方法后關閉資源

     

    package com.jasson.aop;

    import java.lang.reflect.Method;

    import org.springframework.aop.AfterReturningAdvice;

    public class MyAfterReturningAdvice implements AfterReturningAdvice {

        @Override
        public void afterReturning(Object returnValue, Method method, Object[] arg,
                Object target) throws Throwable {
            // TODO Auto-generated method stub
            System.out.println("后置通知調用,關閉資源"+method.getName());
        }
    }
     bean 配置如下:
    <?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:context="http://www.springframework.org/schema/context"
            xmlns:tx="http://www.springframework.org/schema/tx"
            xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
                    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
                    >
    <!-- 配置被代理的對象,即目標對象 -->
    <bean id="testService" class="com.jasson.aop.TestService" />
    <!-- 配置前置通知 -->
    <bean id="myMethodBeforeAdvice" class="com.jasson.aop.MyMethodBeforeAdvice" />
    <!-- 配置后置通知 -->
    <bean id="myAfterReturningAdvice" class="com.jasson.aop.MyAfterReturningAdvice" />
    <!-- 配置代理對象 -->
    <bean id="proxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean">
        <!-- 代理接口集 -->
        <property name="proxyInterfaces">
            <list>
                <value>com.jasson.aop.TestServiceInter1</value>
                <value>com.jasson.aop.TestServiceInter2</value>
            </list>
        </property>
        <!-- 把通知織入到代理對象  -->
        <property name="interceptorNames">
            <!-- 相當于包MyMethodBeforeAdvice前置通知和代理對象關聯,我們也
            可以把通知看出攔截器,struts2核心攔截器 -->
            <list>
                <value>myMethodBeforeAdvice</value>
                <value>myAfterReturningAdvice</value>
            </list>
        </property>
        <!-- 配置被代理對象,即目標對象 -->
        <property name="target" ref="testService"/>
    </bean>
    </beans>

    執行結果如下:

     

    INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@122cdb6: defining beans [testService,myMethodBeforeAdvice,myAfterReturningAdvice,myMethodInterceptor,myThrowsAdvice,proxyFactoryBean]; root of factory hierarchy
    前置通知調用 記錄日志sayHello
    sayHello() method 
    后置通知調用,關閉資源sayHello
    *******************************************
    前置通知調用 記錄日志sayBye
    sayBye() method
    后置通知調用,關閉資源sayBye
    *******************************************
    前置通知調用 記錄日志sayHi
    sayHi() method

    后置通知調用,關閉資源sayHi 

    (3)環繞通知:指在某個具體的方法中,添加相應的操作

    package com.jasson.aop;

    import org.aopalliance.intercept.MethodInterceptor;
    import org.aopalliance.intercept.MethodInvocation;

    public class MyMethodInterceptor implements MethodInterceptor {

        @Override
        public Object invoke(MethodInvocation arg) throws Throwable {
            // TODO Auto-generated method stub
            System.out.println("環繞通知調用方法前");
            Object obj = arg.proceed();
            System.out.println("環繞通知調用方法后");
            return obj;
        }
    }

    配置文件如下:

    <?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:context="http://www.springframework.org/schema/context"
            xmlns:tx="http://www.springframework.org/schema/tx"
            xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
                    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
                    >
    <!-- 配置被代理的對象,即目標對象 -->
    <bean id="testService" class="com.jasson.aop.TestService" />
    <!-- 配置前置通知 -->
    <bean id="myMethodBeforeAdvice" class="com.jasson.aop.MyMethodBeforeAdvice" />
    <!-- 配置后置通知 -->
    <bean id="myAfterReturningAdvice" class="com.jasson.aop.MyAfterReturningAdvice" />
    <!-- 配置環繞通知 -->
    <bean id="myMethodInterceptor" class="com.jasson.aop.MyMethodInterceptor" />
    <!-- 配置代理對象 -->
    <bean id="proxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean">
        <!-- 代理接口集 -->
        <property name="proxyInterfaces">
            <list>
                <value>com.jasson.aop.TestServiceInter1</value>
                <value>com.jasson.aop.TestServiceInter2</value>
            </list>
        </property>
        <!-- 把通知織入到代理對象  -->
        <property name="interceptorNames">
            <!-- 相當于包MyMethodBeforeAdvice前置通知和代理對象關聯,我們也
            可以把通知看出攔截器,struts2核心攔截器 -->
            <list>
                <value>myMethodBeforeAdvice</value>
                <value>myAfterReturningAdvice</value>
                <value>myMethodInterceptor</value>
            </list>
        </property>
        <!-- 配置被代理對象,即目標對象 -->
        <property name="target" ref="testService"/>
    </bean>
    </beans>
     執行結果如下:
    INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1ce2dd4: defining beans [testService,myMethodBeforeAdvice,myAfterReturningAdvice,myMethodInterceptor,proxyFactoryBean]; root of factory hierarchy
    前置通知調用 記錄日志sayHello
    環繞通知調用方法前
    sayHello() method 
    環繞通知調用方法后
    后置通知調用,關閉資源sayHello
    *******************************************
    前置通知調用 記錄日志sayBye
    環繞通知調用方法前
    sayBye() method
    環繞通知調用方法后
    后置通知調用,關閉資源sayBye
    *******************************************
    前置通知調用 記錄日志sayHi
    環繞通知調用方法前
    sayHi() method
    環繞通知調用方法后
    后置通知調用,關閉資源sayHi
     (4)異常通知:當發生異常時,要執行的通知
    package com.jasson.aop;

    import java.lang.reflect.Method;

    import org.springframework.aop.ThrowsAdvice;

    public class MyThrowsAdvice implements ThrowsAdvice {

        public void afterThrowing(Method method, Object[] os, Object target,
                Exception exception) {

            System.out.println("異常通知產生異常,進行處理" + exception.getMessage());
        }
    }
     

     

    <?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:context="http://www.springframework.org/schema/context"
            xmlns:tx="http://www.springframework.org/schema/tx"
            xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
                    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
                    >
    <!-- 配置被代理的對象,即目標對象 -->
    <bean id="testService" class="com.jasson.aop.TestService" />
    <!-- 配置前置通知 -->
    <bean id="myMethodBeforeAdvice" class="com.jasson.aop.MyMethodBeforeAdvice" />
    <!-- 配置后置通知 -->
    <bean id="myAfterReturningAdvice" class="com.jasson.aop.MyAfterReturningAdvice" />
    <!-- 配置環繞通知 -->
    <bean id="myMethodInterceptor" class="com.jasson.aop.MyMethodInterceptor" />
    <!-- 配置異常通知 -->
    <bean id="myThrowsAdvice" class="com.jasson.aop.MyThrowsAdvice" />
    <!-- 配置代理對象 -->
    <bean id="proxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean">
        <!-- 代理接口集 -->
        <property name="proxyInterfaces">
            <list>
                <value>com.jasson.aop.TestServiceInter1</value>
                <value>com.jasson.aop.TestServiceInter2</value>
            </list>
        </property>
        <!-- 把通知織入到代理對象  -->
        <property name="interceptorNames">
            <!-- 相當于包MyMethodBeforeAdvice前置通知和代理對象關聯,我們也
            可以把通知看出攔截器,struts2核心攔截器 -->
            <list>
                <value>myMethodBeforeAdvice</value>
                <value>myAfterReturningAdvice</value>
                <value>myMethodInterceptor</value>
                <value>myThrowsAdvice</value>
            </list>
        </property>
        <!-- 配置被代理對象,即目標對象 -->
        <property name="target" ref="testService"/>
    </bean>
     

    package com.jasson.aop;

    public class TestService implements TestServiceInter1,TestServiceInter2 {

        public void sayHello() {
            System.out.println("sayHello() method ");
        }

        public void sayBye() {
            System.out.println("sayBye() method");
        }
        
        public void sayHi() {
            int a =10/0;
            System.out.println("sayHi() method");
        }
    }
     
    執行結果如下:
    INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1ce2dd4: defining beans [testService,myMethodBeforeAdvice,myAfterReturningAdvice,myMethodInterceptor,myThrowsAdvice,proxyFactoryBean]; root of factory hierarchy
    前置通知調用 記錄日志sayHello
    環繞通知調用方法前
    sayHello() method 
    環繞通知調用方法后
    后置通知調用,關閉資源sayHello
    *******************************************
    前置通知調用 記錄日志sayBye
    環繞通知調用方法前
    sayBye() method
    環繞通知調用方法后
    后置通知調用,關閉資源sayBye
    *******************************************
    前置通知調用 記錄日志sayHi
    環繞通知調用方法前
    異常通知產生異常,進行處理/ by zero
    Exception in thread "main" java.lang.ArithmeticException: / by zero 

    (5)上面的通知都是針對每個方法的,如果只是對單個或者一類的方法進行相應處理的時,可采用名字或者正則表達式的方式進行處理

    配置如下:

    <?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:context="http://www.springframework.org/schema/context"
            xmlns:tx="http://www.springframework.org/schema/tx"
            xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
                    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
                    >
    <!-- 配置被代理的對象,即目標對象 -->
    <bean id="testService" class="com.jasson.aop.TestService" />
    <!-- 配置前置通知 -->
    <bean id="myMethodBeforeAdvice" class="com.jasson.aop.MyMethodBeforeAdvice" />
    <!-- 配置后置通知 -->
    <bean id="myAfterReturningAdvice" class="com.jasson.aop.MyAfterReturningAdvice" />
    <!-- 配置環繞通知 -->
    <bean id="myMethodInterceptor" class="com.jasson.aop.MyMethodInterceptor" />
    <!-- 配置異常通知 -->
    <bean id="myThrowsAdvice" class="com.jasson.aop.MyThrowsAdvice" />

    <!-- 通知與正則表達式切入點一起配置 -->  
    <!-- Advisor等于切入點加通知,所有say開頭的方法添加前置通知 -->  
    <bean id="regexpPointcutAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">  
        <property name="advice" ref="myMethodBeforeAdvice"/>  
        <property name="patterns">  
            <list>  
                <value>.*say.*</value>  
            </list>  
        </property>  
    </bean>  

    <!-- 方法名匹配切入點配置器:只對 sayHello方法添加環繞通知-->  
    <bean id="namePointcutAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">  
        <property name="advice" ref="myMethodInterceptor"/>  
        <property name="mappedNames">  
            <list>  
                <value>sayHello</value>  
            </list>  
        </property>  
    </bean> 

    <!-- 配置代理對象 -->
    <bean id="proxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean">
        <!-- 代理接口集 -->
        <property name="proxyInterfaces">
            <list>
                <value>com.jasson.aop.TestServiceInter1</value>
                <value>com.jasson.aop.TestServiceInter2</value>
            </list>
        </property>
        <!-- 把通知織入到代理對象  -->
        <property name="interceptorNames">
            <!-- 相當于包MyMethodBeforeAdvice前置通知和代理對象關聯,我們也
            可以把通知看出攔截器,struts2核心攔截器 -->
            <list>
                <value>namePointcutAdvisor</value>
                <value>myAfterReturningAdvice</value>
                <value>regexpPointcutAdvisor</value>
                <value>myThrowsAdvice</value>
            </list>
        </property>
        <!-- 配置被代理對象,即目標對象 -->
        <property name="target" ref="testService"/>
    </bean>
    </beans>

    執行結果如下:

    INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1ef9157: defining beans 
    [testService,myMethodBeforeAdvice,myAfterReturningAdvice,myMethodInterceptor,myThrowsAdvice,regexpPointcutAdvisor,namePointcutAdvisor,proxyFactoryBean]; 
    root of factory hierarchy
    環繞通知調用方法前
    前置通知調用 記錄日志sayHello
    sayHello() method 
    后置通知調用,關閉資源sayHello
    環繞通知調用方法后
    *******************************************
    前置通知調用 記錄日志sayBye
    sayBye() method
    后置通知調用,關閉資源sayBye
    *******************************************
    前置通知調用 記錄日志sayHi
    異常通知產生異常,進行處理/ by zero
    Exception in thread "main" java.lang.ArithmeticException: / by zero


    -----------------------------------------------------
    Silence, the way to avoid many problems;
    Smile, the way to solve many problems;

    posted on 2012-12-27 11:30 Chan Chen 閱讀(216) 評論(0)  編輯  收藏 所屬分類: Scala / Java

    主站蜘蛛池模板: 国产AV旡码专区亚洲AV苍井空| 亚洲A∨无码无在线观看| 99亚偷拍自图区亚洲| 最近免费中文字幕高清大全| 久久精品国产亚洲AV网站| 在线毛片片免费观看| 亚洲成AV人片一区二区密柚| 久久国产乱子伦精品免费强| 亚洲AV中文无码字幕色三| 久久久高清日本道免费观看| 久久青青成人亚洲精品| 18禁美女黄网站色大片免费观看| 337p日本欧洲亚洲大胆艺术| 亚洲黄色免费网址| 亚洲色大成WWW亚洲女子| 国产在线a不卡免费视频| 一个人免费观看日本www视频| 亚洲国产精品成人一区| 中文字幕无码免费久久9一区9| 午夜亚洲www湿好大| 国产成人福利免费视频| 亚洲国产精品无码久久九九大片| 国产免费怕怕免费视频观看| 一个人免费观看视频在线中文| 亚洲网址在线观看你懂的| 黄页网站免费观看| 成人精品综合免费视频| 亚洲第一AAAAA片| 在线a级毛片免费视频| 一级做a爰片久久毛片免费陪 | 免费播放在线日本感人片| 亚洲美免无码中文字幕在线| 国产精品无码免费播放| 曰韩无码AV片免费播放不卡| 亚洲午夜久久影院| 国产一级淫片免费播放电影| 国产猛男猛女超爽免费视频| 亚洲色欲啪啪久久WWW综合网| 亚洲精品无码成人片久久| 91情侣在线精品国产免费| 男男gay做爽爽的视频免费|