最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

AspectJ的基本用法

 更新時(shí)間:2017年04月07日 09:27:40   作者:Vonnie_Jade  
本文主要介紹了AspectJ的基本用法。具有很好的參考價(jià)值。下面跟著小編一起來看下吧

AOP雖然是方法論,但就好像OOP中的Java一樣,一些先行者也開發(fā)了一套語言來支持AOP。目前用得比較火的就是AspectJ了,它是一種幾乎和Java完全一樣的語言,而且完全兼容Java(AspectJ應(yīng)該就是一種擴(kuò)展Java,但它不是像Groovy[1]那樣的拓展。)。當(dāng)然,除了使用AspectJ特殊的語言外,AspectJ還支持原生的Java,只要加上對(duì)應(yīng)的AspectJ注解就好。所以,使用AspectJ有兩種方法:

完全使用AspectJ的語言。這語言一點(diǎn)也不難,和Java幾乎一樣,也能在AspectJ中調(diào)用Java的任何類庫。AspectJ只是多了一些關(guān)鍵詞罷了。

或者使用純Java語言開發(fā),然后使用AspectJ注解,簡(jiǎn)稱*@AspectJ*。

AspectJ的配置可以參考另一篇文章Android中使用AspectJ詳解

Join Points介紹

Join Points是AspectJ中的一個(gè)關(guān)鍵概念。Join Points可以看作是程序運(yùn)行時(shí)的一個(gè)執(zhí)行點(diǎn),比如:一個(gè)函數(shù)的調(diào)用可以看作是個(gè)Join Points,如Log.e()這個(gè)函數(shù),e()可以看作是個(gè)Join Points,而調(diào)運(yùn)e()的函數(shù)也可以認(rèn)為是一個(gè)Join Points;設(shè)置一個(gè)變量,或者讀取一個(gè)變量也可以是個(gè)Join Points;for循環(huán)也可以看作是Join Points。

理論上說,一個(gè)程序中很多地方都可以被看做是Join Points,但是AspectJ中,只有下面所示的幾種執(zhí)行點(diǎn)被認(rèn)為是Join Points:

Join Points 說明 示例
method call 函數(shù)調(diào)用 比如調(diào)用Log.e(),這是一處JPoint
method execution 函數(shù)執(zhí)行 比如Log.e()的執(zhí)行內(nèi)部,是一處Join Points。注意它和method call的區(qū)別。method call是調(diào)用某個(gè)函數(shù)的地方。而execution是某個(gè)函數(shù)執(zhí)行的內(nèi)部。
constructor call 構(gòu)造函數(shù)調(diào)用 和method call類似
constructor execution 構(gòu)造函數(shù)執(zhí)行 和method execution類似
field get 獲取某個(gè)變量 比如讀取DemoActivity.debug成員
field set 設(shè)置某個(gè)變量 比如設(shè)置DemoActivity.debug成員
pre-initialization Object在構(gòu)造函數(shù)中做得一些工作。
initialization Object在構(gòu)造函數(shù)中做得工作
static initialization 類初始化 比如類的static{}
handler 異常處理 比如try catch(xxx)中,對(duì)應(yīng)catch內(nèi)的執(zhí)行
advice execution 這個(gè)是AspectJ的內(nèi)容,稍后再說

這里列出了AspectJ所認(rèn)可的JoinPoints的類型。實(shí)際上,也就是你想把新的代碼插在程序的哪個(gè)地方,是插在構(gòu)造方法中,還是插在某個(gè)方法調(diào)用前,或者是插在某個(gè)方法中,這個(gè)地方就是Join Points,當(dāng)然,不是所有地方都能給你插的,只有能插的地方,才叫Join Points。

Pointcuts介紹

一個(gè)程序會(huì)有多個(gè)Join Points,即使同一個(gè)函數(shù),也還分為call和execution類型的Join Points,但并不是所有的Join Points都是我們關(guān)心的,Pointcuts就是提供一種使得開發(fā)者能夠選擇自己需要的JoinPoints的方法。

Advice

Advice就是我們插入的代碼以何種方式插入,有Before還有After、Around。

看個(gè)例子

@Before("execution(* android.app.Activity.on**(..))")
public void onActivityMethodBefore(JoinPoint joinPoint) throws Throwable {
}

這里會(huì)分成幾個(gè)部分,我們依次來看:

  • @Before:Advice,也就是具體的插入點(diǎn)
  • execution:處理Join Point的類型,例如call、execution
  • (* android.app.Activity.on**(..)):這個(gè)是最重要的表達(dá)式,第一個(gè)*表示返回值,*表示返回值為任意類型,后面這個(gè)就是典型的包名路徑,其中可以包含 * 來進(jìn)行通配,幾個(gè) * 沒區(qū)別。同時(shí),這里可以通過&&、||、!來進(jìn)行條件組合。()代表這個(gè)方法的參數(shù),你可以指定類型,例如android.os.Bundle,或者(..)這樣來代表任意類型、任意個(gè)數(shù)的參數(shù)。
  • public void onActivityMethodBefore:實(shí)際切入的代碼。

Before和After其實(shí)還是很好理解的,也就是在Pointcuts之前和之后,插入代碼,那么Around呢,從字面含義上來講,也就是在方法前后各插入代碼,是的,他包含了Before和After的全部功能,代碼如下:

@Around("execution(* com.xys.aspectjxdemo.MainActivity.testAOP())")
public void onActivityMethodAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
 String key = proceedingJoinPoint.getSignature().toString();
 Log.d(TAG, "onActivityMethodAroundFirst: " + key);
 proceedingJoinPoint.proceed();
 Log.d(TAG, "onActivityMethodAroundSecond: " + key);
}

其中,proceedingJoinPoint.proceed()代表執(zhí)行原始的方法,在這之前、之后,都可以進(jìn)行各種邏輯處理。

自定義Pointcuts

自定義Pointcuts可以讓我們更加精確的切入一個(gè)或多個(gè)指定的切入點(diǎn)。

首先我們要定義一個(gè)注解類

@Retention(RetentionPolicy.CLASS)
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD})
public @interface DebugTrace {
}

在需要插入代碼的地方加入這個(gè)注解。如在MainActivity中加入,

public class MainActivity extends AppCompatActivity {
 final String TAG = MainActivity.class.getSimpleName();

 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 logTest();
 }

 @DebugTrace
 public void logTest() {
 Log.e(TAG, "log test");
 }
}

最后,創(chuàng)建切入代碼

@Pointcut("execution(@com.kun.aspectjtest.aspect.DebugTrace * *..*.*(..))")
public void DebugTraceMethod() {}

@Before("DebugTraceMethod()")
public void beforeDebugTraceMethod(JoinPoint joinPoint) throws Throwable {
 String key = joinPoint.getSignature().toString();
 Log.e(TAG, "beforeDebugTraceMethod: " + key);
}

log如下

在AspectJ的切入點(diǎn)表達(dá)式中,我們前面都是使用的execution,實(shí)際上,還有一種類型——call,那么這兩種語法有什么區(qū)別呢,對(duì)于Call來說:

Call(Before)
Pointcut{
 Pointcut Method
}
Call(After)

對(duì)于Execution來說:

Pointcut{
 execution(Before)
 Pointcut Method
 execution(After)
}

withincode

這個(gè)語法通常來進(jìn)行一些切入點(diǎn)條件的過濾,作更加精確的切入控制。如下

public class MainActivity extends AppCompatActivity {
 final String TAG = MainActivity.class.getSimpleName();
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 aspectJ1();
 aspectJ2();
 aspectJ3();
 }
 public void aspectJTest() {
 Log.e(TAG, "execute aspectJTest");
 }
 public void aspectJ1(){
 aspectJTest();
 }
 public void aspectJ2(){
 aspectJTest();
 }
 public void aspectJ3(){
 aspectJTest();
 }
}

aspectJ1(),aspectJ2(),aspectJ3()都調(diào)用了aspectJTest方法,但只想在aspectJ2調(diào)用aspectJTest時(shí)插入代碼,這個(gè)時(shí)候就需要使用到Pointcut和withincode組合的方式,來精確定位切入點(diǎn)。

@Pointcut("(call(* *..aspectJTest()))&&withincode(* *..aspectJ2())")
public void invokeAspectJTestInAspectJ2() {
}

@Before("invokeAspectJTestInAspectJ2()")
public void beforeInvokeaspectJTestInAspectJ2(JoinPoint joinPoint) throws Throwable {
 Log.e(TAG, "method:" + getMethodName(joinPoint).getName());
}
private MethodSignature getMethodName(JoinPoint joinPoint) {
 if (joinPoint == null) return null;
 return (MethodSignature) joinPoint.getSignature();
}

log如下

04-02 23:44:40.681 12107-12107/ E/MainActivity: execute aspectJTest
04-02 23:44:40.681 12107-12107/ E/AspectTest: method:aspectJTest
04-02 23:44:40.681 12107-12107/ E/MainActivity: execute aspectJTest
04-02 23:44:40.681 12107-12107/ E/MainActivity: execute aspectJTest

以上就是Aspecj的基本使用方法,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來一定的幫助,同時(shí)也希望多多支持腳本之家!

相關(guān)文章

  • 阿里的Easyexcel讀取Excel文件的方法(最新版本)

    阿里的Easyexcel讀取Excel文件的方法(最新版本)

    這篇文章主要介紹了阿里的Easyexcel讀取Excel文件(最新版本)的方法,本文通過示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-12-12
  • Java的枚舉enum示例詳解

    Java的枚舉enum示例詳解

    這篇文章主要給大家介紹了關(guān)于Java的枚舉enum的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Java具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • Java入門基礎(chǔ)之Java的基本語法與Java所支持的數(shù)據(jù)類型

    Java入門基礎(chǔ)之Java的基本語法與Java所支持的數(shù)據(jù)類型

    這篇文章主要介紹了Java入門基礎(chǔ)之Java的基本語法與Java所支持的數(shù)據(jù)類型,熟悉語法和數(shù)據(jù)類型通常是了解一種編程語言的開始,需要的朋友可以參考下
    2016-02-02
  • springboot整合redis進(jìn)行數(shù)據(jù)操作(推薦)

    springboot整合redis進(jìn)行數(shù)據(jù)操作(推薦)

    springboot整合redis比較簡(jiǎn)單,并且使用redistemplate可以讓我們更加方便的對(duì)數(shù)據(jù)進(jìn)行操作。下面通過本文給大家分享springboot整合redis進(jìn)行數(shù)據(jù)操作的相關(guān)知識(shí),感興趣的朋友一起看看吧
    2017-10-10
  • Java Swing null絕對(duì)布局的實(shí)現(xiàn)示例

    Java Swing null絕對(duì)布局的實(shí)現(xiàn)示例

    這篇文章主要介紹了Java Swing null絕對(duì)布局的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • SpringBoot中的自動(dòng)裝配原理解析

    SpringBoot中的自動(dòng)裝配原理解析

    這篇文章主要介紹了SpringBoot中的自動(dòng)裝配原理解析,自動(dòng)裝配就是指 Spring 容器在不使用<constructor-arg>和<property>標(biāo)簽的情況下,可以自動(dòng)裝配(autowire)相互協(xié)作的Bean之間的關(guān)聯(lián)關(guān)系,將一個(gè) Bean注入其他Bean的Property中,需要的朋友可以參考下
    2023-08-08
  • Java中sleep()與wait()的區(qū)別總結(jié)

    Java中sleep()與wait()的區(qū)別總結(jié)

    因?yàn)樽罱鼘W(xué)習(xí)時(shí)正好碰到這兩個(gè)方法,就查閱相關(guān)資料,并通過程序?qū)崿F(xiàn),進(jìn)行區(qū)別總結(jié)一下,所以下面這篇文章主要給大家總結(jié)介紹了關(guān)于Java中sleep()與wait()區(qū)別的相關(guān)資料,需要的朋友可以參考,下面來一起看看吧。
    2017-05-05
  • java LRU算法介紹與用法示例

    java LRU算法介紹與用法示例

    這篇文章主要介紹了java LRU算法,簡(jiǎn)單介紹了LRU算法的概念并結(jié)合實(shí)例形式分析了LRU算法的具體使用方法,需要的朋友可以參考下
    2017-09-09
  • Spring Boot DevTools使用教程

    Spring Boot DevTools使用教程

    DevTools通過提供自動(dòng)重啟和LiveReload功能,使您更快、更輕松地開發(fā)Spring Boot應(yīng)用程序。這篇文章主要介紹了Spring Boot DevTools使用教程,需要的朋友可以參考下
    2018-11-11
  • SpringBoot中處理JSON日期格式方式

    SpringBoot中處理JSON日期格式方式

    SpringBoot中處理JSON日期格式主要有三種方式:使用@JsonFormat注解、配置默認(rèn)格式以及自定義Jackson的ObjectMapper,每種方式都有其適用場(chǎng)景,可以根據(jù)具體需求選擇合適的方法
    2025-02-02

最新評(píng)論

平安县| 汉源县| 日喀则市| 青田县| 阳朔县| 双柏县| 灵台县| 南溪县| 金堂县| 安塞县| 定安县| 庆安县| 永济市| 德昌县| 都昌县| 双辽市| 噶尔县| 京山县| 彰武县| 丁青县| 望江县| 德钦县| 枣阳市| 吉林省| 桂阳县| 万全县| 布拖县| 化德县| 荣成市| 洛扎县| 隆化县| 宁波市| 长沙县| 雷山县| 屏边| 桓台县| 交城县| 仙桃市| 拉孜县| 巴彦淖尔市| 鹤壁市|