1. 程式人生 > >結合Java例項程式碼來理解 AOP--面向切面程式設計 中的各個術語

結合Java例項程式碼來理解 AOP--面向切面程式設計 中的各個術語

因為這個AOP--面向切面程式設計是基於動態代理模式的,所以,要想搞清楚這個AOP,就必須得先了解下,什麼是代理模式什麼又是動態代理模式動態代理模式的2種實現方式。

現在假設,你已經可以看得懂動態代理模式的Java程式碼例子。把aop概念裡面的專業術語對應到實際程式碼中去。

下面是cglib實現的動態代理模式的Java程式碼

package com.lxk.designPattern.proxy.dynamicProxy.cglbDynamicProxy;

/**
 * 被代理的類
 * 目標物件類
 */
public class TargetObject {

    /**
     * 目標方法(即目標操作)
     */
    public void business() {
        System.out.println("business");
    }

}

package com.lxk.designPattern.proxy.dynamicProxy.cglbDynamicProxy;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * 動態代理-攔截器
 * <p>
 * Created by lxk on 2016/11/25
 */
public class MyInterceptor implements MethodInterceptor {
    private Object target;//目標類

    public MyInterceptor(Object target) {
        this.target = target;
    }

    /**
     * 返回代理物件
     * 具體實現,暫時先不追究。
     */
    public Object createProxy() {
        Enhancer enhancer = new Enhancer();
        enhancer.setCallback(this);//回撥函式  攔截器
        //設定代理物件的父類,可以看到代理物件是目標物件的子類。所以這個介面類就可以省略了。
        enhancer.setSuperclass(this.target.getClass());
        return enhancer.create();
    }

    /**
     * args 目標方法的引數
     * method 目標方法
     */
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        if(true){//不要在意這為什麼是恆成立的條件語句,為的是說明一個aop的概念:切入點。
            System.out.println("aaaaa");//切面方法a();
            //。。。
            method.invoke(this.target, objects);//呼叫目標類的目標方法
            //。。。
            System.out.println("bbbbb");//切面方法f();
        }
        return null;
    }
}

package com.lxk.designPattern.proxy.dynamicProxy.cglbDynamicProxy;

public class MainTest {
    public static void main(String[] args) {
        //目標物件
        TargetObject target = new TargetObject();
        //攔截器
        MyInterceptor myInterceptor = new MyInterceptor(target);
        //代理物件,呼叫cglib系統方法自動生成
        //注意:代理類是目標類的子類。
        TargetObject proxyObj = (TargetObject) myInterceptor.createProxy();
        proxyObj.business();
    }
}

上面程式碼,看完之後,就來對應AOP裡面的各個概念到實際程式碼裡面去


圖上說了5個術語。加上下面的織入,也就是6個啦。

再加上代理物件,這個就比較簡單了,測試程式碼有寫註釋啦。那麼就是一共7個啦。

唯一漏掉的就是“引入”,這個是系統自己實現的,我們就沒必要去深究了。

注意理解以下幾個概念:
代理物件的方法 = 目標物件的目標方法 + 所有切面的通知。
織入
形成代理物件的方法的過程

通知:實際上就是切面中的方法

切入點的理解:只有符合切入點的目標方法,才能載入通知。也就是呼叫切面的通知(方法)啦,看程式碼也就是說,切入點是控制代理物件內部的切面方法和目標物件的目標方法是否執行的條件。切面可以不止是一個。每個切面裡面的通知即切面方法也是可以有很多的。
連線點的理解:所謂連線點,也就是目標物件或者代理物件之中的方法。為什麼說2個都 可以呢?因為如果是jdk實現的動態代理的話,那麼目標物件和代理物件要實現共同的介面,如果是cglib實現的動態代理的話,那麼代理物件類是目標物件類的子類。都是一個方法啦。所以這麼理解就OK的啦。


現在就簡單的先了解下AOP的幾個概念術語。直接看文件的描述,表示真不是分分鐘就可以看得懂的,現在結合程式碼例項,然後來說明概念就好理解多啦。

下面是摘自文件spring.chm裡面的關於AOP的關鍵術語的描述:請欣賞,大學老師講課。

切面(Aspect):一個關注點的模組化,這個關注點可能會橫切多個物件。事務管理是J2EE應用中一個關於橫切關注點的很好的例子。在Spring AOP中,切面可以使用基於模式)或者基於@Aspect註解的方式來實現。 

連線點(Joinpoint):在程式執行過程中某個特定的點,比如某方法呼叫的時候或者處理異常的時候。在Spring AOP中,一個連線點總是表示一個方法的執行。

通知(Advice):在切面的某個特定的連線點上執行的動作。其中包括了“around”、“before”和“after”等不同型別的通知(通知的型別將在後面部分進行討論)。許多AOP框架(包括Spring)都是以攔截器做通知模型,並維護一個以連線點為中心的攔截器鏈。 

切入點(Pointcut):匹配連線點的斷言。通知和一個切入點表示式關聯,並在滿足這個切入點的連線點上執行(例如,當執行某個特定名稱的方法時)。切入點表示式如何和連線點匹配是AOP的核心:Spring預設使用AspectJ切入點語法。 

引入(Introduction):用來給一個型別宣告額外的方法或屬性(也被稱為連線型別宣告(inter-type declaration))。Spring允許引入新的介面(以及一個對應的實現)到任何被代理的物件。例如,你可以使用引入來使一個bean實現IsModified介面,以便簡化快取機制。 

目標物件(Target Object): 被一個或者多個切面所通知的物件。也被稱做被通知(advised)物件。 既然Spring AOP是通過執行時代理實現的,這個物件永遠是一個被代理(proxied)物件。 

AOP代理(AOP Proxy)AOP框架建立的物件,用來實現切面契約(例如通知方法執行等等)。在Spring中,AOP代理可以是JDK動態代理或者CGLIB代理。 

織入(Weaving):把切面連線到其它的應用程式型別或者物件上,並建立一個被通知的物件。這些可以在編譯時(例如使用AspectJ編譯器),類載入時和執行時完成。Spring和其他純Java AOP框架一樣,在執行時完成織入。 

上面的東西就算背會了,有卵用啊。就算你複製貼上的到處都是,有卵用啊。

在看了上面的例項程式碼之後,這下子知道所謂的切面是什麼意思了吧。後面再看看spring框架裡面到底是怎麼在使用這個aop的吧。後話了。

所以:我原來的那張圖就可以做如下的修改咯。